summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if.c111
-rw-r--r--sys/net/if.h3
2 files changed, 63 insertions, 51 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 185978d06e8..61570477465 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.441 2016/09/04 10:32:01 mpi Exp $ */
+/* $OpenBSD: if.c,v 1.442 2016/09/04 15:10:59 reyk Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -1606,6 +1606,65 @@ if_setlladdr(struct ifnet *ifp, const uint8_t *lladdr)
return (0);
}
+int
+if_setrdomain(struct ifnet *ifp, int rdomain)
+{
+ struct ifreq ifr;
+ int s, error;
+
+ if (rdomain < 0 || rdomain > RT_TABLEID_MAX)
+ return (EINVAL);
+
+ /* make sure that the routing table exists */
+ if (!rtable_exists(rdomain)) {
+ s = splsoftnet();
+ if ((error = rtable_add(rdomain)) == 0)
+ rtable_l2set(rdomain, rdomain);
+ splx(s);
+ if (error)
+ return (error);
+ }
+
+ /* make sure that the routing table is a real rdomain */
+ if (rdomain != rtable_l2(rdomain))
+ return (EINVAL);
+
+ /* remove all routing entries when switching domains */
+ /* XXX this is a bit ugly */
+ if (rdomain != ifp->if_rdomain) {
+ s = splnet();
+ /*
+ * We are tearing down the world.
+ * Take down the IF so:
+ * 1. everything that cares gets a message
+ * 2. the automagic IPv6 bits are recreated
+ */
+ if (ifp->if_flags & IFF_UP)
+ if_down(ifp);
+ rti_delete(ifp);
+#ifdef MROUTING
+ vif_delete(ifp);
+#endif
+ in_ifdetach(ifp);
+#ifdef INET6
+ in6_ifdetach(ifp);
+#endif
+ splx(s);
+ }
+
+ /* Let devices like enc(4) or mpe(4) know about the change */
+ ifr.ifr_rdomainid = rdomain;
+ if ((error = (*ifp->if_ioctl)(ifp, SIOCSIFRDOMAIN,
+ (caddr_t)&ifr)) != ENOTTY)
+ return (error);
+ error = 0;
+
+ /* Add interface to the specified rdomain */
+ ifp->if_rdomain = rdomain;
+
+ return (0);
+}
+
/*
* Interface ioctls.
*/
@@ -1910,56 +1969,8 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
case SIOCSIFRDOMAIN:
if ((error = suser(p, 0)) != 0)
return (error);
- if (ifr->ifr_rdomainid < 0 ||
- ifr->ifr_rdomainid > RT_TABLEID_MAX)
- return (EINVAL);
-
- /* make sure that the routing table exists */
- if (!rtable_exists(ifr->ifr_rdomainid)) {
- s = splsoftnet();
- if ((error = rtable_add(ifr->ifr_rdomainid)) == 0)
- rtable_l2set(ifr->ifr_rdomainid, ifr->ifr_rdomainid);
- splx(s);
- if (error)
- return (error);
- }
-
- /* make sure that the routing table is a real rdomain */
- if (ifr->ifr_rdomainid != rtable_l2(ifr->ifr_rdomainid))
- return (EINVAL);
-
- /* remove all routing entries when switching domains */
- /* XXX hell this is ugly */
- if (ifr->ifr_rdomainid != ifp->if_rdomain) {
- s = splnet();
- if (ifp->if_flags & IFF_UP)
- up = 1;
- /*
- * We are tearing down the world.
- * Take down the IF so:
- * 1. everything that cares gets a message
- * 2. the automagic IPv6 bits are recreated
- */
- if (up)
- if_down(ifp);
- rti_delete(ifp);
-#ifdef MROUTING
- vif_delete(ifp);
-#endif
- in_ifdetach(ifp);
-#ifdef INET6
- in6_ifdetach(ifp);
-#endif
- splx(s);
- }
-
- /* Let devices like enc(4) or mpe(4) know about the change */
- if ((error = (*ifp->if_ioctl)(ifp, cmd, data)) != ENOTTY)
+ if ((error = if_setrdomain(ifp, ifr->ifr_rdomainid)) != 0)
return (error);
- error = 0;
-
- /* Add interface to the specified rdomain */
- ifp->if_rdomain = ifr->ifr_rdomainid;
break;
case SIOCAIFGROUP:
diff --git a/sys/net/if.h b/sys/net/if.h
index 29d1cb074d9..662f7ebaf2a 100644
--- a/sys/net/if.h
+++ b/sys/net/if.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.h,v 1.178 2016/09/03 13:46:57 reyk Exp $ */
+/* $OpenBSD: if.h,v 1.179 2016/09/04 15:10:59 reyk Exp $ */
/* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */
/*
@@ -485,6 +485,7 @@ void if_congestion(void);
int if_congested(void);
__dead void unhandled_af(int);
int if_setlladdr(struct ifnet *, const uint8_t *);
+int if_setrdomain(struct ifnet *, int);
#endif /* _KERNEL */