Date: Sun, 31 Oct 2010 07:40:12 GMT From: "Alexander V. Chernikov" <melifaro@ipfw.ru> To: freebsd-net@FreeBSD.org Subject: Re: kern/134931: [route] Route messages sent to all socket listeners regardless of setfib(1) Message-ID: <201010310740.o9V7eCK4062386@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/134931; it has been noted by GNATS. 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--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201010310740.o9V7eCK4062386>