diff options
40 files changed, 306 insertions, 262 deletions
diff --git a/sys/net/if_stf.c b/sys/net/if_stf.c index 8578818..14116cc 100644 --- a/sys/net/if_stf.c +++ b/sys/net/if_stf.c @@ -678,23 +678,23 @@ stf_checkaddr6(sc, in6, inifp) return 0; } -void -in_stf_input(m, off) - struct mbuf *m; - int off; +int +in_stf_input(struct mbuf **mp, int *offp, int proto) { - int proto; struct stf_softc *sc; struct ip *ip; struct ip6_hdr *ip6; + struct mbuf *m; u_int8_t otos, itos; struct ifnet *ifp; + int off; - proto = mtod(m, struct ip *)->ip_p; + m = *mp; + off = *offp; if (proto != IPPROTO_IPV6) { m_freem(m); - return; + return (IPPROTO_DONE); } ip = mtod(m, struct ip *); @@ -703,7 +703,7 @@ in_stf_input(m, off) if (sc == NULL || (STF2IFP(sc)->if_flags & IFF_UP) == 0) { m_freem(m); - return; + return (IPPROTO_DONE); } ifp = STF2IFP(sc); @@ -719,7 +719,7 @@ in_stf_input(m, off) if (stf_checkaddr4(sc, &ip->ip_dst, NULL) < 0 || stf_checkaddr4(sc, &ip->ip_src, m->m_pkthdr.rcvif) < 0) { m_freem(m); - return; + return (IPPROTO_DONE); } otos = ip->ip_tos; @@ -728,7 +728,7 @@ in_stf_input(m, off) if (m->m_len < sizeof(*ip6)) { m = m_pullup(m, sizeof(*ip6)); if (!m) - return; + return (IPPROTO_DONE); } ip6 = mtod(m, struct ip6_hdr *); @@ -739,7 +739,7 @@ in_stf_input(m, off) if (stf_checkaddr6(sc, &ip6->ip6_dst, NULL) < 0 || stf_checkaddr6(sc, &ip6->ip6_src, m->m_pkthdr.rcvif) < 0) { m_freem(m); - return; + return (IPPROTO_DONE); } itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff; @@ -774,6 +774,7 @@ in_stf_input(m, off) ifp->if_ibytes += m->m_pkthdr.len; M_SETFIB(m, ifp->if_fib); netisr_dispatch(NETISR_IPV6, m); + return (IPPROTO_DONE); } /* ARGSUSED */ diff --git a/sys/net/if_stf.h b/sys/net/if_stf.h index cbaf670..07f585b 100644 --- a/sys/net/if_stf.h +++ b/sys/net/if_stf.h @@ -33,6 +33,6 @@ #ifndef _NET_IF_STF_H_ #define _NET_IF_STF_H_ -void in_stf_input(struct mbuf *, int); +int in_stf_input(struct mbuf **, int *, int); #endif /* _NET_IF_STF_H_ */ diff --git a/sys/netinet/igmp.c b/sys/netinet/igmp.c index 4e22948..5419bb5 100644 --- a/sys/netinet/igmp.c +++ b/sys/netinet/igmp.c @@ -1424,26 +1424,29 @@ out_locked: return (0); } -void -igmp_input(struct mbuf *m, int off) +int +igmp_input(struct mbuf **mp, int *offp, int proto) { int iphlen; struct ifnet *ifp; struct igmp *igmp; struct ip *ip; + struct mbuf *m; int igmplen; int minlen; int queryver; CTR3(KTR_IGMPV3, "%s: called w/mbuf (%p,%d)", __func__, m, off); + m = *mp; ifp = m->m_pkthdr.rcvif; + *mp = NULL; IGMPSTAT_INC(igps_rcv_total); ip = mtod(m, struct ip *); - iphlen = off; - igmplen = ntohs(ip->ip_len) - off; + iphlen = *offp; + igmplen = ntohs(ip->ip_len) - iphlen; /* * Validate lengths. @@ -1451,7 +1454,7 @@ igmp_input(struct mbuf *m, int off) if (igmplen < IGMP_MINLEN) { IGMPSTAT_INC(igps_rcv_tooshort); m_freem(m); - return; + return (IPPROTO_DONE); } /* @@ -1466,7 +1469,7 @@ igmp_input(struct mbuf *m, int off) if ((m->m_flags & M_EXT || m->m_len < minlen) && (m = m_pullup(m, minlen)) == 0) { IGMPSTAT_INC(igps_rcv_tooshort); - return; + return (IPPROTO_DONE); } ip = mtod(m, struct ip *); @@ -1479,7 +1482,7 @@ igmp_input(struct mbuf *m, int off) if (in_cksum(m, igmplen)) { IGMPSTAT_INC(igps_rcv_badsum); m_freem(m); - return; + return (IPPROTO_DONE); } m->m_data -= iphlen; m->m_len += iphlen; @@ -1492,7 +1495,7 @@ igmp_input(struct mbuf *m, int off) if (igmp->igmp_type != IGMP_DVMRP && ip->ip_ttl != 1) { IGMPSTAT_INC(igps_rcv_badttl); m_freem(m); - return; + return (IPPROTO_DONE); } switch (igmp->igmp_type) { @@ -1507,7 +1510,7 @@ igmp_input(struct mbuf *m, int off) } else { IGMPSTAT_INC(igps_rcv_tooshort); m_freem(m); - return; + return (IPPROTO_DONE); } switch (queryver) { @@ -1517,7 +1520,7 @@ igmp_input(struct mbuf *m, int off) break; if (igmp_input_v1_query(ifp, ip, igmp) != 0) { m_freem(m); - return; + return (IPPROTO_DONE); } break; @@ -1527,7 +1530,7 @@ igmp_input(struct mbuf *m, int off) break; if (igmp_input_v2_query(ifp, ip, igmp) != 0) { m_freem(m); - return; + return (IPPROTO_DONE); } break; @@ -1546,7 +1549,7 @@ igmp_input(struct mbuf *m, int off) srclen = sizeof(struct in_addr) * nsrc; if (nsrc * sizeof(in_addr_t) > srclen) { IGMPSTAT_INC(igps_rcv_tooshort); - return; + return (IPPROTO_DONE); } /* * m_pullup() may modify m, so pullup in @@ -1558,13 +1561,13 @@ igmp_input(struct mbuf *m, int off) m->m_len < igmpv3len) && (m = m_pullup(m, igmpv3len)) == NULL) { IGMPSTAT_INC(igps_rcv_tooshort); - return; + return (IPPROTO_DONE); } igmpv3 = (struct igmpv3 *)(mtod(m, uint8_t *) + iphlen); if (igmp_input_v3_query(ifp, ip, igmpv3) != 0) { m_freem(m); - return; + return (IPPROTO_DONE); } } break; @@ -1576,7 +1579,7 @@ igmp_input(struct mbuf *m, int off) break; if (igmp_input_v1_report(ifp, ip, igmp) != 0) { m_freem(m); - return; + return (IPPROTO_DONE); } break; @@ -1587,7 +1590,7 @@ igmp_input(struct mbuf *m, int off) IGMPSTAT_INC(igps_rcv_nora); if (igmp_input_v2_report(ifp, ip, igmp) != 0) { m_freem(m); - return; + return (IPPROTO_DONE); } break; @@ -1608,7 +1611,8 @@ igmp_input(struct mbuf *m, int off) * Pass all valid IGMP packets up to any process(es) listening on a * raw IGMP socket. */ - rip_input(m, off); + *mp = m; + return (rip_input(mp, offp, proto)); } diff --git a/sys/netinet/igmp_var.h b/sys/netinet/igmp_var.h index 8d91cc1..b8e5bf7 100644 --- a/sys/netinet/igmp_var.h +++ b/sys/netinet/igmp_var.h @@ -205,7 +205,7 @@ struct igmp_ifinfo * igmp_domifattach(struct ifnet *); void igmp_domifdetach(struct ifnet *); void igmp_ifdetach(struct ifnet *); -void igmp_input(struct mbuf *, int); +int igmp_input(struct mbuf **, int *, int); void igmp_slowtimo(void); SYSCTL_DECL(_net_inet_igmp); diff --git a/sys/netinet/in_gif.c b/sys/netinet/in_gif.c index 37a6efb..6ee1634 100644 --- a/sys/netinet/in_gif.c +++ b/sys/netinet/in_gif.c @@ -81,7 +81,7 @@ struct protosw in_gif_protosw = { .pr_protocol = 0/* IPPROTO_IPV[46] */, .pr_flags = PR_ATOMIC|PR_ADDR, .pr_input = in_gif_input, - .pr_output = (pr_output_t*)rip_output, + .pr_output = (pr_output_t *)rip_output, .pr_ctloutput = rip_ctloutput, .pr_usrreqs = &rip_usrreqs }; @@ -270,31 +270,34 @@ in_gif_output(struct ifnet *ifp, int family, struct mbuf *m) return (error); } -void -in_gif_input(struct mbuf *m, int off) +int +in_gif_input(struct mbuf **mp, int *offp, int proto) { + struct mbuf *m; struct ifnet *gifp = NULL; struct gif_softc *sc; struct ip *ip; int af; + int off; u_int8_t otos; - int proto; + m = *mp; ip = mtod(m, struct ip *); - proto = ip->ip_p; + off = *offp; + *mp = NULL; sc = (struct gif_softc *)encap_getarg(m); if (sc == NULL) { m_freem(m); KMOD_IPSTAT_INC(ips_nogif); - return; + return (IPPROTO_DONE); } gifp = GIF2IFP(sc); if (gifp == NULL || (gifp->if_flags & IFF_UP) == 0) { m_freem(m); KMOD_IPSTAT_INC(ips_nogif); - return; + return (IPPROTO_DONE); } otos = ip->ip_tos; @@ -309,14 +312,14 @@ in_gif_input(struct mbuf *m, int off) if (m->m_len < sizeof(*ip)) { m = m_pullup(m, sizeof(*ip)); if (!m) - return; + return (IPPROTO_DONE); } ip = mtod(m, struct ip *); if (ip_ecn_egress((gifp->if_flags & IFF_LINK1) ? ECN_ALLOWED : ECN_NOCARE, &otos, &ip->ip_tos) == 0) { m_freem(m); - return; + return (IPPROTO_DONE); } break; } @@ -331,7 +334,7 @@ in_gif_input(struct mbuf *m, int off) if (m->m_len < sizeof(*ip6)) { m = m_pullup(m, sizeof(*ip6)); if (!m) - return; + return (IPPROTO_DONE); } ip6 = mtod(m, struct ip6_hdr *); itos = oitos = (ntohl(ip6->ip6_flow) >> 20) & 0xff; @@ -339,7 +342,7 @@ in_gif_input(struct mbuf *m, int off) ECN_ALLOWED : ECN_NOCARE, &otos, &itos) == 0) { m_freem(m); - return; + return (IPPROTO_DONE); } if (itos != oitos) { ip6->ip6_flow &= ~htonl(0xff << 20); @@ -355,10 +358,10 @@ in_gif_input(struct mbuf *m, int off) default: KMOD_IPSTAT_INC(ips_nogif); m_freem(m); - return; + return (IPPROTO_DONE); } gif_input(m, af, gifp); - return; + return (IPPROTO_DONE); } /* diff --git a/sys/netinet/in_gif.h b/sys/netinet/in_gif.h index e1f4ae4..15cbef1 100644 --- a/sys/netinet/in_gif.h +++ b/sys/netinet/in_gif.h @@ -36,7 +36,7 @@ #define GIF_TTL 30 struct gif_softc; -void in_gif_input(struct mbuf *, int); +int in_gif_input(struct mbuf **, int *, int); int in_gif_output(struct ifnet *, int, struct mbuf *); int gif_encapcheck4(const struct mbuf *, int, int, void *); int in_gif_attach(struct gif_softc *); diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c index c6499bc..1600f8c 100644 --- a/sys/netinet/ip_carp.c +++ b/sys/netinet/ip_carp.c @@ -78,7 +78,6 @@ __FBSDID("$FreeBSD$"); #ifdef INET6 #include <netinet/icmp6.h> #include <netinet/ip6.h> -#include <netinet6/ip6protosw.h> #include <netinet6/in6_var.h> #include <netinet6/ip6_var.h> #include <netinet6/scope6_var.h> @@ -435,18 +434,22 @@ carp_hmac_verify(struct carp_softc *sc, uint32_t counter[2], * but it seems more efficient this way or not possible otherwise. */ #ifdef INET -void -carp_input(struct mbuf *m, int hlen) +int +carp_input(struct mbuf **mp, int *offp, int proto) { + struct mbuf *m = *mp; struct ip *ip = mtod(m, struct ip *); struct carp_header *ch; int iplen, len; + iplen = *offp; + *mp = NULL; + CARPSTATS_INC(carps_ipackets); if (!V_carp_allow) { m_freem(m); - return; + return (IPPROTO_DONE); } /* verify that the IP TTL is 255. */ @@ -456,7 +459,7 @@ carp_input(struct mbuf *m, int hlen) ip->ip_ttl, m->m_pkthdr.rcvif->if_xname); m_freem(m); - return; + return (IPPROTO_DONE); } iplen = ip->ip_hl << 2; @@ -467,14 +470,14 @@ carp_input(struct mbuf *m, int hlen) "on %s\n", __func__, m->m_len - sizeof(struct ip), m->m_pkthdr.rcvif->if_xname); m_freem(m); - return; + return (IPPROTO_DONE); } if (iplen + sizeof(*ch) < m->m_len) { if ((m = m_pullup(m, iplen + sizeof(*ch))) == NULL) { CARPSTATS_INC(carps_hdrops); CARP_DEBUG("%s: pullup failed\n", __func__); - return; + return (IPPROTO_DONE); } ip = mtod(m, struct ip *); } @@ -491,12 +494,12 @@ carp_input(struct mbuf *m, int hlen) m->m_pkthdr.len, m->m_pkthdr.rcvif->if_xname); m_freem(m); - return; + return (IPPROTO_DONE); } if ((m = m_pullup(m, len)) == NULL) { CARPSTATS_INC(carps_hdrops); - return; + return (IPPROTO_DONE); } ip = mtod(m, struct ip *); ch = (struct carp_header *)((char *)ip + iplen); @@ -508,11 +511,12 @@ carp_input(struct mbuf *m, int hlen) CARP_DEBUG("%s: checksum failed on %s\n", __func__, m->m_pkthdr.rcvif->if_xname); m_freem(m); - return; + return (IPPROTO_DONE); } m->m_data -= iplen; carp_input_c(m, ch, AF_INET); + return (IPPROTO_DONE); } #endif @@ -2058,13 +2062,13 @@ static struct protosw in_carp_protosw = { #ifdef INET6 extern struct domain inet6domain; -static struct ip6protosw in6_carp_protosw = { +static struct protosw in6_carp_protosw = { .pr_type = SOCK_RAW, .pr_domain = &inet6domain, .pr_protocol = IPPROTO_CARP, .pr_flags = PR_ATOMIC|PR_ADDR, .pr_input = carp6_input, - .pr_output = rip6_output, + .pr_output = (pr_output_t *)rip6_output, .pr_ctloutput = rip6_ctloutput, .pr_usrreqs = &rip6_usrreqs }; diff --git a/sys/netinet/ip_carp.h b/sys/netinet/ip_carp.h index 9f03d58..5b7e506 100644 --- a/sys/netinet/ip_carp.h +++ b/sys/netinet/ip_carp.h @@ -140,7 +140,7 @@ int carp_ioctl(struct ifreq *, u_long, struct thread *); int carp_attach(struct ifaddr *, int); void carp_detach(struct ifaddr *); void carp_carpdev_state(struct ifnet *); -void carp_input (struct mbuf *, int); +int carp_input(struct mbuf **, int *, int); int carp6_input (struct mbuf **, int *, int); int carp_output (struct ifnet *, struct mbuf *, const struct sockaddr *); diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index 8951182..97fb191 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -173,12 +173,14 @@ div_destroy(void) * IPPROTO_DIVERT is not in the real IP protocol number space; this * function should never be called. Just in case, drop any packets. */ -static void -div_input(struct mbuf *m, int off) +static int +div_input(struct mbuf **mp, int *offp, int proto) { + struct mbuf *m = *mp; KMOD_IPSTAT_INC(ips_noproto); m_freem(m); + return (IPPROTO_DONE); } /* diff --git a/sys/netinet/ip_encap.c b/sys/netinet/ip_encap.c index ce1319d..fcd048a 100644 --- a/sys/netinet/ip_encap.c +++ b/sys/netinet/ip_encap.c @@ -84,7 +84,6 @@ __FBSDID("$FreeBSD$"); #ifdef INET6 #include <netinet/ip6.h> #include <netinet6/ip6_var.h> -#include <netinet6/ip6protosw.h> #endif #include <machine/stdarg.h> @@ -115,18 +114,20 @@ encap_init(void) } #ifdef INET -void -encap4_input(struct mbuf *m, int off) +int +encap4_input(struct mbuf **mp, int *offp, int proto) { struct ip *ip; - int proto; + struct mbuf *m; struct sockaddr_in s, d; const struct protosw *psw; struct encaptab *ep, *match; - int prio, matchprio; + int matchprio, off, prio; + m = *mp; + off = *offp; ip = mtod(m, struct ip *); - proto = ip->ip_p; + *mp = NULL; bzero(&s, sizeof(s)); s.sin_family = AF_INET; @@ -188,14 +189,16 @@ encap4_input(struct mbuf *m, int off) psw = match->psw; if (psw && psw->pr_input) { encap_fillarg(m, match); - (*psw->pr_input)(m, off); + *mp = m; + (*psw->pr_input)(mp, offp, proto); } else m_freem(m); - return; + return (IPPROTO_DONE); } /* last resort: inject to raw socket */ - rip_input(m, off); + *mp = m; + return (rip_input(mp, offp, proto)); } #endif @@ -206,7 +209,7 @@ encap6_input(struct mbuf **mp, int *offp, int proto) struct mbuf *m = *mp; struct ip6_hdr *ip6; struct sockaddr_in6 s, d; - const struct ip6protosw *psw; + const struct protosw *psw; struct encaptab *ep, *match; int prio, matchprio; @@ -252,7 +255,7 @@ encap6_input(struct mbuf **mp, int *offp, int proto) if (match) { /* found a match */ - psw = (const struct ip6protosw *)match->psw; + psw = match->psw; if (psw && psw->pr_input) { encap_fillarg(m, match); return (*psw->pr_input)(mp, offp, proto); diff --git a/sys/netinet/ip_encap.h b/sys/netinet/ip_encap.h index 3b1a5ae..0b8dbd6 100644 --- a/sys/netinet/ip_encap.h +++ b/sys/netinet/ip_encap.h @@ -49,7 +49,7 @@ struct encaptab { }; void encap_init(void); -void encap4_input(struct mbuf *, int); +int encap4_input(struct mbuf **, int *, int); int encap6_input(struct mbuf **, int *, int); const struct encaptab *encap_attach(int, int, const struct sockaddr *, const struct sockaddr *, const struct sockaddr *, diff --git a/sys/netinet/ip_gre.c b/sys/netinet/ip_gre.c index 10fcbce..21a665a 100644 --- a/sys/netinet/ip_gre.c +++ b/sys/netinet/ip_gre.c @@ -92,12 +92,15 @@ static struct mbuf *gre_input2(struct mbuf *, int, u_char); * IPPROTO_GRE and a local destination address). * This really is simple */ -void -gre_input(struct mbuf *m, int off) +int +gre_input(struct mbuf **mp, int *offp, int proto) { - int proto; + struct mbuf *m; + int off; - proto = (mtod(m, struct ip *))->ip_p; + m = *mp; + off = *offp; + *mp = NULL; m = gre_input2(m, off, proto); @@ -105,8 +108,11 @@ gre_input(struct mbuf *m, int off) * If no matching tunnel that is up is found. We inject * the mbuf to raw ip socket to see if anyone picks it up. */ - if (m != NULL) - rip_input(m, off); + if (m != NULL) { + *mp = m; + rip_input(mp, offp, proto); + } + return (IPPROTO_DONE); } /* @@ -213,24 +219,26 @@ gre_input2(struct mbuf *m ,int hlen, u_char proto) * between IP header and payload */ -void -gre_mobile_input(struct mbuf *m, int hlen) +int +gre_mobile_input(struct mbuf **mp, int *offp, int proto) { struct ip *ip; struct mobip_h *mip; + struct mbuf *m; struct gre_softc *sc; int msiz; + m = *mp; if ((sc = gre_lookup(m, IPPROTO_MOBILE)) == NULL) { /* No matching tunnel or tunnel is down. */ m_freem(m); - return; + return (IPPROTO_DONE); } if (m->m_len < sizeof(*mip)) { m = m_pullup(m, sizeof(*mip)); if (m == NULL) - return; + return (IPPROTO_DONE); } ip = mtod(m, struct ip *); mip = mtod(m, struct mobip_h *); @@ -247,7 +255,7 @@ gre_mobile_input(struct mbuf *m, int hlen) if (m->m_len < (ip->ip_hl << 2) + msiz) { m = m_pullup(m, (ip->ip_hl << 2) + msiz); if (m == NULL) - return; + return (IPPROTO_DONE); ip = mtod(m, struct ip *); mip = mtod(m, struct mobip_h *); } @@ -257,7 +265,7 @@ gre_mobile_input(struct mbuf *m, int hlen) if (gre_in_cksum((u_int16_t *)&mip->mh, msiz) != 0) { m_freem(m); - return; + return (IPPROTO_DONE); } bcopy((caddr_t)(ip) + (ip->ip_hl << 2) + msiz, (caddr_t)(ip) + @@ -282,12 +290,13 @@ gre_mobile_input(struct mbuf *m, int hlen) if ((GRE2IFP(sc)->if_flags & IFF_MONITOR) != 0) { m_freem(m); - return; + return (IPPROTO_DONE); } m->m_pkthdr.rcvif = GRE2IFP(sc); netisr_queue(NETISR_IP, m); + return (IPPROTO_DONE); } /* diff --git a/sys/netinet/ip_gre.h b/sys/netinet/ip_gre.h index d2f3866..18d5302 100644 --- a/sys/netinet/ip_gre.h +++ b/sys/netinet/ip_gre.h @@ -31,6 +31,6 @@ */ #ifdef _KERNEL -void gre_input(struct mbuf *, int); -void gre_mobile_input(struct mbuf *, int); +int gre_input(struct mbuf **, int *, int); +int gre_mobile_input(struct mbuf **, int *, int); #endif /* _KERNEL */ diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c index 605060e..0073643 100644 --- a/sys/netinet/ip_icmp.c +++ b/sys/netinet/ip_icmp.c @@ -358,19 +358,22 @@ freeit: /* * Process a received ICMP message. */ -void -icmp_input(struct mbuf *m, int off) +int +icmp_input(struct mbuf **mp, int *offp, int proto) { struct icmp *icp; struct in_ifaddr *ia; + struct mbuf *m = *mp; struct ip *ip = mtod(m, struct ip *); struct sockaddr_in icmpsrc, icmpdst, icmpgw; - int hlen = off; - int icmplen = ntohs(ip->ip_len) - off; + int hlen = *offp; + int icmplen = ntohs(ip->ip_len) - *offp; int i, code; void (*ctlfunc)(int, struct sockaddr *, void *); int fibnum; + *mp = NULL; + /* * Locate icmp structure in mbuf, and check * that not corrupted and of at least minimum length. @@ -390,7 +393,7 @@ icmp_input(struct mbuf *m, int off) i = hlen + min(icmplen, ICMP_ADVLENMIN); if (m->m_len < i && (m = m_pullup(m, i)) == NULL) { ICMPSTAT_INC(icps_tooshort); - return; + return (IPPROTO_DONE); } ip = mtod(m, struct ip *); m->m_len -= hlen; @@ -602,7 +605,7 @@ reflect: ICMPSTAT_INC(icps_reflect); ICMPSTAT_INC(icps_outhist[icp->icmp_type]); icmp_reflect(m); - return; + return (IPPROTO_DONE); case ICMP_REDIRECT: if (V_log_redirect) { @@ -679,11 +682,13 @@ reflect: } raw: - rip_input(m, off); - return; + *mp = m; + rip_input(mp, offp, proto); + return (IPPROTO_DONE); freeit: m_freem(m); + return (IPPROTO_DONE); } /* diff --git a/sys/netinet/ip_icmp.h b/sys/netinet/ip_icmp.h index 9cabdb5..ca1e963 100644 --- a/sys/netinet/ip_icmp.h +++ b/sys/netinet/ip_icmp.h @@ -207,7 +207,7 @@ struct icmp { #ifdef _KERNEL void icmp_error(struct mbuf *, int, int, uint32_t, int); -void icmp_input(struct mbuf *, int); +int icmp_input(struct mbuf **, int *, int); int ip_next_mtu(int, int); #endif diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 3a24296..d622e01 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -726,7 +726,7 @@ ours: */ IPSTAT_INC(ips_delivered); - (*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen); + (*inetsw[ip_protox[ip->ip_p]].pr_input)(&m, &hlen, ip->ip_p); return; bad: m_freem(m); @@ -1715,13 +1715,18 @@ ip_rsvp_done(void) return 0; } -void -rsvp_input(struct mbuf *m, int off) /* XXX must fixup manually */ +int +rsvp_input(struct mbuf **mp, int *offp, int proto) { + struct mbuf *m; + + m = *mp; + *mp = NULL; if (rsvp_input_p) { /* call the real one if loaded */ - rsvp_input_p(m, off); - return; + *mp = m; + rsvp_input_p(mp, offp, proto); + return (IPPROTO_DONE); } /* Can still get packets with rsvp_on = 0 if there is a local member @@ -1731,13 +1736,15 @@ rsvp_input(struct mbuf *m, int off) /* XXX must fixup manually */ if (!V_rsvp_on) { m_freem(m); - return; + return (IPPROTO_DONE); } if (V_ip_rsvpd != NULL) { - rip_input(m, off); - return; + *mp = m; + rip_input(mp, offp, proto); + return (IPPROTO_DONE); } /* Drop the packet */ m_freem(m); + return (IPPROTO_DONE); } diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c index 35e552e..6c4a0d7 100644 --- a/sys/netinet/ip_mroute.c +++ b/sys/netinet/ip_mroute.c @@ -247,7 +247,7 @@ static const struct protosw in_pim_protosw = { .pr_protocol = IPPROTO_PIM, .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR, .pr_input = pim_input, - .pr_output = (pr_output_t*)rip_output, + .pr_output = (pr_output_t *)rip_output, .pr_ctloutput = rip_ctloutput, .pr_usrreqs = &rip_usrreqs }; @@ -1718,12 +1718,16 @@ X_ip_rsvp_force_done(struct socket *so __unused) } -static void -X_rsvp_input(struct mbuf *m, int off __unused) +static int +X_rsvp_input(struct mbuf **mp, int *offp, int proto) { + struct mbuf *m; + m = *mp; + *mp = NULL; if (!V_rsvp_on) m_freem(m); + return (IPPROTO_DONE); } /* @@ -2556,15 +2560,19 @@ pim_encapcheck(const struct mbuf *m, int off, int proto, void *arg) * (used by PIM-SM): the PIM header is stripped off, and the inner packet * is passed to if_simloop(). */ -void -pim_input(struct mbuf *m, int iphlen) +int +pim_input(struct mbuf **mp, int *offp, int proto) { + struct mbuf *m = *mp; struct ip *ip = mtod(m, struct ip *); struct pim *pim; + int iphlen = *offp; int minlen; int datalen = ntohs(ip->ip_len) - iphlen; int ip_tos; + *mp = NULL; + /* Keep statistics */ PIMSTAT_INC(pims_rcv_total_msgs); PIMSTAT_ADD(pims_rcv_total_bytes, datalen); @@ -2577,7 +2585,7 @@ pim_input(struct mbuf *m, int iphlen) CTR3(KTR_IPMF, "%s: short packet (%d) from %s", __func__, datalen, inet_ntoa(ip->ip_src)); m_freem(m); - return; + return (IPPROTO_DONE); } /* @@ -2595,7 +2603,7 @@ pim_input(struct mbuf *m, int iphlen) */ if (m->m_len < minlen && (m = m_pullup(m, minlen)) == 0) { CTR1(KTR_IPMF, "%s: m_pullup() failed", __func__); - return; + return (IPPROTO_DONE); } /* m_pullup() may have given us a new mbuf so reset ip. */ @@ -2620,7 +2628,7 @@ pim_input(struct mbuf *m, int iphlen) PIMSTAT_INC(pims_rcv_badsum); CTR1(KTR_IPMF, "%s: invalid checksum", __func__); m_freem(m); - return; + return (IPPROTO_DONE); } /* PIM version check */ @@ -2629,7 +2637,7 @@ pim_input(struct mbuf *m, int iphlen) CTR3(KTR_IPMF, "%s: bad version %d expect %d", __func__, (int)PIM_VT_V(pim->pim_vt), PIM_VERSION); m_freem(m); - return; + return (IPPROTO_DONE); } /* restore mbuf back to the outer IP */ @@ -2654,7 +2662,7 @@ pim_input(struct mbuf *m, int iphlen) CTR2(KTR_IPMF, "%s: register vif not set: %d", __func__, (int)V_reg_vif_num); m_freem(m); - return; + return (IPPROTO_DONE); } /* XXX need refcnt? */ vifp = V_viftable[V_reg_vif_num].v_ifp; @@ -2668,7 +2676,7 @@ pim_input(struct mbuf *m, int iphlen) PIMSTAT_INC(pims_rcv_badregisters); CTR1(KTR_IPMF, "%s: register packet size too small", __func__); m_freem(m); - return; + return (IPPROTO_DONE); } reghdr = (u_int32_t *)(pim + 1); @@ -2682,7 +2690,7 @@ pim_input(struct mbuf *m, int iphlen) PIMSTAT_INC(pims_rcv_badregisters); CTR1(KTR_IPMF, "%s: bad encap ip version", __func__); m_freem(m); - return; + return (IPPROTO_DONE); } /* verify the inner packet is destined to a mcast group */ @@ -2691,7 +2699,7 @@ pim_input(struct mbuf *m, int iphlen) CTR2(KTR_IPMF, "%s: bad encap ip dest %s", __func__, inet_ntoa(encap_ip->ip_dst)); m_freem(m); - return; + return (IPPROTO_DONE); } /* If a NULL_REGISTER, pass it to the daemon */ @@ -2730,7 +2738,7 @@ pim_input(struct mbuf *m, int iphlen) if (mcp == NULL) { CTR1(KTR_IPMF, "%s: m_copy() failed", __func__); m_freem(m); - return; + return (IPPROTO_DONE); } /* Keep statistics */ @@ -2766,9 +2774,10 @@ pim_input_to_daemon: * XXX: the outer IP header pkt size of a Register is not adjust to * reflect the fact that the inner multicast data is truncated. */ - rip_input(m, iphlen); + *mp = m; + rip_input(mp, offp, proto); - return; + return (IPPROTO_DONE); } static int diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h index b2251ac..4b4b135 100644 --- a/sys/netinet/ip_var.h +++ b/sys/netinet/ip_var.h @@ -234,15 +234,15 @@ void rip_init(void); #ifdef VIMAGE void rip_destroy(void); #endif -void rip_input(struct mbuf *, int); +int rip_input(struct mbuf **, int *, int); int rip_output(struct mbuf *, struct socket *, u_long); -void ipip_input(struct mbuf *, int); -void rsvp_input(struct mbuf *, int); +int ipip_input(struct mbuf **, int *, int); +int rsvp_input(struct mbuf **, int *, int); int ip_rsvp_init(struct socket *); int ip_rsvp_done(void); extern int (*ip_rsvp_vif)(struct socket *, struct sockopt *); extern void (*ip_rsvp_force_done)(struct socket *); -extern void (*rsvp_input_p)(struct mbuf *m, int off); +extern int (*rsvp_input_p)(struct mbuf **, int *, int); VNET_DECLARE(struct pfil_head, inet_pfil_hook); /* packet filter hooks */ #define V_inet_pfil_hook VNET(inet_pfil_hook) diff --git a/sys/netinet/pim_var.h b/sys/netinet/pim_var.h index d7c4493..ae876c9 100644 --- a/sys/netinet/pim_var.h +++ b/sys/netinet/pim_var.h @@ -72,7 +72,7 @@ struct pimstat { #ifdef _KERNEL -void pim_input(struct mbuf *, int); +int pim_input(struct mbuf **, int *, int); SYSCTL_DECL(_net_inet_pim); #endif diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c index 83c8f48..1c90d0c 100644 --- a/sys/netinet/raw_ip.c +++ b/sys/netinet/raw_ip.c @@ -124,7 +124,7 @@ int (*mrt_ioctl)(u_long, caddr_t, int); int (*legal_vif_num)(int); u_long (*ip_mcast_src)(int); -void (*rsvp_input_p)(struct mbuf *m, int off); +int (*rsvp_input_p)(struct mbuf **, int *, int); int (*ip_rsvp_vif)(struct socket *, struct sockopt *); void (*ip_rsvp_force_done)(struct socket *); #endif /* INET */ @@ -270,16 +270,18 @@ rip_append(struct inpcb *last, struct ip *ip, struct mbuf *n, * Setup generic address and protocol structures for raw_input routine, then * pass them along with mbuf chain. */ -void -rip_input(struct mbuf *m, int off) +int +rip_input(struct mbuf **mp, int *offp, int proto) { struct ifnet *ifp; + struct mbuf *m = *mp; struct ip *ip = mtod(m, struct ip *); - int proto = ip->ip_p; struct inpcb *inp, *last; struct sockaddr_in ripsrc; int hash; + *mp = NULL; + bzero(&ripsrc, sizeof(ripsrc)); ripsrc.sin_len = sizeof(ripsrc); ripsrc.sin_family = AF_INET; @@ -416,6 +418,7 @@ rip_input(struct mbuf *m, int off) IPSTAT_INC(ips_noproto); IPSTAT_DEC(ips_delivered); } + return (IPPROTO_DONE); } /* diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index ba624ba..6098f90 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -6108,9 +6108,14 @@ extern int *sctp_cpuarry; #endif -void -sctp_input(struct mbuf *m, int off) +int +sctp_input(struct mbuf **mp, int *offp, int proto) { + struct mbuf *m; + int off; + + m = *mp; + off = *offp; #if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP) struct ip *ip; struct sctphdr *sh; @@ -6130,7 +6135,7 @@ sctp_input(struct mbuf *m, int off) if (SCTP_BUF_LEN(m) < offset) { if ((m = m_pullup(m, offset)) == NULL) { SCTP_STAT_INCR(sctps_hdrops); - return; + return (IPPROTO_DONE); } } ip = mtod(m, struct ip *); @@ -6142,10 +6147,11 @@ sctp_input(struct mbuf *m, int off) } cpu_to_use = sctp_cpuarry[flowid % mp_ncpus]; sctp_queue_to_mcore(m, off, cpu_to_use); - return; + return (IPPROTO_DONE); } #endif sctp_input_with_port(m, off, 0); + return (IPPROTO_DONE); } #endif diff --git a/sys/netinet/sctp_var.h b/sys/netinet/sctp_var.h index 6f01289..31d93dd 100644 --- a/sys/netinet/sctp_var.h +++ b/sys/netinet/sctp_var.h @@ -326,7 +326,7 @@ int sctp_ctloutput(struct socket *, struct sockopt *); #ifdef INET void sctp_input_with_port(struct mbuf *, int, uint16_t); -void sctp_input(struct mbuf *, int); +int sctp_input(struct mbuf **, int *, int); #endif void sctp_pathmtu_adjustment(struct sctp_tcb *, uint16_t); diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index c4595e6..ce515d6 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -522,25 +522,26 @@ tcp6_input(struct mbuf **mp, int *offp, int proto) ip6 = mtod(m, struct ip6_hdr *); icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR, (caddr_t)&ip6->ip6_dst - (caddr_t)ip6); - return IPPROTO_DONE; + return (IPPROTO_DONE); } if (ia6) ifa_free(&ia6->ia_ifa); - tcp_input(m, *offp); - return IPPROTO_DONE; + return (tcp_input(mp, offp, proto)); } #endif /* INET6 */ -void -tcp_input(struct mbuf *m, int off0) +int +tcp_input(struct mbuf **mp, int *offp, int proto) { + struct mbuf *m = *mp; struct tcphdr *th = NULL; struct ip *ip = NULL; struct inpcb *inp = NULL; struct tcpcb *tp = NULL; struct socket *so = NULL; u_char *optp = NULL; + int off0; int optlen = 0; #ifdef INET int len; @@ -580,6 +581,9 @@ tcp_input(struct mbuf *m, int off0) isipv6 = (mtod(m, struct ip *)->ip_v == 6) ? 1 : 0; #endif + off0 = *offp; + m = *mp; + *mp = NULL; to.to_flags = 0; TCPSTAT_INC(tcps_rcvtotal); @@ -591,7 +595,7 @@ tcp_input(struct mbuf *m, int off0) m = m_pullup(m, sizeof(*ip6) + sizeof(*th)); if (m == NULL) { TCPSTAT_INC(tcps_rcvshort); - return; + return (IPPROTO_DONE); } } @@ -643,7 +647,7 @@ tcp_input(struct mbuf *m, int off0) if ((m = m_pullup(m, sizeof (struct tcpiphdr))) == NULL) { TCPSTAT_INC(tcps_rcvshort); - return; + return (IPPROTO_DONE); } } ip = mtod(m, struct ip *); @@ -706,7 +710,7 @@ tcp_input(struct mbuf *m, int off0) if (off > sizeof (struct tcphdr)) { #ifdef INET6 if (isipv6) { - IP6_EXTHDR_CHECK(m, off0, off, ); + IP6_EXTHDR_CHECK(m, off0, off, IPPROTO_DONE); ip6 = mtod(m, struct ip6_hdr *); th = (struct tcphdr *)((caddr_t)ip6 + off0); } @@ -720,7 +724,7 @@ tcp_input(struct mbuf *m, int off0) if ((m = m_pullup(m, sizeof (struct ip) + off)) == NULL) { TCPSTAT_INC(tcps_rcvshort); - return; + return (IPPROTO_DONE); } ip = mtod(m, struct ip *); th = (struct tcphdr *)((caddr_t)ip + off0); @@ -949,7 +953,7 @@ relocked: if (tcp_twcheck(inp, &to, th, m, tlen)) goto findpcb; INP_INFO_WUNLOCK(&V_tcbinfo); - return; + return (IPPROTO_DONE); } /* * The TCPCB may no longer exist if the connection is winding @@ -1138,7 +1142,7 @@ relocked: tcp_do_segment(m, th, so, tp, drop_hdrlen, tlen, iptos, ti_locked); INP_INFO_UNLOCK_ASSERT(&V_tcbinfo); - return; + return (IPPROTO_DONE); } /* * Segment flag validation for new connection attempts: @@ -1338,7 +1342,7 @@ relocked: * Everything already unlocked by syncache_add(). */ INP_INFO_UNLOCK_ASSERT(&V_tcbinfo); - return; + return (IPPROTO_DONE); } else if (tp->t_state == TCPS_LISTEN) { /* * When a listen socket is torn down the SO_ACCEPTCONN @@ -1378,7 +1382,7 @@ relocked: */ tcp_do_segment(m, th, so, tp, drop_hdrlen, tlen, iptos, ti_locked); INP_INFO_UNLOCK_ASSERT(&V_tcbinfo); - return; + return (IPPROTO_DONE); dropwithreset: TCP_PROBE5(receive, NULL, tp, mtod(m, const char *), tp, th); @@ -1428,6 +1432,7 @@ drop: free(s, M_TCPLOG); if (m != NULL) m_freem(m); + return (IPPROTO_DONE); } static void diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index 2ed00e2..5163f6e 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -654,7 +654,7 @@ char *tcp_log_vain(struct in_conninfo *, struct tcphdr *, void *, const void *); int tcp_reass(struct tcpcb *, struct tcphdr *, int *, struct mbuf *); void tcp_reass_flush(struct tcpcb *); -void tcp_input(struct mbuf *, int); +int tcp_input(struct mbuf **, int *, int); u_long tcp_maxmtu(struct in_conninfo *, struct tcp_ifcap *); u_long tcp_maxmtu6(struct in_conninfo *, struct tcp_ifcap *); void tcp_mss_update(struct tcpcb *, int, int, struct hc_metrics_lite *, diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 4b565fc..5860c57 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -368,10 +368,9 @@ udp_append(struct inpcb *inp, struct ip *ip, struct mbuf *n, int off, sorwakeup_locked(so); } -void -udp_input(struct mbuf *m, int off) +int +udp_input(struct mbuf **mp, int *offp, int proto) { - int iphlen = off; struct ip *ip; struct udphdr *uh; struct ifnet *ifp; @@ -380,11 +379,14 @@ udp_input(struct mbuf *m, int off) struct inpcbinfo *pcbinfo; struct ip save_ip; struct sockaddr_in udp_in; + struct mbuf *m; struct m_tag *fwd_tag; - int cscov_partial; - uint8_t pr; + int cscov_partial, iphlen; + m = *mp; + iphlen = *offp; ifp = m->m_pkthdr.rcvif; + *mp = NULL; UDPSTAT_INC(udps_ipackets); /* @@ -404,13 +406,12 @@ udp_input(struct mbuf *m, int off) if (m->m_len < iphlen + sizeof(struct udphdr)) { if ((m = m_pullup(m, iphlen + sizeof(struct udphdr))) == NULL) { UDPSTAT_INC(udps_hdrops); - return; + return (IPPROTO_DONE); } ip = mtod(m, struct ip *); } uh = (struct udphdr *)((caddr_t)ip + iphlen); - pr = ip->ip_p; - cscov_partial = (pr == IPPROTO_UDPLITE) ? 1 : 0; + cscov_partial = (proto == IPPROTO_UDPLITE) ? 1 : 0; /* * Destination port of 0 is illegal, based on RFC768. @@ -434,7 +435,7 @@ udp_input(struct mbuf *m, int off) */ len = ntohs((u_short)uh->uh_ulen); ip_len = ntohs(ip->ip_len) - iphlen; - if (pr == IPPROTO_UDPLITE && len == 0) { + if (proto == IPPROTO_UDPLITE && len == 0) { /* Zero means checksum over the complete packet. */ len = ip_len; cscov_partial = 0; @@ -444,7 +445,7 @@ udp_input(struct mbuf *m, int off) UDPSTAT_INC(udps_badlen); goto badunlocked; } - if (pr == IPPROTO_UDP) + if (proto == IPPROTO_UDP) m_adj(m, len - ip_len); } @@ -470,14 +471,14 @@ udp_input(struct mbuf *m, int off) else uh_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, htonl((u_short)len + - m->m_pkthdr.csum_data + pr)); + m->m_pkthdr.csum_data + proto)); uh_sum ^= 0xffff; } else { char b[9]; bcopy(((struct ipovly *)ip)->ih_x1, b, 9); bzero(((struct ipovly *)ip)->ih_x1, 9); - ((struct ipovly *)ip)->ih_len = (pr == IPPROTO_UDP) ? + ((struct ipovly *)ip)->ih_len = (proto == IPPROTO_UDP) ? uh->uh_ulen : htons(ip_len); uh_sum = in_cksum(m, len + sizeof (struct ip)); bcopy(b, ((struct ipovly *)ip)->ih_x1, 9); @@ -485,12 +486,12 @@ udp_input(struct mbuf *m, int off) if (uh_sum) { UDPSTAT_INC(udps_badsum); m_freem(m); - return; + return (IPPROTO_DONE); } } else UDPSTAT_INC(udps_nosum); - pcbinfo = get_inpcbinfo(pr); + pcbinfo = get_inpcbinfo(proto); if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) || in_broadcast(ip->ip_dst, ifp)) { struct inpcb *last; @@ -498,7 +499,7 @@ udp_input(struct mbuf *m, int off) struct ip_moptions *imo; INP_INFO_RLOCK(pcbinfo); - pcblist = get_pcblist(pr); + pcblist = get_pcblist(proto); last = NULL; LIST_FOREACH(inp, pcblist, inp_list) { if (inp->inp_lport != uh->uh_dport) @@ -592,7 +593,7 @@ udp_input(struct mbuf *m, int off) udp_append(last, ip, m, iphlen, &udp_in); INP_RUNLOCK(last); INP_INFO_RUNLOCK(pcbinfo); - return; + return (IPPROTO_DONE); } /* @@ -654,7 +655,7 @@ udp_input(struct mbuf *m, int off) goto badunlocked; *ip = save_ip; icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0); - return; + return (IPPROTO_DONE); } /* @@ -664,7 +665,7 @@ udp_input(struct mbuf *m, int off) if (inp->inp_ip_minttl && inp->inp_ip_minttl > ip->ip_ttl) { INP_RUNLOCK(inp); m_freem(m); - return; + return (IPPROTO_DONE); } if (cscov_partial) { struct udpcb *up; @@ -673,17 +674,18 @@ udp_input(struct mbuf *m, int off) if (up->u_rxcslen > len) { INP_RUNLOCK(inp); m_freem(m); - return; + return (IPPROTO_DONE); } } UDP_PROBE(receive, NULL, inp, ip, inp, uh); udp_append(inp, ip, m, iphlen, &udp_in); INP_RUNLOCK(inp); - return; + return (IPPROTO_DONE); badunlocked: m_freem(m); + return (IPPROTO_DONE); } #endif /* INET */ diff --git a/sys/netinet/udp_var.h b/sys/netinet/udp_var.h index ef4460c..04b4dbb 100644 --- a/sys/netinet/udp_var.h +++ b/sys/netinet/udp_var.h @@ -148,13 +148,13 @@ VNET_DECLARE(int, udp_blackhole); extern int udp_log_in_vain; static __inline struct inpcbinfo * -get_inpcbinfo(uint8_t protocol) +get_inpcbinfo(int protocol) { return (protocol == IPPROTO_UDP) ? &V_udbinfo : &V_ulitecbinfo; } static __inline struct inpcbhead * -get_pcblist(uint8_t protocol) +get_pcblist(int protocol) { return (protocol == IPPROTO_UDP) ? &V_udb : &V_ulitecb; } @@ -171,7 +171,7 @@ void udplite_init(void); void udp_destroy(void); void udplite_destroy(void); #endif -void udp_input(struct mbuf *, int); +int udp_input(struct mbuf **, int *, int); void udplite_input(struct mbuf *, int); struct inpcb *udp_notify(struct inpcb *inp, int errno); int udp_shutdown(struct socket *so); diff --git a/sys/netinet6/in6_gif.c b/sys/netinet6/in6_gif.c index 28fa823..f740b37 100644 --- a/sys/netinet6/in6_gif.c +++ b/sys/netinet6/in6_gif.c @@ -65,7 +65,6 @@ __FBSDID("$FreeBSD$"); #include <netinet6/in6_gif.h> #include <netinet6/in6_var.h> #endif -#include <netinet6/ip6protosw.h> #include <netinet/ip_ecn.h> #ifdef INET6 #include <netinet6/ip6_ecn.h> @@ -84,13 +83,13 @@ static int gif_validate6(const struct ip6_hdr *, struct gif_softc *, struct ifnet *); extern struct domain inet6domain; -struct ip6protosw in6_gif_protosw = { +struct protosw in6_gif_protosw = { .pr_type = SOCK_RAW, .pr_domain = &inet6domain, .pr_protocol = 0, /* IPPROTO_IPV[46] */ .pr_flags = PR_ATOMIC|PR_ADDR, .pr_input = in6_gif_input, - .pr_output = rip6_output, + .pr_output = (pr_output_t *)rip6_output, .pr_ctloutput = rip6_ctloutput, .pr_usrreqs = &rip6_usrreqs }; diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c index 47bbe3d..209dc3a 100644 --- a/sys/netinet6/in6_proto.c +++ b/sys/netinet6/in6_proto.c @@ -146,7 +146,7 @@ static struct pr_usrreqs nousrreqs; .pr_usrreqs = &nousrreqs \ } -struct ip6protosw inet6sw[] = { +struct protosw inet6sw[] = { { .pr_type = 0, .pr_domain = &inet6domain, @@ -233,7 +233,7 @@ struct ip6protosw inet6sw[] = { .pr_protocol = IPPROTO_RAW, .pr_flags = PR_ATOMIC|PR_ADDR, .pr_input = rip6_input, - .pr_output = rip6_output, + .pr_output = (pr_output_t *)rip6_output, .pr_ctlinput = rip6_ctlinput, .pr_ctloutput = rip6_ctloutput, #ifndef INET /* Do not call initialization twice. */ @@ -247,7 +247,7 @@ struct ip6protosw inet6sw[] = { .pr_protocol = IPPROTO_ICMPV6, .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR, .pr_input = icmp6_input, - .pr_output = rip6_output, + .pr_output = (pr_output_t *)rip6_output, .pr_ctlinput = rip6_ctlinput, .pr_ctloutput = rip6_ctloutput, .pr_fasttimo = icmp6_fasttimo, @@ -312,7 +312,7 @@ struct ip6protosw inet6sw[] = { .pr_protocol = IPPROTO_IPV4, .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR, .pr_input = encap6_input, - .pr_output = rip6_output, + .pr_output = (pr_output_t *)rip6_output, .pr_ctloutput = rip6_ctloutput, .pr_init = encap_init, .pr_usrreqs = &rip6_usrreqs @@ -324,7 +324,7 @@ struct ip6protosw inet6sw[] = { .pr_protocol = IPPROTO_IPV6, .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR, .pr_input = encap6_input, - .pr_output = rip6_output, + .pr_output = (pr_output_t *)rip6_output, .pr_ctloutput = rip6_ctloutput, .pr_init = encap_init, .pr_usrreqs = &rip6_usrreqs @@ -335,7 +335,7 @@ struct ip6protosw inet6sw[] = { .pr_protocol = IPPROTO_PIM, .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR, .pr_input = encap6_input, - .pr_output = rip6_output, + .pr_output = (pr_output_t *)rip6_output, .pr_ctloutput = rip6_ctloutput, .pr_usrreqs = &rip6_usrreqs }, @@ -354,7 +354,7 @@ IP6PROTOSPACER, .pr_domain = &inet6domain, .pr_flags = PR_ATOMIC|PR_ADDR, .pr_input = rip6_input, - .pr_output = rip6_output, + .pr_output = (pr_output_t *)rip6_output, .pr_ctloutput = rip6_ctloutput, .pr_usrreqs = &rip6_usrreqs }, diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c index 13b4b79..fb8cedd 100644 --- a/sys/netinet6/ip6_forward.c +++ b/sys/netinet6/ip6_forward.c @@ -76,8 +76,6 @@ __FBSDID("$FreeBSD$"); #include <netipsec/key.h> #endif /* IPSEC */ -#include <netinet6/ip6protosw.h> - /* * Forward a packet. If some error occurs return the sender * an icmp packet. Note we can't always generate a meaningful diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index a33341d..1f89bd0 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -164,7 +164,7 @@ static struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int); void ip6_init(void) { - struct ip6protosw *pr; + struct protosw *pr; int i; TUNABLE_INT_FETCH("net.inet6.ip6.auto_linklocal", @@ -194,11 +194,7 @@ ip6_init(void) if (!IS_DEFAULT_VNET(curvnet)) return; -#ifdef DIAGNOSTIC - if (sizeof(struct protosw) != sizeof(struct ip6protosw)) - panic("sizeof(protosw) != sizeof(ip6protosw)"); -#endif - pr = (struct ip6protosw *)pffindproto(PF_INET6, IPPROTO_RAW, SOCK_RAW); + pr = pffindproto(PF_INET6, IPPROTO_RAW, SOCK_RAW); if (pr == NULL) panic("ip6_init"); @@ -209,8 +205,8 @@ ip6_init(void) * Cycle through IP protocols and put them into the appropriate place * in ip6_protox[]. */ - for (pr = (struct ip6protosw *)inet6domain.dom_protosw; - pr < (struct ip6protosw *)inet6domain.dom_protoswNPROTOSW; pr++) + for (pr = inet6domain.dom_protosw; + pr < inet6domain.dom_protoswNPROTOSW; pr++) if (pr->pr_domain->dom_family == PF_INET6 && pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW) { /* Be careful to only index valid IP protocols. */ @@ -228,7 +224,7 @@ ip6_init(void) int ip6proto_register(short ip6proto) { - struct ip6protosw *pr; + struct protosw *pr; /* Sanity checks. */ if (ip6proto <= 0 || ip6proto >= IPPROTO_MAX) @@ -238,7 +234,7 @@ ip6proto_register(short ip6proto) * The protocol slot must not be occupied by another protocol * already. An index pointing to IPPROTO_RAW is unused. */ - pr = (struct ip6protosw *)pffindproto(PF_INET6, IPPROTO_RAW, SOCK_RAW); + pr = pffindproto(PF_INET6, IPPROTO_RAW, SOCK_RAW); if (pr == NULL) return (EPFNOSUPPORT); if (ip6_protox[ip6proto] != pr - inet6sw) /* IPPROTO_RAW */ @@ -247,8 +243,8 @@ ip6proto_register(short ip6proto) /* * Find the protocol position in inet6sw[] and set the index. */ - for (pr = (struct ip6protosw *)inet6domain.dom_protosw; - pr < (struct ip6protosw *)inet6domain.dom_protoswNPROTOSW; pr++) { + for (pr = inet6domain.dom_protosw; + pr < inet6domain.dom_protoswNPROTOSW; pr++) { if (pr->pr_domain->dom_family == PF_INET6 && pr->pr_protocol && pr->pr_protocol == ip6proto) { ip6_protox[pr->pr_protocol] = pr - inet6sw; @@ -261,14 +257,14 @@ ip6proto_register(short ip6proto) int ip6proto_unregister(short ip6proto) { - struct ip6protosw *pr; + struct protosw *pr; /* Sanity checks. */ if (ip6proto <= 0 || ip6proto >= IPPROTO_MAX) return (EPROTONOSUPPORT); /* Check if the protocol was indeed registered. */ - pr = (struct ip6protosw *)pffindproto(PF_INET6, IPPROTO_RAW, SOCK_RAW); + pr = pffindproto(PF_INET6, IPPROTO_RAW, SOCK_RAW); if (pr == NULL) return (EPFNOSUPPORT); if (ip6_protox[ip6proto] == pr - inet6sw) /* IPPROTO_RAW */ diff --git a/sys/netinet6/ip6_mroute.c b/sys/netinet6/ip6_mroute.c index 1ded0f6..77bff1f 100644 --- a/sys/netinet6/ip6_mroute.c +++ b/sys/netinet6/ip6_mroute.c @@ -121,7 +121,6 @@ __FBSDID("$FreeBSD$"); #include <netinet6/scope6_var.h> #include <netinet6/nd6.h> #include <netinet6/ip6_mroute.h> -#include <netinet6/ip6protosw.h> #include <netinet6/pim6.h> #include <netinet6/pim6_var.h> @@ -141,13 +140,13 @@ extern int in6_mcast_loop; extern struct domain inet6domain; static const struct encaptab *pim6_encap_cookie; -static const struct ip6protosw in6_pim_protosw = { +static const struct protosw in6_pim_protosw = { .pr_type = SOCK_RAW, .pr_domain = &inet6domain, .pr_protocol = IPPROTO_PIM, .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR, .pr_input = pim6_input, - .pr_output = rip6_output, + .pr_output = (pr_output_t *)rip6_output, .pr_ctloutput = rip6_ctloutput, .pr_usrreqs = &rip6_usrreqs }; diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h index a9729f9..b13d7ea 100644 --- a/sys/netinet6/ip6_var.h +++ b/sys/netinet6/ip6_var.h @@ -438,7 +438,7 @@ void rip6_init(void); int rip6_input(struct mbuf **, int *, int); void rip6_ctlinput(int, struct sockaddr *, void *); int rip6_ctloutput(struct socket *, struct sockopt *); -int rip6_output(struct mbuf *, ...); +int rip6_output(struct mbuf *, struct socket *, ...); int rip6_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct thread *); diff --git a/sys/netinet6/ip6protosw.h b/sys/netinet6/ip6protosw.h index dcaca5d..e8d4bad 100644 --- a/sys/netinet6/ip6protosw.h +++ b/sys/netinet6/ip6protosw.h @@ -110,39 +110,8 @@ struct ip6ctlparam { u_int8_t ip6c_nxt; /* final next header field */ }; -struct ip6protosw { - short pr_type; /* socket type used for */ - struct domain *pr_domain; /* domain protocol a member of */ - short pr_protocol; /* protocol number */ - short pr_flags; /* see below */ - -/* protocol-protocol hooks */ - int (*pr_input) /* input to protocol (from below) */ - (struct mbuf **, int *, int); - int (*pr_output) /* output to protocol (from above) */ - (struct mbuf *, ...); - void (*pr_ctlinput) /* control input (from below) */ - (int, struct sockaddr *, void *); - int (*pr_ctloutput) /* control output (from above) */ - (struct socket *, struct sockopt *); - -/* utility hooks */ - void (*pr_init) /* initialization hook */ - (void); - void (*pr_destroy) /* cleanup hook */ - (void); - - void (*pr_fasttimo) /* fast timeout (200ms) */ - (void); - void (*pr_slowtimo) /* slow timeout (500ms) */ - (void); - void (*pr_drain) /* flush any excess space possible */ - (void); - struct pr_usrreqs *pr_usrreqs; /* user-protocol hook */ -}; - #ifdef _KERNEL -extern struct ip6protosw inet6sw[]; +extern struct protosw inet6sw[]; #endif #endif /* !_NETINET6_IP6PROTOSW_H_ */ diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c index 57f7e90..34e38e4 100644 --- a/sys/netinet6/raw_ip6.c +++ b/sys/netinet6/raw_ip6.c @@ -390,17 +390,10 @@ rip6_ctlinput(int cmd, struct sockaddr *sa, void *d) * may have setup with control call. */ int -#if __STDC__ -rip6_output(struct mbuf *m, ...) -#else -rip6_output(m, va_alist) - struct mbuf *m; - va_dcl -#endif +rip6_output(struct mbuf *m, struct socket *so, ...) { struct mbuf *control; struct m_tag *mtag; - struct socket *so; struct sockaddr_in6 *dstsock; struct in6_addr *dst; struct ip6_hdr *ip6; @@ -415,8 +408,7 @@ rip6_output(m, va_alist) struct in6_addr in6a; va_list ap; - va_start(ap, m); - so = va_arg(ap, struct socket *); + va_start(ap, so); dstsock = va_arg(ap, struct sockaddr_in6 *); control = va_arg(ap, struct mbuf *); va_end(ap); diff --git a/sys/netipsec/ipsec.h b/sys/netipsec/ipsec.h index 24e2543..87413bd 100644 --- a/sys/netipsec/ipsec.h +++ b/sys/netipsec/ipsec.h @@ -354,11 +354,11 @@ extern const char *ipsec_logsastr __P((struct secasvar *)); extern void ipsec_dumpmbuf __P((struct mbuf *)); struct m_tag; -extern void ah4_input(struct mbuf *m, int off); +extern int ah4_input(struct mbuf **mp, int *offp, int proto); extern void ah4_ctlinput(int cmd, struct sockaddr *sa, void *); -extern void esp4_input(struct mbuf *m, int off); +extern int esp4_input(struct mbuf **mp, int *offp, int proto); extern void esp4_ctlinput(int cmd, struct sockaddr *sa, void *); -extern void ipcomp4_input(struct mbuf *m, int off); +extern int ipcomp4_input(struct mbuf **mp, int *offp, int proto); extern int ipsec4_common_input(struct mbuf *m, ...); extern int ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip, int protoff, struct m_tag *mt); diff --git a/sys/netipsec/ipsec_input.c b/sys/netipsec/ipsec_input.c index 40ac8d9..717ae9a 100644 --- a/sys/netipsec/ipsec_input.c +++ b/sys/netipsec/ipsec_input.c @@ -254,10 +254,18 @@ ipsec4_common_input(struct mbuf *m, ...) AF_INET, nxt); } -void -ah4_input(struct mbuf *m, int off) +int +ah4_input(struct mbuf **mp, int *offp, int proto) { + struct mbuf *m; + int off; + + m = *mp; + off = *offp; + *mp = NULL; + ipsec4_common_input(m, off, IPPROTO_AH); + return (IPPROTO_DONE); } void ah4_ctlinput(int cmd, struct sockaddr *sa, void *v) @@ -267,11 +275,20 @@ ah4_ctlinput(int cmd, struct sockaddr *sa, void *v) ipsec4_common_ctlinput(cmd, sa, v, IPPROTO_AH); } -void -esp4_input(struct mbuf *m, int off) +int +esp4_input(struct mbuf **mp, int *offp, int proto) { + struct mbuf *m; + int off; + + m = *mp; + off = *offp; + mp = NULL; + ipsec4_common_input(m, off, IPPROTO_ESP); + return (IPPROTO_DONE); } + void esp4_ctlinput(int cmd, struct sockaddr *sa, void *v) { @@ -280,10 +297,18 @@ esp4_ctlinput(int cmd, struct sockaddr *sa, void *v) ipsec4_common_ctlinput(cmd, sa, v, IPPROTO_ESP); } -void -ipcomp4_input(struct mbuf *m, int off) +int +ipcomp4_input(struct mbuf **mp, int *offp, int proto) { + struct mbuf *m; + int off; + + m = *mp; + off = *offp; + mp = NULL; + ipsec4_common_input(m, off, IPPROTO_IPCOMP); + return (IPPROTO_DONE); } /* diff --git a/sys/netipsec/xform.h b/sys/netipsec/xform.h index e389cab..62e8ca5 100644 --- a/sys/netipsec/xform.h +++ b/sys/netipsec/xform.h @@ -110,7 +110,7 @@ struct cryptoini; /* XF_IP4 */ extern int ip4_input6(struct mbuf **m, int *offp, int proto); -extern void ip4_input(struct mbuf *m, int); +extern int ip4_input(struct mbuf **, int *, int); extern int ipip_output(struct mbuf *, struct ipsecrequest *, struct mbuf **, int, int); diff --git a/sys/netipsec/xform_ipip.c b/sys/netipsec/xform_ipip.c index 07a6391..c0ce7b7 100644 --- a/sys/netipsec/xform_ipip.c +++ b/sys/netipsec/xform_ipip.c @@ -133,8 +133,8 @@ ip4_input6(struct mbuf **m, int *offp, int proto) /* * Really only a wrapper for ipip_input(), for use with IPv4. */ -void -ip4_input(struct mbuf *m, int off) +int +ip4_input(struct mbuf **mp, int *offp, int proto) { #if 0 /* If we do not accept IP-in-IP explicitly, drop. */ @@ -145,7 +145,8 @@ ip4_input(struct mbuf *m, int off) return; } #endif - _ipip_input(m, off, NULL); + _ipip_input(*mp, *offp, NULL); + return (IPPROTO_DONE); } #endif /* INET */ @@ -619,7 +620,7 @@ static struct protosw ipe4_protosw = { }; #endif /* INET */ #if defined(INET6) && defined(INET) -static struct ip6protosw ipe6_protosw = { +static struct protosw ipe6_protosw = { .pr_type = SOCK_RAW, .pr_domain = &inetdomain, .pr_protocol = IPPROTO_IPV6, diff --git a/sys/netpfil/pf/if_pfsync.c b/sys/netpfil/pf/if_pfsync.c index 7cb75ed..d5a6ffa 100644 --- a/sys/netpfil/pf/if_pfsync.c +++ b/sys/netpfil/pf/if_pfsync.c @@ -570,11 +570,12 @@ cleanup_state: /* pf_state_insert() frees the state keys. */ return (error); } -static void -pfsync_input(struct mbuf *m, __unused int off) +static int +pfsync_input(struct mbuf **mp, int *offp __unused, int proto __unused) { struct pfsync_softc *sc = V_pfsyncif; struct pfsync_pkt pkt; + struct mbuf *m = *mp; struct ip *ip = mtod(m, struct ip *); struct pfsync_header *ph; struct pfsync_subheader subh; @@ -583,6 +584,7 @@ pfsync_input(struct mbuf *m, __unused int off) int rv; uint16_t count; + *mp = NULL; V_pfsyncstats.pfsyncs_ipackets++; /* Verify that we have a sync interface configured. */ @@ -613,7 +615,7 @@ pfsync_input(struct mbuf *m, __unused int off) if (offset + sizeof(*ph) > m->m_len) { if (m_pullup(m, offset + sizeof(*ph)) == NULL) { V_pfsyncstats.pfsyncs_hdrops++; - return; + return (IPPROTO_DONE); } ip = mtod(m, struct ip *); } @@ -660,7 +662,7 @@ pfsync_input(struct mbuf *m, __unused int off) rv = (*pfsync_acts[subh.action])(&pkt, m, offset, count); if (rv == -1) { PF_RULES_RUNLOCK(); - return; + return (IPPROTO_DONE); } offset += rv; @@ -669,6 +671,7 @@ pfsync_input(struct mbuf *m, __unused int off) done: m_freem(m); + return (IPPROTO_DONE); } static int diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h index 8553baf..ce8dd74 100644 --- a/sys/sys/protosw.h +++ b/sys/sys/protosw.h @@ -64,8 +64,7 @@ struct sockopt; * similar to the vnode VOP interface. */ /* USE THESE FOR YOUR PROTOTYPES ! */ -typedef void pr_input_t (struct mbuf *, int); -typedef int pr_input6_t (struct mbuf **, int*, int); /* XXX FIX THIS */ +typedef int pr_input_t (struct mbuf **, int*, int); typedef int pr_output_t (struct mbuf *, struct socket *); typedef void pr_ctlinput_t (int, struct sockaddr *, void *); typedef int pr_ctloutput_t (struct socket *, struct sockopt *); |