From nobody@FreeBSD.org  Mon May 25 10:06:54 2009
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 373A81065672
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 25 May 2009 10:06:54 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 09ADF8FC18
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 25 May 2009 10:06:54 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id n4PA6rS9094639
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 25 May 2009 10:06:53 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id n4PA6rxE094638;
	Mon, 25 May 2009 10:06:53 GMT
	(envelope-from nobody)
Message-Id: <200905251006.n4PA6rxE094638@www.freebsd.org>
Date: Mon, 25 May 2009 10:06:53 GMT
From: Stanislav Svirid <count@211.ru>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [route] [fib] Route messages sent to all socket listeners regardless of setfib
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         134931
>Category:       kern
>Synopsis:       [route] Route messages sent to all socket listeners regardless of setfib(1)
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bz
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon May 25 10:10:01 UTC 2009
>Closed-Date:    Tue Oct 04 13:19:38 UTC 2011
>Last-Modified:  Tue Oct  4 13:20:10 UTC 2011
>Originator:     Stanislav Svirid
>Release:        FreeBSD vrf01.211.ru 7.2-RELEASE FreeBSD 7.2-RELEASE #3: Wed May 20 14:24:58 NOVST 2009     root@vrf01.211.ru:/usr/obj/usr/src/sys/VRFSPLITER  amd64
>Organization:
>Environment:
FreeBSD vrf01.211.ru 7.2-RELEASE FreeBSD 7.2-RELEASE #3: Wed May 20 14:24:58 NOVST 2009     root@vrf01.211.ru:/usr/obj/usr/src/sys/VRFSPLITER  amd64

>Description:
I have one router with 2 quagga running with different setfib.
First without setfib (0 i sdefault), second with setfib 1.

When quagga receive route from OSPF/BGP its install it into kernel.
Route installed in right FIB.
When route installed in FIB, kernel sends message into route socket.
Quagga listen routing socket and see ADD message and add route into internal tables as 'Kernel'.

For example,
quagga1# sh ip route 10.0.5.0
Routing entry for 10.0.5.0/24
  Known via "kernel", distance 0, metric 0, best
  * 89.189.190.185, via inet

Quagga1 see route as 'kernel', but there are no route in kernel default rt.
root@vrf01 ttyp4:~#netstat -rn | grep 10.0.5
root@vrf01 ttyp4:~#

But in FIB 1 route is present:
root@vrf01 ttyp4:~#setfib 1 netstat -rn | grep 10.0.5
10.0.5.0/24        89.189.190.185     UG1         0        0   inet
root@vrf01 ttyp4:~#

I think the problem is in listening routing socket, because 'route -n monitor' see all routing events regardless of setfib.

Experiment:
Run:
root@vrf01 ttyp4:~#setfib 1 route -n monitor

than in another session add route '192.168.0.0/24 via 127.0.0.1'
root@vrf01 ttyp5:~#route add 192.168.0.0/24 127.0.0.1
add net 192.168.0.0: gateway 127.0.0.1

And see, in "monitor" session appears:
got message of size 192 on Mon May 25 16:58:39 2009
RTM_ADD: Add Route: len 192, pid: 24923, seq 1, errno 0, flags:<UP,GATEWAY,DONE,STATIC>
locks:  inits: 
sockaddrs: <DST,GATEWAY,NETMASK>
 192.168.0.0 127.0.0.1 (0) 0 ffff ff

I think it's wrong, when route see messages from another fib ;)
>How-To-Repeat:
You must have compiled kernel with more than 1 FIB.
options         ROUTETABLES=2

buildkernel; install; reload.

In one session run:
setfib 1 route -n monitor

In another add route, for example:
route add 192.168.0.0/24 127.0.0.1

In monitor session you must see something like this:
got message of size 192 on Mon May 25 16:58:39 2009
RTM_ADD: Add Route: len 192, pid: 24923, seq 1, errno 0, flags:<UP,GATEWAY,DONE,STATIC>
locks:  inits: 
sockaddrs: <DST,GATEWAY,NETMASK>
 192.168.0.0 127.0.0.1 (0) 0 ffff ff

And its wrong ;)
>Fix:


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-net 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Mon May 25 13:26:31 UTC 2009 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=134931 

From: Mark Linimon <linimon@lonesome.com>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/134931: [route] [fib] Route messages sent to all socket
	listeners regardless of setfib
Date: Tue, 26 May 2009 09:43:41 -0500

 ----- Forwarded message from Bruce Simpson <bms@incunabulum.net> -----
 
 From: Bruce Simpson <bms@incunabulum.net>
 To: linimon@FreeBSD.org
 CC: freebsd-bugs@FreeBSD.org, freebsd-net@FreeBSD.org
 Subject: Re: kern/134931: [route] [fib] Route messages sent to all socket
 	listeners regardless of setfib
 
 linimon@FreeBSD.org wrote:
 > Synopsis: [route] [fib] Route messages sent to all socket listeners regardless of setfib
 >   
 
 That might actually be a feature, however, the "API contract" with the  
 multiple routing table support might not have covered this, so it might be 
 "undefined behaviour".
 
 
 ----- End forwarded message -----

From: Stanislav A Svirid <s.svirid@sibset-team.ru>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/134931: [route] [fib] Route messages sent to all socket
	listeners regardless of setfib
