diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c index 7479f4a83742..8ed7db3e2e05 100644 --- a/sys/net/if_gre.c +++ b/sys/net/if_gre.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_gre.c,v 1.88 2007/03/04 06:03:16 christos Exp $ */ +/* $NetBSD: if_gre.c,v 1.89 2007/03/21 01:56:05 dyoung Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -48,7 +48,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: if_gre.c,v 1.88 2007/03/04 06:03:16 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_gre.c,v 1.89 2007/03/21 01:56:05 dyoung Exp $"); #include "opt_gre.h" #include "opt_inet.h" @@ -439,7 +439,7 @@ gre_thread1(struct gre_softc *sc, struct lwp *l) } gh = mtod(m, const struct gre_h *); - if (gre_input3(sc, m, 0, IPPROTO_GRE, gh) == 0) { + if (gre_input3(sc, m, 0, gh) == 0) { GRE_DPRINTF(sc, "%s: dropping unsupported\n", __func__); ifp->if_ierrors++; @@ -502,7 +502,7 @@ gre_thread(void *arg) } int -gre_input3(struct gre_softc *sc, struct mbuf *m, int hlen, u_char proto, +gre_input3(struct gre_softc *sc, struct mbuf *m, int hlen, const struct gre_h *gh) { u_int16_t flags; @@ -515,56 +515,52 @@ gre_input3(struct gre_softc *sc, struct mbuf *m, int hlen, u_char proto, sc->sc_if.if_ipackets++; sc->sc_if.if_ibytes += m->m_pkthdr.len; - switch (proto) { - case IPPROTO_GRE: - hlen += sizeof(struct gre_h); + hlen += sizeof(struct gre_h); - /* process GRE flags as packet can be of variable len */ - flags = ntohs(gh->flags); + /* process GRE flags as packet can be of variable len */ + flags = ntohs(gh->flags); - /* Checksum & Offset are present */ - if ((flags & GRE_CP) | (flags & GRE_RP)) - hlen += 4; - /* We don't support routing fields (variable length) */ - if (flags & GRE_RP) - return 0; - if (flags & GRE_KP) - hlen += 4; - if (flags & GRE_SP) - hlen += 4; + /* Checksum & Offset are present */ + if ((flags & GRE_CP) | (flags & GRE_RP)) + hlen += 4; + /* We don't support routing fields (variable length) */ + if (flags & GRE_RP) { + sc->sc_if.if_ierrors++; + return 0; + } + if (flags & GRE_KP) + hlen += 4; + if (flags & GRE_SP) + hlen += 4; - switch (ntohs(gh->ptype)) { /* ethertypes */ - case ETHERTYPE_IP: /* shouldn't need a schednetisr(), as */ - ifq = &ipintrq; /* we are in ip_input */ - isr = NETISR_IP; - break; + switch (ntohs(gh->ptype)) { /* ethertypes */ + case ETHERTYPE_IP: /* shouldn't need a schednetisr(), as */ + ifq = &ipintrq; /* we are in ip_input */ + isr = NETISR_IP; + break; #ifdef NETATALK - case ETHERTYPE_ATALK: - ifq = &atintrq1; - isr = NETISR_ATALK; + case ETHERTYPE_ATALK: + ifq = &atintrq1; + isr = NETISR_ATALK; #if NBPFILTER > 0 - af = AF_APPLETALK; + af = AF_APPLETALK; #endif - break; + break; #endif #ifdef INET6 - case ETHERTYPE_IPV6: - GRE_DPRINTF(sc, "%s: IPv6 packet\n", __func__); - ifq = &ip6intrq; - isr = NETISR_IPV6; + case ETHERTYPE_IPV6: + GRE_DPRINTF(sc, "%s: IPv6 packet\n", __func__); + ifq = &ip6intrq; + isr = NETISR_IPV6; #if NBPFILTER > 0 - af = AF_INET6; + af = AF_INET6; #endif - break; -#endif - default: /* others not yet supported */ - printf("%s: unhandled ethertype 0x%04x\n", __func__, - ntohs(gh->ptype)); - return 0; - } break; - default: - /* others not yet supported */ +#endif + default: /* others not yet supported */ + printf("%s: unhandled ethertype 0x%04x\n", __func__, + ntohs(gh->ptype)); + sc->sc_if.if_noproto++; return 0; } @@ -604,7 +600,7 @@ static int gre_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, struct rtentry *rt) { - int error = 0, hlen; + int error = 0, hlen, msiz; struct gre_softc *sc = ifp->if_softc; struct greip *gi; struct gre_h *gh; @@ -632,56 +628,54 @@ gre_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, switch (sc->sc_proto) { case IPPROTO_MOBILE: - if (dst->sa_family == AF_INET) { - int msiz; - - if (M_UNWRITABLE(m, sizeof(*ip)) && - (m = m_pullup(m, sizeof(*ip))) == NULL) { - error = ENOBUFS; - goto end; - } - ip = mtod(m, struct ip *); - - memset(&mob_h, 0, MOB_H_SIZ_L); - mob_h.proto = (ip->ip_p) << 8; - mob_h.odst = ip->ip_dst.s_addr; - ip->ip_dst.s_addr = sc->g_dst.s_addr; - - /* - * If the packet comes from our host, we only change - * the destination address in the IP header. - * Else we also need to save and change the source - */ - if (in_hosteq(ip->ip_src, sc->g_src)) { - msiz = MOB_H_SIZ_S; - } else { - mob_h.proto |= MOB_H_SBIT; - mob_h.osrc = ip->ip_src.s_addr; - ip->ip_src.s_addr = sc->g_src.s_addr; - msiz = MOB_H_SIZ_L; - } - HTONS(mob_h.proto); - mob_h.hcrc = gre_in_cksum((u_int16_t *)&mob_h, msiz); - - M_PREPEND(m, msiz, M_DONTWAIT); - if (m == NULL) { - error = ENOBUFS; - goto end; - } - /* XXX Assuming that ip does not dangle after - * M_PREPEND. In practice, that's true, but - * that's in M_PREPEND's contract. - */ - memmove(mtod(m, void *), ip, sizeof(*ip)); - ip = mtod(m, struct ip *); - memcpy((void *)(ip + 1), &mob_h, (unsigned)msiz); - ip->ip_len = htons(ntohs(ip->ip_len) + msiz); - } else { /* AF_INET */ + if (dst->sa_family != AF_INET) { IF_DROP(&ifp->if_snd); m_freem(m); error = EINVAL; goto end; } + + if (M_UNWRITABLE(m, sizeof(*ip)) && + (m = m_pullup(m, sizeof(*ip))) == NULL) { + error = ENOBUFS; + goto end; + } + ip = mtod(m, struct ip *); + + memset(&mob_h, 0, MOB_H_SIZ_L); + mob_h.proto = (ip->ip_p) << 8; + mob_h.odst = ip->ip_dst.s_addr; + ip->ip_dst.s_addr = sc->g_dst.s_addr; + + /* + * If the packet comes from our host, we only change + * the destination address in the IP header. + * Else we also need to save and change the source + */ + if (in_hosteq(ip->ip_src, sc->g_src)) { + msiz = MOB_H_SIZ_S; + } else { + mob_h.proto |= MOB_H_SBIT; + mob_h.osrc = ip->ip_src.s_addr; + ip->ip_src.s_addr = sc->g_src.s_addr; + msiz = MOB_H_SIZ_L; + } + HTONS(mob_h.proto); + mob_h.hcrc = gre_in_cksum((u_int16_t *)&mob_h, msiz); + + M_PREPEND(m, msiz, M_DONTWAIT); + if (m == NULL) { + error = ENOBUFS; + goto end; + } + /* XXX Assuming that ip does not dangle after + * M_PREPEND. In practice, that's true, but + * that's in M_PREPEND's contract. + */ + memmove(mtod(m, void *), ip, sizeof(*ip)); + ip = mtod(m, struct ip *); + memcpy((void *)(ip + 1), &mob_h, (unsigned)msiz); + ip->ip_len = htons(ntohs(ip->ip_len) + msiz); break; case IPPROTO_UDP: case IPPROTO_GRE: diff --git a/sys/net/if_gre.h b/sys/net/if_gre.h index fac9d3375b7a..321405dfe2ac 100644 --- a/sys/net/if_gre.h +++ b/sys/net/if_gre.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_gre.h,v 1.20 2007/01/26 03:01:32 dyoung Exp $ */ +/* $NetBSD: if_gre.h,v 1.21 2007/03/21 01:56:05 dyoung Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -163,8 +163,7 @@ LIST_HEAD(gre_softc_head, gre_softc); extern struct gre_softc_head gre_softc_list; u_int16_t gre_in_cksum(u_short *, u_int); -int gre_input3(struct gre_softc *, struct mbuf *, int, u_char, - const struct gre_h *); +int gre_input3(struct gre_softc *, struct mbuf *, int, const struct gre_h *); #endif /* _KERNEL */ #endif /* !_NET_IF_GRE_H_ */ diff --git a/sys/netinet/ip_gre.c b/sys/netinet/ip_gre.c index bdaaf80e7585..49553d1509da 100644 --- a/sys/netinet/ip_gre.c +++ b/sys/netinet/ip_gre.c @@ -1,4 +1,4 @@ -/* $NetBSD: ip_gre.c,v 1.44 2006/11/16 22:54:14 dyoung Exp $ */ +/* $NetBSD: ip_gre.c,v 1.45 2007/03/21 01:56:05 dyoung Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -45,7 +45,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ip_gre.c,v 1.44 2006/11/16 22:54:14 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_gre.c,v 1.45 2007/03/21 01:56:05 dyoung Exp $"); #include "gre.h" #if NGRE > 0 @@ -156,7 +156,7 @@ gre_input2(struct mbuf *m, int hlen, u_char proto) } gip = mtod(m, const struct greip *); - return gre_input3(sc, m, hlen, proto, &gip->gi_g); + return gre_input3(sc, m, hlen, &gip->gi_g); } /*