summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2019-02-15 01:06:39 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2019-02-15 01:06:39 +0000
commit2123b9e382ebf7e59538d92745ff9c9417a53403 (patch)
tree3fa3624f1f7f8a992f4618f10155e63a0b341894 /sys
parenta2ba4cc48d47c6b9099a51b953c006ad5eaa820b (diff)
allow configuration of the rdomain that mpls operates in
this is based on the changes to mpe i made yesterday. unfortunately mpw has a monstor ioctl that configures all the things, which makes the kernel side complicated. hopefully i can split them up.
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if_mpw.c62
1 files changed, 48 insertions, 14 deletions
diff --git a/sys/net/if_mpw.c b/sys/net/if_mpw.c
index 53f5803932c..edde0672b66 100644
--- a/sys/net/if_mpw.c
+++ b/sys/net/if_mpw.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_mpw.c,v 1.36 2019/02/14 03:29:46 dlg Exp $ */
+/* $OpenBSD: if_mpw.c,v 1.37 2019/02/15 01:06:38 dlg Exp $ */
/*
* Copyright (c) 2015 Rafael Zalamena <rzalamena@openbsd.org>
@@ -48,6 +48,7 @@ struct mpw_softc {
struct arpcom sc_ac;
#define sc_if sc_ac.ac_if
+ unsigned int sc_rdomain;
struct ifaddr sc_ifa;
struct sockaddr_mpls sc_smpls; /* Local label */
@@ -103,6 +104,7 @@ mpw_clone_create(struct if_clone *ifc, int unit)
if_attach(ifp);
ether_ifattach(ifp);
+ sc->sc_rdomain = 0;
sc->sc_ifa.ifa_ifp = ifp;
sc->sc_ifa.ifa_addr = sdltosa(ifp->if_sadl);
sc->sc_smpls.smpls_len = sizeof(sc->sc_smpls);
@@ -120,7 +122,7 @@ mpw_clone_destroy(struct ifnet *ifp)
if (sc->sc_smpls.smpls_label) {
rt_ifa_del(&sc->sc_ifa, RTF_MPLS|RTF_LOCAL,
- smplstosa(&sc->sc_smpls), 0);
+ smplstosa(&sc->sc_smpls), sc->sc_rdomain);
}
ether_ifdetach(ifp);
@@ -132,6 +134,27 @@ mpw_clone_destroy(struct ifnet *ifp)
}
int
+mpw_set_label(struct mpw_softc *sc, uint32_t label, unsigned int rdomain)
+{
+ int error;
+
+ if (sc->sc_smpls.smpls_label) {
+ rt_ifa_del(&sc->sc_ifa, RTF_MPLS|RTF_LOCAL,
+ smplstosa(&sc->sc_smpls), sc->sc_rdomain);
+ }
+
+ sc->sc_smpls.smpls_label = label;
+ sc->sc_rdomain = rdomain;
+
+ error = rt_ifa_add(&sc->sc_ifa, RTF_MPLS|RTF_LOCAL,
+ smplstosa(&sc->sc_smpls), sc->sc_rdomain);
+ if (error != 0)
+ sc->sc_smpls.smpls_label = 0;
+
+ return (0);
+}
+
+int
mpw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
struct ifreq *ifr = (struct ifreq *) data;
@@ -193,17 +216,10 @@ mpw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
MPLS_LABEL2SHIM(imr.imr_rshim.shim_label);
if (sc->sc_smpls.smpls_label != imr.imr_lshim.shim_label) {
- if (sc->sc_smpls.smpls_label)
- rt_ifa_del(&sc->sc_ifa, RTF_MPLS|RTF_LOCAL,
- smplstosa(&sc->sc_smpls), 0);
-
- sc->sc_smpls.smpls_label = imr.imr_lshim.shim_label;
- error = rt_ifa_add(&sc->sc_ifa, RTF_MPLS|RTF_LOCAL,
- smplstosa(&sc->sc_smpls), 0);
- if (error != 0) {
- sc->sc_smpls.smpls_label = 0;
+ error = mpw_set_label(sc, imr.imr_lshim.shim_label,
+ sc->sc_rdomain);
+ if (error != 0)
break;
- }
}
/* Apply configuration */
@@ -232,6 +248,24 @@ mpw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
error = copyout(&imr, ifr->ifr_data, sizeof(imr));
break;
+ case SIOCSLIFPHYRTABLE:
+ if (ifr->ifr_rdomainid < 0 ||
+ ifr->ifr_rdomainid > RT_TABLEID_MAX ||
+ !rtable_exists(ifr->ifr_rdomainid) ||
+ ifr->ifr_rdomainid != rtable_l2(ifr->ifr_rdomainid)) {
+ error = EINVAL;
+ break;
+ }
+ if (sc->sc_rdomain != ifr->ifr_rdomainid) {
+ error = mpw_set_label(sc, sc->sc_smpls.smpls_label,
+ ifr->ifr_rdomainid);
+ }
+ break;
+ case SIOCGLIFPHYRTABLE:
+ ifr->ifr_rdomainid = sc->sc_rdomain;
+ break;
+
+
case SIOCADDMULTI:
case SIOCDELMULTI:
break;
@@ -311,7 +345,7 @@ mpw_input(struct mpw_softc *sc, struct mbuf *m)
if (n == NULL)
return;
m = n;
- }
+ }
ml_enqueue(&ml, m);
if_input(ifp, &ml);
@@ -355,7 +389,7 @@ mpw_start(struct ifnet *ifp)
return;
}
- rt = rtalloc(sstosa(&sc->sc_nexthop), RT_RESOLVE, 0);
+ rt = rtalloc(sstosa(&sc->sc_nexthop), RT_RESOLVE, sc->sc_rdomain);
if (!rtisvalid(rt)) {
IFQ_PURGE(&ifp->if_snd);
goto rtfree;