Date: Wed, 27 May 2009 12:28:58 +0700

 Bruce Simpson wrote:
 >> Synopsis: [route] [fib] Route messages sent to all socket listeners regardless of setfib
 >>
 >
 > That might actually be a feature, however, the "API contract" with the
 > multiple routing table support might not have covered this, so it might be
 > "undefined behaviour".
 
 So, how routing daemon can decide in what FIB route is changed?
 Or it can't now?
 
 -- 
 Stanislav Svirid
 > Siberian Networks, Novosibirsk, Russia
 > SAS-RIPE, 3909675@ICQ

From: Stef Walter <stef-list@memberwebs.com>
To: bug-followup@FreeBSD.org, count@211.ru
Cc:  
Subject: Re: kern/134931:[route] [fib] Route messages sent to all socket listeners
 regardless of setfib
Date: Mon, 31 Aug 09 17:20:06 UTC

 This is a multi-part message in MIME format.
 --------------030509050508050401080102
 Content-Type: text/plain; charset=ISO-8859-1
 Content-Transfer-Encoding: 7bit
 
 As it currently stands, using routing daemons + multiple fibs in FreeBSD
 7.x and 8.x is pretty much broken. Here's a patch which fixes the problem.
 
 I agree in principle with Mark that having future route messages might
 be able to let routing daemons differentiate between various fibs and
 manage them, and that this might be a feature.... However any
 implementation of that would likely break API and ABI, and very probably
 exist purely in FreeBSD 9.x.
 
 All the best,
 
 Stef
 
 --------------030509050508050401080102
 Content-Type: text/x-diff;
  name="freebsd-route-messages-respect-fib.patch"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="freebsd-route-messages-respect-fib.patch"
 
 --- sys/net/rtsock.c.orig	2009-08-31 15:26:03.000000000 +0000
 +++ sys/net/rtsock.c	2009-08-31 16:07:06.000000000 +0000
 @@ -777,4 +777,5 @@
  	}
  	if (m) {
 +		M_SETFIB(m, so->so_fibnum);
  		if (rp) {
  			/*
 --- sys/net/raw_usrreq.c.orig	2009-08-31 16:04:58.000000000 +0000
 +++ sys/net/raw_usrreq.c	2009-08-31 16:05:11.000000000 +0000
 @@ -84,4 +84,7 @@
  		    rp->rcb_proto.sp_protocol != proto->sp_protocol)
  			continue;
 +		if (proto->sp_family == PF_ROUTE && rp->rcb_socket &&
 +		    M_GETFIB (m) != rp->rcb_socket->so_fibnum) 
 +			continue; 
  		if (last) {
  			struct mbuf *n;
 
 --------------030509050508050401080102--
 

From: Stef Walter <stef-list@memberwebs.com>
To: "Li, Qing" <qing.li@bluecoat.com>
Cc: "freebsd-net@FreeBSD.org" <freebsd-net@freebsd.org>, 
 bug-followup@FreeBSD.org, julian@elischer.org
Subject: Re: kern/134931 [patch] Unbreak setfib + routing daemons
Date: Mon, 31 Aug 09 20:00:13 UTC

 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--
 

From: "Dyadchenko Mihail, Siberian Networks" <m.dyadchenko@sibset-team.ru>
To: bug-followup@FreeBSD.org, Stef Walter <stef-list@memberwebs.com>
Cc:  
Subject: Re: kern/134931: [route] [fib] Route messages sent to all socket
 listeners regardless of setfib
Date: Tue, 22 Sep 2009 16:33:58 +0700

 For that version of source code this patch?
 And date of it.
 
 -- 
 Dyadchenko Mihail
 Senior System Administrator, Siberian Networks
 Tel. (383) 205 0000 Fax. (383) 201-13-54
 M.Dyadchenko@sibset-team.ru http://www.sibset.ru/

From: Stef Walter <stef@memberwebs.com>
To: bug-followup@FreeBSD.org, count@211.ru, m.dyadchenko@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--

From: "Dyadchenko Mihail, Siberian Networks" <m.dyadchenko@sibset-team.ru>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/134931: [route] [fib] Route messages sent to all socket
 listeners regardless of setfib
Date: Mon, 5 Oct 2009 11:30:32 +0700

 Hello.
 
 Thanks, 7.2-Release was patched and recompiled successful, test with
 route add + route monitor also looks normal.
 
 May be on this week I will test in in real network.
 
 
 -- 
 Dyadchenko Mihail
 Senior System Administrator, Siberian Networks
 Tel. (383) 205 0000 Fax. (383) 201-13-54
 M.Dyadchenko@sibset-team.ru http://www.sibset.ru/

From: "Alexander V. Chernikov" <melifaro@ipfw.ru>
To: bug-followup@FreeBSD.org, count@211.ru
Cc:  
Subject: Re: kern/134931: [route] Route messages sent to all socket listeners
 regardless of setfib(1)
Date: Sun, 31 Oct 2010 10:27:29 +0300

 This is a multi-part message in MIME format.
 --------------040709010609040905070606
 Content-Type: text/plain; charset=ISO-8859-1
 Content-Transfer-Encoding: 7bit
 
 This modified patch works well for me on FreeBSD 7.2-RELEASE-p5 amd64
 
 --------------040709010609040905070606
 Content-Type: text/plain;
  name="rtsock.diff"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="rtsock.diff"
 
 --- sys/net/rtsock.c.orig	2009-04-15 07:14:26.000000000 +0400
 +++ sys/net/rtsock.c	2010-10-15 16:52:57.000000000 +0400
 @@ -88,6 +88,11 @@
  SYSCTL_INT(_net_route, OID_AUTO, netisr_maxqlen, CTLFLAG_RW,
      &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;
  	int	w_op, w_arg;
 @@ -109,7 +114,7 @@
  			struct rt_metrics_lite *out);
  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
  rts_init(void)
 @@ -128,19 +133,21 @@
  rts_input(struct mbuf *m)
  {
  	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);
  }
  
  /*
 @@ -729,10 +736,10 @@
  			 */
  			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);
  	}
      }
  	return (error);
 @@ -953,7 +960,7 @@
   * destination.
   */
  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;
  	struct mbuf *m;
 @@ -968,7 +975,7 @@
  	rtm->rtm_flags = RTF_DONE | flags;
  	rtm->rtm_errno = error;
  	rtm->rtm_addrs = rtinfo->rti_addrs;
 -	rt_dispatch(m, sa);
 +	rt_dispatch(m, sa, fibnum);
  }
  
  /*
 @@ -993,7 +1000,7 @@
  	ifm->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
  	ifm->ifm_data = ifp->if_data;
  	ifm->ifm_addrs = 0;
 -	rt_dispatch(m, NULL);
 +	rt_dispatch(m, NULL, -1);
  }
  
  /*
 @@ -1005,7 +1012,7 @@
   * copies of it.
   */
  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;
  	struct sockaddr *sa = NULL;
 @@ -1061,7 +1068,7 @@
  			rtm->rtm_errno = error;
  			rtm->rtm_addrs = info.rti_addrs;
  		}
 -		rt_dispatch(m, sa);
 +		rt_dispatch(m, sa, fibnum);
  	}
  }
  
 @@ -1097,7 +1104,7 @@
  	    __func__));
  	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);
  }
  
  static struct mbuf *
 @@ -1157,7 +1164,7 @@
  		if (m->m_flags & M_PKTHDR)
  			m->m_pkthdr.len += data_len;
  		mtod(m, struct if_announcemsghdr *)->ifan_msglen += data_len;
 -		rt_dispatch(m, NULL);
 +		rt_dispatch(m, NULL, -1);
  	}
  }
  
 @@ -1173,27 +1180,30 @@
  
  	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;
  
  	/*
  	 * 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);
  	}
  	netisr_queue(NETISR_ROUTE, m);	/* mbuf is free'd on failure. */
 --- sys/net/raw_usrreq.c.orig	2009-04-15 07:14:26.000000000 +0400
 +++ sys/net/raw_usrreq.c	2010-10-15 16:52:57.000000000 +0400
 @@ -67,7 +67,7 @@
   * Raw protocol interface.
   */
  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;
  	struct mbuf *m = m0;
 @@ -81,6 +81,9 @@
  		if (rp->rcb_proto.sp_protocol  &&
  		    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;
  			n = m_copy(m, 0, (int)M_COPYALL);
 --- sys/net/raw_cb.h.orig	2009-04-15 07:14:26.000000000 +0400
 +++ sys/net/raw_cb.h	2010-10-15 16:52:57.000000000 +0400
 @@ -70,7 +70,7 @@
   */
  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);
  
  /*
   * Generic pr_usrreqs entries for raw socket protocols, usually wrapped so
 --- sys/net/route.c.orig	2009-04-15 07:14:26.000000000 +0400
 +++ sys/net/route.c	2010-10-15 17:02:25.000000000 +0400
 @@ -344,7 +344,7 @@
  				    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(RTM_ADD, &info, newrt->rt_flags, 0, fibnum);
  		} else {
  			KASSERT(rt == newrt, ("locking wrong route"));
  			RT_LOCK(newrt);
 @@ -370,7 +370,7 @@
  			 */
  			bzero(&info, sizeof(info));
  			info.rti_info[RTAX_DST] = dst;
 -			rt_missmsg(msgtype, &info, 0, err);
 +			rt_missmsg(msgtype, &info, 0, err, fibnum);
  		}
  	}
  	if (newrt)
 @@ -591,7 +591,7 @@
  	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(RTM_REDIRECT, &info, flags, error, fibnum);
  }
  
  int
 @@ -1482,7 +1482,7 @@
  			 * notify any listening routing agents of the change
  			 */
  			RT_LOCK(rt);
 -			rt_newaddrmsg(cmd, ifa, error, rt);
 +			rt_newaddrmsg(cmd, ifa, error, rt, fibnum);
  			if (cmd == RTM_DELETE) {
  				/*
  				 * If we are deleting, and we found an entry, then
 --- sys/net/route.h.orig	2009-04-15 07:14:26.000000000 +0400
 +++ sys/net/route.h	2010-10-15 16:52:57.000000000 +0400
 @@ -350,8 +350,8 @@
  void	 rt_ieee80211msg(struct ifnet *, int, void *, size_t);
  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/in6.c.orig	2009-06-10 14:31:11.000000000 +0400
 +++ sys/netinet6/in6.c	2010-10-15 17:03:36.000000000 +0400
 @@ -190,7 +190,7 @@
  			nrt->rt_ifa = ifa;
  		}
  
 -		rt_newaddrmsg(cmd, ifa, e, nrt);
 +		rt_newaddrmsg(cmd, ifa, e, nrt, -1);
  		if (cmd == RTM_DELETE)
  			RTFREE_LOCKED(nrt);
  		else {
 --- sys/sys/mbuf.h.orig	2009-04-15 07:14:26.000000000 +0400
 +++ sys/sys/mbuf.h	2010-10-15 16:54:59.000000000 +0400
 @@ -851,7 +851,7 @@
  #define	PACKET_TAG_IPFORWARD			18 /* ipforward info */
  #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 */
  
 
 --------------040709010609040905070606--
Responsible-Changed-From-To: freebsd-net->hrs 
Responsible-Changed-By: hrs 
Responsible-Changed-When: Sat Jul 16 15:46:50 UTC 2011 
Responsible-Changed-Why:  
I'll take this. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=134931 

From: "Alexander V. Chernikov" <melifaro@ipfw.ru>
To: bug-followup@FreeBSD.org, count@211.ru
Cc:  
Subject: Re: kern/134931: [route] Route messages sent to all socket listeners
 regardless of setfib(1)
Date: Mon, 25 Jul 2011 18:31:30 +0400

 This is a multi-part message in MIME format.
 --------------070803030307060008080104
 Content-Type: text/plain; charset=ISO-8859-1; format=flowed
 Content-Transfer-Encoding: 7bit
 
 Updated version, against current@223792
 
 --------------070803030307060008080104
 Content-Type: text/plain;
  name="rtmsg_20110725-CURRENT.diff"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: attachment;
  filename="rtmsg_20110725-CURRENT.diff"
 
 Index: netinet/in.c
 ===================================================================
 --- netinet/in.c	(revision 223741)
 +++ netinet/in.c	(working copy)
 @@ -1009,7 +1009,7 @@ static void in_addralias_rtmsg(int cmd, struct in_
  			(struct sockaddr *)&target->ia_addr;
  		rt_newaddrmsg(cmd, 
  			      (struct ifaddr *)target,
 -			      0, &msg_rt);
 +			      0, &msg_rt, RT_ALLFIBS);
  		RTFREE(pfx_ro.ro_rt);
  	}
  	return;
 Index: net/route.c
 ===================================================================
 --- net/route.c	(revision 223741)
 +++ net/route.c	(working copy)
 @@ -384,7 +384,7 @@ miss:
  		 */
  		bzero(&info, sizeof(info));
  		info.rti_info[RTAX_DST] = dst;
 -		rt_missmsg(msgtype, &info, 0, err);
 +		rt_missmsg(msgtype, &info, 0, err, fibnum);
  	}	
  done:
  	if (newrt)
 @@ -609,7 +609,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(RTM_REDIRECT, &info, flags, error, fibnum);
  	if (ifa != NULL)
  		ifa_free(ifa);
  }
 @@ -1522,7 +1522,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, in
  			}
  			RT_ADDREF(rt);
  			RT_UNLOCK(rt);
 -			rt_newaddrmsg(cmd, ifa, error, rt);
 +			rt_newaddrmsg(cmd, ifa, error, rt, fibnum);
  			RT_LOCK(rt);
  			RT_REMREF(rt);
  			if (cmd == RTM_DELETE) {
 Index: net/route.h
 ===================================================================
 --- net/route.h	(revision 223741)
 +++ net/route.h	(working copy)
 @@ -303,6 +303,11 @@ struct rt_addrinfo {
  	struct	ifnet *rti_ifp;
  };
  
 +struct rt_dispatch_ctx {
 +	unsigned short family;  /* Socket family */
 +	int            fibnum;  /* FIB for message or -1 for all */
 +};	
 +
  /*
   * This macro returns the size of a struct sockaddr when passed
   * through a routing socket. Basically we round up sa_len to
 @@ -317,6 +322,8 @@ struct rt_addrinfo {
  
  #ifdef _KERNEL
  
 +#define RT_ALLFIBS		-1
 +
  #define RT_LINK_IS_UP(ifp)	(!((ifp)->if_capabilities & IFCAP_LINKSTATE) \
  				 || (ifp)->if_link_state == LINK_STATE_UP)
  
 @@ -364,8 +371,8 @@ struct ifmultiaddr;
  void	 rt_ieee80211msg(struct ifnet *, int, void *, size_t);
  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 *);
  void 	 rt_maskedcopy(struct sockaddr *, struct sockaddr *, struct sockaddr *);
 Index: net/rtsock.c
 ===================================================================
 --- net/rtsock.c	(revision 223741)
 +++ net/rtsock.c	(working copy)
 @@ -159,7 +159,7 @@ static void	rt_setmetrics(u_long which, const stru
  			struct rt_metrics_lite *out);
  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 = {
  	.nh_name = "rtsock",
 @@ -200,17 +200,16 @@ static void
  rts_input(struct mbuf *m)
  {
  	struct sockproto route_proto;
 -	unsigned short *family;
 +	struct rt_dispatch_ctx *ctx;
  	struct m_tag *tag;
  
  	route_proto.sp_family = PF_ROUTE;
 -	tag = m_tag_find(m, PACKET_TAG_RTSOCKFAM, NULL);
 +	route_proto.sp_protocol = 0;
 +	tag = m_tag_find(m, PACKET_TAG_RTSOCK, NULL);
  	if (tag != NULL) {
 -		family = (unsigned short *)(tag + 1);
 -		route_proto.sp_protocol = *family;
 -		m_tag_delete(m, tag);
 -	} else
 -		route_proto.sp_protocol = 0;
 +		ctx = (struct rt_dispatch_ctx*)(tag + 1);
 +		route_proto.sp_protocol = ctx->family;
 +	}
  
  	raw_input(m, &route_proto, &route_src);
  }
 @@ -892,10 +891,10 @@ flush:
  			 */
  			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);
  	}
  	/* info.rti_info[RTAX_DST] (used above) can point inside of rtm */
  	if (rtm)
 @@ -1127,7 +1126,7 @@ again:
   * destination.
   */
  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;
  	struct mbuf *m;
 @@ -1142,7 +1141,7 @@ void
  	rtm->rtm_flags = RTF_DONE | flags;
  	rtm->rtm_errno = error;
  	rtm->rtm_addrs = rtinfo->rti_addrs;
 -	rt_dispatch(m, sa);
 +	rt_dispatch(m, sa, fibnum);
  }
  
  /*
 @@ -1167,7 +1166,7 @@ rt_ifmsg(struct ifnet *ifp)
  	ifm->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
  	ifm->ifm_data = ifp->if_data;
  	ifm->ifm_addrs = 0;
 -	rt_dispatch(m, NULL);
 +	rt_dispatch(m, NULL, RT_ALLFIBS);
  }
  
  /*
 @@ -1179,7 +1178,7 @@ rt_ifmsg(struct ifnet *ifp)
   * copies of it.
   */
  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;
  	struct sockaddr *sa = NULL;
 @@ -1237,7 +1236,7 @@ void
  			rtm->rtm_errno = error;
  			rtm->rtm_addrs = info.rti_addrs;
  		}
 -		rt_dispatch(m, sa);
 +		rt_dispatch(m, sa, fibnum);
  	}
  }
  
 @@ -1273,7 +1272,7 @@ rt_newmaddrmsg(int cmd, struct ifmultiaddr *ifma)
  	    __func__));
  	ifmam->ifmam_index = ifp->if_index;
  	ifmam->ifmam_addrs = info.rti_addrs;
 -	rt_dispatch(m, ifma->ifma_addr);
 +	rt_dispatch(m, ifma->ifma_addr, RT_ALLFIBS);
  }
  
  static struct mbuf *
 @@ -1333,7 +1332,7 @@ rt_ieee80211msg(struct ifnet *ifp, int what, void
  		if (m->m_flags & M_PKTHDR)
  			m->m_pkthdr.len += data_len;
  		mtod(m, struct if_announcemsghdr *)->ifan_msglen += data_len;
 -		rt_dispatch(m, NULL);
 +		rt_dispatch(m, NULL, RT_ALLFIBS);
  	}
  }
  
 @@ -1349,27 +1348,30 @@ rt_ifannouncemsg(struct ifnet *ifp, int what)
  
  	m = rt_makeifannouncemsg(ifp, RTM_IFANNOUNCE, what, &info);
  	if (m != NULL)
 -		rt_dispatch(m, NULL);
 +		rt_dispatch(m, NULL, RT_ALLFIBS);
  }
  
  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;
  
  	/*
  	 * 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);
  	}
  #ifdef VIMAGE
 Index: net/raw_usrreq.c
 ===================================================================
 --- net/raw_usrreq.c	(revision 223741)
 +++ net/raw_usrreq.c	(working copy)
 @@ -48,6 +48,7 @@
  #include <net/if.h>
  #include <net/raw_cb.h>
  #include <net/vnet.h>
 +#include <net/route.h>
  
  MTX_SYSINIT(rawcb_mtx, &rawcb_mtx, "rawcb", MTX_DEF);
  
 @@ -74,7 +75,18 @@ raw_input(struct mbuf *m0, struct sockproto *proto
  	struct rawcb *rp;
  	struct mbuf *m = m0;
  	struct socket *last;
 +	struct rt_dispatch_ctx *ctx;
 +	struct m_tag *tag = NULL;
 +	int fibnum = RT_ALLFIBS;
  
 +	if (proto->sp_family == PF_ROUTE) {
 +		tag = m_tag_find(m, PACKET_TAG_RTSOCK, NULL);
 +		if (tag != NULL) {
 +			ctx = (struct rt_dispatch_ctx*)(tag + 1);
 +			fibnum = ctx->fibnum;
 +		}
 +	}
 +
  	last = 0;
  	mtx_lock(&rawcb_mtx);
  	LIST_FOREACH(rp, &V_rawcb_list, list) {
 @@ -83,6 +95,10 @@ raw_input(struct mbuf *m0, struct sockproto *proto
  		if (rp->rcb_proto.sp_protocol  &&
  		    rp->rcb_proto.sp_protocol != proto->sp_protocol)
  			continue;
 +		if ((proto->sp_family == PF_ROUTE) && (fibnum >= 0) && 
 +				(rp->rcb_socket != NULL) &&
 +				(fibnum != rp->rcb_socket->so_fibnum))
 +			continue; 
  		if (last) {
  			struct mbuf *n;
  			n = m_copy(m, 0, (int)M_COPYALL);
 Index: netinet6/in6.c
 ===================================================================
 --- netinet6/in6.c	(revision 223741)
 +++ netinet6/in6.c	(working copy)
 @@ -1280,7 +1280,7 @@ in6_purgeaddr(struct ifaddr *ifa)
  	rt_mask(&rt0) = (struct sockaddr *)&mask;
  	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, RT_ALLFIBS);
  
  	/*
  	 * leave from multicast groups we have joined for the interface
 @@ -1858,7 +1858,7 @@ in6_ifinit(struct ifnet *ifp, struct in6_ifaddr *i
  		rt_mask(&rt) = (struct sockaddr *)&mask;
  		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, RT_ALLFIBS);
  	}
  
  	return (error);
 Index: netinet6/nd6_rtr.c
 ===================================================================
 --- netinet6/nd6_rtr.c	(revision 223741)
 +++ netinet6/nd6_rtr.c	(working copy)
 @@ -458,7 +458,7 @@ nd6_rtmsg(int cmd, struct rtentry *rt)
  	} else
  		ifa = NULL;
  
 -	rt_missmsg(cmd, &info, rt->rt_flags, 0);
 +	rt_missmsg(cmd, &info, rt->rt_flags, 0, RT_ALLFIBS);
  	if (ifa != NULL)
  		ifa_free(ifa);
  }
 Index: sys/mbuf.h
 ===================================================================
 --- sys/mbuf.h	(revision 223741)
 +++ sys/mbuf.h	(working copy)
 @@ -945,7 +945,7 @@ struct mbuf	*m_unshare(struct mbuf *, int how);
  #define	PACKET_TAG_IPFORWARD			18 /* ipforward info */
  #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 info */
  #define	PACKET_TAG_IPOPTIONS			27 /* Saved IP options */
  #define	PACKET_TAG_CARP				28 /* CARP info */
  #define	PACKET_TAG_IPSEC_NAT_T_PORTS		29 /* two uint16_t */
 
 --------------070803030307060008080104--

