svn commit: r275625 - in projects/routing/sys: net netinet netinet6
Alexander V. Chernikov
melifaro at FreeBSD.org
Mon Dec 8 23:23:57 UTC 2014
Author: melifaro
Date: Mon Dec 8 23:23:53 2014
New Revision: 275625
URL: https://svnweb.freebsd.org/changeset/base/275625
Log:
Simplify lle lookup/create api by using addresses instead of sockaddrs.
Modified:
projects/routing/sys/net/if_llatbl.c
projects/routing/sys/net/if_llatbl.h
projects/routing/sys/net/rt_nhops.c
projects/routing/sys/netinet/if_ether.c
projects/routing/sys/netinet/if_ether.h
projects/routing/sys/netinet/in.c
projects/routing/sys/netinet/in_var.h
projects/routing/sys/netinet/toecore.c
projects/routing/sys/netinet6/in6.c
projects/routing/sys/netinet6/in6_var.h
projects/routing/sys/netinet6/nd6.c
projects/routing/sys/netinet6/nd6.h
Modified: projects/routing/sys/net/if_llatbl.c
==============================================================================
--- projects/routing/sys/net/if_llatbl.c Mon Dec 8 21:14:13 2014 (r275624)
+++ projects/routing/sys/net/if_llatbl.c Mon Dec 8 23:23:53 2014 (r275625)
@@ -229,9 +229,12 @@ llentry_alloc(struct ifnet *ifp, struct
struct sockaddr_storage *dst)
{
struct llentry *la;
+ const void *l3addr;
+
+ l3addr = lt->llt_get_sa_addr((struct sockaddr *)dst);
IF_AFDATA_RLOCK(ifp);
- la = lt->llt_lookup(lt, LLE_EXCLUSIVE, (struct sockaddr *)dst);
+ la = lt->llt_lookup(lt, LLE_EXCLUSIVE, l3addr);
IF_AFDATA_RUNLOCK(ifp);
if ((la == NULL) &&
(ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) == 0) {
@@ -441,6 +444,7 @@ lla_rt_output(struct rt_msghdr *rtm, str
struct ifnet *ifp;
struct lltable *llt;
struct llentry *lle, *lle_tmp;
+ const void *l3addr;
u_int laflags = 0;
int error;
@@ -469,6 +473,7 @@ lla_rt_output(struct rt_msghdr *rtm, str
switch (rtm->rtm_type) {
case RTM_ADD:
/* Add static LLE */
+ l3addr = llt->llt_get_sa_addr(dst);
lle = llt->llt_create(llt, 0, dst);
if (lle == NULL)
return (ENOMEM);
@@ -491,7 +496,7 @@ lla_rt_output(struct rt_msghdr *rtm, str
LLE_WLOCK(lle);
/* Check if we already have this lle */
/* XXX: Use LLE_UNLOCKED */
- lle_tmp = llt->llt_lookup(llt, LLE_EXCLUSIVE, dst);
+ lle_tmp = llt->llt_lookup(llt, LLE_EXCLUSIVE, l3addr);
if (lle_tmp != NULL) {
IF_AFDATA_CFG_WUNLOCK(ifp);
LLE_WUNLOCK(lle_tmp);
Modified: projects/routing/sys/net/if_llatbl.h
==============================================================================
--- projects/routing/sys/net/if_llatbl.h Mon Dec 8 21:14:13 2014 (r275624)
+++ projects/routing/sys/net/if_llatbl.h Mon Dec 8 23:23:53 2014 (r275625)
@@ -148,9 +148,9 @@ struct llentry {
#endif
typedef struct llentry *(llt_lookup_t)(struct lltable *, u_int flags,
- const struct sockaddr *l3addr);
+ const void *paddr);
typedef struct llentry *(llt_create_t)(struct lltable *, u_int flags,
- const struct sockaddr *l3addr);
+ const void *paddr);
typedef int (llt_delete_addr_t)(struct lltable *, u_int flags,
const struct sockaddr *l3addr);
typedef int (llt_dump_entry_t)(struct lltable *, struct llentry *,
@@ -164,6 +164,7 @@ typedef void (llt_link_entry_t)(struct l
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 int (llt_foreach_cb_t)(struct lltable *, struct llentry *, void *);
typedef int (llt_foreach_entry_t)(struct lltable *, llt_foreach_cb_t *, void *);
@@ -186,6 +187,7 @@ struct lltable {
llt_link_entry_t *llt_link_entry;
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_free_tbl_t *llt_free_tbl;
};
@@ -233,18 +235,18 @@ size_t lltable_drop_entry_queue(struct
*/
static __inline struct llentry *
lltable_lookup_lle(struct lltable *llt, u_int flags,
- const struct sockaddr *l3addr)
+ const void *paddr)
{
- return llt->llt_lookup(llt, flags, l3addr);
+ return (llt->llt_lookup(llt, flags, paddr));
}
static __inline struct llentry *
lltable_create_lle(struct lltable *llt, u_int flags,
- const struct sockaddr *l3addr)
+ const void *paddr)
{
- return llt->llt_create(llt, flags, l3addr);
+ return (llt->llt_create(llt, flags, paddr));
}
static __inline int
Modified: projects/routing/sys/net/rt_nhops.c
==============================================================================
--- projects/routing/sys/net/rt_nhops.c Mon Dec 8 21:14:13 2014 (r275624)
+++ projects/routing/sys/net/rt_nhops.c Mon Dec 8 23:23:53 2014 (r275625)
@@ -680,7 +680,6 @@ fib6_storelladdr(struct ifnet *ifp, stru
u_char *desten)
{
struct llentry *ln;
- struct sockaddr_in6 dst_sa;
IF_AFDATA_RUN_TRACKER;
if (mm_flags & M_MCAST) {
@@ -688,19 +687,11 @@ fib6_storelladdr(struct ifnet *ifp, stru
return (0);
}
- memset(&dst_sa, 0, sizeof(dst_sa));
- dst_sa.sin6_family = AF_INET6;
- dst_sa.sin6_len = sizeof(dst_sa);
- dst_sa.sin6_addr = *dst;
- dst_sa.sin6_scope_id = ifp->if_index;
-
-
/*
* the entry should have been created in nd6_store_lladdr
*/
IF_AFDATA_RUN_RLOCK(ifp);
- ln = lltable_lookup_lle(LLTABLE6(ifp), LLE_UNLOCKED,
- (struct sockaddr *)&dst_sa);
+ ln = lltable_lookup_lle6(ifp, LLE_UNLOCKED, dst);
/*
* Perform fast path for the following cases:
Modified: projects/routing/sys/netinet/if_ether.c
==============================================================================
--- projects/routing/sys/netinet/if_ether.c Mon Dec 8 21:14:13 2014 (r275624)
+++ projects/routing/sys/netinet/if_ether.c Mon Dec 8 23:23:53 2014 (r275625)
@@ -417,8 +417,6 @@ arpresolve_fast(struct ifnet *ifp, struc
u_char *dst_addr)
{
struct llentry *la;
- struct sockaddr_in sin;
- const struct sockaddr *sa_dst;
IF_AFDATA_RUN_TRACKER;
if (mflags & M_BCAST) {
@@ -430,14 +428,8 @@ arpresolve_fast(struct ifnet *ifp, struc
return (0);
}
- memset(&sin, 0, sizeof(sin));
- sin.sin_addr = dst;
- sin.sin_family = AF_INET;
- sin.sin_len = sizeof(sin);
- sa_dst = (const struct sockaddr *)&sin;
-
IF_AFDATA_RUN_RLOCK(ifp);
- la = lltable_lookup_lle(LLTABLE(ifp), LLE_UNLOCKED, sa_dst);
+ la = lltable_lookup_lle4(ifp, LLE_UNLOCKED, &dst);
if (la != NULL && (la->r_flags & RLLE_VALID) != 0) {
/* Entry found, let's copy lle info */
bcopy(&la->ll_addr, dst_addr, ifp->if_addrlen);
@@ -503,9 +495,12 @@ arpresolve(struct ifnet *ifp, struct rte
const struct sockaddr *dst, u_char *desten, struct llentry **lle)
{
struct llentry *la = NULL;
+ struct in_addr dst4;
int is_gw;
IF_AFDATA_RUN_TRACKER;
+ dst4 = SIN(dst)->sin_addr;
+
*lle = NULL;
if (m != NULL) {
if (m->m_flags & M_BCAST) {
@@ -516,13 +511,13 @@ arpresolve(struct ifnet *ifp, struct rte
}
if (m->m_flags & M_MCAST && ifp->if_type != IFT_ARCNET) {
/* multicast */
- ETHER_MAP_IP_MULTICAST(&SIN(dst)->sin_addr, desten);
+ ETHER_MAP_IP_MULTICAST(&dst4, desten);
return (0);
}
}
IF_AFDATA_RUN_RLOCK(ifp);
- la = lltable_lookup_lle(LLTABLE(ifp), LLE_UNLOCKED, dst);
+ la = lltable_lookup_lle4(ifp, LLE_UNLOCKED, &dst4);
if (la != NULL && (la->r_flags & RLLE_VALID) != 0) {
/* Entry found, let's copy lle info */
bcopy(&la->ll_addr, desten, ifp->if_addrlen);
@@ -545,22 +540,23 @@ arpresolve_slow(struct ifnet *ifp, int i
struct llentry *la, *la_tmp;
struct mbuf *curr = NULL;
struct mbuf *next = NULL;
+ struct in_addr dst4;
int create, error;
create = 0;
*lle = NULL;
+ dst4 = SIN(dst)->sin_addr;
IF_AFDATA_RLOCK(ifp);
- la = lltable_lookup_lle(LLTABLE(ifp), LLE_EXCLUSIVE, dst);
+ la = lltable_lookup_lle4(ifp, LLE_EXCLUSIVE, &dst4);
IF_AFDATA_RUNLOCK(ifp);
if (la == NULL && (ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) == 0) {
create = 1;
- la = lltable_create_lle(LLTABLE(ifp), 0, dst);
+ la = lltable_create_lle4(ifp, 0, &dst4);
if (la != NULL) {
IF_AFDATA_CFG_WLOCK(ifp);
LLE_WLOCK(la);
- la_tmp = lltable_lookup_lle(LLTABLE(ifp), LLE_EXCLUSIVE,
- dst);
+ la_tmp = lltable_lookup_lle4(ifp, LLE_EXCLUSIVE, &dst4);
if (la_tmp == NULL) {
/*
* No entry has been found. Link new one.
@@ -582,7 +578,7 @@ arpresolve_slow(struct ifnet *ifp, int i
if (create != 0)
log(LOG_DEBUG,
"arpresolve: can't allocate llinfo for %s on %s\n",
- inet_ntoa(SIN(dst)->sin_addr), ifp->if_xname);
+ inet_ntoa(dst4), ifp->if_xname);
m_freem(m);
return (EINVAL);
}
@@ -781,13 +777,8 @@ in_arpinput(struct mbuf *m)
int bridged = 0, is_bridge = 0;
int carped;
struct nhop4_extended nh_ext;
- struct sockaddr_in sin;
struct llentry *la_tmp;
- sin.sin_len = sizeof(struct sockaddr_in);
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = 0;
-
if (ifp->if_bridge)
bridged = 1;
if (ifp->if_type == IFT_BRIDGE)
@@ -938,14 +929,8 @@ match:
if (ifp->if_flags & IFF_STATICARP)
goto reply;
- bzero(&sin, sizeof(sin));
- sin.sin_len = sizeof(struct sockaddr_in);
- sin.sin_family = AF_INET;
- sin.sin_addr = isaddr;
-
IF_AFDATA_CFG_RLOCK(ifp);
- la = lltable_lookup_lle(LLTABLE(ifp), LLE_EXCLUSIVE,
- (struct sockaddr *)&sin);
+ la = lltable_lookup_lle4(ifp, LLE_EXCLUSIVE, &isaddr);
IF_AFDATA_CFG_RUNLOCK(ifp);
if (la != NULL)
arp_update_lle(ah, isaddr, ifp, bridged, la);
@@ -955,14 +940,12 @@ match:
* Reply to our address, but no lle exists yet.
* do we really have to create an entry?
*/
- la = lltable_create_lle(LLTABLE(ifp), 0,
- (struct sockaddr *)&sin);
+ la = lltable_create_lle4(ifp, 0, &isaddr);
if (la != NULL) {
IF_AFDATA_CFG_WLOCK(ifp);
LLE_WLOCK(la);
/* Let's try to search another time */
- la_tmp = lltable_lookup_lle(LLTABLE(ifp), LLE_EXCLUSIVE,
- (struct sockaddr *)&sin);
+ la_tmp = lltable_lookup_lle4(ifp, LLE_EXCLUSIVE, &isaddr);
if (la_tmp != NULL) {
/*
* Someone has already inserted another entry.
@@ -995,10 +978,8 @@ reply:
} else {
struct llentry *lle = NULL;
- sin.sin_addr = itaddr;
IF_AFDATA_RLOCK(ifp);
- lle = lltable_lookup_lle(LLTABLE(ifp), 0,
- (struct sockaddr *)&sin);
+ lle = lltable_lookup_lle4(ifp, 0, &itaddr);
IF_AFDATA_RUNLOCK(ifp);
if ((lle != NULL) && (lle->la_flags & LLE_PUB)) {
@@ -1013,7 +994,6 @@ reply:
if (!V_arp_proxyall)
goto drop;
- sin.sin_addr = itaddr;
/* XXX MRT use table 0 for arp reply */
if (fib4_lookup_nh_ext(0, itaddr, 0, 0, &nh_ext) != 0)
goto drop;
@@ -1035,7 +1015,6 @@ reply:
* avoids ARP chaos if an interface is connected to the
* wrong network.
*/
- sin.sin_addr = isaddr;
/* XXX MRT use table 0 for arp checks */
if (fib4_lookup_nh_ext(0, isaddr, 0, 0, &nh_ext) != 0)
@@ -1252,8 +1231,7 @@ arp_ifinit(struct ifnet *ifp, struct ifa
* because the output of the arp utility shows
* that L2 entry as permanent
*/
- lle = lltable_create_lle(LLTABLE(ifp), LLE_IFADDR | LLE_STATIC,
- (struct sockaddr *)IA_SIN(ifa));
+ lle = lltable_create_lle4(ifp, LLE_IFADDR | LLE_STATIC, &addr);
if (lle == NULL) {
log(LOG_INFO, "arp_ifinit: cannot create arp "
"entry for interface address\n");
@@ -1271,8 +1249,7 @@ arp_ifinit(struct ifnet *ifp, struct ifa
* Instead of dealing with callouts/flags/etc we simply
* delete it and add new one.
*/
- lle_tmp = lltable_lookup_lle(llt, LLE_EXCLUSIVE,
- (struct sockaddr *)IA_SIN(ifa));
+ lle_tmp = lltable_lookup_lle4(ifp, LLE_EXCLUSIVE, &addr);
IF_AFDATA_RUN_WLOCK(ifp);
if (lle_tmp != NULL)
Modified: projects/routing/sys/netinet/if_ether.h
==============================================================================
--- projects/routing/sys/netinet/if_ether.h Mon Dec 8 21:14:13 2014 (r275624)
+++ projects/routing/sys/netinet/if_ether.h Mon Dec 8 23:23:53 2014 (r275625)
@@ -117,6 +117,21 @@ struct llentry;
struct ifaddr;
struct rt_addrinfo;
+#define LLTABLE(ifp) \
+ ((struct in_ifinfo *)(ifp)->if_afdata[AF_INET])->ii_llt
+
+static __inline const void *
+_check_in_addr_typecast(const struct in_addr *paddr)
+{
+
+ return ((const void *)paddr);
+}
+
+#define lltable_lookup_lle4(i, f, a) \
+ lltable_lookup_lle(LLTABLE(i), (f), _check_in_addr_typecast(a))
+#define lltable_create_lle4(i, f, a) \
+ lltable_create_lle(LLTABLE(i), (f), _check_in_addr_typecast(a))
+
int arpresolve(struct ifnet *ifp, struct rtentry *rt, struct mbuf *m,
const struct sockaddr *dst, u_char *desten, struct llentry **lle);
int arpresolve_fast(struct ifnet *ifp, struct in_addr dst, u_int mflags,
Modified: projects/routing/sys/netinet/in.c
==============================================================================
--- projects/routing/sys/netinet/in.c Mon Dec 8 21:14:13 2014 (r275624)
+++ projects/routing/sys/netinet/in.c Mon Dec 8 23:23:53 2014 (r275625)
@@ -1009,18 +1009,19 @@ in_lltable_free(struct llentry *lle)
}
static struct llentry *
-in_lltable_new(const struct sockaddr *l3addr, u_int flags)
+in_lltable_new(struct in_addr addr4, u_int flags)
{
struct in_llentry *lle;
- const struct sockaddr_in *l3addr_sin;
lle = malloc(sizeof(struct in_llentry), M_LLTABLE, M_NOWAIT | M_ZERO);
if (lle == NULL) /* NB: caller generates msg */
return NULL;
- l3addr_sin = (const struct sockaddr_in *)l3addr;
- lle->base.r_l3addr.addr4 = l3addr_sin->sin_addr;
- lle->l3_addr4 = *l3addr_sin;
+ 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
@@ -1058,15 +1059,10 @@ in_lltable_match_prefix(const struct soc
}
static int
-in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr)
+in_lltable_rtcheck(struct ifnet *ifp, u_int flags, struct in_addr dst)
{
struct nhop4_basic nh4;
- struct in_addr dst;
-
- KASSERT(l3addr->sa_family == AF_INET,
- ("sin_family %d", l3addr->sa_family));
- dst = ((struct sockaddr_in *)l3addr)->sin_addr;
if (fib4_lookup_nh(ifp->if_fib, dst, 0, 0, &nh4) != 0)
return (EINVAL);
@@ -1112,6 +1108,16 @@ in_lltable_hash(const struct llentry *ll
return (in_lltable_hash_dst(lle->r_l3addr.addr4));
}
+static const void *
+in_lltable_get_sa_addr(const struct sockaddr *l3addr)
+{
+ const struct sockaddr_in *sin;
+
+ sin = (const struct sockaddr_in *)l3addr;
+
+ return ((const void *)&sin->sin_addr);
+}
+
static inline struct llentry *
in_lltable_find_dst(struct lltable *llt, struct in_addr dst)
{
@@ -1174,13 +1180,13 @@ in_lltable_delete(struct lltable *llt, u
}
static struct llentry *
-in_lltable_create(struct lltable *llt, u_int flags, const struct sockaddr *l3addr)
+in_lltable_create(struct lltable *llt, u_int flags, const void *paddr)
{
struct ifnet *ifp = llt->llt_ifp;
struct llentry *lle;
+ struct in_addr addr4;
- KASSERT(l3addr->sa_family == AF_INET,
- ("sin_family %d", l3addr->sa_family));
+ addr4 = *((const struct in_addr *)paddr);
/*
* A route that covers the given address must have
@@ -1188,10 +1194,10 @@ in_lltable_create(struct lltable *llt, u
* verify this.
*/
if (!(flags & LLE_IFADDR) &&
- in_lltable_rtcheck(ifp, flags, l3addr) != 0)
+ in_lltable_rtcheck(ifp, flags, addr4) != 0)
return (NULL);
- lle = in_lltable_new(l3addr, flags);
+ lle = in_lltable_new(addr4, flags);
if (lle == NULL) {
log(LOG_INFO, "lla_lookup: new lle malloc failed\n");
return (NULL);
@@ -1206,7 +1212,7 @@ in_lltable_create(struct lltable *llt, u
* If found return lle read locked.
*/
static struct llentry *
-in_lltable_lookup(struct lltable *llt, u_int flags, const struct sockaddr *l3addr)
+in_lltable_lookup(struct lltable *llt, u_int flags, const void *paddr)
{
struct llentry *lle;
struct in_addr dst;
@@ -1216,10 +1222,8 @@ in_lltable_lookup(struct lltable *llt, u
* by different locks.
* IF_AFDATA_LOCK_ASSERT(llt->llt_ifp);
*/
- KASSERT(l3addr->sa_family == AF_INET,
- ("sin_family %d", l3addr->sa_family));
- dst = ((const struct sockaddr_in *)l3addr)->sin_addr;
+ dst = *((const struct in_addr *)paddr);
lle = in_lltable_find_dst(llt, dst);
if (lle == NULL)
@@ -1312,6 +1316,7 @@ in_domifattach(struct ifnet *ifp)
llt->llt_delete_addr = in_lltable_delete;
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_clear_entry = arp_lltable_clear_entry;
llt->llt_match_prefix = in_lltable_match_prefix;
llt->llt_prepare_static_entry = arp_lltable_prepare_static_entry;
Modified: projects/routing/sys/netinet/in_var.h
==============================================================================
--- projects/routing/sys/netinet/in_var.h Mon Dec 8 21:14:13 2014 (r275624)
+++ projects/routing/sys/netinet/in_var.h Mon Dec 8 23:23:53 2014 (r275625)
@@ -96,8 +96,6 @@ struct in_aliasreq {
#ifdef _KERNEL
extern u_char inetctlerrmap[];
-#define LLTABLE(ifp) \
- ((struct in_ifinfo *)(ifp)->if_afdata[AF_INET])->ii_llt
/*
* Hash table for IP addresses.
*/
Modified: projects/routing/sys/netinet/toecore.c
==============================================================================
--- projects/routing/sys/netinet/toecore.c Mon Dec 8 21:14:13 2014 (r275624)
+++ projects/routing/sys/netinet/toecore.c Mon Dec 8 23:23:53 2014 (r275625)
@@ -456,22 +456,24 @@ static int
toe_nd6_resolve(struct ifnet *ifp, struct sockaddr *sa, uint8_t *lladdr)
{
struct llentry *lle, *lle_tmp;
- struct sockaddr_in6 *sin6 = (void *)sa;
+ struct in6_addr *dst;
int rc, flags = 0;
+ dst = &((struct sockaddr_in6 *)sa)->sin6_addr;
+
restart:
IF_AFDATA_RLOCK(ifp);
- lle = lltable_lookup_lle(LLTABLE6(ifp), flags, sa);
+ lle = lltable_lookup_lle6(ifp, flags, dst);
IF_AFDATA_RUNLOCK(ifp);
if (lle == NULL) {
- lle = nd6_create(&sin6->sin6_addr, 0, ifp);
+ lle = lltable_create_lle6(ifp, 0, dst);
if (lle == NULL)
return (ENOMEM); /* Couldn't create entry in cache. */
lle->ln_state = ND6_LLINFO_INCOMPLETE;
IF_AFDATA_CFG_WLOCK(ifp);
LLE_WLOCK(lle);
/* Check if the same record was addded */
- lle_tmp = lltable_lookup_lle(LLTABLE6(ifp), LLE_EXCLUSIVE, sa);
+ lle_tmp = lltable_lookup_lle6(ifp, LLE_EXCLUSIVE, dst);
if (lle_tmp == NULL) {
/*
* No entry has been found. Link new one.
@@ -487,7 +489,7 @@ restart:
(long)ND_IFINFO(ifp)->retrans * hz / 1000);
LLE_WUNLOCK(lle);
- nd6_ns_output(ifp, NULL, &sin6->sin6_addr, NULL, 0);
+ nd6_ns_output(ifp, NULL, dst, NULL, 0);
return (EWOULDBLOCK);
}
Modified: projects/routing/sys/netinet6/in6.c
==============================================================================
--- projects/routing/sys/netinet6/in6.c Mon Dec 8 21:14:13 2014 (r275624)
+++ projects/routing/sys/netinet6/in6.c Mon Dec 8 23:23:53 2014 (r275625)
@@ -2064,18 +2064,19 @@ in6_lltable_free(struct llentry *lle)
}
static struct llentry *
-in6_lltable_new(const struct sockaddr *l3addr, u_int flags)
+in6_lltable_new(const struct in6_addr *addr6, u_int flags)
{
struct in6_llentry *lle;
- const struct sockaddr_in6 *l3addr_sin6;
lle = malloc(sizeof(struct in6_llentry), M_LLTABLE, M_NOWAIT | M_ZERO);
if (lle == NULL) /* NB: caller generates msg */
return NULL;
- l3addr_sin6 = (const struct sockaddr_in6 *)l3addr;
- lle->l3_addr6 = *l3addr_sin6;
- lle->base.r_l3addr.addr6 = l3addr_sin6->sin6_addr;
+ 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);
@@ -2103,20 +2104,18 @@ in6_lltable_match_prefix(const struct so
static int
in6_lltable_rtcheck(struct ifnet *ifp,
u_int flags,
- const struct sockaddr *l3addr)
+ const struct in6_addr *addr6)
{
struct nhop6_basic nh6;
+ struct sockaddr_in6 sin6;
struct in6_addr dst;
uint32_t scopeid;
int error;
char ip6buf[INET6_ADDRSTRLEN];
- KASSERT(l3addr->sa_family == AF_INET6,
- ("sin_family %d", l3addr->sa_family));
-
/* Our local addresses are always only installed on the default FIB. */
- in6_splitscope(&((struct sockaddr_in6 *)l3addr)->sin6_addr, &dst, &scopeid);
+ in6_splitscope(addr6, &dst, &scopeid);
error = fib6_lookup_nh(RT_DEFAULT_FIB, &dst, scopeid, 0, 0, &nh6);
if (error != 0 || ((nh6.nh_flags & NHF_GATEWAY) != 0) || nh6.nh_ifp != ifp) {
struct ifaddr *ifa;
@@ -2125,13 +2124,17 @@ in6_lltable_rtcheck(struct ifnet *ifp,
* that is not covered by our own prefix.
*/
/* XXX ifaof_ifpforaddr should take a const param */
- ifa = ifaof_ifpforaddr(__DECONST(struct sockaddr *, l3addr), ifp);
+ bzero(&sin6, sizeof(sin6));
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_len = sizeof(sin6);
+ sin6.sin6_addr = *addr6;
+ ifa = ifaof_ifpforaddr(__DECONST(struct sockaddr *, &sin6), ifp);
if (ifa != NULL) {
ifa_free(ifa);
return 0;
}
log(LOG_INFO, "IPv6 address: \"%s\" is not on the network\n",
- ip6_sprintf(ip6buf, &((const struct sockaddr_in6 *)l3addr)->sin6_addr));
+ ip6_sprintf(ip6buf, addr6));
return EINVAL;
}
return 0;
@@ -2151,6 +2154,16 @@ in6_lltable_hash(const struct llentry *l
return (in6_lltable_hash_dst(&lle->r_l3addr.addr6));
}
+static const void *
+in6_lltable_get_sa_addr(const struct sockaddr *l3addr)
+{
+ const struct sockaddr_in6 *sin6;
+
+ sin6 = (const struct sockaddr_in6 *)l3addr;
+
+ return ((const void *)&sin6->sin6_addr);
+}
+
static inline struct llentry *
in6_lltable_find_dst(struct lltable *llt, const struct in6_addr *dst)
{
@@ -2213,26 +2226,25 @@ in6_lltable_delete(struct lltable *llt,
static struct llentry *
in6_lltable_create(struct lltable *llt, u_int flags,
- const struct sockaddr *l3addr)
+ const void *paddr)
{
struct ifnet *ifp = llt->llt_ifp;
struct llentry *lle;
-
- KASSERT(l3addr->sa_family == AF_INET6,
- ("sin_family %d", l3addr->sa_family));
+ const struct in6_addr *addr6;
IF_AFDATA_CFG_UNLOCK_ASSERT(ifp);
+ addr6 = (const struct in6_addr *)paddr;
/*
* A route that covers the given address must have
* been installed 1st because we are doing a resolution,
* verify this.
*/
if (!(flags & LLE_IFADDR) &&
- in6_lltable_rtcheck(ifp, flags, l3addr) != 0)
+ in6_lltable_rtcheck(ifp, flags, addr6) != 0)
return NULL;
- lle = in6_lltable_new(l3addr, flags);
+ lle = in6_lltable_new(addr6, flags);
if (lle == NULL) {
log(LOG_INFO, "lla_lookup: new lle malloc failed\n");
return NULL;
@@ -2244,9 +2256,9 @@ in6_lltable_create(struct lltable *llt,
static struct llentry *
in6_lltable_lookup(struct lltable *llt, u_int flags,
- const struct sockaddr *l3addr)
+ const void *l3addr)
{
- const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)l3addr;
+ const struct in6_addr *dst6;
struct llentry *lle;
/*
@@ -2254,10 +2266,9 @@ in6_lltable_lookup(struct lltable *llt,
* by different locks.
* IF_AFDATA_LOCK_ASSERT(llt->llt_ifp);
*/
- KASSERT(l3addr->sa_family == AF_INET6,
- ("sin_family %d", l3addr->sa_family));
+ dst6 = (const struct in6_addr *)l3addr;
- lle = in6_lltable_find_dst(llt, &sin6->sin6_addr);
+ lle = in6_lltable_find_dst(llt, dst6);
if (lle == NULL)
return (NULL);
@@ -2377,6 +2388,7 @@ in6_domifattach(struct ifnet *ifp)
llt->llt_delete_addr = in6_lltable_delete;
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_clear_entry = nd6_lltable_clear_entry;
llt->llt_match_prefix = in6_lltable_match_prefix;
llt->llt_prepare_static_entry = nd6_lltable_prepare_static_entry;
Modified: projects/routing/sys/netinet6/in6_var.h
==============================================================================
--- projects/routing/sys/netinet6/in6_var.h Mon Dec 8 21:14:13 2014 (r275624)
+++ projects/routing/sys/netinet6/in6_var.h Mon Dec 8 23:23:53 2014 (r275625)
@@ -108,8 +108,6 @@ struct in6_ifextra {
struct mld_ifinfo *mld_ifinfo;
};
-#define LLTABLE6(ifp) (((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->lltable)
-
#if defined(_KERNEL) || defined(_WANT_IFADDR)
struct in6_ifaddr {
struct ifaddr ia_ifa; /* protocol-independent info */
Modified: projects/routing/sys/netinet6/nd6.c
==============================================================================
--- projects/routing/sys/netinet6/nd6.c Mon Dec 8 21:14:13 2014 (r275624)
+++ projects/routing/sys/netinet6/nd6.c Mon Dec 8 23:23:53 2014 (r275625)
@@ -889,55 +889,6 @@ nd6_purge(struct ifnet *ifp)
*/
}
-/*
- * the caller acquires and releases the lock on the lltbls
- * Returns the llentry locked
- */
-struct llentry *
-nd6_lookup(struct in6_addr *addr6, int flags, struct ifnet *ifp)
-{
- struct sockaddr_in6 sin6;
- struct llentry *ln;
- int llflags;
-
- bzero(&sin6, sizeof(sin6));
- sin6.sin6_len = sizeof(struct sockaddr_in6);
- sin6.sin6_family = AF_INET6;
- sin6.sin6_addr = *addr6;
-
- /*
- * IF_AFDATA_LOCK_ASSERT(ifp);
- */
-
- llflags = (flags & ND6_EXCLUSIVE) ? LLE_EXCLUSIVE : 0;
- ln = lltable_lookup_lle(LLTABLE6(ifp), llflags,
- (struct sockaddr *)&sin6);
-
- return (ln);
-}
-
-/*
- * Creates and returns new, unlinked and unlocked lle.
- */
-struct llentry *
-nd6_create(struct in6_addr *addr6, int flags, struct ifnet *ifp)
-{
- struct sockaddr_in6 sin6;
- struct llentry *ln;
-
- bzero(&sin6, sizeof(sin6));
- sin6.sin6_len = sizeof(struct sockaddr_in6);
- sin6.sin6_family = AF_INET6;
- sin6.sin6_addr = *addr6;
-
- IF_AFDATA_CFG_UNLOCK_ASSERT(ifp);
-
- ln = lltable_create_lle(LLTABLE6(ifp), 0, (struct sockaddr *)&sin6);
- ln->ln_state = ND6_LLINFO_NOSTATE;
-
- return (ln);
-}
-
/*
* Test whether a given IPv6 address is a neighbor or not, ignoring
* the actual neighbor cache. The neighbor cache is ignored in order
@@ -1295,7 +1246,7 @@ nd6_nud_hint(struct rtentry *rt, struct
ifp = rt->rt_ifp;
IF_AFDATA_RLOCK(ifp);
- ln = nd6_lookup(dst6, ND6_EXCLUSIVE, NULL);
+ ln = nd6_lookup(dst6, ND6_EXCLUSIVE, ifp);
IF_AFDATA_RUNLOCK(ifp);
if (ln == NULL)
return;
@@ -1798,9 +1749,11 @@ nd6_cache_lladdr(struct ifnet *ifp, stru
ln = nd6_lookup(from, ND6_EXCLUSIVE, ifp);
IF_AFDATA_CFG_RUNLOCK(ifp);
if (ln == NULL) {
- ln = nd6_create(from, 0, ifp);
- if (ln != NULL)
+ ln = lltable_create_lle6(ifp, 0, from);
+ if (ln != NULL) {
LLE_WLOCK(ln);
+ ln->ln_state = ND6_LLINFO_NOSTATE;
+ }
is_newentry = 1;
} else {
/* do nothing if record is static */
@@ -2204,8 +2157,9 @@ nd6_output_lle(struct ifnet *ifp, struct
* the condition below is not very efficient. But we believe
* it is tolerable, because this should be a rare case.
*/
- lle = nd6_create(&dst->sin6_addr, 0, ifp);
+ lle = lltable_create_lle6(ifp, 0, &dst->sin6_addr);
if (lle != NULL) {
+ lle->ln_state = ND6_LLINFO_NOSTATE;
IF_AFDATA_CFG_WLOCK(ifp);
LLE_WLOCK(lle);
/* Check if the same record was addded */
@@ -2483,12 +2437,13 @@ nd6_add_ifa_lle(struct in6_ifaddr *ia)
struct ifnet *ifp;
struct llentry *ln, *ln_tmp;
struct lltable *llt;
+ struct in6_addr *addr6;
ifp = ia->ia_ifa.ifa_ifp;
+ addr6 = &ia->ia_addr.sin6_addr;
ia->ia_ifa.ifa_rtrequest = nd6_rtrequest;
- ln = lltable_create_lle(LLTABLE6(ifp), LLE_IFADDR,
- (struct sockaddr *)&ia->ia_addr);
+ ln = lltable_create_lle6(ifp, LLE_IFADDR, addr6);
if (ln == NULL)
return (ENOBUFS);
@@ -2507,8 +2462,7 @@ nd6_add_ifa_lle(struct in6_ifaddr *ia)
* Instead of dealing with callouts/flags/etc we simply
* delete it and add new one.
*/
- ln_tmp = lltable_lookup_lle(llt, LLE_EXCLUSIVE,
- (struct sockaddr *)&ia->ia_addr);
+ ln_tmp = lltable_lookup_lle6(ifp, LLE_EXCLUSIVE, addr6);
bcopy(IF_LLADDR(ifp), &ln->ll_addr, ifp->if_addrlen);
/* Finally, link our lle to the list */
@@ -2563,8 +2517,10 @@ nd6_storelladdr(struct ifnet *ifp, struc
const struct sockaddr *dst, u_char *desten, struct llentry **lle)
{
struct llentry *ln;
+ const struct in6_addr *addr6;
*lle = NULL;
+ addr6 = &SIN6(dst)->sin6_addr;
IF_AFDATA_CFG_UNLOCK_ASSERT(ifp);
if (m != NULL && m->m_flags & M_MCAST) {
int i;
@@ -2580,8 +2536,7 @@ nd6_storelladdr(struct ifnet *ifp, struc
#endif
case IFT_BRIDGE:
case IFT_ISO88025:
- ETHER_MAP_IPV6_MULTICAST(&SIN6(dst)->sin6_addr,
- desten);
+ ETHER_MAP_IPV6_MULTICAST(addr6, desten);
return (0);
case IFT_IEEE1394:
/*
@@ -2605,7 +2560,7 @@ nd6_storelladdr(struct ifnet *ifp, struc
* the entry should have been created in nd6_store_lladdr
*/
IF_AFDATA_RLOCK(ifp);
- ln = lltable_lookup_lle(LLTABLE6(ifp), 0, dst);
+ ln = lltable_lookup_lle6(ifp, 0, addr6);
IF_AFDATA_RUNLOCK(ifp);
if ((ln == NULL) || !(ln->la_flags & LLE_VALID)) {
if (ln != NULL)
Modified: projects/routing/sys/netinet6/nd6.h
==============================================================================
--- projects/routing/sys/netinet6/nd6.h Mon Dec 8 21:14:13 2014 (r275624)
+++ projects/routing/sys/netinet6/nd6.h Mon Dec 8 23:23:53 2014 (r275625)
@@ -89,8 +89,6 @@ struct nd_ifinfo {
#define ND6_IFF_NO_RADR 0x40
#define ND6_IFF_NO_PREFER_IFACE 0x80 /* XXX: not related to ND. */
-#define ND6_EXCLUSIVE LLE_EXCLUSIVE
-
#ifdef _KERNEL
#define ND_IFINFO(ifp) \
(((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->nd_ifinfo)
@@ -389,14 +387,33 @@ void nd6_init(void);
#ifdef VIMAGE
void nd6_destroy(void);
#endif
+
+#define LLTABLE6(ifp) \
+ (((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->lltable)
+
+static __inline const void *
+_check_in6_addr_typecast(const struct in6_addr *paddr)
+{
+
+ return ((const void *)paddr);
+}
+
+#define lltable_lookup_lle6(i, f, a) \
+ lltable_lookup_lle(LLTABLE6(i), (f), _check_in6_addr_typecast(a))
+#define lltable_create_lle6(i, f, a) \
+ lltable_create_lle(LLTABLE6(i), (f), _check_in6_addr_typecast(a))
+
+#define nd6_lookup(a, f, i) lltable_lookup_lle6((i), (f), (a))
+#define ND6_EXCLUSIVE LLE_EXCLUSIVE
+
+
+
struct nd_ifinfo *nd6_ifattach(struct ifnet *);
void nd6_ifdetach(struct nd_ifinfo *);
int nd6_is_addr_neighbor(struct sockaddr_in6 *, struct ifnet *);
void nd6_option_init(void *, int, union nd_opts *);
struct nd_opt_hdr *nd6_option(union nd_opts *);
int nd6_options(union nd_opts *);
-struct llentry *nd6_lookup(struct in6_addr *, int, struct ifnet *);
-struct llentry *nd6_create(struct in6_addr *, int, struct ifnet *);
void nd6_setmtu(struct ifnet *);
void nd6_llinfo_settimer(struct llentry *, long);
void nd6_llinfo_settimer_locked(struct llentry *, long);
More information about the svn-src-projects
mailing list