From owner-svn-src-projects@FreeBSD.ORG Mon Dec 8 23:23:57 2014 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 78994BF4; Mon, 8 Dec 2014 23:23:57 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 639AFFDC; Mon, 8 Dec 2014 23:23:57 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id sB8NNv9j022359; Mon, 8 Dec 2014 23:23:57 GMT (envelope-from melifaro@FreeBSD.org) Received: (from melifaro@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id sB8NNsch022336; Mon, 8 Dec 2014 23:23:54 GMT (envelope-from melifaro@FreeBSD.org) Message-Id: <201412082323.sB8NNsch022336@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: melifaro set sender to melifaro@FreeBSD.org using -f From: "Alexander V. Chernikov" Date: Mon, 8 Dec 2014 23:23:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r275625 - in projects/routing/sys: net netinet netinet6 X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 08 Dec 2014 23:23:57 -0000 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);