summaryrefslogtreecommitdiffstats
path: root/sys/net/rtsock.c
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2007-03-22 10:51:03 +0000
committerglebius <glebius@FreeBSD.org>2007-03-22 10:51:03 +0000
commit060c94f5be5dc06fae3d10b45b46f15f5b349d26 (patch)
tree1513fa0ff2d6ce85d22bf0c7b04067cac23a6315 /sys/net/rtsock.c
parentd983ff428ea8ec97e3222bf26598dc5dea9cb4b1 (diff)
downloadFreeBSD-src-060c94f5be5dc06fae3d10b45b46f15f5b349d26.zip
FreeBSD-src-060c94f5be5dc06fae3d10b45b46f15f5b349d26.tar.gz
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
Diffstat (limited to 'sys/net/rtsock.c')
-rw-r--r--sys/net/rtsock.c35
1 files changed, 17 insertions, 18 deletions
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index c13f4ec..16b94ad 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -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),
+ 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 (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_UNLOCK(rt);
+ senderr(error);
+ }
+ rt->rt_flags |= RTF_GATEWAY;
}
- 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_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. */
OpenPOWER on IntegriCloud