summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2009-11-21 14:08:15 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2009-11-21 14:08:15 +0000
commitbd9ee9386e3b82970f52fecd6e1608d23375f21a (patch)
treec0eebd731e931973f84e9287c5bdbc600178d2ee /sys/net
parent66549b4a5c09c74b99b04b1d1805ecf09a58d7fc (diff)
Add a way to bind the tunnel endpoint of a gif/gre interface into a
different rdomain than the default one. This allows to do MPLS VPNs without the MPLS madness. OK deraadt@, henning@
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if.c4
-rw-r--r--sys/net/if_gif.c14
-rw-r--r--sys/net/if_gif.h3
-rw-r--r--sys/net/if_gre.c36
-rw-r--r--sys/net/if_gre.h7
5 files changed, 53 insertions, 11 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 5c989cc8ab0..4637bf5af93 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.200 2009/11/03 10:59:04 claudio Exp $ */
+/* $OpenBSD: if.c,v 1.201 2009/11/21 14:08:14 claudio Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -1381,6 +1381,7 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
case SIOCSIFPHYADDR_IN6:
#endif
case SIOCSLIFPHYADDR:
+ case SIOCSLIFPHYRTABLEID:
case SIOCADDMULTI:
case SIOCDELMULTI:
case SIOCSIFMEDIA:
@@ -1390,6 +1391,7 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
case SIOCGIFPSRCADDR:
case SIOCGIFPDSTADDR:
case SIOCGLIFPHYADDR:
+ case SIOCGLIFPHYRTABLEID:
case SIOCGIFMEDIA:
if (ifp->if_ioctl == 0)
return (EOPNOTSUPP);
diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c
index 0869fb961df..fda89a0d958 100644
--- a/sys/net/if_gif.c
+++ b/sys/net/if_gif.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_gif.c,v 1.51 2008/11/24 14:55:53 claudio Exp $ */
+/* $OpenBSD: if_gif.c,v 1.52 2009/11/21 14:08:14 claudio Exp $ */
/* $KAME: if_gif.c,v 1.43 2001/02/20 08:51:07 itojun Exp $ */
/*
@@ -598,6 +598,18 @@ gif_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
ifp->if_mtu = ifr->ifr_mtu;
break;
+ case SIOCSLIFPHYRTABLEID:
+ if (ifr->ifr_rdomainid < 0 ||
+ ifr->ifr_rdomainid > RT_TABLEID_MAX ||
+ !rtable_exists(ifr->ifr_rdomainid)) {
+ error = EINVAL;
+ break;
+ }
+ sc->gif_rtableid = ifr->ifr_rdomainid;
+ break;
+ case SIOCGLIFPHYRTABLEID:
+ ifr->ifr_rdomainid = sc->gif_rtableid;
+ break;
default:
error = ENOTTY;
break;
diff --git a/sys/net/if_gif.h b/sys/net/if_gif.h
index 88cd1810f84..a1e8dd66f85 100644
--- a/sys/net/if_gif.h
+++ b/sys/net/if_gif.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_gif.h,v 1.9 2003/12/03 14:51:05 markus Exp $ */
+/* $OpenBSD: if_gif.h,v 1.10 2009/11/21 14:08:14 claudio Exp $ */
/* $KAME: if_gif.h,v 1.17 2000/09/11 11:36:41 sumikawa Exp $ */
/*
@@ -52,6 +52,7 @@ struct gif_softc {
#endif
} gifsc_gifscr;
int gif_flags;
+ u_int gif_rtableid;
LIST_ENTRY(gif_softc) gif_list; /* list of all gifs */
};
diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c
index 63695536a0d..d4b52337256 100644
--- a/sys/net/if_gre.c
+++ b/sys/net/if_gre.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_gre.c,v 1.45 2009/06/02 17:10:23 henning Exp $ */
+/* $OpenBSD: if_gre.c,v 1.46 2009/11/21 14:08:14 claudio Exp $ */
/* $NetBSD: if_gre.c,v 1.9 1999/10/25 19:18:11 drochner Exp $ */
/*
@@ -207,6 +207,15 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
goto end;
}
+#ifdef DIAGNOSTIC
+ if (ifp->if_rdomain != rtable_l2(m->m_pkthdr.rdomain)) {
+ printf("%s: trying to send packet on wrong domain. "
+ "if %d vs. mbuf %d, AF %d\n", ifp->if_xname,
+ ifp->if_rdomain, rtable_l2(m->m_pkthdr.rdomain),
+ dst->sa_family);
+ }
+#endif
+
/* Try to limit infinite recursion through misconfiguration. */
for (mtag = m_tag_find(m, PACKET_TAG_GRE, NULL); mtag;
mtag = m_tag_find(m, PACKET_TAG_GRE, mtag)) {
@@ -410,6 +419,9 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
ifp->if_opackets++;
ifp->if_obytes += m->m_pkthdr.len;
+
+ m->m_pkthdr.rdomain = sc->g_rtableid;
+
#if NPF > 0
pf_pkt_addr_changed(m);
#endif
@@ -514,7 +526,7 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
sc->g_src = (satosin(sa))->sin_addr;
if (cmd == GRESADDRD )
sc->g_dst = (satosin(sa))->sin_addr;
- recompute:
+recompute:
if ((sc->g_src.s_addr != INADDR_ANY) &&
(sc->g_dst.s_addr != INADDR_ANY)) {
if (sc->route.ro_rt != 0) {
@@ -579,6 +591,20 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
si.sin_addr.s_addr = sc->g_dst.s_addr;
memcpy(&lifr->dstaddr, &si, sizeof(si));
break;
+ case SIOCSLIFPHYRTABLEID:
+ if ((error = suser(prc, 0)) != 0)
+ break;
+ if (ifr->ifr_rdomainid < 0 ||
+ ifr->ifr_rdomainid > RT_TABLEID_MAX ||
+ !rtable_exists(ifr->ifr_rdomainid)) {
+ error = EINVAL;
+ break;
+ }
+ sc->g_rtableid = ifr->ifr_rdomainid;
+ goto recompute;
+ case SIOCGLIFPHYRTABLEID:
+ ifr->ifr_rdomainid = sc->g_rtableid;
+ break;
default:
error = ENOTTY;
}
@@ -627,8 +653,8 @@ gre_compute_route(struct gre_softc *sc)
((struct sockaddr_in *) &ro->ro_dst)->sin_addr.s_addr = htonl(a);
}
- rtalloc(ro);
- if (ro->ro_rt == 0)
+ ro->ro_rt = rtalloc1(&ro->ro_dst, 1, sc->g_rtableid);
+ if (ro->ro_rt == NULL)
return;
/*
@@ -638,7 +664,7 @@ gre_compute_route(struct gre_softc *sc)
*/
if (ro->ro_rt->rt_ifp == &sc->sc_if) {
RTFREE(ro->ro_rt);
- ro->ro_rt = (struct rtentry *) 0;
+ ro->ro_rt = NULL;
return;
}
diff --git a/sys/net/if_gre.h b/sys/net/if_gre.h
index 51c90779560..4b4e0c89678 100644
--- a/sys/net/if_gre.h
+++ b/sys/net/if_gre.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_gre.h,v 1.11 2008/06/26 05:42:20 ray Exp $ */
+/* $OpenBSD: if_gre.h,v 1.12 2009/11/21 14:08:14 claudio Exp $ */
/* $NetBSD: if_gre.h,v 1.5 1999/11/19 20:41:19 thorpej Exp $ */
/*
@@ -36,12 +36,13 @@
struct gre_softc {
struct ifnet sc_if;
LIST_ENTRY(gre_softc) sc_list;
- int gre_unit;
- int gre_flags;
struct in_addr g_src; /* source address of gre packets */
struct in_addr g_dst; /* destination address of gre packets */
struct route route; /* routing entry that determines, where a
encapsulated packet should go */
+ int gre_unit;
+ int gre_flags;
+ u_int g_rtableid; /* routing table used for the tunnel */
u_char g_proto; /* protocol of encapsulator */
};