kern/134931: [route] Route messages sent to all socket listeners regardless of setfib(1)

Alexander V. Chernikov melifaro at ipfw.ru
Sun Oct 31 07:40:13 UTC 2010


The following reply was made to PR kern/134931; it has been noted by GNATS.

From: "Alexander V. Chernikov" <melifaro at ipfw.ru>
To: bug-followup at FreeBSD.org, count at 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--


More information about the freebsd-net mailing list