Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 31 Aug 2009 19:50:38 -0000
From:      Stef Walter <stef-list@memberwebs.com>
To:        "Li, Qing" <qing.li@bluecoat.com>
Cc:        "freebsd-net@FreeBSD.org" <freebsd-net@freebsd.org>, julian@elischer.org, bug-followup@FreeBSD.org
Subject:   Re: kern/134931 [patch] Unbreak setfib + routing daemons
Resent-Message-ID: <none>
References:  <200908311702.n7VH2iHI022732@whisker.bluecoat.com> <B583FBF374231F4A89607B4D08578A430527800B@bcs-mail03.internal.cacheflow.com>

| previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------000601070001040803040904
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Li, Qing wrote:
> There are other commands through the routing socket that
> can trigger routing messages. For example, issuing "ifconfig"
> to add and remove interface addresses.

Thanks for taking a look at this and catching that problem. Here's a new
patch which does the following:

 * Both rt_dispatch and raw_input accept an fib, or -1 (for any fib).
 * Pases the fib along in the context to the netisr routine
   that actually dispatches route messages.
 * As you noted, some senders of route messages don't have the
   context necessary to know what fib a message would belong to.
   Where possible we pass in the appropriate fib to the routines
   that send off route messages.

Cheers,

Stef


--------------000601070001040803040904
Content-Type: text/x-diff;
 name="freebsd-route-messages-respect-fib-2.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
	filename="freebsd-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 */

--------------000601070001040803040904--




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