Re: Create a default local route for every IPv4 address
On 28/05/14(Wed) 16:15, Martin Pieuchot wrote: On 26/05/14(Mon) 15:17, Martin Pieuchot wrote: On 26/05/14(Mon) 08:03, Kenneth Westerback wrote: [...] dhclient used to create such routes but that was removed as useless so I'm not sure why we want/need to add them back. I'm not a routing table guru so perhaps this is different in some way. We want it back to be able to tell if an address is configured locally by using the routing table. But to be able to trust the routing table we must ensure that every local address is associated to a route entry. This diff is a step in this direction. Extra RTM_NEWADDR messages may cause problems for dhclient, since it will exit on what it thinks are attempts to add addresses to an interface. Not sure if RTM_NEWADDR makes sense if all you are doing is adding a route. That's a really good question, and I don't have the answer. Originally RTM_NEWADDR was generated when a route to prefix was added for a new address. It was simple: 1 address - 1 route + message. Later on the logic in netinet/in.c has been modified to be able to setup an address without adding a route to prefix, if this route was already present for example. That's what happens if you have two addresses on the same subnet configured on your machine. With this, we now have: 1 address - maybe 1 route + message. With this diff we always create a route, but maybe a second one if it is the first address of a subnet. So we have: 1 address - 1 or 2 route + messages. Here's a more complete diff that seems to not freak out dhclient(8). It makes use of the RTF_LOCAL flag to restore the original behavior of the RTM_NEWADDR message. I appreciate if people can test it and report back. It should be pretty safe from the IPv4 side, but I'd like to know if it causes any regression in IPv6 land. Unless I hear an objection I'll commit this diff tomorrow. Index: net/route.c === RCS file: /home/ncvs/src/sys/net/route.c,v retrieving revision 1.168 diff -u -p -r1.168 route.c --- net/route.c 27 May 2014 19:38:15 - 1.168 +++ net/route.c 28 May 2014 11:59:14 - @@ -1097,6 +1097,7 @@ rt_ifa_add(struct ifaddr *ifa, int flags struct sockaddr_rtlabel sa_rl; struct rt_addrinfo info; u_short rtableid = ifa-ifa_ifp-if_rdomain; + u_int8_t prio = RTP_CONNECTED; int error; memset(info, 0, sizeof(info)); @@ -1110,7 +,10 @@ rt_ifa_add(struct ifaddr *ifa, int flags if ((flags RTF_HOST) == 0) info.rti_info[RTAX_NETMASK] = ifa-ifa_netmask; - error = rtrequest1(RTM_ADD, info, RTP_CONNECTED, nrt, rtableid); + if (flags RTF_LOCAL) + prio = RTP_LOCAL; + + error = rtrequest1(RTM_ADD, info, prio, nrt, rtableid); if (error == 0 (rt = nrt) != NULL) { rt-rt_refcnt--; if (rt-rt_ifa != ifa) { @@ -1125,7 +1129,8 @@ rt_ifa_add(struct ifaddr *ifa, int flags if (ifa-ifa_rtrequest) ifa-ifa_rtrequest(RTM_ADD, rt); } - rt_newaddrmsg(RTM_ADD, ifa, error, nrt); + if (flags RTF_LOCAL) + rt_newaddrmsg(RTM_ADD, ifa, error, nrt); } return (error); } @@ -1139,6 +1144,7 @@ rt_ifa_del(struct ifaddr *ifa, int flags struct rt_addrinfo info; struct sockaddr_rtlabel sa_rl; u_short rtableid = ifa-ifa_ifp-if_rdomain; + u_int8_t prio = RTP_CONNECTED; int error; if ((flags RTF_HOST) == 0 ifa-ifa_netmask) { @@ -1173,9 +1179,13 @@ rt_ifa_del(struct ifaddr *ifa, int flags if ((flags RTF_HOST) == 0) info.rti_info[RTAX_NETMASK] = ifa-ifa_netmask; - error = rtrequest1(RTM_DELETE, info, RTP_CONNECTED, nrt, rtableid); + if (flags RTF_LOCAL) + prio = RTP_LOCAL; + + error = rtrequest1(RTM_DELETE, info, prio, nrt, rtableid); if (error == 0 (rt = nrt) != NULL) { - rt_newaddrmsg(RTM_DELETE, ifa, error, nrt); + if (flags RTF_LOCAL) + rt_newaddrmsg(RTM_DELETE, ifa, error, nrt); if (rt-rt_refcnt = 0) { rt-rt_refcnt++; rtfree(rt); @@ -1199,7 +1209,8 @@ rt_ifa_addloop(struct ifaddr *ifa) rt = rtalloc1(ifa-ifa_addr, 0, ifa-ifa_ifp-if_rdomain); if (rt == NULL || (rt-rt_flags RTF_HOST) == 0 || (rt-rt_ifp-if_flags IFF_LOOPBACK) == 0) - rt_ifa_add(ifa, RTF_UP| RTF_HOST | RTF_LLINFO, ifa-ifa_addr); + rt_ifa_add(ifa, RTF_UP| RTF_HOST | RTF_LLINFO | RTF_LOCAL, + ifa-ifa_addr); if (rt) rt-rt_refcnt--; } @@ -1223,7
Re: Create a default local route for every IPv4 address
On 26/05/14(Mon) 15:17, Martin Pieuchot wrote: On 26/05/14(Mon) 08:03, Kenneth Westerback wrote: [...] dhclient used to create such routes but that was removed as useless so I'm not sure why we want/need to add them back. I'm not a routing table guru so perhaps this is different in some way. We want it back to be able to tell if an address is configured locally by using the routing table. But to be able to trust the routing table we must ensure that every local address is associated to a route entry. This diff is a step in this direction. Extra RTM_NEWADDR messages may cause problems for dhclient, since it will exit on what it thinks are attempts to add addresses to an interface. Not sure if RTM_NEWADDR makes sense if all you are doing is adding a route. That's a really good question, and I don't have the answer. Originally RTM_NEWADDR was generated when a route to prefix was added for a new address. It was simple: 1 address - 1 route + message. Later on the logic in netinet/in.c has been modified to be able to setup an address without adding a route to prefix, if this route was already present for example. That's what happens if you have two addresses on the same subnet configured on your machine. With this, we now have: 1 address - maybe 1 route + message. With this diff we always create a route, but maybe a second one if it is the first address of a subnet. So we have: 1 address - 1 or 2 route + messages. Here's a more complete diff that seems to not freak out dhclient(8). It makes use of the RTF_LOCAL flag to restore the original behavior of the RTM_NEWADDR message. I appreciate if people can test it and report back. It should be pretty safe from the IPv4 side, but I'd like to know if it causes any regression in IPv6 land. Index: net/route.c === RCS file: /home/ncvs/src/sys/net/route.c,v retrieving revision 1.168 diff -u -p -r1.168 route.c --- net/route.c 27 May 2014 19:38:15 - 1.168 +++ net/route.c 28 May 2014 11:59:14 - @@ -1097,6 +1097,7 @@ rt_ifa_add(struct ifaddr *ifa, int flags struct sockaddr_rtlabel sa_rl; struct rt_addrinfo info; u_short rtableid = ifa-ifa_ifp-if_rdomain; + u_int8_t prio = RTP_CONNECTED; int error; memset(info, 0, sizeof(info)); @@ -1110,7 +,10 @@ rt_ifa_add(struct ifaddr *ifa, int flags if ((flags RTF_HOST) == 0) info.rti_info[RTAX_NETMASK] = ifa-ifa_netmask; - error = rtrequest1(RTM_ADD, info, RTP_CONNECTED, nrt, rtableid); + if (flags RTF_LOCAL) + prio = RTP_LOCAL; + + error = rtrequest1(RTM_ADD, info, prio, nrt, rtableid); if (error == 0 (rt = nrt) != NULL) { rt-rt_refcnt--; if (rt-rt_ifa != ifa) { @@ -1125,7 +1129,8 @@ rt_ifa_add(struct ifaddr *ifa, int flags if (ifa-ifa_rtrequest) ifa-ifa_rtrequest(RTM_ADD, rt); } - rt_newaddrmsg(RTM_ADD, ifa, error, nrt); + if (flags RTF_LOCAL) + rt_newaddrmsg(RTM_ADD, ifa, error, nrt); } return (error); } @@ -1139,6 +1144,7 @@ rt_ifa_del(struct ifaddr *ifa, int flags struct rt_addrinfo info; struct sockaddr_rtlabel sa_rl; u_short rtableid = ifa-ifa_ifp-if_rdomain; + u_int8_t prio = RTP_CONNECTED; int error; if ((flags RTF_HOST) == 0 ifa-ifa_netmask) { @@ -1173,9 +1179,13 @@ rt_ifa_del(struct ifaddr *ifa, int flags if ((flags RTF_HOST) == 0) info.rti_info[RTAX_NETMASK] = ifa-ifa_netmask; - error = rtrequest1(RTM_DELETE, info, RTP_CONNECTED, nrt, rtableid); + if (flags RTF_LOCAL) + prio = RTP_LOCAL; + + error = rtrequest1(RTM_DELETE, info, prio, nrt, rtableid); if (error == 0 (rt = nrt) != NULL) { - rt_newaddrmsg(RTM_DELETE, ifa, error, nrt); + if (flags RTF_LOCAL) + rt_newaddrmsg(RTM_DELETE, ifa, error, nrt); if (rt-rt_refcnt = 0) { rt-rt_refcnt++; rtfree(rt); @@ -1199,7 +1209,8 @@ rt_ifa_addloop(struct ifaddr *ifa) rt = rtalloc1(ifa-ifa_addr, 0, ifa-ifa_ifp-if_rdomain); if (rt == NULL || (rt-rt_flags RTF_HOST) == 0 || (rt-rt_ifp-if_flags IFF_LOOPBACK) == 0) - rt_ifa_add(ifa, RTF_UP| RTF_HOST | RTF_LLINFO, ifa-ifa_addr); + rt_ifa_add(ifa, RTF_UP| RTF_HOST | RTF_LLINFO | RTF_LOCAL, + ifa-ifa_addr); if (rt) rt-rt_refcnt--; } @@ -1223,7 +1234,8 @@ rt_ifa_delloop(struct ifaddr *ifa) rt = rtalloc1(ifa-ifa_addr, 0, ifa-ifa_ifp-if_rdomain); if (rt != NULL
Re: Create a default local route for every IPv4 address
On 28 May 2014 10:15, Martin Pieuchot mpieuc...@nolizard.org wrote: On 26/05/14(Mon) 15:17, Martin Pieuchot wrote: On 26/05/14(Mon) 08:03, Kenneth Westerback wrote: [...] dhclient used to create such routes but that was removed as useless so I'm not sure why we want/need to add them back. I'm not a routing table guru so perhaps this is different in some way. We want it back to be able to tell if an address is configured locally by using the routing table. But to be able to trust the routing table we must ensure that every local address is associated to a route entry. This diff is a step in this direction. Extra RTM_NEWADDR messages may cause problems for dhclient, since it will exit on what it thinks are attempts to add addresses to an interface. Not sure if RTM_NEWADDR makes sense if all you are doing is adding a route. That's a really good question, and I don't have the answer. Originally RTM_NEWADDR was generated when a route to prefix was added for a new address. It was simple: 1 address - 1 route + message. Later on the logic in netinet/in.c has been modified to be able to setup an address without adding a route to prefix, if this route was already present for example. That's what happens if you have two addresses on the same subnet configured on your machine. With this, we now have: 1 address - maybe 1 route + message. With this diff we always create a route, but maybe a second one if it is the first address of a subnet. So we have: 1 address - 1 or 2 route + messages. Here's a more complete diff that seems to not freak out dhclient(8). It makes use of the RTF_LOCAL flag to restore the original behavior of the RTM_NEWADDR message. I appreciate if people can test it and report back. It should be pretty safe from the IPv4 side, but I'd like to know if it causes any regression in IPv6 land. In my tree and snap a-building. Ken Index: net/route.c === RCS file: /home/ncvs/src/sys/net/route.c,v retrieving revision 1.168 diff -u -p -r1.168 route.c --- net/route.c 27 May 2014 19:38:15 - 1.168 +++ net/route.c 28 May 2014 11:59:14 - @@ -1097,6 +1097,7 @@ rt_ifa_add(struct ifaddr *ifa, int flags struct sockaddr_rtlabel sa_rl; struct rt_addrinfo info; u_short rtableid = ifa-ifa_ifp-if_rdomain; + u_int8_t prio = RTP_CONNECTED; int error; memset(info, 0, sizeof(info)); @@ -1110,7 +,10 @@ rt_ifa_add(struct ifaddr *ifa, int flags if ((flags RTF_HOST) == 0) info.rti_info[RTAX_NETMASK] = ifa-ifa_netmask; - error = rtrequest1(RTM_ADD, info, RTP_CONNECTED, nrt, rtableid); + if (flags RTF_LOCAL) + prio = RTP_LOCAL; + + error = rtrequest1(RTM_ADD, info, prio, nrt, rtableid); if (error == 0 (rt = nrt) != NULL) { rt-rt_refcnt--; if (rt-rt_ifa != ifa) { @@ -1125,7 +1129,8 @@ rt_ifa_add(struct ifaddr *ifa, int flags if (ifa-ifa_rtrequest) ifa-ifa_rtrequest(RTM_ADD, rt); } - rt_newaddrmsg(RTM_ADD, ifa, error, nrt); + if (flags RTF_LOCAL) + rt_newaddrmsg(RTM_ADD, ifa, error, nrt); } return (error); } @@ -1139,6 +1144,7 @@ rt_ifa_del(struct ifaddr *ifa, int flags struct rt_addrinfo info; struct sockaddr_rtlabel sa_rl; u_short rtableid = ifa-ifa_ifp-if_rdomain; + u_int8_t prio = RTP_CONNECTED; int error; if ((flags RTF_HOST) == 0 ifa-ifa_netmask) { @@ -1173,9 +1179,13 @@ rt_ifa_del(struct ifaddr *ifa, int flags if ((flags RTF_HOST) == 0) info.rti_info[RTAX_NETMASK] = ifa-ifa_netmask; - error = rtrequest1(RTM_DELETE, info, RTP_CONNECTED, nrt, rtableid); + if (flags RTF_LOCAL) + prio = RTP_LOCAL; + + error = rtrequest1(RTM_DELETE, info, prio, nrt, rtableid); if (error == 0 (rt = nrt) != NULL) { - rt_newaddrmsg(RTM_DELETE, ifa, error, nrt); + if (flags RTF_LOCAL) + rt_newaddrmsg(RTM_DELETE, ifa, error, nrt); if (rt-rt_refcnt = 0) { rt-rt_refcnt++; rtfree(rt); @@ -1199,7 +1209,8 @@ rt_ifa_addloop(struct ifaddr *ifa) rt = rtalloc1(ifa-ifa_addr, 0, ifa-ifa_ifp-if_rdomain); if (rt == NULL || (rt-rt_flags RTF_HOST) == 0 || (rt-rt_ifp-if_flags IFF_LOOPBACK) == 0) - rt_ifa_add(ifa, RTF_UP| RTF_HOST | RTF_LLINFO, ifa-ifa_addr); + rt_ifa_add(ifa, RTF_UP| RTF_HOST | RTF_LLINFO | RTF_LOCAL, + ifa-ifa_addr); if (rt)
Re: Create a default local route for every IPv4 address
On 28 May 2014 10:18, Kenneth Westerback kwesterb...@gmail.com wrote: On 28 May 2014 10:15, Martin Pieuchot mpieuc...@nolizard.org wrote: On 26/05/14(Mon) 15:17, Martin Pieuchot wrote: On 26/05/14(Mon) 08:03, Kenneth Westerback wrote: [...] dhclient used to create such routes but that was removed as useless so I'm not sure why we want/need to add them back. I'm not a routing table guru so perhaps this is different in some way. We want it back to be able to tell if an address is configured locally by using the routing table. But to be able to trust the routing table we must ensure that every local address is associated to a route entry. This diff is a step in this direction. Extra RTM_NEWADDR messages may cause problems for dhclient, since it will exit on what it thinks are attempts to add addresses to an interface. Not sure if RTM_NEWADDR makes sense if all you are doing is adding a route. That's a really good question, and I don't have the answer. Originally RTM_NEWADDR was generated when a route to prefix was added for a new address. It was simple: 1 address - 1 route + message. Later on the logic in netinet/in.c has been modified to be able to setup an address without adding a route to prefix, if this route was already present for example. That's what happens if you have two addresses on the same subnet configured on your machine. With this, we now have: 1 address - maybe 1 route + message. With this diff we always create a route, but maybe a second one if it is the first address of a subnet. So we have: 1 address - 1 or 2 route + messages. Here's a more complete diff that seems to not freak out dhclient(8). It makes use of the RTF_LOCAL flag to restore the original behavior of the RTM_NEWADDR message. I appreciate if people can test it and report back. It should be pretty safe from the IPv4 side, but I'd like to know if it causes any regression in IPv6 land. In my tree and snap a-building. Ken And dhclient does seem to like this much better. I withdraw my objection, even if I don't understand enough to ok it. :-) Ken Index: net/route.c === RCS file: /home/ncvs/src/sys/net/route.c,v retrieving revision 1.168 diff -u -p -r1.168 route.c --- net/route.c 27 May 2014 19:38:15 - 1.168 +++ net/route.c 28 May 2014 11:59:14 - @@ -1097,6 +1097,7 @@ rt_ifa_add(struct ifaddr *ifa, int flags struct sockaddr_rtlabel sa_rl; struct rt_addrinfo info; u_short rtableid = ifa-ifa_ifp-if_rdomain; + u_int8_t prio = RTP_CONNECTED; int error; memset(info, 0, sizeof(info)); @@ -1110,7 +,10 @@ rt_ifa_add(struct ifaddr *ifa, int flags if ((flags RTF_HOST) == 0) info.rti_info[RTAX_NETMASK] = ifa-ifa_netmask; - error = rtrequest1(RTM_ADD, info, RTP_CONNECTED, nrt, rtableid); + if (flags RTF_LOCAL) + prio = RTP_LOCAL; + + error = rtrequest1(RTM_ADD, info, prio, nrt, rtableid); if (error == 0 (rt = nrt) != NULL) { rt-rt_refcnt--; if (rt-rt_ifa != ifa) { @@ -1125,7 +1129,8 @@ rt_ifa_add(struct ifaddr *ifa, int flags if (ifa-ifa_rtrequest) ifa-ifa_rtrequest(RTM_ADD, rt); } - rt_newaddrmsg(RTM_ADD, ifa, error, nrt); + if (flags RTF_LOCAL) + rt_newaddrmsg(RTM_ADD, ifa, error, nrt); } return (error); } @@ -1139,6 +1144,7 @@ rt_ifa_del(struct ifaddr *ifa, int flags struct rt_addrinfo info; struct sockaddr_rtlabel sa_rl; u_short rtableid = ifa-ifa_ifp-if_rdomain; + u_int8_t prio = RTP_CONNECTED; int error; if ((flags RTF_HOST) == 0 ifa-ifa_netmask) { @@ -1173,9 +1179,13 @@ rt_ifa_del(struct ifaddr *ifa, int flags if ((flags RTF_HOST) == 0) info.rti_info[RTAX_NETMASK] = ifa-ifa_netmask; - error = rtrequest1(RTM_DELETE, info, RTP_CONNECTED, nrt, rtableid); + if (flags RTF_LOCAL) + prio = RTP_LOCAL; + + error = rtrequest1(RTM_DELETE, info, prio, nrt, rtableid); if (error == 0 (rt = nrt) != NULL) { - rt_newaddrmsg(RTM_DELETE, ifa, error, nrt); + if (flags RTF_LOCAL) + rt_newaddrmsg(RTM_DELETE, ifa, error, nrt); if (rt-rt_refcnt = 0) { rt-rt_refcnt++; rtfree(rt); @@ -1199,7 +1209,8 @@ rt_ifa_addloop(struct ifaddr *ifa) rt = rtalloc1(ifa-ifa_addr, 0, ifa-ifa_ifp-if_rdomain); if (rt == NULL || (rt-rt_flags RTF_HOST) == 0 || (rt-rt_ifp-if_flags IFF_LOOPBACK) == 0) -
Create a default local route for every IPv4 address
Diff below changes the behavior of the kernel to add a route for every new IPv4 address, when it is configured on an interface. Actually such route is created the first time a program tries to resolve it. That's why with this diff you don't see the cloned flag: -10.3.3.2 00:00:24:cc:21:eb UHLc 02 - 4 lo0 +10.3.3.2 00:00:24:cc:21:eb UHL00 - 4 lo0 This now automagically created route can still be deleted from userland. In such case it will be re-created as soon as a program tries to resolve it, just like it is now. Addresses configured on a point-to-point will have a slightly different route added, which matches the IPv6 behavior: 97.78.45.33 127.0.0.1 H 00 - 4 lo0 Such addresses are also not automatically re-created if they are previously deleted, and you'll need to re-configure the address on your interface or add it manually if you want it back. With this diff, a new route will always be created when an address is configured, which mean that a RTM_NEWADDR message will be generated at least once per-address. If the address is the first in a particular subnet, two messages will be generated, one for the route to prefix and one for the local route. Do you see any problem with all of this? Can it goes in? Index: netinet/if_ether.c === RCS file: /home/ncvs/src/sys/netinet/if_ether.c,v retrieving revision 1.127 diff -u -p -r1.127 if_ether.c --- netinet/if_ether.c 7 May 2014 08:14:59 - 1.127 +++ netinet/if_ether.c 26 May 2014 09:46:42 - @@ -174,7 +174,8 @@ arp_rtrequest(int req, struct rtentry *r if ((rt-rt_flags RTF_HOST) == 0 rt_mask(rt) satosin(rt_mask(rt))-sin_addr.s_addr != 0x) rt-rt_flags |= RTF_CLONING; - if (rt-rt_flags RTF_CLONING) { + if (rt-rt_flags RTF_CLONING || + ((rt-rt_flags RTF_LLINFO) !la)) { /* * Case 1: This route should come from a route to iface. */ @@ -189,7 +190,8 @@ arp_rtrequest(int req, struct rtentry *r * from it do not need their expiration time set. */ rt-rt_expire = time_second; - break; + if ((rt-rt_flags RTF_CLONING) != 0) + break; } /* Announce a new entry if requested. */ if (rt-rt_flags RTF_ANNOUNCE) Index: netinet/in.c === RCS file: /home/ncvs/src/sys/netinet/in.c,v retrieving revision 1.96 diff -u -p -r1.96 in.c --- netinet/in.c25 Apr 2014 09:44:38 - 1.96 +++ netinet/in.c26 May 2014 09:46:42 - @@ -702,6 +702,7 @@ out: * carp(4). */ ifa_add(ifp, ia-ia_ifa); + rt_ifa_addloop(ia-ia_ifa); if (error newaddr) in_purgeaddr(ia-ia_ifa); @@ -718,6 +719,8 @@ in_purgeaddr(struct ifaddr *ifa) splsoftassert(IPL_SOFTNET); in_ifscrub(ifp, ia); + + rt_ifa_delloop(ia-ia_ifa); ifa_del(ifp, ia-ia_ifa); TAILQ_REMOVE(in_ifaddr, ia, ia_list);
Re: Create a default local route for every IPv4 address
On 26 May 2014 06:10, Martin Pieuchot mpieuc...@nolizard.org wrote: Diff below changes the behavior of the kernel to add a route for every new IPv4 address, when it is configured on an interface. Actually such route is created the first time a program tries to resolve it. That's why with this diff you don't see the cloned flag: -10.3.3.2 00:00:24:cc:21:eb UHLc 02 - 4 lo0 +10.3.3.2 00:00:24:cc:21:eb UHL00 - 4 lo0 This now automagically created route can still be deleted from userland. In such case it will be re-created as soon as a program tries to resolve it, just like it is now. Addresses configured on a point-to-point will have a slightly different route added, which matches the IPv6 behavior: 97.78.45.33 127.0.0.1 H 00 - 4 lo0 Such addresses are also not automatically re-created if they are previously deleted, and you'll need to re-configure the address on your interface or add it manually if you want it back. With this diff, a new route will always be created when an address is configured, which mean that a RTM_NEWADDR message will be generated at least once per-address. If the address is the first in a particular subnet, two messages will be generated, one for the route to prefix and one for the local route. Do you see any problem with all of this? Can it goes in? dhclient used to create such routes but that was removed as useless so I'm not sure why we want/need to add them back. I'm not a routing table guru so perhaps this is different in some way. Extra RTM_NEWADDR messages may cause problems for dhclient, since it will exit on what it thinks are attempts to add addresses to an interface. Not sure if RTM_NEWADDR makes sense if all you are doing is adding a route. I'm in the middle of some other stuff but I certainly want to test this to make sure there are no bad side effects on dhclient. Ken Index: netinet/if_ether.c === RCS file: /home/ncvs/src/sys/netinet/if_ether.c,v retrieving revision 1.127 diff -u -p -r1.127 if_ether.c --- netinet/if_ether.c 7 May 2014 08:14:59 - 1.127 +++ netinet/if_ether.c 26 May 2014 09:46:42 - @@ -174,7 +174,8 @@ arp_rtrequest(int req, struct rtentry *r if ((rt-rt_flags RTF_HOST) == 0 rt_mask(rt) satosin(rt_mask(rt))-sin_addr.s_addr != 0x) rt-rt_flags |= RTF_CLONING; - if (rt-rt_flags RTF_CLONING) { + if (rt-rt_flags RTF_CLONING || + ((rt-rt_flags RTF_LLINFO) !la)) { /* * Case 1: This route should come from a route to iface. */ @@ -189,7 +190,8 @@ arp_rtrequest(int req, struct rtentry *r * from it do not need their expiration time set. */ rt-rt_expire = time_second; - break; + if ((rt-rt_flags RTF_CLONING) != 0) + break; } /* Announce a new entry if requested. */ if (rt-rt_flags RTF_ANNOUNCE) Index: netinet/in.c === RCS file: /home/ncvs/src/sys/netinet/in.c,v retrieving revision 1.96 diff -u -p -r1.96 in.c --- netinet/in.c25 Apr 2014 09:44:38 - 1.96 +++ netinet/in.c26 May 2014 09:46:42 - @@ -702,6 +702,7 @@ out: * carp(4). */ ifa_add(ifp, ia-ia_ifa); + rt_ifa_addloop(ia-ia_ifa); if (error newaddr) in_purgeaddr(ia-ia_ifa); @@ -718,6 +719,8 @@ in_purgeaddr(struct ifaddr *ifa) splsoftassert(IPL_SOFTNET); in_ifscrub(ifp, ia); + + rt_ifa_delloop(ia-ia_ifa); ifa_del(ifp, ia-ia_ifa); TAILQ_REMOVE(in_ifaddr, ia, ia_list);
Re: Create a default local route for every IPv4 address
* Kenneth Westerback kwesterb...@gmail.com [2014-05-26 14:05]: dhclient used to create such routes but that was removed as useless so I'm not sure why we want/need to add them back. I'm not a routing table guru so perhaps this is different in some way. there is a broad difference between the kernel does it always and in some cases, some userland app does it. in the former case, the existance of the local route can be used e. g. for the local/remote decision, in the latter case that is utterly unreliable. -- Henning Brauer, h...@bsws.de, henn...@openbsd.org BS Web Services GmbH, http://bsws.de, Full-Service ISP Secure Hosting, Mail and DNS. Virtual Dedicated Servers, Root to Fully Managed Henning Brauer Consulting, http://henningbrauer.com/
Re: Create a default local route for every IPv4 address
On 26/05/14(Mon) 08:03, Kenneth Westerback wrote: [...] dhclient used to create such routes but that was removed as useless so I'm not sure why we want/need to add them back. I'm not a routing table guru so perhaps this is different in some way. We want it back to be able to tell if an address is configured locally by using the routing table. But to be able to trust the routing table we must ensure that every local address is associated to a route entry. This diff is a step in this direction. Extra RTM_NEWADDR messages may cause problems for dhclient, since it will exit on what it thinks are attempts to add addresses to an interface. Not sure if RTM_NEWADDR makes sense if all you are doing is adding a route. That's a really good question, and I don't have the answer. Originally RTM_NEWADDR was generated when a route to prefix was added for a new address. It was simple: 1 address - 1 route + message. Later on the logic in netinet/in.c has been modified to be able to setup an address without adding a route to prefix, if this route was already present for example. That's what happens if you have two addresses on the same subnet configured on your machine. With this, we now have: 1 address - maybe 1 route + message. With this diff we always create a route, but maybe a second one if it is the first address of a subnet. So we have: 1 address - 1 or 2 route + messages. I'm in the middle of some other stuff but I certainly want to test this to make sure there are no bad side effects on dhclient. No rush, let me know when you're done :) Martin