If we do not recognize the protocol of a received packet, then
increase ifi_noproto. If the GRE header contains routing options, increase the input-error count, ifi_ierrors. While I am here, make some cosmetic changes: remove unnecessary 'proto' argument from gre_input3(). Shorten some staircases.
This commit is contained in:
parent
bbcca898c4
commit
271d77fa58
172
sys/net/if_gre.c
172
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 <sys/cdefs.h>
|
||||
__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:
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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 <sys/cdefs.h>
|
||||
__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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue