Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 4 Oct 2011 13:18:14 +0000 (UTC)
From:      "Bjoern A. Zeeb" <bz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r225975 - stable/8/sys/net
Message-ID:  <201110041318.p94DIE3o059214@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bz
Date: Tue Oct  4 13:18:14 2011
New Revision: 225975
URL: http://svn.freebsd.org/changeset/base/225975

Log:
  MFC r225837:
  
   Pass the fibnum where we need filtering of the message on the
   rtsock allowing routing daemons to filter routing updates on an
   rtsock per FIB.
  
   Adjust raw_input() and split it into wrapper and a new function
   taking an optional callback argument even though we only have one
   consumer [1] to keep the hackish flags local to rtsock.c.
  
   PR:		kern/134931
   Submitted by:	multiple (see PR)
   Suggested by:	rwatson [1]
   Reviewed by:	rwatson

Modified:
  stable/8/sys/net/raw_cb.h
  stable/8/sys/net/raw_usrreq.c
  stable/8/sys/net/route.c
  stable/8/sys/net/route.h
  stable/8/sys/net/rtsock.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/net/raw_cb.h
==============================================================================
--- stable/8/sys/net/raw_cb.h	Tue Oct  4 13:15:12 2011	(r225974)
+++ stable/8/sys/net/raw_cb.h	Tue Oct  4 13:18:14 2011	(r225975)
@@ -70,9 +70,14 @@ pr_init_t	raw_init;
  * Library routines for raw socket usrreq functions; will always be wrapped
  * so that protocol-specific functions can be handled.
  */
+typedef int (*raw_input_cb_fn)(struct mbuf *, struct sockproto *,
+    struct sockaddr *, struct rawcb *);
+
 int	 raw_attach(struct socket *, int);
 void	 raw_detach(struct rawcb *);
 void	 raw_input(struct mbuf *, struct sockproto *, struct sockaddr *);
+void	 raw_input_ext(struct mbuf *, struct sockproto *, struct sockaddr *,
+	    raw_input_cb_fn);
 
 /*
  * Generic pr_usrreqs entries for raw socket protocols, usually wrapped so

Modified: stable/8/sys/net/raw_usrreq.c
==============================================================================
--- stable/8/sys/net/raw_usrreq.c	Tue Oct  4 13:15:12 2011	(r225974)
+++ stable/8/sys/net/raw_usrreq.c	Tue Oct  4 13:18:14 2011	(r225975)
@@ -71,6 +71,14 @@ raw_init(void)
 void
 raw_input(struct mbuf *m0, struct sockproto *proto, struct sockaddr *src)
 {
+
+	return (raw_input_ext(m0, proto, src, NULL));
+}
+
+void
+raw_input_ext(struct mbuf *m0, struct sockproto *proto, struct sockaddr *src,
+    raw_input_cb_fn cb)
+{
 	struct rawcb *rp;
 	struct mbuf *m = m0;
 	struct socket *last;
@@ -83,6 +91,8 @@ raw_input(struct mbuf *m0, struct sockpr
 		if (rp->rcb_proto.sp_protocol  &&
 		    rp->rcb_proto.sp_protocol != proto->sp_protocol)
 			continue;
+		if (cb != NULL && (*cb)(m, proto, src, rp) != 0)
+			continue;
 		if (last) {
 			struct mbuf *n;
 			n = m_copy(m, 0, (int)M_COPYALL);

Modified: stable/8/sys/net/route.c
==============================================================================
--- stable/8/sys/net/route.c	Tue Oct  4 13:15:12 2011	(r225974)
+++ stable/8/sys/net/route.c	Tue Oct  4 13:18:14 2011	(r225975)
@@ -390,7 +390,7 @@ miss:
 		 */
 		bzero(&info, sizeof(info));
 		info.rti_info[RTAX_DST] = dst;
