diff options
-rw-r--r-- | sys/net/route.c | 32 | ||||
-rw-r--r-- | sys/netinet/if_ether.c | 14 |
2 files changed, 39 insertions, 7 deletions
diff --git a/sys/net/route.c b/sys/net/route.c index f8a6583a1f3..b31351c13cb 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -1,4 +1,4 @@ -/* $OpenBSD: route.c,v 1.178 2014/08/14 09:01:47 mpi Exp $ */ +/* $OpenBSD: route.c,v 1.179 2014/08/19 12:49:41 mpi Exp $ */ /* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */ /* @@ -790,7 +790,8 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio, * sure that local routes are only modified by the * kernel. */ - if (rt->rt_flags & RTF_LOCAL && prio != RTP_LOCAL) + if ((rt->rt_flags & (RTF_LOCAL | RTF_BROADCAST)) && + prio != RTP_LOCAL) senderr(EINVAL); if ((rn = rnh->rnh_deladdr(info->rti_info[RTAX_DST], @@ -1109,7 +1110,7 @@ rt_ifa_add(struct ifaddr *ifa, int flags, struct sockaddr *dst) if ((flags & RTF_HOST) == 0) info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask; - if (flags & RTF_LOCAL) + if (flags & (RTF_LOCAL|RTF_BROADCAST)) prio = RTP_LOCAL; error = rtrequest1(RTM_ADD, &info, prio, &nrt, rtableid); @@ -1127,6 +1128,12 @@ rt_ifa_add(struct ifaddr *ifa, int flags, struct sockaddr *dst) if (ifa->ifa_rtrequest) ifa->ifa_rtrequest(RTM_ADD, rt); } + + /* + * A local route is created for every address configured + * on an interface, so use this information to notify + * userland that a new address has been added. + */ if (flags & RTF_LOCAL) rt_newaddrmsg(RTM_ADD, ifa, error, nrt); } @@ -1177,7 +1184,7 @@ rt_ifa_del(struct ifaddr *ifa, int flags, struct sockaddr *dst) if ((flags & RTF_HOST) == 0) info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask; - if (flags & RTF_LOCAL) + if (flags & (RTF_LOCAL|RTF_BROADCAST)) prio = RTP_LOCAL; error = rtrequest1(RTM_DELETE, &info, prio, &nrt, rtableid); @@ -1228,9 +1235,16 @@ rt_ifa_addloop(struct ifaddr *ifa) /* If there is no loopback entry, allocate one. */ 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->rt_ifp->if_flags & IFF_LOOPBACK) == 0) { rt_ifa_add(ifa, RTF_UP| RTF_HOST | RTF_LLINFO | RTF_LOCAL, ifa->ifa_addr); + + if ((ifa->ifa_ifp->if_flags & IFF_BROADCAST) && + ifa->ifa_broadaddr) + rt_ifa_add(ifa, RTF_UP | RTF_HOST | RTF_LLINFO | + RTF_BROADCAST, ifa->ifa_broadaddr); + + } if (rt) rt->rt_refcnt--; } @@ -1273,9 +1287,15 @@ rt_ifa_delloop(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->rt_ifp->if_flags & IFF_LOOPBACK) != 0) { rt_ifa_del(ifa, RTF_HOST | RTF_LLINFO | RTF_LOCAL, ifa->ifa_addr); + + if ((ifa->ifa_ifp->if_flags & IFF_BROADCAST) && + ifa->ifa_broadaddr) + rt_ifa_del(ifa, RTF_HOST | RTF_LLINFO | RTF_BROADCAST, + ifa->ifa_broadaddr); + } if (rt) rt->rt_refcnt--; } diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index 3d8d7f81c1b..11f7876a472 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ether.c,v 1.133 2014/08/11 13:51:07 mpi Exp $ */ +/* $OpenBSD: if_ether.c,v 1.134 2014/08/19 12:49:41 mpi Exp $ */ /* $NetBSD: if_ether.c,v 1.31 1996/05/11 12:59:58 mycroft Exp $ */ /* @@ -232,6 +232,18 @@ arp_rtrequest(int req, struct rtentry *rt) rt->rt_flags |= RTF_LLINFO; LIST_INSERT_HEAD(&llinfo_arp, la, la_list); + /* + * Routes to broadcast addresses must be incomplete + * arp entries so that they won't be picked up, but + * since we expect them to always be present in the + * routing table, make sure arptimer() won't free + * them. + */ + if (rt->rt_flags & RTF_BROADCAST) { + rt->rt_expire = 0; + break; + } + TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { if ((ifa->ifa_addr->sa_family == AF_INET) && ifatoia(ifa)->ia_addr.sin_addr.s_addr == |