From: "Bjoern A. Zeeb" <bz@FreeBSD.org>
To: bug-followup@FreeBSD.org,
 count@211.ru,
 Stanislav A Svirid <s.svirid@sibset-team.ru>,
 Stef Walter <stef-list@memberwebs.com>
Cc: "Dyadchenko Mihail, Siberian Networks" <m.dyadchenko@sibset-team.ru>,
 "Alexander V. Chernikov" <melifaro@ipfw.ru>,
 Julian Elischer <julian@freebsd.org>,
 "Christian S.J. Peron" <csjp@freebsd.org>
Subject: Re: kern/134931: [route] Route messages sent to all socket listeners regardless of setfib(1)
Date: Sat, 17 Sep 2011 13:50:10 +0000

 Hi,
 
 can you please check out
 http://people.freebsd.org/~bz/20110917-01-rtsock-fib-filter.diff
 
 and let me know if it works for you.  I am not yet happy about the raw_*
 changes but this seems to work and be the most non-intrusive way I could
 think of and is even MFC-able.
 
 /bz
 
 -- 
 Bjoern A. Zeeb                                 You have to have visions!
          Stop bit received. Insert coin for new address family.
 

From: "Alexander V. Chernikov" <melifaro@ipfw.ru>
To: "Bjoern A. Zeeb" <bz@FreeBSD.org>
Cc: bug-followup@FreeBSD.org, count@211.ru, 
 Stanislav A Svirid <s.svirid@sibset-team.ru>,
 Stef Walter <stef-list@memberwebs.com>, 
 "Dyadchenko Mihail, Siberian Networks" <m.dyadchenko@sibset-team.ru>,
 Julian Elischer <julian@freebsd.org>, 
 "Christian S.J. Peron" <csjp@freebsd.org>
