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 0 2 - 4 lo0 +10.3.3.2 00:00:24:cc:21:eb UHL 0 0 - 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 0 0 - 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 -0000 1.127 +++ netinet/if_ether.c 26 May 2014 09:46:42 -0000 @@ -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 != 0xffffffff) 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.c 25 Apr 2014 09:44:38 -0000 1.96 +++ netinet/in.c 26 May 2014 09:46:42 -0000 @@ -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);