summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2018-02-16 01:28:08 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2018-02-16 01:28:08 +0000
commit862eb01a1e43a4ce0c783b54a2c42c1ca04c967a (patch)
treee9a46d3bdf15f5a40cac5770a0e0bb6704f00fb7 /sys
parentb3913d6e5bff55a1853903df1b7142c16fdfc017 (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.c36
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) {