-		rt_missmsg(msgtype, &info, 0, err);
+		rt_missmsg_fib(msgtype, &info, 0, err, fibnum);
 	}	
 done:
 	if (newrt)
@@ -615,7 +615,7 @@ out:
 	info.rti_info[RTAX_GATEWAY] = gateway;
 	info.rti_info[RTAX_NETMASK] = netmask;
 	info.rti_info[RTAX_AUTHOR] = src;
-	rt_missmsg(RTM_REDIRECT, &info, flags, error);
+	rt_missmsg_fib(RTM_REDIRECT, &info, flags, error, fibnum);
 	if (ifa != NULL)
 		ifa_free(ifa);
 }
@@ -1527,7 +1527,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int
 			}
 			RT_ADDREF(rt);
 			RT_UNLOCK(rt);
-			rt_newaddrmsg(cmd, ifa, error, rt);
+			rt_newaddrmsg_fib(cmd, ifa, error, rt, fibnum);
 			RT_LOCK(rt);
 			RT_REMREF(rt);
 			if (cmd == RTM_DELETE) {

Modified: stable/8/sys/net/route.h
==============================================================================
--- stable/8/sys/net/route.h	Tue Oct  4 13:15:12 2011	(r225974)
+++ stable/8/sys/net/route.h	Tue Oct  4 13:18:14 2011	(r225975)
@@ -367,7 +367,9 @@ void	 rt_ieee80211msg(struct ifnet *, in
 void	 rt_ifannouncemsg(struct ifnet *, int);
 void	 rt_ifmsg(struct ifnet *);
 void	 rt_missmsg(int, struct rt_addrinfo *, int, int);
+void	 rt_missmsg_fib(int, struct rt_addrinfo *, int, int, int);
 void	 rt_newaddrmsg(int, struct ifaddr *, int, struct rtentry *);
+void	 rt_newaddrmsg_fib(int, struct ifaddr *, int, struct rtentry *, int);
 void	 rt_newmaddrmsg(int, struct ifmultiaddr *);
 int	 rt_setgate(struct rtentry *, struct sockaddr *, struct sockaddr *);
 void 	 rt_maskedcopy(struct sockaddr *, struct sockaddr *, struct sockaddr *);

Modified: stable/8/sys/net/rtsock.c
==============================================================================
--- stable/8/sys/net/rtsock.c	Tue Oct  4 13:15:12 2011	(r225974)
+++ stable/8/sys/net/rtsock.c	Tue Oct  4 13:18:14 2011	(r225975)
@@ -122,6 +122,13 @@ MALLOC_DEFINE(M_RTABLE, "routetbl", "rou
 static struct	sockaddr route_src = { 2, PF_ROUTE, };
 static struct	sockaddr sa_zero   = { sizeof(sa_zero), AF_INET, };
 
+/*
+ * Used by rtsock/raw_input callback code to decide whether to filter the update
+ * notification to a socket bound to a particular FIB.
+ */
+#define	RTS_FILTER_FIB	M_PROTO8
+#define	RTS_ALLFIBS	-1
+
 static struct {
 	int	ip_count;	/* attached w/ AF_INET */
 	int	ip6_count;	/* attached w/ AF_INET6 */
@@ -196,6 +203,31 @@ rts_init(void)
 }
 SYSINIT(rtsock, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, rts_init, 0);
 
+static int
+raw_input_rts_cb(struct mbuf *m, struct sockproto *proto, struct sockaddr *src,
+    struct rawcb *rp)
+{
+	int fibnum;
+
+	KASSERT(m != NULL, ("%s: m is NULL", __func__));
+	KASSERT(proto != NULL, ("%s: proto is NULL", __func__));
+	KASSERT(rp != NULL, ("%s: rp is NULL", __func__));
+
+	/* No filtering requested. */
+	if ((m->m_flags & RTS_FILTER_FIB) == 0)
+		return (0);
+
+	/* Check if it is a rts and the fib matches the one of the socket. */
+	fibnum = M_GETFIB(m);
+	if (proto->sp_family != PF_ROUTE ||
+	    rp->rcb_socket == NULL ||
+	    rp->rcb_socket->so_fibnum == fibnum)
+		return (0);
+
+	/* Filtering requested and no match, the socket shall be skipped. */
+	return (1);
+}
+
 static void
 rts_input(struct mbuf *m)
 {
@@ -212,7 +244,7 @@ rts_input(struct mbuf *m)
 	} else
 		route_proto.sp_protocol = 0;
 
-	raw_input(m, &route_proto, &route_src);
+	raw_input_ext(m, &route_proto, &route_src, raw_input_rts_cb);
 }
 
 /*
@@ -886,6 +918,8 @@ flush:
 		Free(rtm);
 	}
 	if (m) {
+		M_SETFIB(m, so->so_fibnum);
+		m->m_flags |= RTS_FILTER_FIB;
 		if (rp) {
 			/*
 			 * XXX insure we don't get a copy by
@@ -1125,7 +1159,8 @@ again:
  * destination.
  */
 void
-rt_missmsg(int type, struct rt_addrinfo *rtinfo, int flags, int error)
+rt_missmsg_fib(int type, struct rt_addrinfo *rtinfo, int flags, int error,
+    int fibnum)
 {
 	struct rt_msghdr *rtm;
 	struct mbuf *m;
@@ -1136,6 +1171,14 @@ rt_missmsg(int type, struct rt_addrinfo 
 	m = rt_msg1(type, rtinfo);
 	if (m == NULL)
 		return;
+
+	if (fibnum != RTS_ALLFIBS) {
+		KASSERT(fibnum >= 0 && fibnum < rt_numfibs, ("%s: fibnum out "
+		    "of range 0 <= %d < %d", __func__, fibnum, rt_numfibs));
+		M_SETFIB(m, fibnum);
+		m->m_flags |= RTS_FILTER_FIB;
+	}
+
 	rtm = mtod(m, struct rt_msghdr *);
 	rtm->rtm_flags = RTF_DONE | flags;
 	rtm->rtm_errno = error;
@@ -1143,6 +1186,13 @@ rt_missmsg(int type, struct rt_addrinfo 
 	rt_dispatch(m, sa);
 }
 
+void
+rt_missmsg(int type, struct rt_addrinfo *rtinfo, int flags, int error)
+{
+
+	rt_missmsg_fib(type, rtinfo, flags, error, RTS_ALLFIBS);
+}
+
 /*
  * This routine is called to generate a message from the routing
  * socket indicating that the status of a network interface has changed.
@@ -1177,7 +1227,8 @@ rt_ifmsg(struct ifnet *ifp)
  * copies of it.
  */
 void
-rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt)
+rt_newaddrmsg_fib(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt,
+    int fibnum)
 {
 	struct rt_addrinfo info;
 	struct sockaddr *sa = NULL;
@@ -1235,10 +1286,24 @@ rt_newaddrmsg(int cmd, struct ifaddr *if
 			rtm->rtm_errno = error;
 			rtm->rtm_addrs = info.rti_addrs;
 		}
+		if (fibnum != RTS_ALLFIBS) {
+			KASSERT(fibnum >= 0 && fibnum < rt_numfibs, ("%s: "
+			    "fibnum out of range 0 <= %d < %d", __func__,
+			     fibnum, rt_numfibs));
+			M_SETFIB(m, fibnum);
+			m->m_flags |= RTS_FILTER_FIB;
+		}
 		rt_dispatch(m, sa);
 	}
 }
 
+void
+rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt)
+{
+
+	rt_newaddrmsg_fib(cmd, ifa, error, rt, RTS_ALLFIBS);
+}
+
 /*
  * This is the analogue to the rt_newaddrmsg which performs the same
  * function but for multicast group memberhips.  This is easier since



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201110041318.p94DIE3o059214>