X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/fe8ab488e9161c46dd9885d58fc52996dc0249ff..a39ff7e25e19b3a8c3020042a3872ca9ec9659f1:/bsd/netinet/in_gif.c diff --git a/bsd/netinet/in_gif.c b/bsd/netinet/in_gif.c index 66bf01c30..86a2b9920 100644 --- a/bsd/netinet/in_gif.c +++ b/bsd/netinet/in_gif.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2013 Apple Inc. All rights reserved. + * Copyright (c) 2000-2018 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -110,8 +110,13 @@ in_gif_output( struct ip iphdr; /* capsule IP header, host byte ordered */ int proto, error; u_int8_t tos; - struct ip_out_args ipoa = - { IFSCOPE_NONE, { 0 }, IPOAF_SELECT_SRCIF, 0 }; + struct ip_out_args ipoa; + + bzero(&ipoa, sizeof(ipoa)); + ipoa.ipoa_boundif = IFSCOPE_NONE; + ipoa.ipoa_flags = IPOAF_SELECT_SRCIF; + ipoa.ipoa_sotc = SO_TC_UNSPEC; + ipoa.ipoa_netsvctype = _NET_SERVICE_TYPE_UNSPEC; GIF_LOCK_ASSERT(sc); @@ -177,12 +182,12 @@ in_gif_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); + ip_ecn_ingress(ECN_NORMAL, &iphdr.ip_tos, &tos); else ip_ecn_ingress(ECN_NOCARE, &iphdr.ip_tos, &tos); /* prepend new IP header */ - M_PREPEND(m, sizeof (struct ip), M_DONTWAIT); + M_PREPEND(m, sizeof (struct ip), M_DONTWAIT, 0); if (m && mbuf_len(m) < sizeof (struct ip)) m = m_pullup(m, sizeof (struct ip)); if (m == NULL) { @@ -232,14 +237,14 @@ in_gif_output( } void -in_gif_input(m, off) - struct mbuf *m; - int off; +in_gif_input(struct mbuf *m, int off) { struct ifnet *gifp = NULL; struct ip *ip; int af, proto; - u_int8_t otos; + u_int8_t otos, old_tos; + int egress_success = 0; + int sum; ip = mtod(m, struct ip *); proto = ip->ip_p; @@ -267,10 +272,18 @@ 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 (gifp->if_flags & IFF_LINK1) { + old_tos = ip->ip_tos; + egress_success = ip_ecn_egress(ECN_NORMAL, &otos, &ip->ip_tos); + if (old_tos != ip->ip_tos) { + sum = ~ntohs(ip->ip_sum) & 0xffff; + sum += (~otos & 0xffff) + ip->ip_tos; + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); /* add carry */ + ip->ip_sum = htons(~sum & 0xffff); + } + } else + egress_success = ip_ecn_egress(ECN_NOCARE, &otos, &ip->ip_tos); break; } #endif @@ -288,9 +301,9 @@ in_gif_input(m, off) 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); + egress_success = ip_ecn_egress(ECN_NORMAL, &otos, &itos); else - ip_ecn_egress(ECN_NOCARE, &otos, &itos); + egress_success = ip_ecn_egress(ECN_NOCARE, &otos, &itos); ip6->ip6_flow &= ~htonl(0xff << 20); ip6->ip6_flow |= htonl((u_int32_t)itos << 20); break; @@ -301,6 +314,13 @@ in_gif_input(m, off) m_freem(m); return; } + + if (egress_success == 0) { + OSAddAtomic(1, &ipstat.ips_nogif); + m_freem(m); + return; + } + #ifdef __APPLE__ /* Replace the rcvif by gifp for dlil to route it correctly */ if (m->m_pkthdr.rcvif)