diff options
author | ume <ume@FreeBSD.org> | 2003-10-29 15:07:04 +0000 |
---|---|---|
committer | ume <ume@FreeBSD.org> | 2003-10-29 15:07:04 +0000 |
commit | b9fecc82d3e55cefb5fd427307272fed377b780a (patch) | |
tree | ff2af6160ee3c3b0bf6e218dc2107ae003e82cde /sys/netinet/in_gif.c | |
parent | f965698ed4683de29221f38b96189223a4cf0b2e (diff) | |
download | FreeBSD-src-b9fecc82d3e55cefb5fd427307272fed377b780a.zip FreeBSD-src-b9fecc82d3e55cefb5fd427307272fed377b780a.tar.gz |
add ECN support in layer-3.
- implement the tunnel egress rule in ip_ecn_egress() in ip_ecn.c.
make ip{,6}_ecn_egress() return integer to tell the caller that
this packet should be dropped.
- handle ECN at fragment reassembly in ip_input.c and frag6.c.
Obtained from: KAME
Diffstat (limited to 'sys/netinet/in_gif.c')
-rw-r--r-- | sys/netinet/in_gif.c | 37 |
1 files changed, 21 insertions, 16 deletions
diff --git a/sys/netinet/in_gif.c b/sys/netinet/in_gif.c index 3d2ff66..fd6397e 100644 --- a/sys/netinet/in_gif.c +++ b/sys/netinet/in_gif.c @@ -161,10 +161,8 @@ in_gif_output(ifp, family, m) /* version will be set in ip_output() */ iphdr.ip_ttl = ip_gif_ttl; iphdr.ip_len = m->m_pkthdr.len + sizeof(struct ip); - if (ifp->if_flags & IFF_LINK1) - ip_ecn_ingress(ECN_ALLOWED, &iphdr.ip_tos, &tos); - else - ip_ecn_ingress(ECN_NOCARE, &iphdr.ip_tos, &tos); + ip_ecn_ingress((ifp->if_flags & IFF_LINK1) ? ECN_ALLOWED : ECN_NOCARE, + &iphdr.ip_tos, &tos); /* prepend new IP header */ M_PREPEND(m, sizeof(struct ip), M_DONTWAIT); @@ -250,10 +248,12 @@ in_gif_input(m, off) return; } ip = mtod(m, struct ip *); - if (gifp->if_flags & IFF_LINK1) - ip_ecn_egress(ECN_ALLOWED, &otos, &ip->ip_tos); - else - ip_ecn_egress(ECN_NOCARE, &otos, &ip->ip_tos); + if (ip_ecn_egress((gifp->if_flags & IFF_LINK1) ? + ECN_ALLOWED : ECN_NOCARE, + &otos, &ip->ip_tos) == 0) { + m_freem(m); + return; + } break; } #endif @@ -261,7 +261,8 @@ in_gif_input(m, off) case IPPROTO_IPV6: { struct ip6_hdr *ip6; - u_int8_t itos; + u_int8_t itos, oitos; + af = AF_INET6; if (m->m_len < sizeof(*ip6)) { m = m_pullup(m, sizeof(*ip6)); @@ -269,13 +270,17 @@ in_gif_input(m, off) return; } ip6 = mtod(m, struct ip6_hdr *); - itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff; - if (gifp->if_flags & IFF_LINK1) - ip_ecn_egress(ECN_ALLOWED, &otos, &itos); - else - ip_ecn_egress(ECN_NOCARE, &otos, &itos); - ip6->ip6_flow &= ~htonl(0xff << 20); - ip6->ip6_flow |= htonl((u_int32_t)itos << 20); + itos = oitos = (ntohl(ip6->ip6_flow) >> 20) & 0xff; + if (ip_ecn_egress((gifp->if_flags & IFF_LINK1) ? + ECN_ALLOWED : ECN_NOCARE, + &otos, &itos) == 0) { + m_freem(m); + return; + } + if (itos != oitos) { + ip6->ip6_flow &= ~htonl(0xff << 20); + ip6->ip6_flow |= htonl((u_int32_t)itos << 20); + } break; } #endif /* INET6 */ |