diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2009-11-21 14:08:15 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2009-11-21 14:08:15 +0000 |
commit | bd9ee9386e3b82970f52fecd6e1608d23375f21a (patch) | |
tree | c0eebd731e931973f84e9287c5bdbc600178d2ee /sys/net | |
parent | 66549b4a5c09c74b99b04b1d1805ecf09a58d7fc (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.c | 4 | ||||
-rw-r--r-- | sys/net/if_gif.c | 14 | ||||
-rw-r--r-- | sys/net/if_gif.h | 3 | ||||
-rw-r--r-- | sys/net/if_gre.c | 36 | ||||
-rw-r--r-- | sys/net/if_gre.h | 7 |
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 */ }; |