Subject: Re: kern/134931: [route] Route messages sent to all socket listeners
 regardless of setfib(1)
Date: Sun, 18 Sep 2011 15:58:19 +0400

 Bjoern A. Zeeb wrote:
 > Hi,
 > 
 > can you please check out
 > http://people.freebsd.org/~bz/20110917-01-rtsock-fib-filter.diff
 > 
 > and let me know if it works for you.  I am not yet happy about the raw_*
 > changes but this seems to work and be the most non-intrusive way I could
 > think of and is even MFC-able.
 It works for my setup and it is definitely better than patches residing
 in PR. Thank you for finding time to look & fix this PR finally!
 
 
 We can get rid of raw protocol in rtsock entirely since there are 2-3
 function which are really used in rtsock, others are blanks. I've done
 such a change in some of rtsock change variant patches. But it's too
 late and it is not the 'most non-inrusive' way, unfortunately..
 
 
 
 > 
 > /bz
 > 
 
 

From: "Bjoern A. Zeeb" <bz@FreeBSD.org>
To: bug-followup@FreeBSD.org
Cc: count@211.ru,
 Stanislav A Svirid <s.svirid@sibset-team.ru>,
 Stef Walter <stef-list@memberwebs.com>,
 "Dyadchenko Mihail, Siberian Networks" <m.dyadchenko@sibset-team.ru>,
 "Alexander V. Chernikov" <melifaro@ipfw.ru>,
 Julian Elischer <julian@freebsd.org>,
 "Christian S.J. Peron" <csjp@freebsd.org>
