summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/net/route.c32
-rw-r--r--sys/netinet/if_ether.c14
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 ==