Mark arprequest static and introduce arpannounce so that gratuitous
ARP requests are only send from valid addresses.
This commit is contained in:
parent
f2d015f995
commit
103ec7fade
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_llatbl.c,v 1.14 2016/06/16 03:03:33 ozaki-r Exp $ */
|
||||
/* $NetBSD: if_llatbl.c,v 1.15 2016/10/11 12:32:30 roy Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2004 Luigi Rizzo, Alessandro Cerri. All rights reserved.
|
||||
* Copyright (c) 2004-2008 Qing Li. All rights reserved.
|
||||
|
@ -60,6 +60,7 @@
|
|||
#include <net/if_dl.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/if_inarp.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet6/in6_var.h>
|
||||
#include <netinet6/nd6.h>
|
||||
|
||||
|
@ -671,11 +672,19 @@ lla_rt_output(const u_char rtm_type, const int rtm_flags, const time_t rtm_expir
|
|||
IF_AFDATA_WUNLOCK(ifp);
|
||||
#if defined(INET) && NARP > 0
|
||||
/* gratuitous ARP */
|
||||
if ((laflags & LLE_PUB) && dst->sa_family == AF_INET)
|
||||
arprequest(ifp,
|
||||
&((const struct sockaddr_in *)dst)->sin_addr,
|
||||
&((const struct sockaddr_in *)dst)->sin_addr,
|
||||
CLLADDR(dl));
|
||||
if ((laflags & LLE_PUB) && dst->sa_family == AF_INET) {
|
||||
const struct sockaddr_in *sin;
|
||||
struct in_ifaddr *ia;
|
||||
struct psref _psref;
|
||||
|
||||
sin = satocsin(dst);
|
||||
ia = in_get_ia_on_iface_psref(sin->sin_addr,
|
||||
ifp, &_psref);
|
||||
if (ia != NULL) {
|
||||
arpannounce(ifp, &ia->ia_ifa, CLLADDR(dl));
|
||||
ia4_release(ia, &_psref);
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)laflags;
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_arp.c,v 1.228 2016/10/03 11:06:06 ozaki-r Exp $ */
|
||||
/* $NetBSD: if_arp.c,v 1.229 2016/10/11 12:32:30 roy Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc.
|
||||
|
@ -68,7 +68,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.228 2016/10/03 11:06:06 ozaki-r Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.229 2016/10/11 12:32:30 roy Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_ddb.h"
|
||||
|
@ -157,6 +157,10 @@ int arp_debug = 0;
|
|||
|
||||
static void arp_init(void);
|
||||
|
||||
static void arprequest(struct ifnet *,
|
||||
const struct in_addr *, const struct in_addr *,
|
||||
const u_int8_t *);
|
||||
static void arpannounce1(struct ifaddr *);
|
||||
static struct sockaddr *arp_setgate(struct rtentry *, struct sockaddr *,
|
||||
const struct sockaddr *);
|
||||
static void arptimer(void *);
|
||||
|
@ -452,22 +456,8 @@ arp_rtrequest(int req, struct rtentry *rt, const struct rt_addrinfo *info)
|
|||
int s;
|
||||
|
||||
if (req == RTM_LLINFO_UPD) {
|
||||
struct in_addr *in;
|
||||
|
||||
if ((ifa = info->rti_ifa) == NULL)
|
||||
return;
|
||||
|
||||
in = &ifatoia(ifa)->ia_addr.sin_addr;
|
||||
|
||||
if (ifatoia(ifa)->ia4_flags &
|
||||
(IN_IFF_NOTREADY | IN_IFF_DETACHED))
|
||||
{
|
||||
arplog(LOG_DEBUG, "%s not ready\n", in_fmtaddr(*in));
|
||||
return;
|
||||
}
|
||||
|
||||
arprequest(ifa->ifa_ifp, in, in,
|
||||
CLLADDR(ifa->ifa_ifp->if_sadl));
|
||||
if ((ifa = info->rti_ifa) != NULL)
|
||||
arpannounce1(ifa);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -563,16 +553,11 @@ arp_rtrequest(int req, struct rtentry *rt, const struct rt_addrinfo *info)
|
|||
struct psref psref;
|
||||
ia = in_get_ia_on_iface_psref(
|
||||
satocsin(rt_getkey(rt))->sin_addr, ifp, &psref);
|
||||
if (ia == NULL ||
|
||||
ia->ia4_flags & (IN_IFF_NOTREADY | IN_IFF_DETACHED))
|
||||
;
|
||||
else
|
||||
arprequest(ifp,
|
||||
&satocsin(rt_getkey(rt))->sin_addr,
|
||||
&satocsin(rt_getkey(rt))->sin_addr,
|
||||
if (ia != NULL) {
|
||||
arpannounce(ifp, &ia->ia_ifa,
|
||||
CLLADDR(satocsdl(gate)));
|
||||
if (ia != NULL)
|
||||
ia4_release(ia, &psref);
|
||||
}
|
||||
}
|
||||
|
||||
if (gate->sa_family != AF_LINK ||
|
||||
|
@ -645,7 +630,7 @@ arp_rtrequest(int req, struct rtentry *rt, const struct rt_addrinfo *info)
|
|||
* - arp header target ip address
|
||||
* - arp header source ethernet address
|
||||
*/
|
||||
void
|
||||
static void
|
||||
arprequest(struct ifnet *ifp,
|
||||
const struct in_addr *sip, const struct in_addr *tip,
|
||||
const u_int8_t *enaddr)
|
||||
|
@ -702,6 +687,26 @@ arprequest(struct ifnet *ifp,
|
|||
if_output_lock(ifp, ifp, m, &sa, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
arpannounce(struct ifnet *ifp, struct ifaddr *ifa, const uint8_t *enaddr)
|
||||
{
|
||||
struct in_ifaddr *ia = ifatoia(ifa);
|
||||
struct in_addr *ip = &IA_SIN(ifa)->sin_addr;
|
||||
|
||||
if (ia->ia4_flags & (IN_IFF_NOTREADY | IN_IFF_DETACHED)) {
|
||||
arplog(LOG_DEBUG, "%s not ready\n", in_fmtaddr(*ip));
|
||||
return;
|
||||
}
|
||||
arprequest(ifp, ip, ip, enaddr);
|
||||
}
|
||||
|
||||
static void
|
||||
arpannounce1(struct ifaddr *ifa)
|
||||
{
|
||||
|
||||
arpannounce(ifa->ifa_ifp, ifa, CLLADDR(ifa->ifa_ifp->if_sadl));
|
||||
}
|
||||
|
||||
/*
|
||||
* Resolve an IP address into an ethernet address. If success,
|
||||
* desten is filled in. If there is no entry in arptab,
|
||||
|
@ -1353,7 +1358,6 @@ reply:
|
|||
m->m_flags |= M_BCAST;
|
||||
m->m_len = sizeof(*ah) + (2 * ah->ar_pln) + ah->ar_hln;
|
||||
break;
|
||||
|
||||
default:
|
||||
m->m_flags &= ~(M_BCAST|M_MCAST); /* never reply by broadcast */
|
||||
m->m_len = sizeof(*ah) + (2 * ah->ar_pln) + (2 * ah->ar_hln);
|
||||
|
@ -1457,8 +1461,6 @@ arp_ifinit(struct ifnet *ifp, struct ifaddr *ifa)
|
|||
(ia->ia4_flags & (IN_IFF_NOTREADY | IN_IFF_DETACHED)) == 0) {
|
||||
struct llentry *lle;
|
||||
|
||||
arprequest(ifp, ip, ip, CLLADDR(ifp->if_sadl));
|
||||
|
||||
/*
|
||||
* interface address is considered static entry
|
||||
* because the output of the arp utility shows
|
||||
|
@ -1492,6 +1494,8 @@ arp_ifinit(struct ifnet *ifp, struct ifaddr *ifa)
|
|||
ia->ia_dad_stop = arp_dad_stop;
|
||||
if (ia->ia4_flags & IN_IFF_TRYTENTATIVE)
|
||||
ia->ia4_flags |= IN_IFF_TENTATIVE;
|
||||
else
|
||||
arpannounce1(ifa);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1590,12 +1594,9 @@ arp_dad_start(struct ifaddr *ifa)
|
|||
return;
|
||||
}
|
||||
if (!ip_dad_count) {
|
||||
struct in_addr *ip = &IA_SIN(ifa)->sin_addr;
|
||||
|
||||
ia->ia4_flags &= ~IN_IFF_TENTATIVE;
|
||||
rt_newaddrmsg(RTM_NEWADDR, ifa, 0, NULL);
|
||||
arprequest(ifa->ifa_ifp, ip, ip,
|
||||
CLLADDR(ifa->ifa_ifp->if_sadl));
|
||||
arpannounce1(ifa);
|
||||
return;
|
||||
}
|
||||
KASSERT(ifa->ifa_ifp != NULL);
|
||||
|
@ -1674,7 +1675,6 @@ arp_dad_timer(struct ifaddr *ifa)
|
|||
{
|
||||
struct in_ifaddr *ia = (struct in_ifaddr *)ifa;
|
||||
struct dadq *dp;
|
||||
struct in_addr *ip;
|
||||
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
|
@ -1750,9 +1750,7 @@ announce:
|
|||
/*
|
||||
* Announce the address.
|
||||
*/
|
||||
ip = &IA_SIN(ifa)->sin_addr;
|
||||
arprequest(ifa->ifa_ifp, ip, ip,
|
||||
CLLADDR(ifa->ifa_ifp->if_sadl));
|
||||
arpannounce1(ifa);
|
||||
dp->dad_arp_acount++;
|
||||
if (dp->dad_arp_acount < dp->dad_arp_announce) {
|
||||
arp_dad_starttimer(dp, ANNOUNCE_INTERVAL * hz);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_inarp.h,v 1.49 2016/04/19 04:13:56 ozaki-r Exp $ */
|
||||
/* $NetBSD: if_inarp.h,v 1.50 2016/10/11 12:32:30 roy Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
|
@ -78,8 +78,7 @@ void arp_rtrequest(int, struct rtentry *, const struct rt_addrinfo *);
|
|||
int arpresolve(struct ifnet *, const struct rtentry *, struct mbuf *,
|
||||
const struct sockaddr *, void *, size_t);
|
||||
void arpintr(void);
|
||||
void arprequest(struct ifnet *, const struct in_addr *, const struct in_addr *,
|
||||
const u_int8_t *);
|
||||
void arpannounce(struct ifnet *, struct ifaddr *, const uint8_t *);
|
||||
void arp_drain(void);
|
||||
int arpioctl(u_long, void *);
|
||||
void arpwhohas(struct ifnet *, struct in_addr *);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ip_carp.c,v 1.77 2016/08/01 03:15:30 ozaki-r Exp $ */
|
||||
/* $NetBSD: ip_carp.c,v 1.78 2016/10/11 12:32:30 roy Exp $ */
|
||||
/* $OpenBSD: ip_carp.c,v 1.113 2005/11/04 08:11:54 mcbride Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -33,7 +33,7 @@
|
|||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip_carp.c,v 1.77 2016/08/01 03:15:30 ozaki-r Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip_carp.c,v 1.78 2016/10/11 12:32:30 roy Exp $");
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
|
@ -1231,8 +1231,7 @@ carp_send_arp(struct carp_softc *sc)
|
|||
if (ifa->ifa_addr->sa_family != AF_INET)
|
||||
continue;
|
||||
|
||||
in = &ifatoia(ifa)->ia_addr.sin_addr;
|
||||
arprequest(sc->sc_carpdev, in, in, CLLADDR(sc->sc_if.if_sadl));
|
||||
arpannounce(sc->sc_carpdev, ifa, CLLADDR(sc->sc_if.if_sadl));
|
||||
}
|
||||
splx(s);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
|
|
Loading…
Reference in New Issue