ethernet likes to attach a struct to RTF_LLINFO routes in things
like ether_rtrequest/arp_rtrequest, and then deref that struct
unconditionally in a ether_output/arpresolve.

if that struct cannot be allocated in arp_rtrequest, we should
report failure and let the routing layer unwind.

this is a step toward that, it makes if_rtrequest return an int we
can then check for failure.

ok?

Index: net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.547
diff -u -p -r1.547 if.c
--- net/if.c    20 Feb 2018 03:46:45 -0000      1.547
+++ net/if.c    27 Feb 2018 21:40:27 -0000
@@ -1447,16 +1447,17 @@ ifaof_ifpforaddr(struct sockaddr *addr, 
        return (ifa_maybe);
 }
 
-void
+int
 if_rtrequest_dummy(struct ifnet *ifp, int req, struct rtentry *rt)
 {
+       return (0);
 }
 
 /*
  * Default action when installing a local route on a point-to-point
  * interface.
  */
-void
+int
 p2p_rtrequest(struct ifnet *ifp, int req, struct rtentry *rt)
 {
        struct ifnet *lo0ifp;
@@ -1497,6 +1498,8 @@ p2p_rtrequest(struct ifnet *ifp, int req
        default:
                break;
        }
+
+       return (0);
 }
 
 
Index: net/if_ethersubr.c
===================================================================
RCS file: /cvs/src/sys/net/if_ethersubr.c,v
retrieving revision 1.251
diff -u -p -r1.251 if_ethersubr.c
--- net/if_ethersubr.c  2 Feb 2018 22:00:39 -0000       1.251
+++ net/if_ethersubr.c  27 Feb 2018 21:40:27 -0000
@@ -162,21 +162,26 @@ ether_ioctl(struct ifnet *ifp, struct ar
 }
 
 
-void
+int
 ether_rtrequest(struct ifnet *ifp, int req, struct rtentry *rt)
 {
+       int error;
+
        switch (rt_key(rt)->sa_family) {
        case AF_INET:
-               arp_rtrequest(ifp, req, rt);
+               error = arp_rtrequest(ifp, req, rt);
                break;
 #ifdef INET6
        case AF_INET6:
-               nd6_rtrequest(ifp, req, rt);
+               error = nd6_rtrequest(ifp, req, rt);
                break;
 #endif
        default:
+               error = 0;
                break;
        }
+
+       return (error);
 }
 /*
  * Ethernet output routine.
Index: net/if_loop.c
===================================================================
RCS file: /cvs/src/sys/net/if_loop.c,v
retrieving revision 1.86
diff -u -p -r1.86 if_loop.c
--- net/if_loop.c       10 Feb 2018 05:32:21 -0000      1.86
+++ net/if_loop.c       27 Feb 2018 21:40:27 -0000
@@ -143,7 +143,7 @@
 int    loioctl(struct ifnet *, u_long, caddr_t);
 void   loopattach(int);
 void   loop_delayed_create(void *);
-void   lortrequest(struct ifnet *, int, struct rtentry *);
+int    lortrequest(struct ifnet *, int, struct rtentry *);
 int    loinput(struct ifnet *, struct mbuf *, void *);
 int    looutput(struct ifnet *,
            struct mbuf *, struct sockaddr *, struct rtentry *);
@@ -253,11 +253,13 @@ looutput(struct ifnet *ifp, struct mbuf 
        return (if_output_local(ifp, m, dst->sa_family));
 }
 
-void
+int
 lortrequest(struct ifnet *ifp, int cmd, struct rtentry *rt)
 {
        if (rt && rt->rt_mtu == 0)
                rt->rt_mtu = LOMTU;
+
+       return (0);
 }
 
 /*
Index: net/if_var.h
===================================================================
RCS file: /cvs/src/sys/net/if_var.h,v
retrieving revision 1.89
diff -u -p -r1.89 if_var.h
--- net/if_var.h        10 Jan 2018 23:50:39 -0000      1.89
+++ net/if_var.h        27 Feb 2018 21:40:27 -0000
@@ -124,7 +124,7 @@ struct ifnet {                              /* and the 
entries */
        struct hook_desc_head *if_linkstatehooks; /* [I] link change callbacks*/
        struct hook_desc_head *if_detachhooks; /* [I] detach callbacks */
                                /* [I] check or clean routes (+ or -)'d */
-       void    (*if_rtrequest)(struct ifnet *, int, struct rtentry *);
+       int     (*if_rtrequest)(struct ifnet *, int, struct rtentry *);
        char    if_xname[IFNAMSIZ];     /* [I] external name (name + unit) */
        int     if_pcount;              /* [k] # of promiscuous listeners */
        caddr_t if_bpf;                 /* packet filter structure */
@@ -317,8 +317,8 @@ void        if_input(struct ifnet *, struct mbu
 void   if_input_process(struct ifnet *, struct mbuf_list *);
 int    if_input_local(struct ifnet *, struct mbuf *, sa_family_t);
 int    if_output_local(struct ifnet *, struct mbuf *, sa_family_t);
-void   if_rtrequest_dummy(struct ifnet *, int, struct rtentry *);
-void   p2p_rtrequest(struct ifnet *, int, struct rtentry *);
+int    if_rtrequest_dummy(struct ifnet *, int, struct rtentry *);
+int    p2p_rtrequest(struct ifnet *, int, struct rtentry *);
 
 struct ifaddr *ifa_ifwithaddr(struct sockaddr *, u_int);
 struct ifaddr *ifa_ifwithdstaddr(struct sockaddr *, u_int);
Index: netinet/if_ether.c
===================================================================
RCS file: /cvs/src/sys/netinet/if_ether.c,v
retrieving revision 1.233
diff -u -p -r1.233 if_ether.c
--- netinet/if_ether.c  16 Jan 2018 10:33:55 -0000      1.233
+++ netinet/if_ether.c  27 Feb 2018 21:40:27 -0000
@@ -123,7 +123,7 @@ arptimer(void *arg)
        NET_UNLOCK();
 }
 
