Author: bz
Date: Tue Oct  4 13:19:21 2011
New Revision: 225976
URL: http://svn.freebsd.org/changeset/base/225976

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/7/sys/net/raw_cb.h
  stable/7/sys/net/raw_usrreq.c
  stable/7/sys/net/route.c
  stable/7/sys/net/route.h
  stable/7/sys/net/rtsock.c
Directory Properties:
  stable/7/sys/   (props changed)
  stable/7/sys/cddl/contrib/opensolaris/   (props changed)
  stable/7/sys/contrib/dev/acpica/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/net/raw_cb.h
==============================================================================
--- stable/7/sys/net/raw_cb.h   Tue Oct  4 13:18:14 2011        (r225975)
+++ stable/7/sys/net/raw_cb.h   Tue Oct  4 13:19:21 2011        (r225976)
@@ -68,9 +68,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/7/sys/net/raw_usrreq.c
==============================================================================
--- stable/7/sys/net/raw_usrreq.c       Tue Oct  4 13:18:14 2011        
(r225975)
+++ stable/7/sys/net/raw_usrreq.c       Tue Oct  4 13:19:21 2011        
(r225976)
@@ -69,6 +69,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;
@@ -81,6 +89,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/7/sys/net/route.c
==============================================================================
--- stable/7/sys/net/route.c    Tue Oct  4 13:18:14 2011        (r225975)
+++ stable/7/sys/net/route.c    Tue Oct  4 13:19:21 2011        (r225976)
@@ -344,7 +344,8 @@ rtalloc1_fib(struct sockaddr *dst, int r
                                    newrt->rt_ifp->if_addr->ifa_addr;
                                info.rti_info[RTAX_IFA] = 
newrt->rt_ifa->ifa_addr;
                        }
-                       rt_missmsg(RTM_ADD, &info, newrt->rt_flags, 0);
+                       rt_missmsg_fib(RTM_ADD, &info, newrt->rt_flags, 0,
+                           fibnum);
                } else {
                        KASSERT(rt == newrt, ("locking wrong route"));
                        RT_LOCK(newrt);
@@ -370,7 +371,7 @@ rtalloc1_fib(struct sockaddr *dst, int r
                         */
                        bzero(&info, sizeof(info));
                        info.rti_info[RTAX_DST] = dst;
-                       rt_missmsg(msgtype, &info, 0, err);
+                       rt_missmsg_fib(msgtype, &info, 0, err, fibnum);
                }
        }
        if (newrt)
@@ -591,7 +592,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);
 }
 
 int
@@ -1482,7 +1483,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int
                         * notify any listening routing agents of the change
                         */
                        RT_LOCK(rt);
-                       rt_newaddrmsg(cmd, ifa, error, rt);
+                       rt_newaddrmsg_fib(cmd, ifa, error, rt, fibnum);
                        if (cmd == RTM_DELETE) {
                                /*
                                 * If we are deleting, and we found an entry, 
then

Modified: stable/7/sys/net/route.h
==============================================================================
--- stable/7/sys/net/route.h    Tue Oct  4 13:18:14 2011        (r225975)
+++ stable/7/sys/net/route.h    Tue Oct  4 13:19:21 2011        (r225976)
@@ -351,7 +351,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 *);
 

Modified: stable/7/sys/net/rtsock.c
==============================================================================
--- stable/7/sys/net/rtsock.c   Tue Oct  4 13:18:14 2011        (r225975)
+++ stable/7/sys/net/rtsock.c   Tue Oct  4 13:19:21 2011        (r225976)
@@ -68,6 +68,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 */
@@ -124,6 +131,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)
 {
@@ -140,7 +172,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);
 }
 
 /*
@@ -727,6 +759,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
@@ -958,7 +992,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;
@@ -969,6 +1004,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;
@@ -976,6 +1019,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.
@@ -1010,7 +1060,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;
@@ -1066,10 +1117,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
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to