* Do not assume lle has sockaddr key after struct lle:
use llt_fill_sa_entry() llt method to store lle address in sa. * Eliminate L3_ADDR macro and either reference IPv4/IPv6 address directly from lle or use newly-created llt_fill_sa_entry(). * Do not store sockaddr inside arp/ndp lle anymore.
This commit is contained in:
parent
d82ed5051c
commit
ee7e9a4e17
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/routing/; revision=275628
@ -135,10 +135,6 @@ struct llentry {
|
||||
#define ln_timer_ch lle_timer.ln_timer_ch
|
||||
#define la_timer lle_timer.la_timer
|
||||
|
||||
/* XXX bad name */
|
||||
#define L3_ADDR(lle) ((struct sockaddr *)(&lle[1]))
|
||||
#define L3_ADDR_LEN(lle) (((struct sockaddr *)(&lle[1]))->sa_len)
|
||||
|
||||
#ifndef LLTBL_HASHTBL_SIZE
|
||||
#define LLTBL_HASHTBL_SIZE 32 /* default 32 ? */
|
||||
#endif
|
||||
@ -165,6 +161,7 @@ typedef void (llt_unlink_entry_t)(struct llentry *);
|
||||
typedef int (llt_prepare_sentry_t)(struct lltable *, struct llentry *,
|
||||
struct rt_addrinfo *);
|
||||
typedef const void *(llt_get_sa_addr_t)(const struct sockaddr *l3addr);
|
||||
typedef void (llt_fill_sa_entry_t)(const struct llentry *, struct sockaddr *);
|
||||
|
||||
typedef int (llt_foreach_cb_t)(struct lltable *, struct llentry *, void *);
|
||||
typedef int (llt_foreach_entry_t)(struct lltable *, llt_foreach_cb_t *, void *);
|
||||
@ -188,6 +185,7 @@ struct lltable {
|
||||
llt_unlink_entry_t *llt_unlink_entry;
|
||||
llt_prepare_sentry_t *llt_prepare_static_entry;
|
||||
llt_get_sa_addr_t *llt_get_sa_addr;
|
||||
llt_fill_sa_entry_t *llt_fill_sa_entry;
|
||||
llt_free_tbl_t *llt_free_tbl;
|
||||
};
|
||||
|
||||
@ -271,6 +269,16 @@ lltable_unlink_entry(struct lltable *llt, struct llentry *lle)
|
||||
llt->llt_unlink_entry(lle);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
lltable_fill_sa_entry(const struct llentry *lle, struct sockaddr *sa)
|
||||
{
|
||||
struct lltable *llt;
|
||||
|
||||
llt = lle->lle_tbl;
|
||||
|
||||
llt->llt_fill_sa_entry(lle, sa);
|
||||
}
|
||||
|
||||
int lla_rt_output(struct rt_msghdr *, struct rt_addrinfo *);
|
||||
|
||||
#include <sys/eventhandler.h>
|
||||
|
@ -232,9 +232,7 @@ arptimer(void *arg)
|
||||
case ARP_LLINFO_VERIFY:
|
||||
if (lle->r_kick == 0 && lle->la_preempt > 0) {
|
||||
/* Entry was used, issue refresh request */
|
||||
struct sockaddr_in *dst;
|
||||
dst = (struct sockaddr_in *)L3_ADDR(lle);
|
||||
arprequest(ifp, NULL, &dst->sin_addr, NULL);
|
||||
arprequest(ifp, NULL, &lle->r_l3addr.addr4, NULL);
|
||||
lle->la_preempt--;
|
||||
lle->r_kick = 1;
|
||||
callout_schedule(&lle->la_timer, hz * V_arpt_rexmit);
|
||||
@ -1193,7 +1191,7 @@ arp_update_lle(struct arphdr *ah, struct in_addr isaddr, struct ifnet *ifp,
|
||||
m_hold = la->la_hold;
|
||||
la->la_hold = NULL;
|
||||
la->la_numheld = 0;
|
||||
memcpy(&sin, L3_ADDR(la), sizeof(sin));
|
||||
lltable_fill_sa_entry(la, (struct sockaddr *)&sin);
|
||||
LLE_WUNLOCK(la);
|
||||
for (; m_hold != NULL; m_hold = m_hold_next) {
|
||||
m_hold_next = m_hold->m_nextpkt;
|
||||
|
@ -988,11 +988,6 @@ in_purgemaddrs(struct ifnet *ifp)
|
||||
IN_MULTI_UNLOCK();
|
||||
}
|
||||
|
||||
struct in_llentry {
|
||||
struct llentry base;
|
||||
struct sockaddr_in l3_addr4;
|
||||
};
|
||||
|
||||
/*
|
||||
* Frees unlinked record.
|
||||
* This function is called by the timer functions
|
||||
@ -1011,17 +1006,13 @@ in_lltable_free(struct llentry *lle)
|
||||
static struct llentry *
|
||||
in_lltable_new(struct in_addr addr4, u_int flags)
|
||||
{
|
||||
struct in_llentry *lle;
|
||||
struct llentry *lle;
|
||||
|
||||
lle = malloc(sizeof(struct in_llentry), M_LLTABLE, M_NOWAIT | M_ZERO);
|
||||
lle = malloc(sizeof(struct llentry), M_LLTABLE, M_NOWAIT | M_ZERO);
|
||||
if (lle == NULL) /* NB: caller generates msg */
|
||||
return NULL;
|
||||
|
||||
lle->base.r_l3addr.addr4 = addr4;
|
||||
/* XXX: Legacy */
|
||||
lle->l3_addr4.sin_len = sizeof(lle->l3_addr4);
|
||||
lle->l3_addr4.sin_family = AF_INET;
|
||||
lle->l3_addr4.sin_addr = addr4;
|
||||
|
||||
/*
|
||||
* For IPv4 this will trigger "arpresolve" to generate
|
||||
@ -1038,7 +1029,7 @@ in_lltable_new(struct in_addr addr4, u_int flags)
|
||||
}
|
||||
|
||||
#define IN_ARE_MASKED_ADDR_EQUAL(d, a, m) ( \
|
||||
(((ntohl((d)->sin_addr.s_addr) ^ (a)->sin_addr.s_addr) & (m)->sin_addr.s_addr)) == 0 )
|
||||
(((ntohl((d).s_addr) ^ (a)->sin_addr.s_addr) & (m)->sin_addr.s_addr)) == 0 )
|
||||
|
||||
static int
|
||||
in_lltable_match_prefix(const struct sockaddr *prefix,
|
||||
@ -1051,7 +1042,7 @@ in_lltable_match_prefix(const struct sockaddr *prefix,
|
||||
* (flags & LLE_STATIC) means deleting all entries
|
||||
* including static ARP entries.
|
||||
*/
|
||||
if (IN_ARE_MASKED_ADDR_EQUAL(satosin(L3_ADDR(lle)), pfx, msk) &&
|
||||
if (IN_ARE_MASKED_ADDR_EQUAL(lle->r_l3addr.addr4, pfx, msk) &&
|
||||
((flags & LLE_STATIC) || !(lle->la_flags & LLE_STATIC)))
|
||||
return (1);
|
||||
|
||||
@ -1118,6 +1109,18 @@ in_lltable_get_sa_addr(const struct sockaddr *l3addr)
|
||||
return ((const void *)&sin->sin_addr);
|
||||
}
|
||||
|
||||
static void
|
||||
in_lltable_fill_sa_entry(const struct llentry *lle, struct sockaddr *sa)
|
||||
{
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
sin = (struct sockaddr_in *)sa;
|
||||
bzero(sin, sizeof(*sin));
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_len = sizeof(*sin);
|
||||
sin->sin_addr = lle->r_l3addr.addr4;
|
||||
}
|
||||
|
||||
static inline struct llentry *
|
||||
in_lltable_find_dst(struct lltable *llt, struct in_addr dst)
|
||||
{
|
||||
@ -1251,8 +1254,11 @@ in_lltable_dump_entry(struct lltable *llt, struct llentry *lle,
|
||||
struct sockaddr_dl *sdl;
|
||||
int error;
|
||||
|
||||
bzero(&arpc, sizeof(arpc));
|
||||
/* Skip if jailed and not a valid IP of the prison. */
|
||||
if (prison_if(wr->td->td_ucred, L3_ADDR(lle)) != 0)
|
||||
lltable_fill_sa_entry(lle,(struct sockaddr *)&arpc.sin);
|
||||
if (prison_if(wr->td->td_ucred,
|
||||
(struct sockaddr *)&arpc.sin) != 0)
|
||||
return (0);
|
||||
/*
|
||||
* produce a msg made of:
|
||||
@ -1260,15 +1266,11 @@ in_lltable_dump_entry(struct lltable *llt, struct llentry *lle,
|
||||
* struct sockaddr_in; (IPv4)
|
||||
* struct sockaddr_dl;
|
||||
*/
|
||||
bzero(&arpc, sizeof(arpc));
|
||||
arpc.rtm.rtm_msglen = sizeof(arpc);
|
||||
arpc.rtm.rtm_version = RTM_VERSION;
|
||||
arpc.rtm.rtm_type = RTM_GET;
|
||||
arpc.rtm.rtm_flags = RTF_UP;
|
||||
arpc.rtm.rtm_addrs = RTA_DST | RTA_GATEWAY;
|
||||
arpc.sin.sin_family = AF_INET;
|
||||
arpc.sin.sin_len = sizeof(arpc.sin);
|
||||
arpc.sin.sin_addr.s_addr = lle->r_l3addr.addr4.s_addr;
|
||||
|
||||
/* publish */
|
||||
if (lle->la_flags & LLE_PUB)
|
||||
@ -1317,6 +1319,7 @@ in_domifattach(struct ifnet *ifp)
|
||||
llt->llt_dump_entry = in_lltable_dump_entry;
|
||||
llt->llt_hash = in_lltable_hash;
|
||||
llt->llt_get_sa_addr = in_lltable_get_sa_addr;
|
||||
llt->llt_fill_sa_entry = in_lltable_fill_sa_entry;
|
||||
llt->llt_clear_entry = arp_lltable_clear_entry;
|
||||
llt->llt_match_prefix = in_lltable_match_prefix;
|
||||
llt->llt_prepare_static_entry = arp_lltable_prepare_static_entry;
|
||||
|
@ -392,21 +392,26 @@ toe_lle_event(void *arg __unused, struct llentry *lle, int evt)
|
||||
struct sockaddr *sa;
|
||||
uint8_t *lladdr;
|
||||
uint16_t vtag;
|
||||
int sa_family;
|
||||
struct sockaddr_storage ss;
|
||||
|
||||
LLE_WLOCK_ASSERT(lle);
|
||||
|
||||
ifp = lle->lle_tbl->llt_ifp;
|
||||
sa = L3_ADDR(lle);
|
||||
sa_family = lle->lle_tbl->llt_af;
|
||||
|
||||
#if 0
|
||||
/* XXX: Do not panic, ignore event instead */
|
||||
KASSERT(sa->sa_family == AF_INET || sa->sa_family == AF_INET6,
|
||||
("%s: lle_event %d for lle %p but sa %p !INET && !INET6",
|
||||
__func__, evt, lle, sa));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Not interested if the interface's TOE capability is not enabled.
|
||||
*/
|
||||
if ((sa->sa_family == AF_INET && !(ifp->if_capenable & IFCAP_TOE4)) ||
|
||||
(sa->sa_family == AF_INET6 && !(ifp->if_capenable & IFCAP_TOE6)))
|
||||
if ((sa_family == AF_INET && !(ifp->if_capenable & IFCAP_TOE4)) ||
|
||||
(sa_family == AF_INET6 && !(ifp->if_capenable & IFCAP_TOE6)))
|
||||
return;
|
||||
|
||||
tod = TOEDEV(ifp);
|
||||
@ -433,6 +438,8 @@ toe_lle_event(void *arg __unused, struct llentry *lle, int evt)
|
||||
#endif
|
||||
}
|
||||
|
||||
sa = (struct sockaddr *)&ss;
|
||||
lltable_fill_sa_entry(lle, sa);
|
||||
tod->tod_l2_update(tod, ifp, sa, lladdr, vtag);
|
||||
}
|
||||
|
||||
|
@ -2046,11 +2046,6 @@ in6_if2idlen(struct ifnet *ifp)
|
||||
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
struct in6_llentry {
|
||||
struct llentry base;
|
||||
struct sockaddr_in6 l3_addr6;
|
||||
};
|
||||
|
||||
/*
|
||||
* Frees already unlinked @lle.
|
||||
*/
|
||||
@ -2066,17 +2061,13 @@ in6_lltable_free(struct llentry *lle)
|
||||
static struct llentry *
|
||||
in6_lltable_new(const struct in6_addr *addr6, u_int flags)
|
||||
{
|
||||
struct in6_llentry *lle;
|
||||
struct llentry *lle;
|
||||
|
||||
lle = malloc(sizeof(struct in6_llentry), M_LLTABLE, M_NOWAIT | M_ZERO);
|
||||
lle = malloc(sizeof(struct llentry), M_LLTABLE, M_NOWAIT | M_ZERO);
|
||||
if (lle == NULL) /* NB: caller generates msg */
|
||||
return NULL;
|
||||
|
||||
lle->base.r_l3addr.addr6 = *addr6;
|
||||
/* XXX: legacy */
|
||||
lle->l3_addr6.sin6_family = AF_INET6;
|
||||
lle->l3_addr6.sin6_len = sizeof(lle->l3_addr6);
|
||||
lle->l3_addr6.sin6_addr = *addr6;
|
||||
lle->base.lle_refcnt = 1;
|
||||
lle->base.lle_free = in6_lltable_free;
|
||||
LLE_LOCK_INIT(&lle->base);
|
||||
@ -2093,7 +2084,7 @@ in6_lltable_match_prefix(const struct sockaddr *prefix,
|
||||
const struct sockaddr_in6 *pfx = (const struct sockaddr_in6 *)prefix;
|
||||
const struct sockaddr_in6 *msk = (const struct sockaddr_in6 *)mask;
|
||||
|
||||
if (IN6_ARE_MASKED_ADDR_EQUAL(&satosin6(L3_ADDR(lle))->sin6_addr,
|
||||
if (IN6_ARE_MASKED_ADDR_EQUAL(&lle->r_l3addr.addr6,
|
||||
&pfx->sin6_addr, &msk->sin6_addr) &&
|
||||
((flags & LLE_STATIC) || !(lle->la_flags & LLE_STATIC)))
|
||||
return (1);
|
||||
@ -2164,6 +2155,18 @@ in6_lltable_get_sa_addr(const struct sockaddr *l3addr)
|
||||
return ((const void *)&sin6->sin6_addr);
|
||||
}
|
||||
|
||||
static void
|
||||
in6_lltable_fill_sa_entry(const struct llentry *lle, struct sockaddr *sa)
|
||||
{
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
sin6 = (struct sockaddr_in6 *)sa;
|
||||
bzero(sin6, sizeof(*sin6));
|
||||
sin6->sin6_family = AF_INET6;
|
||||
sin6->sin6_len = sizeof(*sin6);
|
||||
sin6->sin6_addr = lle->r_l3addr.addr6;
|
||||
}
|
||||
|
||||
static inline struct llentry *
|
||||
in6_lltable_find_dst(struct lltable *llt, const struct in6_addr *dst)
|
||||
{
|
||||
@ -2300,11 +2303,15 @@ in6_lltable_dump_entry(struct lltable *llt, struct llentry *lle,
|
||||
struct sockaddr_dl *sdl;
|
||||
int error;
|
||||
|
||||
bzero(&ndpc, sizeof(ndpc));
|
||||
/* skip invalid entries */
|
||||
if ((lle->la_flags & LLE_VALID) == 0)
|
||||
return (0);
|
||||
/* Skip if jailed and not a valid IP of the prison. */
|
||||
if (prison_if(wr->td->td_ucred, L3_ADDR(lle)) != 0)
|
||||
lltable_fill_sa_entry(lle,
|
||||
(struct sockaddr *)&ndpc.sin6);
|
||||
if (prison_if(wr->td->td_ucred,
|
||||
(struct sockaddr *)&ndpc.sin6) != 0)
|
||||
return (0);
|
||||
/*
|
||||
* produce a msg made of:
|
||||
@ -2312,15 +2319,11 @@ in6_lltable_dump_entry(struct lltable *llt, struct llentry *lle,
|
||||
* struct sockaddr_in6 (IPv6)
|
||||
* struct sockaddr_dl;
|
||||
*/
|
||||
bzero(&ndpc, sizeof(ndpc));
|
||||
ndpc.rtm.rtm_msglen = sizeof(ndpc);
|
||||
ndpc.rtm.rtm_version = RTM_VERSION;
|
||||
ndpc.rtm.rtm_type = RTM_GET;
|
||||
ndpc.rtm.rtm_flags = RTF_UP;
|
||||
ndpc.rtm.rtm_addrs = RTA_DST | RTA_GATEWAY;
|
||||
ndpc.sin6.sin6_family = AF_INET6;
|
||||
ndpc.sin6.sin6_len = sizeof(ndpc.sin6);
|
||||
bcopy(L3_ADDR(lle), &ndpc.sin6, L3_ADDR_LEN(lle));
|
||||
if (V_deembed_scopeid)
|
||||
sa6_recoverscope(&ndpc.sin6);
|
||||
|
||||
@ -2389,6 +2392,7 @@ in6_domifattach(struct ifnet *ifp)
|
||||
llt->llt_dump_entry = in6_lltable_dump_entry;
|
||||
llt->llt_hash = in6_lltable_hash;
|
||||
llt->llt_get_sa_addr = in6_lltable_get_sa_addr;
|
||||
llt->llt_fill_sa_entry = in6_lltable_fill_sa_entry;
|
||||
llt->llt_clear_entry = nd6_lltable_clear_entry;
|
||||
llt->llt_match_prefix = in6_lltable_match_prefix;
|
||||
llt->llt_prepare_static_entry = nd6_lltable_prepare_static_entry;
|
||||
|
@ -68,7 +68,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_kdtrace.h>
|
||||
#include <net/if_llatbl.h>
|
||||
#define L3_ADDR_SIN6(le) ((struct sockaddr_in6 *) L3_ADDR(le))
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet6/in6_var.h>
|
||||
#include <netinet/ip6.h>
|
||||
@ -543,7 +542,7 @@ nd6_llinfo_timer(void *arg)
|
||||
CURVNET_SET(ifp->if_vnet);
|
||||
|
||||
ndi = ND_IFINFO(ifp);
|
||||
dst = &L3_ADDR_SIN6(ln)->sin6_addr;
|
||||
dst = &ln->r_l3addr.addr6;
|
||||
|
||||
/*
|
||||
* Each case statement needs to unlock @ln before break/return.
|
||||
@ -1122,7 +1121,7 @@ nd6_check_del_defrtr(struct lltable *llt, struct llentry *ln)
|
||||
struct in6_addr dst;
|
||||
|
||||
ifp = llt->llt_ifp;
|
||||
dst = L3_ADDR_SIN6(ln)->sin6_addr;
|
||||
dst = ln->r_l3addr.addr6;
|
||||
|
||||
LLE_WLOCK_ASSERT(ln);
|
||||
|
||||
@ -1165,7 +1164,7 @@ nd6_check_recalc_defrtr(struct lltable *llt, struct llentry *ln)
|
||||
struct in6_addr dst;
|
||||
|
||||
ifp = llt->llt_ifp;
|
||||
dst = L3_ADDR_SIN6(ln)->sin6_addr;
|
||||
dst = ln->r_l3addr.addr6;
|
||||
|
||||
LLE_WLOCK_ASSERT(ln);
|
||||
|
||||
@ -1909,6 +1908,8 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
|
||||
if (ln->la_hold) {
|
||||
struct mbuf *m_hold, *m_hold_next;
|
||||
|
||||
lltable_fill_sa_entry(ln, (struct sockaddr *)&sin6);
|
||||
|
||||
/*
|
||||
* reset the la_hold in advance, to explicitly
|
||||
* prevent a la_hold lookup in nd6_output()
|
||||
@ -1924,15 +1925,12 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
|
||||
* just set the 2nd argument as the
|
||||
* 1st one.
|
||||
*/
|
||||
nd6_output_lle(ifp, ifp, m_hold, L3_ADDR_SIN6(ln), NULL, ln, &chain);
|
||||
nd6_output_lle(ifp, ifp, m_hold, &sin6, NULL, ln, &chain);
|
||||
}
|
||||
/*
|
||||
* If we have mbufs in the chain we need to do
|
||||
* deferred transmit. Copy the address from the
|
||||
* llentry before dropping the lock down below.
|
||||
* deferred transmit.
|
||||
*/
|
||||
if (chain != NULL)
|
||||
memcpy(&sin6, L3_ADDR_SIN6(ln), sizeof(sin6));
|
||||
}
|
||||
} else if (ln->ln_state == ND6_LLINFO_INCOMPLETE) {
|
||||
/* probe right away */
|
||||
|
@ -65,7 +65,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <net/if_llatbl.h>
|
||||
#define L3_ADDR_SIN6(le) ((struct sockaddr_in6 *) L3_ADDR(le))
|
||||
#include <netinet6/in6_var.h>
|
||||
#include <netinet6/in6_ifattach.h>
|
||||
#include <netinet/ip6.h>
|
||||
@ -824,7 +823,7 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
|
||||
struct nd_defrouter *dr;
|
||||
struct in6_addr *in6;
|
||||
|
||||
in6 = &L3_ADDR_SIN6(ln)->sin6_addr;
|
||||
in6 = &ln->r_l3addr.addr6;
|
||||
|
||||
/*
|
||||
* Lock to protect the default router list.
|
||||
@ -879,13 +878,15 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
|
||||
m_tag_prepend(m, mtag);
|
||||
}
|
||||
|
||||
nd6_output_lle(ifp, ifp, m_hold, L3_ADDR_SIN6(ln), NULL, ln, &chain);
|
||||
lltable_fill_sa_entry(ln, (struct sockaddr *)&sin6);
|
||||
nd6_output_lle(ifp, ifp, m_hold, &sin6, NULL, ln,
|
||||
&chain);
|
||||
}
|
||||
}
|
||||
freeit:
|
||||
if (ln != NULL) {
|
||||
if (chain)
|
||||
memcpy(&sin6, L3_ADDR_SIN6(ln), sizeof(sin6));
|
||||
lltable_fill_sa_entry(ln, (struct sockaddr *)&sin6);
|
||||
LLE_WUNLOCK(ln);
|
||||
|
||||
if (chain)
|
||||
|
Loading…
Reference in New Issue
Block a user