-void
+int
 arp_rtrequest(struct ifnet *ifp, int req, struct rtentry *rt)
 {
        struct sockaddr *gate = rt->rt_gateway;
@@ -142,7 +142,7 @@ arp_rtrequest(struct ifnet *ifp, int req
        }
 
        if (ISSET(rt->rt_flags, RTF_GATEWAY|RTF_BROADCAST|RTF_MULTICAST))
-               return;
+               return (0);
 
        switch (req) {
 
@@ -222,6 +222,8 @@ arp_rtrequest(struct ifnet *ifp, int req
                        arpinvalidate(rt);
                break;
        }
+
+       return (0);
 }
 
 /*
Index: netinet/if_ether.h
===================================================================
RCS file: /cvs/src/sys/netinet/if_ether.h,v
retrieving revision 1.73
diff -u -p -r1.73 if_ether.h
--- netinet/if_ether.h  29 Nov 2016 10:09:57 -0000      1.73
+++ netinet/if_ether.h  27 Feb 2018 21:40:27 -0000
@@ -230,7 +230,7 @@ void        arpwhohas(struct arpcom *, struct i
 int    arpproxy(struct in_addr, unsigned int);
 int    arpresolve(struct ifnet *, struct rtentry *, struct mbuf *,
            struct sockaddr *, u_char *);
-void   arp_rtrequest(struct ifnet *, int, struct rtentry *);
+int    arp_rtrequest(struct ifnet *, int, struct rtentry *);
 
 void   ether_fakeaddr(struct ifnet *);
 int    ether_addmulti(struct ifreq *, struct arpcom *);
@@ -242,7 +242,7 @@ int ether_ioctl(struct ifnet *, struct a
 int    ether_input(struct ifnet *, struct mbuf *, void *);
 int    ether_output(struct ifnet *,
            struct mbuf *, struct sockaddr *, struct rtentry *);
-void   ether_rtrequest(struct ifnet *, int, struct rtentry *);
+int    ether_rtrequest(struct ifnet *, int, struct rtentry *);
 char   *ether_sprintf(u_char *);
 
 
Index: netinet6/nd6.c
===================================================================
RCS file: /cvs/src/sys/netinet6/nd6.c,v
retrieving revision 1.223
diff -u -p -r1.223 nd6.c
--- netinet6/nd6.c      15 Jan 2018 13:48:31 -0000      1.223
+++ netinet6/nd6.c      27 Feb 2018 21:40:27 -0000
@@ -778,7 +778,7 @@ out:
        if_put(ifp);
 }
 
-void
+int
 nd6_rtrequest(struct ifnet *ifp, int req, struct rtentry *rt)
 {
        struct sockaddr *gate = rt->rt_gateway;
@@ -786,7 +786,7 @@ nd6_rtrequest(struct ifnet *ifp, int req
        struct ifaddr *ifa;
 
        if (ISSET(rt->rt_flags, RTF_GATEWAY|RTF_MULTICAST))
-               return;
+               return (0);
 
        if (nd6_need_cache(ifp) == 0 && (rt->rt_flags & RTF_HOST) == 0) {
                /*
@@ -796,7 +796,7 @@ nd6_rtrequest(struct ifnet *ifp, int req
                 * Moreover, the RTF_LLINFO flag which would be set below
                 * would annoy the ndp(8) command.
                 */
-               return;
+               return (0);
        }
 
        if (req == RTM_RESOLVE && nd6_need_cache(ifp) == 0) {
@@ -815,7 +815,7 @@ nd6_rtrequest(struct ifnet *ifp, int req
                 * of the destination.
                 */
                rt->rt_flags &= ~RTF_LLINFO;
-               return;
+               return (0);
        }
 
        switch (req) {
@@ -1006,6 +1006,8 @@ nd6_rtrequest(struct ifnet *ifp, int req
                        nd6_invalidate(rt);
                break;
        }
+
+       return (0);
 }
 
 int
Index: netinet6/nd6.h
===================================================================
RCS file: /cvs/src/sys/netinet6/nd6.h,v
retrieving revision 1.74
diff -u -p -r1.74 nd6.h
--- netinet6/nd6.h      27 Nov 2017 15:41:30 -0000      1.74
+++ netinet6/nd6.h      27 Feb 2018 21:40:27 -0000
@@ -173,7 +173,7 @@ void nd6_setmtu(struct ifnet *);
 void nd6_llinfo_settimer(struct llinfo_nd6 *, unsigned int);
 void nd6_purge(struct ifnet *);
 void nd6_nud_hint(struct rtentry *);
-void nd6_rtrequest(struct ifnet *, int, struct rtentry *);
+int nd6_rtrequest(struct ifnet *, int, struct rtentry *);
 int nd6_ioctl(u_long, caddr_t, struct ifnet *);
 void nd6_cache_lladdr(struct ifnet *, struct in6_addr *, char *, int, int, 
int);
 int nd6_resolve(struct ifnet *, struct rtentry *, struct mbuf *,

Reply via email to