When working on an RTM_CHANGE do the route editing in the following
sequence. First, if rt_ifa is going to be changed, then call ifa_rtrequest(RTM_DELETE). Second, if gateway is going to be changed, then call rt_setgate(). Third, change rt_ifa. With this change we are able to change a link level route to a gateway one, that wasn't possible before: # ifconfig em0 192.168.22.1/24 # arp -s 192.168.22.99 00:11:22:33:44:55 # route change 192.168.22.99 192.168.22.199 # ping 192.168.22.99 db> Reported by: avatar
This commit is contained in:
parent
d983ff428e
commit
060c94f5be
@ -318,7 +318,6 @@ route_output(struct mbuf *m, struct socket *so)
|
||||
struct rt_addrinfo info;
|
||||
int len, error = 0;
|
||||
struct ifnet *ifp = NULL;
|
||||
struct ifaddr *ifa = NULL;
|
||||
struct sockaddr_in jail;
|
||||
|
||||
#define senderr(e) { error = e; goto flush;}
|
||||
@ -515,25 +514,25 @@ route_output(struct mbuf *m, struct socket *so)
|
||||
senderr(error);
|
||||
RT_LOCK(rt);
|
||||
}
|
||||
if (info.rti_info[RTAX_GATEWAY] != NULL &&
|
||||
(error = rt_setgate(rt, rt_key(rt),
|
||||
info.rti_info[RTAX_GATEWAY])) != 0) {
|
||||
RT_UNLOCK(rt);
|
||||
senderr(error);
|
||||
if (info.rti_ifa != rt->rt_ifa && rt->rt_ifa != NULL &&
|
||||
rt->rt_ifa->ifa_rtrequest != NULL) {
|
||||
rt->rt_ifa->ifa_rtrequest(RTM_DELETE, rt,
|
||||
&info);
|
||||
IFAFREE(rt->rt_ifa);
|
||||
}
|
||||
if ((ifa = info.rti_ifa) != NULL) {
|
||||
struct ifaddr *oifa = rt->rt_ifa;
|
||||
if (oifa != ifa) {
|
||||
if (oifa) {
|
||||
if (oifa->ifa_rtrequest)
|
||||
oifa->ifa_rtrequest(
|
||||
RTM_DELETE, rt,
|
||||
&info);
|
||||
IFAFREE(oifa);
|
||||
}
|
||||
IFAREF(ifa);
|
||||
rt->rt_ifa = ifa;
|
||||
rt->rt_ifp = info.rti_ifp;
|
||||
if (info.rti_info[RTAX_GATEWAY] != NULL) {
|
||||
if ((error = rt_setgate(rt, rt_key(rt),
|
||||
info.rti_info[RTAX_GATEWAY])) != 0) {
|
||||
RT_UNLOCK(rt);
|
||||
senderr(error);
|
||||
}
|
||||
rt->rt_flags |= RTF_GATEWAY;
|
||||
}
|
||||
if (info.rti_ifa != rt->rt_ifa) {
|
||||
rt->rt_ifa = info.rti_ifa;
|
||||
if (info.rti_ifa != NULL) {
|
||||
IFAREF(info.rti_ifa);
|
||||
rt->rt_ifp = info.rti_ifp;
|
||||
}
|
||||
}
|
||||
/* Allow some flags to be toggled on change. */
|
||||
|
Loading…
Reference in New Issue
Block a user