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