summaryrefslogtreecommitdiff
path: root/sys/src/9/ip/icmp6.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2022-03-12 20:53:17 +0000
committercinap_lenrek <cinap_lenrek@felloff.net>2022-03-12 20:53:17 +0000
commitd2a7d886624c56673a6d7ba7d6a7958d2be5b867 (patch)
tree483c16a36a4fcb97f66708a0d11f1e43f6fcbddf /sys/src/9/ip/icmp6.c
parentc14ea9fdd1521ff9322f9af71b801e016622c0cd (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.c6
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;
}