summaryrefslogtreecommitdiff
path: root/sys/netinet
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2018-02-07 22:31:00 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2018-02-07 22:31:00 +0000
commitd156bb23773c4488a3c312605523cc7a692af0da (patch)
tree2bf73a89653721ee43b55027301c98a9984c29ab /sys/netinet
parent0c80ef07be4e7a1851f58908f8948640a05519f5 (diff)
update the gre driver.
the main new feature is gre keys, supported by the vnetid ioctls. this also adds support for gre over ipv6, the use of hfsc, and allows tx mitigation in the future. this diff removes keepalive support, but i promised claudio@ and patrick@ i would put it back after this goes in. ok claudio@
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/ip_gre.c254
-rw-r--r--sys/netinet/ip_gre.h6
2 files changed, 3 insertions, 257 deletions
diff --git a/sys/netinet/ip_gre.c b/sys/netinet/ip_gre.c
index 5dad1d88d38..147ab23ccea 100644
--- a/sys/netinet/ip_gre.c
+++ b/sys/netinet/ip_gre.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_gre.c,v 1.70 2018/02/07 01:09:57 dlg Exp $ */
+/* $OpenBSD: ip_gre.c,v 1.71 2018/02/07 22:30:59 dlg Exp $ */
/* $NetBSD: ip_gre.c,v 1.9 1999/10/25 19:18:11 drochner Exp $ */
/*
@@ -47,269 +47,19 @@
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/sysctl.h>
+
#include <net/if.h>
-#include <net/netisr.h>
#include <net/route.h>
-#include <net/bpf.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
-#include <netinet/ip_gre.h>
-#include <netinet/if_ether.h>
#include <netinet/in_pcb.h>
-#ifdef MPLS
-#include <netmpls/mpls.h>
-#endif
-
-#include "bpfilter.h"
-#include "pf.h"
-
-#if NPF > 0
-#include <net/pfvar.h>
-#endif
-
#ifdef PIPEX
#include <net/pipex.h>
#endif
-/* Needs IP headers. */
-#include <net/if_gre.h>
-
-struct gre_softc *gre_lookup(struct mbuf *, u_int8_t);
-int gre_input2(struct mbuf *, int, int);
-
-/*
- * Decapsulate.
- * Does the real work and is called from gre_input() (above)
- * returns 0 if packet is not yet processed
- * and 1 if it needs no further processing
- * proto is the protocol number of the "calling" foo_input()
- * routine.
- */
-
-int
-gre_input2(struct mbuf *m, int hlen, int proto)
-{
- struct greip *gip;
- struct gre_softc *sc;
- u_short flags;
- u_int af;
-
- if ((sc = gre_lookup(m, proto)) == NULL) {
- /* No matching tunnel or tunnel is down. */
- return (0);
- }
-
- if (m->m_len < sizeof(*gip)) {
- m = m_pullup(m, sizeof(*gip));
- if (m == NULL)
- return (ENOBUFS);
- }
- gip = mtod(m, struct greip *);
-
- m->m_pkthdr.ph_ifidx = sc->sc_if.if_index;
- m->m_pkthdr.ph_rtableid = sc->sc_if.if_rdomain;
-
- sc->sc_if.if_ipackets++;
- sc->sc_if.if_ibytes += m->m_pkthdr.len;
-
- switch (proto) {
- case IPPROTO_GRE:
- hlen += sizeof (struct gre_h);
-
- /* process GRE flags as packet can be of variable len */
- flags = ntohs(gip->gi_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;
-
- switch (ntohs(gip->gi_ptype)) { /* ethertypes */
- case GREPROTO_WCCP:
- /* 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
- * only in its protocol number. At least, it works for me.
- *
- * The Internet Drafts can be found if you look for
- * 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).
- */
- if (!gre_wccp)
- return (0);
- /*
- * For WCCPv2, additionally skip the 4 byte
- * redirect header.
- */
- if (gre_wccp == 2)
- hlen += 4;
- case ETHERTYPE_IP:
- af = AF_INET;
- break;
-#ifdef INET6
- case ETHERTYPE_IPV6:
- af = AF_INET6;
- break;
-#endif
- case 0:
- /* keepalive reply, retrigger hold timer */
- gre_recv_keepalive(sc);
- m_freem(m);
- return (1);
-#ifdef MPLS
- case ETHERTYPE_MPLS:
- case ETHERTYPE_MPLS_MCAST:
- mpls_input(&sc->sc_if, m);
- return (1);
-#endif
- default: /* others not yet supported */
- return (0);
- }
- break;
- default:
- /* others not yet supported */
- return (0);
- }
-
- if (hlen > m->m_pkthdr.len) {
- m_freem(m);
- return (EINVAL);
- }
- m_adj(m, hlen);
-
-#if NBPFILTER > 0
- if (sc->sc_if.if_bpf)
- bpf_mtap_af(sc->sc_if.if_bpf, af, m, BPF_DIRECTION_IN);
-#endif
-
-#if NPF > 0
- pf_pkt_addr_changed(m);
-#endif
-
- switch (af) {
- case AF_INET:
- ipv4_input(&sc->sc_if, m);
- break;
-#ifdef INET6
- case AF_INET6:
- ipv6_input(&sc->sc_if, m);
- break;
-#endif
- default:
- return (0);
- }
-
-
- return (1); /* packet is done, no further processing needed */
-}
-
-/*
- * Decapsulate a packet and feed it back through ip_input (this
- * routine is called whenever IP gets a packet with proto type
- * IPPROTO_GRE and a local destination address).
- */
-int
-gre_input(struct mbuf **mp, int *offp, int proto, int af)
-{
- struct mbuf *m = *mp;
- int hlen = *offp;
- int ret;
-
- if (!gre_allow) {
- m_freem(m);
- return IPPROTO_DONE;
- }
-
-#ifdef PIPEX
- if (pipex_enable) {
- struct pipex_session *session;
-
- if ((session = pipex_pptp_lookup_session(m)) != NULL) {
- if (pipex_pptp_input(m, session) == NULL)
- return IPPROTO_DONE;
- }
- }
-#endif
-
- ret = gre_input2(m, hlen, proto);
- /*
- * ret == 0: packet not processed, but input from here
- * means no matching tunnel that is up is found.
- * we inject it to raw ip socket to see if anyone picks it up.
- * possible that we received a WCCPv1-style GRE packet
- * but we're not set to accept them.
- */
- if (!ret)
- return rip_input(mp, offp, proto, af);
- return IPPROTO_DONE;
-}
-
-/*
- * Find the gre interface associated with our src/dst/proto set.
- */
-struct gre_softc *
-gre_lookup(struct mbuf *m, u_int8_t proto)
-{
- struct ip *ip = mtod(m, struct ip *);
- struct gre_softc *sc;
-
- NET_ASSERT_LOCKED();
- LIST_FOREACH(sc, &gre_softc_list, sc_list) {
- if ((sc->g_dst.s_addr == ip->ip_src.s_addr) &&
- (sc->g_src.s_addr == ip->ip_dst.s_addr) &&
- (sc->g_proto == proto) &&
- (rtable_l2(sc->g_rtableid) ==
- rtable_l2(m->m_pkthdr.ph_rtableid)) &&
- ((sc->sc_if.if_flags & IFF_UP) != 0))
- return (sc);
- }
-
- return (NULL);
-}
-
-int
-gre_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
- size_t newlen)
-{
- int error;
-
- /* All sysctl names at this level are terminal. */
- if (namelen != 1)
- return (ENOTDIR);
-
- switch (name[0]) {
- case GRECTL_ALLOW:
- NET_LOCK();
- error = sysctl_int(oldp, oldlenp, newp, newlen, &gre_allow);
- NET_UNLOCK();
- return (error);
- case GRECTL_WCCP:
- NET_LOCK();
- error = sysctl_int(oldp, oldlenp, newp, newlen, &gre_wccp);
- NET_UNLOCK();
- return (error);
- default:
- return (ENOPROTOOPT);
- }
- /* NOTREACHED */
-}
-
int
gre_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
struct mbuf *control, struct proc *p)
diff --git a/sys/netinet/ip_gre.h b/sys/netinet/ip_gre.h
index b072532d998..3a517896cf3 100644
--- a/sys/netinet/ip_gre.h
+++ b/sys/netinet/ip_gre.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_gre.h,v 1.12 2017/04/14 20:46:31 bluhm Exp $ */
+/* $OpenBSD: ip_gre.h,v 1.13 2018/02/07 22:30:59 dlg Exp $ */
/* $NetBSD: ip_gre.h,v 1.3 1998/10/07 23:33:02 thorpej Exp $ */
/*
@@ -64,10 +64,6 @@
}
#ifdef _KERNEL
-int gre_input(struct mbuf **, int *, int, int);
-int gre_mobile_input(struct mbuf **, int *, int, int);
-int ipmobile_sysctl(int *, u_int, void *, size_t *, void *, size_t);
-int gre_sysctl(int *, u_int, void *, size_t *, void *, size_t);
int gre_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *);
#endif /* _KERNEL */
#endif /* _NETINET_IP_GRE_H_ */