summaryrefslogtreecommitdiff
path: root/sys/src/9/ip
AgeCommit message (Collapse)Author
2022-11-20devip: lilu dallas multicast.cinap_lenrek
Allow accepting udp "connections" using a multicast local address. Before, it was only possible to receive multicast using the headers option. Having a connection orirented stream can be very usefull when receiving multicast audio data. One gets a "connection" for every source. Implement (optional) support for IGMPv2 and MLDv1. This can be usefull if bridges on the network have IGMP/MLD snooping enabled, and wont forward multicast traffic unless we report what we excpect. This is experimental for now, so the igmp protocol must be manually added to the kernel configuration.
2022-11-20icmp6: no need set vcf and ttl before ipoput6(), use MAXTTL instead of HOP_LIMITcinap_lenrek
2022-11-02kernel: Do not treat IPv6 ULA's as GUA's (thanks Arne Meyer)Jacob Moody
2022-10-08devip: use port/netif.h constants for ethermediumcinap_lenrek
2022-09-28devip: get rid of Ipifc.mintucinap_lenrek
All the mediums we have implemented know their minimum transmit unit. The minimum transfer unit is not adjustable so there is no point in caching it in the ip interface.
2022-09-28arp: move arp expire logic into own functioncinap_lenrek
Add arphit() function, handling validation and checking for maximum life-time of the enty as well as copying out the mac address.
2022-09-27arp: don't leak data in the padding of arp repliescinap_lenrek
2022-09-27arp: make sure arpresolve() only returns single packetcinap_lenrek
Due to locking changes, it is possible for arpresolve() to return multiple packets in the multicast case, resulting in etherbwrite() to fail assert(bp->list == nil). Ensure that arpresolve() always returns the first packet from the hold chain and frees the rest if any. For arpenter(), we want to transmit the whole chain of packets, so we detach them from the arp entry before calling arpresolve() and ignoring its result.
2022-09-25devip: fix ipv6 mss clampingcinap_lenrek
2022-09-18tcpmssclamp: pass correct size tcpmssclamp()cinap_lenrek
The len variable refers to the total length of a Block list in ipoputX(), but we need to pass the size of the buffer we pass instead, which can be less if there are multiple blocks.
2022-09-18devip: less stupid hnputs_csum()cinap_lenrek
2022-09-17tcpmssclamp: only check the first ipv4 fragment for tcp headercinap_lenrek
2022-09-17devip: do tcp mss clamping when forwarding packetscinap_lenrek
when forwarding packets (gating), unconditionally check tcp-syn packets for the mss-size option and reduce it to fit the mtu of the outgoing interface. this is done by exporting a new tcpmssclamp() function from ip/tcp.c that takes an ip packet and its buffer size and the effective mtu of the interface and adjusts the mss value of tcp syn options. this function is now also used by devbridge, enforcing a tcp mss below the tunnel mtu.
2022-09-03devip: make Rproxy flag explicitcinap_lenrek
2022-09-03devip: replicate the nat-flag (Rtrans) when superceding interface routecinap_lenrek
Superceding interface routes is handled specially, only incrementing reference count, but need to take the new Rtrans flag into account.
2022-03-14ip(3): use flags instead of tag for 8 column route add/removecinap_lenrek
This avoids ipconfig having to explicitely specify the tag when we want to set route type, as the tag can be provided implicitely thru the "tag" command.
2022-03-13devip: allow setting the "trans" flag on a logical interfacecinap_lenrek
This makes the interface route have the "t"-flag, which causes packets routed to the interface to get source translated.
2022-03-12devip: implement network address translation routescinap_lenrek
This adds a new route "t"-flag that enables network address translation, replacing the source address (and local port) of a forwarded packet to one of the outgoing interface. The state for a translation is kept in a new Translation structure, which contains two Iphash entries, so it can be inserted into the per protocol 4-tuple hash table, requiering no extra lookups. Translations have a low overhead (~200 bytes on amd64), so we can have many of them. They get reused after 5 minutes of inactivity or when the per protocol limit of 1000 entries is reached (then the one with longest inactivity is reused). The protocol needs to export a "forward" function that is responsible for modifying the forwarded packet, and then handle translations in its input function for iphash hits with Iphash.trans != 0. This patch also fixes a few minor things found during development: - Include the Iphash in the Conv structure, avoiding estra malloc - Fix ttl exceeded check (ttl < 1 -> ttl <= 1) - Router should not reply with ttl exceeded for multicast flows - Extra checks for icmp advice to avoid protocol confusions.
2022-02-16devip: dont hold ifc wlock during medium bind/unbindcinap_lenrek
Wlock()'ing the ifc causes a deadlock with Medium bind/unbind as the routine can walk /net, while ndb/dns or ndb/cs are currently blocked enumerating /net/ipifc/*. The fix is to have a fake medium, called "unbound", that is set temporarily during the call of Medium bind and unbind. That way, the interface rwlock can be released while bind/unbind is in progress. The ipifcunbind() routine will refuse to unbind a ifc that is currently assigned to the "unbound" medium, preventing any accidents.
2021-10-11devip: improve tcp error handling for ipoputcinap_lenrek
The ipoput4() and ipoput6() functions can raise an error(), which means before calling sndrst() or limbo() (from tcpiput()), we have to get rid of our blist by calling freeblist(bp). Makse sure to set the Block pointer to nil after freeing in ipiput() to avoid accidents. Fix wrong panic string in sndsynack, and make any sending functions like sndrst(), sndsynack() and tcpsendka() return the value of ipoput*(), so we can distinguish "no route" error. Add a Enoroute[] string constant. Both htontcp4() and htontcp6() can never return nil, as they will allocate new or resize the existing block. Remove the misleading error handling code that assumes that it can fail. Unlock proto on error in limborexmit() which can be raised from sndsynack() -> ipoput*() -> error(). Make sndsynack() pass a Routehint pointer to ipoput*() as it already did the route lookup, so we dont have todo it twice.
2021-10-11devip: add comment to ip.h explaining Routehint structcinap_lenrek
2021-10-10devip: properly rlock() the routelock for v4lookup() and v6lookup()cinap_lenrek
i'm not confident about mutating the route tree pointers and have concurrent readers walking the pointer chains. given that most route lookups are bypassed now for non-routing case and we are not building a high performance router here, lets play it safe.
2021-10-10devip: use top bit (type) | subnet-id for V6H() route hash macrocinap_lenrek
theres no structure in the lower 32 bits of an ipv6 address. use the top bit to distinguish special stuff like multicast and link-local addresses, and use the 16-bit subnet-id bits for the rest.
2021-10-09devip: cache arp entry in Routehintcinap_lenrek
Instead of having to do an arp hash table lookup for each outgoing ip packet, forward the Routehint pointer to the medium's bwrite() function and let it cache the arp entry pointer. This avoids route and arp hash table lookups for tcp, il and connection oriented udp. It also allows us to avoid multiple route and arp table lookups for the retransmits once an arp/neighbour solicitation response arrives.
2021-10-03devip: use better hashipa() macro, use RWlock for arp cachecinap_lenrek
2021-09-26devip: implement ipv4 arp timeout with icmp host unreachable notificationcinap_lenrek
The IPv4 ARP cache used to indefinitely buffer packets in the Arpent hold list. This is bad in case of a router, because it opens a 1 second (retransmit time) window to leak all the to be forwarded packets. This change makes the ipv4 arp code path similar to the IPv6 neighbour solicitation path, using the retransmit process to time out old entries (after 3 arp retransmits => 3 seconds). A new function arpcontinue() has been added that unifies the point when we schedule the (ipv6 sol retransmit) / (ipv4 arp timeout) and reduce the hold queue to the last packet and unlock the cache. As a bonus, we also now send a icmp host unreachable notification for the dropped packets.
2020-06-07devip: implement ipv6 support in ipmux packet filtercinap_lenrek
Added a ver= field to the filter to distinguish the ip version. By default, a filter is parsed as ipv6, and after parsing proto, src and dst fields are converted to ipv4. When no ver= field is specified, a ip version filter is implicitely added and both protocols are parsed. This change also gets rid of the fast compare types as the filed might not be aligned correctly in the packet. This also fixes the ifc= filter, as we have to check any local address.
2020-06-07devip: fix parseipmask() prototype in ip.hcinap_lenrek
2020-06-06devip: pick less surprising interface address in header for incoming UDP packetscinap_lenrek
We used to just return the first address of the incoming interface regardless of if the address matches the source ip type and scope. This change tries to find the best interface address that will match the source ip so it can be used as a source address when replying to the packet.
2020-05-10devip: fix ifc recursive rlock() deadlockcinap_lenrek
ipiput4() and ipiput6() are called with the incoming interface rlocked while ipoput4() and ipoput6() also rlock() the outgoing interface once a route has been found. it is common that the incoming and outgoing interfaces are the same recusive rlocking(). the deadlock happens when a reader holds the rlock for the incoming interface, then ip/ipconfig tries to add a new address, trying to wlock the interface. as there are still active readers on the ifc, ip/ipconfig process gets queued on the inteface RWlock. now the reader finds the outgoing route which has the same interface as the incoming packet and tries to rlock the ifc again. but now theres a writer queued, so we also go to sleep waiting four outselfs to release the lock. the solution is to never wait for the outgoing interface rlock, but instead use non-queueing canrlock() and if it cannot be acquired, discard the packet.
2020-01-05devip: fix packet loss when interface is wlockedcinap_lenrek
to prevent deadlock on media unbind (which is called with the interface wlock()'ed), the medias reader processes that unbind was waiting for used to discard packets when the interface could not be rlocked. this has the unfortunate side effect that when we change addresses on a interface that packets are getting lost. this is problematic for the processing of ipv6 router advertisements when multiple RA's are getting received in quick succession. this change removes that packet dropping behaviour and instead changes the unbind process to avoid the deadlock by wunlock()ing the interface temporarily while waiting for the reader processes to finish. the interface media is also changed to the mullmedium before unlocking (see the comment).
2019-11-10devip: use the routing table for local source ip address selectioncinap_lenrek
when making outgoing connections, the source ip was selected by just iterating from the first to the last interface and trying each local address until a route was found. the result was kind of hard to predict as it depends on the interface order. this change replaces the algorithm with the route lookup algorithm that we already have which takes more specific desination and source prefixes into account. so the order of interfaces does not matter anymore.
2019-09-21devip: fix permission checkingcinap_lenrek
permission checking had the "other" and "owner" bits swapped plus incoming connections where always owned by "network" instead of the owner of the listening connection. also, ipwstat() was not effective as the uid strings where not parsed. this fixes the permission checks for data/ctl/err file and makes incoming connections inherit the owner from the listening connection. we also allow ipwstat() to change ownership to the commonuser() or anyone if we are eve. we might have to add additional restrictions for none at a later point...
2019-05-22devip: if the server does not support TCP ws option, disable window scaling ↵cinap_lenrek
(thanks joe9) if the server responds without a window scale option in its syn-ack, disable window scaling alltogether as both sides need to understand the option.
2019-05-12devip: do not lock selftab in ipselftabread(), remove unused fields from Ipselfcinap_lenrek
the Ipselftab is designed to not require locking on read operation. locking the selftab in ipselftabread() risks deadlock when accessing the user buffer creates a fault. remove unused fields from the Ipself struct.
2019-05-11devip: reset speed and delay on bind, adjust burst on mtu change, ifc->m nil ↵cinap_lenrek
check, consistent error strings initialize the rate limits when the device gets bound, not when it is created. so that the rate limtis get reset to default when the ifc is reused. adjust the burst delay when the mtu is changed. this is to make sure that we allow at least one full sized packet burst. make a local copy of ifc->m before doing nil check as it can change under us when we do not have the ifc locked. specify Ebound[] and Eunbound[] error strings and use them consistently.
2019-05-11devip: make sure ifc is bound in add6 ctl commandcinap_lenrek
2019-05-11devip: remove unused c->car qlock, avoid potential deadlock in ↵cinap_lenrek
ipifcregisterproxy() remove references to the unused Conv.car qlock. ipifcregisterproxy() is called with the proxy ifc wlock'd, which means we cannot acquire the rwlock of the interfaces that will proxy for us because it is allowed to rlock() multiple ifc's in any order. to get arround this, we use canrlock() and skip the interface when we cannot acquire the lock. the ifc should get wlock'd only when we are about to modify the ifc or its lifc chain. that is when adding or removing addresses. wlock is not required when we addresses to the selfcache, which has its own qlock.
2019-05-11devip: avoid media bind/unbind kproc reader startup race, simplify etherbindcinap_lenrek
mark reader process pointers with (void*)-1 to mean not started yet. this avoids the race condition when media unbind happens before the kproc has set its Proc* pointer. then we would not post the note and the reader would continue running after unbind. etherbind can be simplified by reading the #lX/addr file to get the mac address, avoiding the temporary buffer.
2019-04-14devip: reject bad numeric ports (such as 9fs -> 9)cinap_lenrek
2019-03-07devip: ignore the evil bit in fragment info fieldcinap_lenrek
using ~IP_DF mask to select offset and "more fragments" bits includes the evil bit 15. so instead define a constant IP_FO for the fragment offset bits and use (IP_MF|IP_FO). that way the evil bit gets ignored and doesnt cause any useless calls to ipreassemble().
2019-03-07devip: ignore icmp advise about laggard fragmentscinap_lenrek
icmp has to advise protocols about the first fragment only. all other fragments should be ignored.
2019-03-04devip: ignore reserved fragment offset bitscinap_lenrek
2019-03-04devip: handle packet too big advise for icmp6, remove fragment headercinap_lenrek
2019-03-04devip: use common code in icmp for handling advisecinap_lenrek
2019-03-04devip: zero fragment offset after reassembly, remove tos magic, cleanupcinap_lenrek
2019-03-04devip: fix fragment forwardingcinap_lenrek
unfraglen() had the side effect that it would always copy the nexthdr field from the fragment header to the previous nexthdr field. this is fine when we reassemble packets but breaks fragments that we want to just forward unchanged.
2019-03-03devip: simplify ip reassembly functions, getting rid of Ipfrag.hlencinap_lenrek
given that we now keep the block size consistent with the ip packet size, the variable header part of the ip packet is just: BLEN(bp) - fp->flen == fp->hlen. fix bug in ip6reassemble() in the non-fragmented case: reload ih after ip header was moved before writing ih->ploadlen. use concatbloc() instead of pullupblock().
2019-03-03devip: fix block list handling for icmp/icmp6, use proper MinAdvise for icmp6cinap_lenrek
2019-03-03devip: fix ip fragmentation handling issues with header optionscinap_lenrek
some protocols assume that Ip4hdr.length[] and Ip6hdr.ploadlen[] are valid and not out of range within the block but this has not been verified. also, the ipv4 and ipv6 headers can have variable length options, which was not considered in the fragmentation and reassembly code. to make this sane, ipiput4() and ipiput6() now verify that everything is in range and trims to block to the expected size before it does any further processing. now blocklen() and Ip4hdr.length[] are conistent. ipoput4() and ipoput6() are simpler now, as they can rely on blocklen() only, not having a special routing case. ip fragmentation reassembly has to consider that fragments could arrive with different ip header options, so we store the header+option size in new Ipfrag.hlen field. unfraglen() has to make sure not to run past the buffer, and hadle the case when it encounters multiple fragment headers.