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.
ok mpi@
> Index: net/rtsock.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/net/rtsock.c,v
> retrieving revision 1.225
> diff -u -p -r1.225 rtsock.c
> --- net/rtsock.c 2 Mar 2017 09:37:04 -0000 1.225
> +++ net/rtsock.c 3 Mar 2017 00:18:47 -0000
> @@ -505,10 +505,7 @@ rt_report(struct rtentry *rt, u_char typ
>
> /* build new route message */
> len = rt_msg2(type, RTM_VERSION, &info, NULL, NULL);
> - /* XXX why can't we wait? Should be process context... */
> - rtm = malloc(len, M_RTABLE, M_NOWAIT | M_ZERO);
> - if (rtm == NULL)
> - return NULL;
> + rtm = malloc(len, M_RTABLE, M_WAITOK | M_ZERO);
>
> rt_msg2(type, RTM_VERSION, &info, (caddr_t)rtm, NULL);
> rtm->rtm_type = type;
> @@ -571,11 +568,7 @@ route_output(struct mbuf *m, ...)
> error = EMSGSIZE;
> goto fail;
> }
> - rtm = malloc(len, M_RTABLE, M_NOWAIT);
> - if (rtm == NULL) {
> - error = ENOBUFS;
> - goto fail;
> - }
> + rtm = malloc(len, M_RTABLE, M_WAITOK);
> m_copydata(m, 0, len, (caddr_t)rtm);
> break;
> default:
> @@ -846,11 +839,7 @@ change:
> if (rt->rt_llinfo == NULL) {
> rt->rt_llinfo =
> malloc(sizeof(struct rt_mpls),
> - M_TEMP, M_NOWAIT|M_ZERO);
> - }
> - if (rt->rt_llinfo == NULL) {
> - error = ENOMEM;
> - goto flush;
> + M_TEMP, M_WAITOK | M_ZERO);
> }
>
> rt_mpls = (struct rt_mpls *)rt->rt_llinfo;
> @@ -945,10 +934,7 @@ change:
> rtm = rt_report(rt, type, seq, tableid);
> flush:
> rtfree(rt);
> - if (rtm == NULL) {
> - error = ENOBUFS;
> - goto fail;
> - } else if (error) {
> + if (error) {
> rtm->rtm_errno = error;
> } else {
> rtm->rtm_flags |= RTF_DONE;
>