summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoritojun <itojun@openbsd.org>2003-05-17 15:15:23 +0000
committeritojun <itojun@openbsd.org>2003-05-17 15:15:23 +0000
commit5bf569ea2da25d95a4c71f35ca88da4d9eb927ae (patch)
treebfcf41a258a9bc239ba90c7cd6db373dae0bf48f
parentno need for O0 on hppa anymore (diff)
downloadwireguard-openbsd-5bf569ea2da25d95a4c71f35ca88da4d9eb927ae.tar.xz
wireguard-openbsd-5bf569ea2da25d95a4c71f35ca88da4d9eb927ae.zip
don't send ARP for secondary IPv4 addresses, treat them as local.
kwesterback tdeval ok
-rw-r--r--sys/netinet/if_ether.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index 8c133413626..09177379747 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ether.c,v 1.46 2003/05/04 11:56:32 dhartmei Exp $ */
+/* $OpenBSD: if_ether.c,v 1.47 2003/05/17 15:15:23 itojun Exp $ */
/* $NetBSD: if_ether.c,v 1.31 1996/05/11 12:59:58 mycroft Exp $ */
/*
@@ -144,6 +144,8 @@ arp_rtrequest(req, rt, info)
register struct sockaddr *gate = rt->rt_gateway;
register struct llinfo_arp *la = (struct llinfo_arp *)rt->rt_llinfo;
static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
+ struct in_ifaddr *ia;
+ struct ifaddr *ifa;
if (!arpinit_done) {
static struct timeout arptimer_to;
@@ -252,8 +254,14 @@ arp_rtrequest(req, rt, info)
la->la_rt = rt;
rt->rt_flags |= RTF_LLINFO;
LIST_INSERT_HEAD(&llinfo_arp, la, la_list);
- if (SIN(rt_key(rt))->sin_addr.s_addr ==
- (IA_SIN(rt->rt_ifa))->sin_addr.s_addr) {
+
+ TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
+ if (ia->ia_ifp == rt->rt_ifp &&
+ SIN(rt_key(rt))->sin_addr.s_addr ==
+ (IA_SIN(ia))->sin_addr.s_addr)
+ break;
+ }
+ if (ia) {
/*
* This test used to be
* if (lo0ifp->if_flags & IFF_UP)
@@ -264,6 +272,12 @@ arp_rtrequest(req, rt, info)
* packets they send. It is now necessary to clear
* "useloopback" and remove the route to force
* traffic out to the hardware.
+ *
+ * In 4.4BSD, the above "if" statement checked
+ * rt->rt_ifa against rt_key(rt). It was changed
+ * to the current form so that we can provide a
+ * better support for multiple IPv4 addresses on a
+ * interface.
*/
rt->rt_expire = 0;
Bcopy(((struct arpcom *)rt->rt_ifp)->ac_enaddr,
@@ -271,6 +285,17 @@ arp_rtrequest(req, rt, info)
SDL(gate)->sdl_alen = ETHER_ADDR_LEN);
if (useloopback)
rt->rt_ifp = lo0ifp;
+ /*
+ * make sure to set rt->rt_ifa to the interface
+ * address we are using, otherwise we will have trouble
+ * with source address selection.
+ */
+ ifa = &ia->ia_ifa;
+ if (ifa != rt->rt_ifa) {
+ IFAFREE(rt->rt_ifa);
+ ifa->ifa_refcnt++;
+ rt->rt_ifa = ifa;
+ }
}
break;