Subject: Re: kern/134931: [route] Route messages sent to all socket listeners regardless of setfib(1)
Date: Tue, 20 Sep 2011 22:55:19 +0000

 On Sep 17, 2011, at 1:50 PM, Bjoern A. Zeeb wrote:
 
 Based on feedback from rwatson here's an updated version:
 http://people.freebsd.org/~bz/20110920-01-rtsock-fib-filter.diff
 
 which I intend to commit as soon as possible.
 
 -- 
 Bjoern A. Zeeb                                 You have to have visions!
          Stop bit received. Insert coin for new address family.
 

From: Julian Elischer <julian@freebsd.org>
To: "Bjoern A. Zeeb" <bz@freebsd.org>
Cc: bug-followup@freebsd.org, count@211.ru,
        Stanislav A Svirid <s.svirid@sibset-team.ru>,
        Stef Walter <stef-list@memberwebs.com>,
        "Dyadchenko Mihail, Siberian Networks" <m.dyadchenko@sibset-team.ru>,
        "Alexander V. Chernikov" <melifaro@ipfw.ru>,
        "Christian S.J. Peron" <csjp@freebsd.org>
Subject: Re: kern/134931: [route] Route messages sent to all socket listeners
 regardless of setfib(1)
Date: Tue, 20 Sep 2011 17:20:11 -0700

 On 9/20/11 3:55 PM, Bjoern A. Zeeb wrote:
 > On Sep 17, 2011, at 1:50 PM, Bjoern A. Zeeb wrote:
 >
 > Based on feedback from rwatson here's an updated version:
 > http://people.freebsd.org/~bz/20110920-01-rtsock-fib-filter.diff
 >
 > which I intend to commit as soon as possible.
 >
 small nit.... the two wrappers  could be made into inlines in the .h file
 
 e.g.
 
 
 +void
 +rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt)
 +{
 +
 +	rt_newaddrmsg_fib(cmd, ifa, error, rt, RTS_ALLFIBS);
 +}
 
 could be made an inline in the .h file so that callers would have less 
 overhead..
 (or even a macro, which might be even less overhead)
 
 otherwise looks good.
 

