diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2018-02-16 01:28:08 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2018-02-16 01:28:08 +0000 |
commit | 862eb01a1e43a4ce0c783b54a2c42c1ca04c967a (patch) | |
tree | e9a46d3bdf15f5a40cac5770a0e0bb6704f00fb7 /sys | |
parent | b3913d6e5bff55a1853903df1b7142c16fdfc017 (diff) |
allow wccp processing to be enabled per interface with the link0 flag.
this also changes the wccp handling to peek into it's payload to
determine whether it is wccp 1 or 2. wccp1 says the gre header is
followed by ipv4, while wccp2 says there's a small header before
the ipv4 packet. the wccp2 header cannot have 4 in the first nibble,
while ipv4 must have 4 in the first nibble. the code now looks at
the nibble to determine whether it should strip the wccp2 header
or not.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/if_gre.c | 36 |
1 files changed, 20 insertions, 16 deletions
diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c index 7a73b732d34..1a76d97178f 100644 --- a/sys/net/if_gre.c +++ b/sys/net/if_gre.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_gre.c,v 1.101 2018/02/15 01:03:17 dlg Exp $ */ +/* $OpenBSD: if_gre.c,v 1.102 2018/02/16 01:28:07 dlg Exp $ */ /* $NetBSD: if_gre.c,v 1.9 1999/10/25 19:18:11 drochner Exp $ */ /* @@ -563,8 +563,13 @@ gre_input_key(struct mbuf **mp, int *offp, int type, int af, if (sc == NULL) goto decline; + ifp = &sc->sc_if; + switch (gh->gre_proto) { - case htons(GRE_WCCP): + case htons(GRE_WCCP): { + struct mbuf *n; + int off; + /* WCCP/GRE: * So far as I can see (and test) it seems that Cisco's WCCP * GRE tunnel is precisely a IP-in-GRE tunnel that differs @@ -574,22 +579,23 @@ gre_input_key(struct mbuf **mp, int *offp, int type, int af, * the following: * draft-forster-wrec-wccp-v1-00.txt * draft-wilson-wrec-wccp-v2-01.txt - * - * So yes, we're doing a fall-through (unless, of course, - * net.inet.gre.wccp is 0). */ - switch (gre_wccp) { - case 1: - break; - case 2: - hlen += sizeof(gre_wccp); - break; - case 0: - default: + + if (!gre_wccp && !ISSET(ifp->if_flags, IFF_LINK0)) goto decline; - } + + /* + * If the first nibble of the payload does not look like + * IPv4, assume it is WCCP v2. + */ + n = m_getptr(m, hlen, &off); + if (n == NULL) + goto decline; + if (n->m_data[off] >> 4 != IPVERSION) + hlen += sizeof(gre_wccp); /* FALLTHROUGH */ + } case htons(ETHERTYPE_IP): #if NBPFILTER > 0 bpf_af = AF_INET; @@ -629,8 +635,6 @@ gre_input_key(struct mbuf **mp, int *offp, int type, int af, goto decline; } - ifp = &sc->sc_if; - m_adj(m, hlen); if (sc->sc_tunnel.t_ttl == -1) { |