diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2022-03-12 20:53:17 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2022-03-12 20:53:17 +0000 |
commit | d2a7d886624c56673a6d7ba7d6a7958d2be5b867 (patch) | |
tree | 483c16a36a4fcb97f66708a0d11f1e43f6fcbddf /sys/src/9/ip/icmp6.c | |
parent | c14ea9fdd1521ff9322f9af71b801e016622c0cd (diff) |
devip: implement network address translation routes
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.
Diffstat (limited to 'sys/src/9/ip/icmp6.c')
-rw-r--r-- | sys/src/9/ip/icmp6.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/sys/src/9/ip/icmp6.c b/sys/src/9/ip/icmp6.c index a4b4b50c8..5db8ef11b 100644 --- a/sys/src/9/ip/icmp6.c +++ b/sys/src/9/ip/icmp6.c @@ -711,9 +711,8 @@ icmpiput6(Proto *icmp, Ipifc *ifc, Block *bp) goto raise; } p = (IPICMP *)bp->rp; - /* get rid of fragment header if this is the first fragment */ - if(p->proto == FH && BLEN(bp) >= MinAdvise+IP6FHDR && MinAdvise > IP6HDR){ + if((p->vcf[0] & 0xF0) == IP_VER6 && p->proto == FH && BLEN(bp) >= MinAdvise+IP6FHDR && MinAdvise > IP6HDR){ Fraghdr6 *fh = (Fraghdr6*)(bp->rp + IP6HDR); if((nhgets(fh->offsetRM) & ~7) == 0){ /* first fragment */ p->proto = fh->nexthdr; @@ -725,9 +724,10 @@ icmpiput6(Proto *icmp, Ipifc *ifc, Block *bp) bp->rp -= IP6HDR; } } - if(p->proto != FH){ + if((p->vcf[0] & 0xF0) == IP_VER6 && p->proto != FH){ pr = Fsrcvpcolx(icmp->f, p->proto); if(pr != nil && pr->advise != nil) { + netlog(icmp->f, Logicmp, "advising %s!%I -> %I: %s\n", pr->name, p->src, p->dst, msg); (*pr->advise)(pr, bp, msg); return; } |