From: "Bjoern A. Zeeb" <bz@freebsd.org>
To: bug-followup@freebsd.org
Cc:  
Subject: Re: kern/134931: [route] Route messages sent to all socket listeners regardless of setfib(1)
Date: Tue, 27 Sep 2011 13:32:06 +0000

 On Sep 21, 2011, at 12:20 AM, Julian Elischer wrote:
 
 > On 9/20/11 3:55 PM, Bjoern A. Zeeb wrote:
 >> On Sep 17, 2011, at 1:50 PM, Bjoern A. Zeeb wrote:
 >>=20
 >> Based on feedback from rwatson here's an updated version:
 >> http://people.freebsd.org/~bz/20110920-01-rtsock-fib-filter.diff
 >>=20
 >> which I intend to commit as soon as possible.
 >>=20
 > small nit.... the two wrappers  could be made into inlines in the .h =
 file
 >=20
 > e.g.
 >=20
 >=20
 > +void
 > +rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry =
 *rt)
 > +{
 > +
 > +	rt_newaddrmsg_fib(cmd, ifa, error, rt, RTS_ALLFIBS);
 > +}
 >=20
 > could be made an inline in the .h file so that callers would have less =
 overhead..
 > (or even a macro, which might be even less overhead)
 
 Just that we'd lose the symbols for the public KPI then, which is =
 exactly not
 what we want at this point in time.
 
 --=20
 Bjoern A. Zeeb                                 You have to have visions!
          Stop bit received. Insert coin for new address family.
 
