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