diff options
author | 2003-05-17 15:15:23 +0000 | |
---|---|---|
committer | 2003-05-17 15:15:23 +0000 | |
commit | 5bf569ea2da25d95a4c71f35ca88da4d9eb927ae (patch) | |
tree | bfcf41a258a9bc239ba90c7cd6db373dae0bf48f /sys | |
parent | no need for O0 on hppa anymore (diff) | |
download | wireguard-openbsd-5bf569ea2da25d95a4c71f35ca88da4d9eb927ae.tar.xz wireguard-openbsd-5bf569ea2da25d95a4c71f35ca88da4d9eb927ae.zip |
don't send ARP for secondary IPv4 addresses, treat them as local.
kwesterback tdeval ok
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet/if_ether.c | 31 |
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; |