On Fri, Mar 03, 2017 at 08:16:43AM +0100, Martin Pieuchot wrote:
> On 03/03/17(Fri) 01:40, Alexander Bluhm wrote:
> > On Thu, Mar 02, 2017 at 10:55:41AM +0100, Martin Pieuchot wrote:
> > > Actually the malloc(9) could be converted to M_WAIT like the one in
> > > rt_report() that claudio@ commented like that: 
> > 
> > So let's do that.  This avoids that we loose routing messages due
> > to low memory.
> > 
> > Note that we cannot wait in m_copyback() as rp->rcb_proto.sp_family
> > is temporarily set to 0 while calling route_input().
> 
> It'd be nice to change route_input() to get rid of this hack.
> 

How about something like this.

-- 
:wq Claudio


Index: net/rtsock.c
===================================================================
RCS file: /cvs/src/sys/net/rtsock.c,v
retrieving revision 1.228
diff -u -p -r1.228 rtsock.c
--- net/rtsock.c        3 Mar 2017 15:48:02 -0000       1.228
+++ net/rtsock.c        5 Mar 2017 10:39:11 -0000
@@ -99,7 +99,7 @@ struct walkarg {
 };
 
 int    route_ctloutput(int, struct socket *, int, int, struct mbuf *);
-void   route_input(struct mbuf *m0, sa_family_t);
+void   route_input(struct mbuf *m0, struct socket *, sa_family_t);
 int    route_arp_conflict(struct rtentry *, struct rt_addrinfo *);
 int    route_cleargateway(struct rtentry *, void *, unsigned int);
 
@@ -332,7 +332,7 @@ rt_senddesync(void *data)
 }
 
 void
-route_input(struct mbuf *m0, sa_family_t sa_family)
+route_input(struct mbuf *m0, struct socket *so, sa_family_t sa_family)
 {
        struct rawcb *rp;
        struct routecb *rop;
@@ -356,6 +356,10 @@ route_input(struct mbuf *m0, sa_family_t
                        continue;
                if (rp->rcb_proto.sp_family != PF_ROUTE)
                        continue;
+               /* Check to see if we don't want our own messages. */
+               if (so == rp->rcb_socket && !(so->so_options & SO_USELOOPBACK))
+                       continue;
+
                /*
                 * If route socket is bound to an address family only send
                 * messages that match the address family. Address family
@@ -537,7 +541,6 @@ route_output(struct mbuf *m, struct sock
        int                      plen, len, seq, newgate = 0, error = 0;
        struct ifnet            *ifp = NULL;
        struct ifaddr           *ifa = NULL;
-       struct rawcb            *rp = NULL;
 #ifdef MPLS
        struct sockaddr_mpls    *psa_mpls;
 #endif
@@ -953,9 +956,7 @@ flush:
                rtm->rtm_flags |= RTF_DONE;
        }
 
-       /*
-        * Check to see if we don't want our own messages.
-        */
+       /* Check to see if we don't want our own messages. */
        if (!(so->so_options & SO_USELOOPBACK)) {
                if (route_cb.any_count <= 1) {
                        /* no other listener and no loopback of messages */
@@ -964,9 +965,6 @@ fail:
                        m_freem(m);
                        return (error);
                }
-               /* There is another listener, so construct message */
-               rp = sotorawcb(so);
-               rp->rcb_proto.sp_family = 0; /* Avoid us */
        }
        if (rtm) {
                if (m_copyback(m, 0, rtm->rtm_msglen, rtm, M_NOWAIT)) {
@@ -977,10 +975,8 @@ fail:
                free(rtm, M_RTABLE, 0);
        }
        if (m)
-               route_input(m, info.rti_info[RTAX_DST] ?
+               route_input(m, so, info.rti_info[RTAX_DST] ?
                    info.rti_info[RTAX_DST]->sa_family : AF_UNSPEC);
-       if (rp)
-               rp->rcb_proto.sp_family = PF_ROUTE; /* Readd us */
 
        return (error);
 }
@@ -1253,7 +1249,7 @@ rt_missmsg(int type, struct rt_addrinfo 
        rtm->rtm_tableid = tableid;
        rtm->rtm_addrs = rtinfo->rti_addrs;
        rtm->rtm_index = ifidx;
-       route_input(m, sa ? sa->sa_family : AF_UNSPEC);
+       route_input(m, NULL, sa ? sa->sa_family : AF_UNSPEC);
 }
 
 /*
@@ -1278,7 +1274,7 @@ rt_ifmsg(struct ifnet *ifp)
        ifm->ifm_xflags = ifp->if_xflags;
        if_getdata(ifp, &ifm->ifm_data);
        ifm->ifm_addrs = 0;
-       route_input(m, AF_UNSPEC);
+       route_input(m, NULL, AF_UNSPEC);
 }
 
 /*
@@ -1314,7 +1310,8 @@ rt_sendaddrmsg(struct rtentry *rt, int c
        ifam->ifam_addrs = info.rti_addrs;
        ifam->ifam_tableid = ifp->if_rdomain;
 
-       route_input(m, ifa->ifa_addr ? ifa->ifa_addr->sa_family : AF_UNSPEC);
+       route_input(m, NULL,
+           ifa->ifa_addr ? ifa->ifa_addr->sa_family : AF_UNSPEC);
 }
 
 /*
@@ -1336,7 +1333,7 @@ rt_ifannouncemsg(struct ifnet *ifp, int 
        ifan->ifan_index = ifp->if_index;
        strlcpy(ifan->ifan_name, ifp->if_xname, sizeof(ifan->ifan_name));
        ifan->ifan_what = what;
-       route_input(m, AF_UNSPEC);
+       route_input(m, NULL, AF_UNSPEC);
 }
 
 #ifdef BFD
@@ -1367,7 +1364,7 @@ rt_bfdmsg(struct bfd_config *bfd)
        bfd2sa(bfd->bc_rt, &sa_bfd);
        memcpy(&bfdm->bm_sa, &sa_bfd, sizeof(sa_bfd));
 
-       route_input(m, info.rti_info[RTAX_DST]->sa_family);
+       route_input(m, NULL, info.rti_info[RTAX_DST]->sa_family);
 }
 #endif /* BFD */
 

Reply via email to