State-Changed-From-To: open->patched 
State-Changed-By: bz 
State-Changed-When: Wed Sep 28 13:49:14 UTC 2011 
State-Changed-Why:  
Change committed to HEAD. 


Responsible-Changed-From-To: hrs->bz 
Responsible-Changed-By: bz 
Responsible-Changed-When: Wed Sep 28 13:49:14 UTC 2011 
Responsible-Changed-Why:  
Huh, not realized it wasn't mine at all. Take. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=134931 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/134931: commit references a PR
Date: Wed, 28 Sep 2011 13:48:47 +0000 (UTC)

 Author: bz
 Date: Wed Sep 28 13:48:36 2011
 New Revision: 225837
 URL: http://svn.freebsd.org/changeset/base/225837
 
 Log:
   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
   MFC after:	3 days
 
 Modified:
   head/sys/net/raw_cb.h
   head/sys/net/raw_usrreq.c
   head/sys/net/route.c
   head/sys/net/route.h
   head/sys/net/rtsock.c
 
 Modified: head/sys/net/raw_cb.h
 ==============================================================================
 --- head/sys/net/raw_cb.h	Wed Sep 28 13:27:31 2011	(r225836)
 +++ head/sys/net/raw_cb.h	Wed Sep 28 13:48:36 2011	(r225837)
 @@ -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: head/sys/net/raw_usrreq.c
 ==============================================================================
 --- head/sys/net/raw_usrreq.c	Wed Sep 28 13:27:31 2011	(r225836)
 +++ head/sys/net/raw_usrreq.c	Wed Sep 28 13:48:36 2011	(r225837)
 @@ -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: head/sys/net/route.c
 ==============================================================================
 --- head/sys/net/route.c	Wed Sep 28 13:27:31 2011	(r225836)
 +++ head/sys/net/route.c	Wed Sep 28 13:48:36 2011	(r225837)
 @@ -384,7 +384,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)
 @@ -609,7 +609,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);
  }
 @@ -1522,7 +1522,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: head/sys/net/route.h
 ==============================================================================
 --- head/sys/net/route.h	Wed Sep 28 13:27:31 2011	(r225836)
 +++ head/sys/net/route.h	Wed Sep 28 13:48:36 2011	(r225837)
 @@ -369,7 +369,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: head/sys/net/rtsock.c
 ==============================================================================
 --- head/sys/net/rtsock.c	Wed Sep 28 13:27:31 2011	(r225836)
 +++ head/sys/net/rtsock.c	Wed Sep 28 13:48:36 2011	(r225837)
 @@ -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);
  }
  
  /*
 @@ -885,6 +917,8 @@ flush:
  			m_adj(m, rtm->rtm_msglen - m->m_pkthdr.len);
  	}
  	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
 @@ -1127,7 +1161,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;
 @@ -1138,6 +1173,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;
 @@ -1145,6 +1188,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.
 @@ -1179,7 +1229,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;
 @@ -1237,10 +1288,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
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/134931: commit references a PR
Date: Tue,  4 Oct 2011 11:35:38 +0000 (UTC)

 Author: bz
 Date: Tue Oct  4 11:35:18 2011
 New Revision: 225970
 URL: http://svn.freebsd.org/changeset/base/225970
 
 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.
   
    Submitted by:	multiple (see PR)
    Suggested by:	rwatson [1]
    Reviewed by:	rwatson
   PR:		kern/134931
   Approved by:	re (kib)
 
 Modified:
   stable/9/sys/net/raw_cb.h
   stable/9/sys/net/raw_usrreq.c
   stable/9/sys/net/route.c
   stable/9/sys/net/route.h
   stable/9/sys/net/rtsock.c
 Directory Properties:
   stable/9/sys/   (props changed)
   stable/9/sys/amd64/include/xen/   (props changed)
   stable/9/sys/boot/   (props changed)
   stable/9/sys/boot/i386/efi/   (props changed)
   stable/9/sys/boot/ia64/efi/   (props changed)
   stable/9/sys/boot/ia64/ski/   (props changed)
   stable/9/sys/boot/powerpc/boot1.chrp/   (props changed)
   stable/9/sys/boot/powerpc/ofw/   (props changed)
   stable/9/sys/cddl/contrib/opensolaris/   (props changed)
   stable/9/sys/conf/   (props changed)
   stable/9/sys/contrib/dev/acpica/   (props changed)
   stable/9/sys/contrib/octeon-sdk/   (props changed)
   stable/9/sys/contrib/pf/   (props changed)
   stable/9/sys/contrib/x86emu/   (props changed)
 
 Modified: stable/9/sys/net/raw_cb.h
 ==============================================================================
 --- stable/9/sys/net/raw_cb.h	Tue Oct  4 11:23:03 2011	(r225969)
 +++ stable/9/sys/net/raw_cb.h	Tue Oct  4 11:35:18 2011	(r225970)
 @@ -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/9/sys/net/raw_usrreq.c
 ==============================================================================
 --- stable/9/sys/net/raw_usrreq.c	Tue Oct  4 11:23:03 2011	(r225969)
 +++ stable/9/sys/net/raw_usrreq.c	Tue Oct  4 11:35:18 2011	(r225970)
 @@ -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/9/sys/net/route.c
 ==============================================================================
 --- stable/9/sys/net/route.c	Tue Oct  4 11:23:03 2011	(r225969)
 +++ stable/9/sys/net/route.c	Tue Oct  4 11:35:18 2011	(r225970)
 @@ -384,7 +384,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)
 @@ -609,7 +609,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);
  }
 @@ -1522,7 +1522,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/9/sys/net/route.h
 ==============================================================================
 --- stable/9/sys/net/route.h	Tue Oct  4 11:23:03 2011	(r225969)
 +++ stable/9/sys/net/route.h	Tue Oct  4 11:35:18 2011	(r225970)
 @@ -369,7 +369,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/9/sys/net/rtsock.c
 ==============================================================================
 --- stable/9/sys/net/rtsock.c	Tue Oct  4 11:23:03 2011	(r225969)
 +++ stable/9/sys/net/rtsock.c	Tue Oct  4 11:35:18 2011	(r225970)
 @@ -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);
  }
  
  /*
 @@ -885,6 +917,8 @@ flush:
  			m_adj(m, rtm->rtm_msglen - m->m_pkthdr.len);
  	}
  	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
 @@ -1127,7 +1161,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;
 @@ -1138,6 +1173,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;
 @@ -1145,6 +1188,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.
 @@ -1179,7 +1229,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;
 @@ -1237,10 +1288,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
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: bz 
State-Changed-When: Tue Oct 4 13:19:25 UTC 2011 
State-Changed-Why:  
Merged all the way down to 7. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=134931 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/134931: commit references a PR
Date: Tue,  4 Oct 2011 13:18:34 +0000 (UTC)

 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
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/134931: commit references a PR
Date: Tue,  4 Oct 2011 13:19:30 +0000 (UTC)

 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
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
>Unformatted:
