svn commit: r225976 - stable/7/sys/net
Bjoern A. Zeeb
bz at FreeBSD.org
Tue Oct 4 13:19:22 UTC 2011
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
More information about the svn-src-stable-7
mailing list