/*
- * Copyright (c) 2000-2013 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
#include <netinet/ip6.h>
#endif
-#if MROUTING
-#include <netinet/ip_mroute.h>
-#endif /* MROUTING */
-
#include <net/if_gif.h>
#include <net/net_osdep.h>
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);
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) {
}
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;
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
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;
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)