kern/134931: [route] [fib] Route messages sent to all socket
listeners regardless of setfib
Stef Walter
stef at memberwebs.com
Tue Sep 22 17:10:03 UTC 2009
The following reply was made to PR kern/134931; it has been noted by GNATS.
From: Stef Walter <stef at memberwebs.com>
To: bug-followup at FreeBSD.org, count at 211.ru, m.dyadchenko at sibset-team.ru
Cc:
Subject: Re: kern/134931: [route] [fib] Route messages sent to all socket
listeners regardless of setfib
Date: Tue, 22 Sep 2009 11:42:02 -0500
This is a multi-part message in MIME format.
--------------010409020702060203010308
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
I'm having a bit of a hard time building FreeBSD current (LOR
diagnostics spew out on the console while building).
But here are the patches I've deployed into production, on a whole bunch
of network routers. They've behaved solidly, and have been running for a
couple weeks.
I've used one patch with 7.2-RELEASE-p3 (and should work against 7
stable), the other I've used with 8.0-BETA4 (and should work against
8.0-RC1 as well).
Cheers,
Stef
--------------010409020702060203010308
Content-Type: text/x-diff;
name="freebsd-80-route-messages-respect-fib-2.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="freebsd-80-route-messages-respect-fib-2.patch"
--- ./sys/net/rtsock.c.orig 2009-08-31 15:26:03.000000000 +0000
+++ ./sys/net/rtsock.c 2009-08-31 19:06:53.000000000 +0000
@@ -93,4 +93,9 @@
SYSCTL_NODE(_net, OID_AUTO, route, CTLFLAG_RD, 0, "");
+struct rt_dispatch_ctx {
+ unsigned short family; /* Socket family */
+ int fibnum; /* FIB for message or -1 for all */
+};
+
struct walkarg {
int w_tmemsize;
@@ -114,5 +119,5 @@
static void rt_getmetrics(const struct rt_metrics_lite *in,
struct rt_metrics *out);
-static void rt_dispatch(struct mbuf *, const struct sockaddr *);
+static void rt_dispatch(struct mbuf *, const struct sockaddr *, int);
static struct netisr_handler rtsock_nh = {
@@ -155,17 +160,19 @@
{
struct sockproto route_proto;
- unsigned short *family;
+ struct rt_dispatch_ctx *ctx;
struct m_tag *tag;
+ int fibnum = -1;
route_proto.sp_family = PF_ROUTE;
- tag = m_tag_find(m, PACKET_TAG_RTSOCKFAM, NULL);
+ tag = m_tag_find(m, PACKET_TAG_RTSOCK, NULL);
if (tag != NULL) {
- family = (unsigned short *)(tag + 1);
- route_proto.sp_protocol = *family;
+ ctx = (struct rt_dispatch_ctx*)(tag + 1);
+ route_proto.sp_protocol = ctx->family;
+ fibnum = ctx->fibnum;
m_tag_delete(m, tag);
} else
route_proto.sp_protocol = 0;
- raw_input(m, &route_proto, &route_src);
+ raw_input(m, &route_proto, &route_src, fibnum);
}
@@ -784,8 +791,8 @@
unsigned short family = rp->rcb_proto.sp_family;
rp->rcb_proto.sp_family = 0;
- rt_dispatch(m, info.rti_info[RTAX_DST]);
+ rt_dispatch(m, info.rti_info[RTAX_DST], so->so_fibnum);
rp->rcb_proto.sp_family = family;
} else
- rt_dispatch(m, info.rti_info[RTAX_DST]);
+ rt_dispatch(m, info.rti_info[RTAX_DST], so->so_fibnum);
}
}
@@ -1010,5 +1017,5 @@
*/
void
-rt_missmsg(int type, struct rt_addrinfo *rtinfo, int flags, int error)
+rt_missmsg(int type, struct rt_addrinfo *rtinfo, int flags, int error, int fibnum)
{
struct rt_msghdr *rtm;
@@ -1025,5 +1032,5 @@
rtm->rtm_errno = error;
rtm->rtm_addrs = rtinfo->rti_addrs;
- rt_dispatch(m, sa);
+ rt_dispatch(m, sa, fibnum);
}
@@ -1050,5 +1057,5 @@
ifm->ifm_data = ifp->if_data;
ifm->ifm_addrs = 0;
- rt_dispatch(m, NULL);
+ rt_dispatch(m, NULL, -1);
}
@@ -1062,5 +1069,5 @@
*/
void
-rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt)
+rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt, int fibnum)
{
struct rt_addrinfo info;
@@ -1120,5 +1127,5 @@
rtm->rtm_addrs = info.rti_addrs;
}
- rt_dispatch(m, sa);
+ rt_dispatch(m, sa, fibnum);
}
}
@@ -1156,5 +1163,5 @@
ifmam->ifmam_index = ifp->if_index;
ifmam->ifmam_addrs = info.rti_addrs;
- rt_dispatch(m, ifma->ifma_addr);
+ rt_dispatch(m, ifma->ifma_addr, -1);
}
@@ -1216,5 +1223,5 @@
m->m_pkthdr.len += data_len;
mtod(m, struct if_announcemsghdr *)->ifan_msglen += data_len;
- rt_dispatch(m, NULL);
+ rt_dispatch(m, NULL, -1);
}
}
@@ -1232,10 +1239,11 @@
m = rt_makeifannouncemsg(ifp, RTM_IFANNOUNCE, what, &info);
if (m != NULL)
- rt_dispatch(m, NULL);
+ rt_dispatch(m, NULL, -1);
}
static void
-rt_dispatch(struct mbuf *m, const struct sockaddr *sa)
+rt_dispatch(struct mbuf *m, const struct sockaddr *sa, int fibnum)
{
+ struct rt_dispatch_ctx *ctx;
struct m_tag *tag;
@@ -1243,14 +1251,16 @@
* Preserve the family from the sockaddr, if any, in an m_tag for
* use when injecting the mbuf into the routing socket buffer from
- * the netisr.
+ * the netisr. Additionally save the fibnum if needed.
*/
- if (sa != NULL) {
- tag = m_tag_get(PACKET_TAG_RTSOCKFAM, sizeof(unsigned short),
- M_NOWAIT);
+ if (sa != NULL || fibnum >= 0) {
+ tag = m_tag_get(PACKET_TAG_RTSOCK,
+ sizeof(struct rt_dispatch_ctx*), M_NOWAIT);
if (tag == NULL) {
m_freem(m);
return;
}
- *(unsigned short *)(tag + 1) = sa->sa_family;
+ ctx = (struct rt_dispatch_ctx*)(tag + 1);
+ ctx->family = sa->sa_family;
+ ctx->fibnum = fibnum;
m_tag_prepend(m, tag);
}
--- ./sys/net/raw_usrreq.c.orig 2009-08-31 16:04:58.000000000 +0000
+++ ./sys/net/raw_usrreq.c 2009-08-31 18:34:38.000000000 +0000
@@ -70,5 +70,5 @@
*/
void
-raw_input(struct mbuf *m0, struct sockproto *proto, struct sockaddr *src)
+raw_input(struct mbuf *m0, struct sockproto *proto, struct sockaddr *src, int fibnum)
{
struct rawcb *rp;
@@ -84,4 +84,7 @@
rp->rcb_proto.sp_protocol != proto->sp_protocol)
continue;
+ if (fibnum >= 0 && rp->rcb_socket &&
+ fibnum != rp->rcb_socket->so_fibnum)
+ continue;
if (last) {
struct mbuf *n;
--- ./sys/net/raw_cb.h.orig 2009-08-31 18:34:56.000000000 +0000
+++ ./sys/net/raw_cb.h 2009-08-31 18:35:05.000000000 +0000
@@ -73,5 +73,5 @@
int raw_attach(struct socket *, int);
void raw_detach(struct rawcb *);
-void raw_input(struct mbuf *, struct sockproto *, struct sockaddr *);
+void raw_input(struct mbuf *, struct sockproto *, struct sockaddr *, int);
/*
--- ./sys/net/route.c.orig 2009-08-31 18:18:30.000000000 +0000
+++ ./sys/net/route.c 2009-08-31 18:59:20.000000000 +0000
@@ -384,5 +384,5 @@
bzero(&info, sizeof(info));
info.rti_info[RTAX_DST] = dst;
- rt_missmsg(msgtype, &info, 0, err);
+ rt_missmsg(msgtype, &info, 0, err, fibnum);
}
done:
@@ -609,5 +609,5 @@
info.rti_info[RTAX_NETMASK] = netmask;
info.rti_info[RTAX_AUTHOR] = src;
- rt_missmsg(RTM_REDIRECT, &info, flags, error);
+ rt_missmsg(RTM_REDIRECT, &info, flags, error, fibnum);
if (ifa != NULL)
ifa_free(ifa);
@@ -1433,5 +1433,5 @@
rt->rt_ifp->if_index;
}
- rt_newaddrmsg(cmd, ifa, error, rt);
+ rt_newaddrmsg(cmd, ifa, error, rt, fibnum);
if (cmd == RTM_DELETE) {
/*
--- ./sys/net/route.h.orig 2009-08-31 18:56:05.000000000 +0000
+++ ./sys/net/route.h 2009-08-31 18:59:32.000000000 +0000
@@ -381,6 +381,6 @@
void rt_ifannouncemsg(struct ifnet *, int);
void rt_ifmsg(struct ifnet *);
-void rt_missmsg(int, struct rt_addrinfo *, int, int);
-void rt_newaddrmsg(int, struct ifaddr *, int, struct rtentry *);
+void rt_missmsg(int, struct rt_addrinfo *, int, int, int);
+void rt_newaddrmsg(int, struct ifaddr *, int, struct rtentry *, int);
void rt_newmaddrmsg(int, struct ifmultiaddr *);
int rt_setgate(struct rtentry *, struct sockaddr *, struct sockaddr *);
--- ./sys/netinet6/nd6_rtr.c.orig 2009-08-31 18:19:54.000000000 +0000
+++ ./sys/netinet6/nd6_rtr.c 2009-08-31 19:09:27.000000000 +0000
@@ -449,5 +449,5 @@
ifa = NULL;
- rt_missmsg(cmd, &info, rt->rt_flags, 0);
+ rt_missmsg(cmd, &info, rt->rt_flags, 0, -1);
if (ifa != NULL)
ifa_free(ifa);
--- ./sys/netinet6/in6.c.orig 2009-08-31 19:00:43.000000000 +0000
+++ ./sys/netinet6/in6.c 2009-08-31 19:01:00.000000000 +0000
@@ -1238,5 +1238,5 @@
rt_key(&rt0) = (struct sockaddr *)&addr;
rt0.rt_flags = RTF_HOST | RTF_STATIC;
- rt_newaddrmsg(RTM_DELETE, ifa, 0, &rt0);
+ rt_newaddrmsg(RTM_DELETE, ifa, 0, &rt0, -1);
/*
@@ -1831,5 +1831,5 @@
rt_key(&rt) = (struct sockaddr *)&addr;
rt.rt_flags = RTF_UP | RTF_HOST | RTF_STATIC;
- rt_newaddrmsg(RTM_ADD, &ia->ia_ifa, 0, &rt);
+ rt_newaddrmsg(RTM_ADD, &ia->ia_ifa, 0, &rt, -1);
}
--- ./sys/sys/mbuf.h.orig 2009-08-31 18:26:12.000000000 +0000
+++ ./sys/sys/mbuf.h 2009-08-31 18:26:24.000000000 +0000
@@ -897,5 +897,5 @@
#define PACKET_TAG_MACLABEL (19 | MTAG_PERSISTENT) /* MAC label */
#define PACKET_TAG_PF 21 /* PF + ALTQ information */
-#define PACKET_TAG_RTSOCKFAM 25 /* rtsock sa family */
+#define PACKET_TAG_RTSOCK 25 /* rtsock extra info */
#define PACKET_TAG_IPOPTIONS 27 /* Saved IP options */
#define PACKET_TAG_CARP 28 /* CARP info */
--------------010409020702060203010308
Content-Type: text/x-diff;
name="freebsd-72-route-messages-respect-fib-2.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="freebsd-72-route-messages-respect-fib-2.patch"
--- ./sys/net/rtsock.c.orig 2008-11-25 02:59:29.000000000 +0000
+++ ./sys/net/rtsock.c 2009-09-11 00:07:13.000000000 +0000
@@ -83,4 +83,9 @@
&rtsintrq.ifq_maxlen, 0, "maximum routing socket dispatch queue length");
+struct rt_dispatch_ctx {
+ unsigned short family; /* Socket family */
+ int fibnum; /* FIB for message or -1 for all */
+};
+
struct walkarg {
int w_tmemsize;
@@ -104,5 +109,5 @@
static void rt_getmetrics(const struct rt_metrics_lite *in,
struct rt_metrics *out);
-static void rt_dispatch(struct mbuf *, const struct sockaddr *);
+static void rt_dispatch(struct mbuf *, const struct sockaddr *, int);
static void
@@ -123,17 +128,19 @@
{
struct sockproto route_proto;
- unsigned short *family;
+ struct rt_dispatch_ctx *ctx;
struct m_tag *tag;
+ int fibnum = -1;
route_proto.sp_family = PF_ROUTE;
- tag = m_tag_find(m, PACKET_TAG_RTSOCKFAM, NULL);
+ tag = m_tag_find(m, PACKET_TAG_RTSOCK, NULL);
if (tag != NULL) {
- family = (unsigned short *)(tag + 1);
- route_proto.sp_protocol = *family;
+ ctx = (struct rt_dispatch_ctx*)(tag + 1);
+ route_proto.sp_protocol = ctx->family;
+ fibnum = ctx->fibnum;
m_tag_delete(m, tag);
} else
route_proto.sp_protocol = 0;
- raw_input(m, &route_proto, &route_src);
+ raw_input(m, &route_proto, &route_src, fibnum);
}
@@ -605,8 +612,8 @@
unsigned short family = rp->rcb_proto.sp_family;
rp->rcb_proto.sp_family = 0;
- rt_dispatch(m, info.rti_info[RTAX_DST]);
+ rt_dispatch(m, info.rti_info[RTAX_DST], so->so_fibnum);
rp->rcb_proto.sp_family = family;
} else
- rt_dispatch(m, info.rti_info[RTAX_DST]);
+ rt_dispatch(m, info.rti_info[RTAX_DST], so->so_fibnum);
}
}
@@ -829,5 +836,5 @@
*/
void
-rt_missmsg(int type, struct rt_addrinfo *rtinfo, int flags, int error)
+rt_missmsg(int type, struct rt_addrinfo *rtinfo, int flags, int error, int fibnum)
{
struct rt_msghdr *rtm;
@@ -844,5 +851,5 @@
rtm->rtm_errno = error;
rtm->rtm_addrs = rtinfo->rti_addrs;
- rt_dispatch(m, sa);
+ rt_dispatch(m, sa, fibnum);
}
@@ -869,5 +876,5 @@
ifm->ifm_data = ifp->if_data;
ifm->ifm_addrs = 0;
- rt_dispatch(m, NULL);
+ rt_dispatch(m, NULL, -1);
}
@@ -881,5 +888,5 @@
*/
void
-rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt)
+rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt, int fibnum)
{
struct rt_addrinfo info;
@@ -937,5 +944,5 @@
rtm->rtm_addrs = info.rti_addrs;
}
- rt_dispatch(m, sa);
+ rt_dispatch(m, sa, fibnum);
}
}
@@ -973,5 +980,5 @@
ifmam->ifmam_index = ifp->if_index;
ifmam->ifmam_addrs = info.rti_addrs;
- rt_dispatch(m, ifma->ifma_addr);
+ rt_dispatch(m, ifma->ifma_addr, -1);
}
@@ -1033,5 +1040,5 @@
m->m_pkthdr.len += data_len;
mtod(m, struct if_announcemsghdr *)->ifan_msglen += data_len;
- rt_dispatch(m, NULL);
+ rt_dispatch(m, NULL, -1);
}
}
@@ -1049,10 +1056,11 @@
m = rt_makeifannouncemsg(ifp, RTM_IFANNOUNCE, what, &info);
if (m != NULL)
- rt_dispatch(m, NULL);
+ rt_dispatch(m, NULL, -1);
}
static void
-rt_dispatch(struct mbuf *m, const struct sockaddr *sa)
+rt_dispatch(struct mbuf *m, const struct sockaddr *sa, int fibnum)
{
+ struct rt_dispatch_ctx *ctx;
struct m_tag *tag;
@@ -1060,14 +1068,16 @@
* Preserve the family from the sockaddr, if any, in an m_tag for
* use when injecting the mbuf into the routing socket buffer from
- * the netisr.
+ * the netisr. Additionally save the fibnum if needed.
*/
- if (sa != NULL) {
- tag = m_tag_get(PACKET_TAG_RTSOCKFAM, sizeof(unsigned short),
- M_NOWAIT);
+ if (sa != NULL || fibnum >= 0) {
+ tag = m_tag_get(PACKET_TAG_RTSOCK,
+ sizeof(struct rt_dispatch_ctx*), M_NOWAIT);
if (tag == NULL) {
m_freem(m);
return;
}
- *(unsigned short *)(tag + 1) = sa->sa_family;
+ ctx = (struct rt_dispatch_ctx*)(tag + 1);
+ ctx->family = sa->sa_family;
+ ctx->fibnum = fibnum;
m_tag_prepend(m, tag);
}
--- ./sys/net/raw_usrreq.c.orig 2008-11-25 02:59:29.000000000 +0000
+++ ./sys/net/raw_usrreq.c 2009-09-11 00:07:13.000000000 +0000
@@ -68,5 +68,5 @@
*/
void
-raw_input(struct mbuf *m0, struct sockproto *proto, struct sockaddr *src)
+raw_input(struct mbuf *m0, struct sockproto *proto, struct sockaddr *src, int fibnum)
{
struct rawcb *rp;
@@ -82,4 +82,7 @@
rp->rcb_proto.sp_protocol != proto->sp_protocol)
continue;
+ if (fibnum >= 0 && rp->rcb_socket &&
+ fibnum != rp->rcb_socket->so_fibnum)
+ continue;
if (last) {
struct mbuf *n;
--- ./sys/net/raw_cb.h.orig 2008-11-25 02:59:29.000000000 +0000
+++ ./sys/net/raw_cb.h 2009-09-11 00:07:13.000000000 +0000
@@ -71,5 +71,5 @@
int raw_attach(struct socket *, int);
void raw_detach(struct rawcb *);
-void raw_input(struct mbuf *, struct sockproto *, struct sockaddr *);
+void raw_input(struct mbuf *, struct sockproto *, struct sockaddr *, int);
/*
--- ./sys/net/route.c.orig 2008-11-25 02:59:29.000000000 +0000
+++ ./sys/net/route.c 2009-09-11 00:08:28.000000000 +0000
@@ -338,5 +338,5 @@
info.rti_info[RTAX_IFA] = newrt->rt_ifa->ifa_addr;
}
- rt_missmsg(RTM_ADD, &info, newrt->rt_flags, 0);
+ rt_missmsg(RTM_ADD, &info, newrt->rt_flags, 0, fibnum);
} else {
KASSERT(rt == newrt, ("locking wrong route"));
@@ -362,5 +362,5 @@
bzero(&info, sizeof(info));
info.rti_info[RTAX_DST] = dst;
- rt_missmsg(msgtype, &info, 0, err);
+ rt_missmsg(msgtype, &info, 0, err, fibnum);
}
}
@@ -575,5 +575,5 @@
info.rti_info[RTAX_NETMASK] = netmask;
info.rti_info[RTAX_AUTHOR] = src;
- rt_missmsg(RTM_REDIRECT, &info, flags, error);
+ rt_missmsg(RTM_REDIRECT, &info, flags, error, fibnum);
}
@@ -1464,5 +1464,5 @@
*/
RT_LOCK(rt);
- rt_newaddrmsg(cmd, ifa, error, rt);
+ rt_newaddrmsg(cmd, ifa, error, rt, fibnum);
if (cmd == RTM_DELETE) {
/*
--- ./sys/net/route.h.orig 2008-11-25 02:59:29.000000000 +0000
+++ ./sys/net/route.h 2009-09-11 00:07:13.000000000 +0000
@@ -350,6 +350,6 @@
void rt_ifannouncemsg(struct ifnet *, int);
void rt_ifmsg(struct ifnet *);
-void rt_missmsg(int, struct rt_addrinfo *, int, int);
-void rt_newaddrmsg(int, struct ifaddr *, int, struct rtentry *);
+void rt_missmsg(int, struct rt_addrinfo *, int, int, int);
+void rt_newaddrmsg(int, struct ifaddr *, int, struct rtentry *, int);
void rt_newmaddrmsg(int, struct ifmultiaddr *);
int rt_setgate(struct rtentry *, struct sockaddr *, struct sockaddr *);
--- ./sys/netinet6/nd6_rtr.c.orig 2008-11-25 02:59:29.000000000 +0000
+++ ./sys/netinet6/nd6_rtr.c 2009-09-11 00:07:13.000000000 +0000
@@ -444,5 +444,5 @@
}
- rt_missmsg(cmd, &info, rt->rt_flags, 0);
+ rt_missmsg(cmd, &info, rt->rt_flags, 0, -1);
}
--- ./sys/netinet6/in6.c.orig 2009-06-10 10:31:11.000000000 +0000
+++ ./sys/netinet6/in6.c 2009-09-11 00:09:37.000000000 +0000
@@ -190,5 +190,5 @@
}
- rt_newaddrmsg(cmd, ifa, e, nrt);
+ rt_newaddrmsg(cmd, ifa, e, nrt, -1);
if (cmd == RTM_DELETE)
RTFREE_LOCKED(nrt);
--- ./sys/sys/mbuf.h.orig 2008-11-25 02:59:29.000000000 +0000
+++ ./sys/sys/mbuf.h 2009-09-11 00:10:16.000000000 +0000
@@ -852,5 +852,5 @@
#define PACKET_TAG_MACLABEL (19 | MTAG_PERSISTENT) /* MAC label */
#define PACKET_TAG_PF 21 /* PF + ALTQ information */
-#define PACKET_TAG_RTSOCKFAM 25 /* rtsock sa family */
+#define PACKET_TAG_RTSOCK 25 /* rtsock extra info */
#define PACKET_TAG_IPOPTIONS 27 /* Saved IP options */
#define PACKET_TAG_CARP 28 /* CARP info */
--------------010409020702060203010308--
More information about the freebsd-net
mailing list