From owner-svn-src-projects@freebsd.org Sun Aug 23 18:31:29 2015 Return-Path: Delivered-To: svn-src-projects@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 23D739C1BE5 for ; Sun, 23 Aug 2015 18:31:29 +0000 (UTC) (envelope-from melifaro@FreeBSD.org) Received: from repo.freebsd.org (repo.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 0FCD610EA; Sun, 23 Aug 2015 18:31:29 +0000 (UTC) (envelope-from melifaro@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id t7NIVTFl051482; Sun, 23 Aug 2015 18:31:29 GMT (envelope-from melifaro@FreeBSD.org) Received: (from melifaro@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t7NIVRXi051146; Sun, 23 Aug 2015 18:31:27 GMT (envelope-from melifaro@FreeBSD.org) Message-Id: <201508231831.t7NIVRXi051146@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: melifaro set sender to melifaro@FreeBSD.org using -f From: "Alexander V. Chernikov" Date: Sun, 23 Aug 2015 18:31:27 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r287073 - in projects/routing/sys: kern net netinet netinet6 netpfil/ipfw netpfil/pf nfs 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.20 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: Sun, 23 Aug 2015 18:31:29 -0000 Author: melifaro Date: Sun Aug 23 18:31:26 2015 New Revision: 287073 URL: https://svnweb.freebsd.org/changeset/base/287073 Log: Separate radix and routing: use different structures for route and for other customers. Introduce new 'struct rib_head' for routing purposes and make all routing api use it. Modified: projects/routing/sys/kern/vfs_export.c projects/routing/sys/net/radix.c projects/routing/sys/net/radix.h projects/routing/sys/net/radix_mpath.c projects/routing/sys/net/route.c projects/routing/sys/net/route.h projects/routing/sys/net/rt_nhops.c projects/routing/sys/net/rt_nhops.h projects/routing/sys/net/rtsock.c projects/routing/sys/netinet/in_rmx.c projects/routing/sys/netinet/in_var.h projects/routing/sys/netinet6/in6_rmx.c projects/routing/sys/netinet6/nd6_rtr.c projects/routing/sys/netpfil/ipfw/ip_fw_table_algo.c projects/routing/sys/netpfil/pf/pf_table.c projects/routing/sys/nfs/bootp_subr.c Modified: projects/routing/sys/kern/vfs_export.c ============================================================================== --- projects/routing/sys/kern/vfs_export.c Sun Aug 23 18:30:44 2015 (r287072) +++ projects/routing/sys/kern/vfs_export.c Sun Aug 23 18:31:26 2015 (r287073) @@ -199,7 +199,7 @@ vfs_hang_addrlist(struct mount *mp, stru goto out; } RADIX_NODE_HEAD_LOCK(rnh); - rn = (*rnh->rnh_addaddr)(saddr, smask, rnh, np->netc_rnodes); + rn = (*rnh->rnh_addaddr)(saddr, smask, &rnh->rh, np->netc_rnodes); RADIX_NODE_HEAD_UNLOCK(rnh); if (rn == NULL || np != (struct netcred *)rn) { /* already exists */ error = EPERM; @@ -231,7 +231,7 @@ vfs_free_netcred(struct radix_node *rn, struct radix_node_head *rnh = (struct radix_node_head *) w; struct ucred *cred; - (*rnh->rnh_deladdr) (rn->rn_key, rn->rn_mask, rnh); + (*rnh->rnh_deladdr) (rn->rn_key, rn->rn_mask, &rnh->rh); cred = ((struct netcred *)rn)->netc_anon; if (cred != NULL) crfree(cred); @@ -256,7 +256,7 @@ vfs_free_addrlist_af(struct radix_node_h rnh = *prnh; RADIX_NODE_HEAD_LOCK(rnh); - (*rnh->rnh_walktree) (rnh, vfs_free_netcred, rnh); + (*rnh->rnh_walktree)(&rnh->rh, vfs_free_netcred, &rnh->rh); RADIX_NODE_HEAD_UNLOCK(rnh); RADIX_NODE_HEAD_DESTROY(rnh); free(rnh, M_RTABLE); @@ -470,7 +470,7 @@ vfs_export_lookup(struct mount *mp, stru if (rnh != NULL) { RADIX_NODE_HEAD_RLOCK(rnh); np = (struct netcred *) - (*rnh->rnh_matchaddr)(saddr, rnh); + (*rnh->rnh_matchaddr)(saddr, &rnh->rh); RADIX_NODE_HEAD_RUNLOCK(rnh); if (np && np->netc_rnodes->rn_flags & RNF_ROOT) np = NULL; Modified: projects/routing/sys/net/radix.c ============================================================================== --- projects/routing/sys/net/radix.c Sun Aug 23 18:30:44 2015 (r287072) +++ projects/routing/sys/net/radix.c Sun Aug 23 18:31:26 2015 (r287073) @@ -56,9 +56,6 @@ #include #endif /* !_KERNEL */ -static int rn_walktree_from(struct radix_head *h, void *a, void *m, - walktree_f_t *f, void *w); -static int rn_walktree(struct radix_head *, walktree_f_t *, void *); static struct radix_node *rn_insert(void *, struct radix_head *, int *, struct radix_node [2]), @@ -68,7 +65,6 @@ static struct radix_node static struct radix_node *rn_addmask(void *, struct radix_head *, int, int); static void rn_detachhead_internal(void **head); -static int rn_inithead_internal(void **head, int off); #define RADIX_MAX_KEY_LEN 32 @@ -225,7 +221,7 @@ rn_lookup(void *v_arg, void *m_arg, stru /* * Most common case: search exact prefix/mask */ - x = rn_addmask(m_arg, head->rnh_masks, 1, + x = rn_addmask(m_arg, head->s.rnh_masks, 1, head->rnh_treetop->rn_offset); if (x == NULL) return (NULL); @@ -507,7 +503,7 @@ rn_addmask(void *n_arg, struct radix_hea if (skip == 0) skip = 1; if (mlen <= skip) - return (((struct radix_node_head *)maskhead)->rnh_nodes); + return (maskhead->s.mask_nodes); bzero(addmask_key, RADIX_MAX_KEY_LEN); if (skip > 1) @@ -520,7 +516,7 @@ rn_addmask(void *n_arg, struct radix_hea cp--; mlen = cp - addmask_key; if (mlen <= skip) - return (((struct radix_node_head *)maskhead)->rnh_nodes); + return (maskhead->s.mask_nodes); *addmask_key = mlen; x = rn_search(addmask_key, maskhead->rnh_treetop); if (bcmp(addmask_key, x->rn_key, mlen) != 0) @@ -619,7 +615,7 @@ rn_addroute(void *v_arg, void *n_arg, st * nodes and possibly save time in calculating indices. */ if (netmask) { - x = rn_addmask(netmask, head->rnh_masks, 0, top->rn_offset); + x = rn_addmask(netmask, head->s.rnh_masks, 0, top->rn_offset); if (x == NULL) return (0); b_leaf = x->rn_bit; @@ -797,7 +793,7 @@ rn_delete(void *v_arg, void *netmask_arg * Delete our route from mask lists. */ if (netmask) { - x = rn_addmask(netmask, head->rnh_masks, 1, head_off); + x = rn_addmask(netmask, head->s.rnh_masks, 1, head_off); if (x == NULL) return (0); netmask = x->rn_key; @@ -961,7 +957,7 @@ out: * This is the same as rn_walktree() except for the parameters and the * exit. */ -static int +int rn_walktree_from(struct radix_head *h, void *a, void *m, walktree_f_t *f, void *w) { @@ -1067,7 +1063,7 @@ rn_walktree_from(struct radix_head *h, v return (0); } -static int +int rn_walktree(struct radix_head *h, walktree_f_t *f, void *w) { int error; @@ -1107,76 +1103,75 @@ rn_walktree(struct radix_head *h, walktr } /* - * Allocate and initialize an empty tree. This has 3 nodes, which are - * part of the radix_node_head (in the order ) and are + * Initialize an empty tree. This has 3 nodes, which are passed + * via base_nodes (in the order ) and are * marked RNF_ROOT so they cannot be freed. * The leaves have all-zero and all-one keys, with significant * bits starting at 'off'. - * Return 1 on success, 0 on error. */ -static int -rn_inithead_internal(void **head, int off) +void +rn_inithead_internal(struct radix_head *rh, struct radix_node *base_nodes, int off) { - struct radix_node_head *rnh; struct radix_node *t, *tt, *ttt; - if (*head) - return (1); - R_Zalloc(rnh, struct radix_node_head *, sizeof (*rnh)); - if (rnh == 0) - return (0); - *head = rnh; - t = rn_newpair(rn_zeros, off, rnh->rnh_nodes); - ttt = rnh->rnh_nodes + 2; + + t = rn_newpair(rn_zeros, off, base_nodes); + ttt = base_nodes + 2; t->rn_right = ttt; t->rn_parent = t; - tt = t->rn_left; /* ... which in turn is rnh->rnh_nodes */ + tt = t->rn_left; /* ... which in turn is base_nodes */ tt->rn_flags = t->rn_flags = RNF_ROOT | RNF_ACTIVE; tt->rn_bit = -1 - off; *ttt = *tt; ttt->rn_key = rn_ones; - rnh->rnh_addaddr = (rn_addaddr_f_t *)rn_addroute; - rnh->rnh_deladdr = (rn_deladdr_f_t *)rn_delete; - rnh->rnh_matchaddr = (rn_matchaddr_f_t *)rn_match; - rnh->rnh_lookup = (rn_lookup_f_t *)rn_lookup; - rnh->rnh_walktree = (rn_walktree_t *)rn_walktree; - rnh->rnh_walktree_from = (rn_walktree_from_t *)rn_walktree_from; - rnh->rh.rnh_treetop = t; - return (1); + + rh->rnh_treetop = t; } static void rn_detachhead_internal(void **head) { - struct radix_node_head *rnh; KASSERT((head != NULL && *head != NULL), ("%s: head already freed", __func__)); - rnh = *head; /* Free nodes. */ - R_Free(rnh); + R_Free(*head); *head = NULL; } +/* BELOW ARE FUNCTIONS TO SUPPORT struct radix_node_head USERS */ int rn_inithead(void **head, int off) { struct radix_node_head *rnh; + struct radix_mask_head *rmh; if (*head != NULL) return (1); - if (rn_inithead_internal(head, off) == 0) - return (0); - - rnh = (struct radix_node_head *)(*head); - - if (rn_inithead_internal((void **)&rnh->rh.rnh_masks, 0) == 0) { - rn_detachhead_internal(head); - return (0); + R_Zalloc(rnh, struct radix_node_head *, sizeof (*rnh)); + R_Zalloc(rmh, struct radix_mask_head *, sizeof (*rmh)); + if (rnh == NULL || rmh == NULL) { + if (rnh != NULL) + R_Free(rnh); + return (1); } + /* Init trees */ + rn_inithead_internal(&rnh->rh, rnh->rnh_nodes, off); + rn_inithead_internal(&rmh->head, rmh->mask_nodes, 0); + rnh->rh.s.rnh_masks = &rmh->head; + rmh->head.s.mask_nodes = rmh->mask_nodes; + + /* Finally, set base callbacks */ + rnh->rnh_addaddr = rn_addroute; + rnh->rnh_deladdr = rn_delete; + rnh->rnh_matchaddr = rn_match; + rnh->rnh_lookup = rn_lookup; + rnh->rnh_walktree = rn_walktree; + rnh->rnh_walktree_from = rn_walktree_from; + return (1); } @@ -1202,8 +1197,8 @@ rn_detachhead(void **head) rnh = *head; - rn_walktree(rnh->rh.rnh_masks, rn_freeentry, rnh->rh.rnh_masks); - rn_detachhead_internal((void **)&rnh->rh.rnh_masks); + rn_walktree(rnh->rh.s.rnh_masks, rn_freeentry, rnh->rh.s.rnh_masks); + rn_detachhead_internal((void **)&rnh->rh.s.rnh_masks); rn_detachhead_internal(head); return (1); } Modified: projects/routing/sys/net/radix.h ============================================================================== --- projects/routing/sys/net/radix.h Sun Aug 23 18:30:44 2015 (r287072) +++ projects/routing/sys/net/radix.h Sun Aug 23 18:31:26 2015 (r287073) @@ -101,26 +101,29 @@ struct radix_mask { #define rm_mask rm_rmu.rmu_mask #define rm_leaf rm_rmu.rmu_leaf /* extra field would make 32 bytes */ -struct radix_node_head; +struct radix_head; typedef int walktree_f_t(struct radix_node *, void *); typedef struct radix_node *rn_matchaddr_f_t(void *v, - struct radix_node_head *head); + struct radix_head *head); typedef struct radix_node *rn_addaddr_f_t(void *v, void *mask, - struct radix_node_head *head, struct radix_node nodes[]); + struct radix_head *head, struct radix_node nodes[]); typedef struct radix_node *rn_deladdr_f_t(void *v, void *mask, - struct radix_node_head *head); + struct radix_head *head); typedef struct radix_node *rn_lookup_f_t(void *v, void *mask, - struct radix_node_head *head); -typedef int rn_walktree_t(struct radix_node_head *head, walktree_f_t *f, + struct radix_head *head); +typedef int rn_walktree_t(struct radix_head *head, walktree_f_t *f, void *w); -typedef int rn_walktree_from_t(struct radix_node_head *head, +typedef int rn_walktree_from_t(struct radix_head *head, void *a, void *m, walktree_f_t *f, void *w); -typedef void rn_close_t(struct radix_node *rn, struct radix_node_head *head); +typedef void rn_close_t(struct radix_node *rn, struct radix_head *head); struct radix_head { struct radix_node *rnh_treetop; - struct radix_head *rnh_masks; /* Storage for our masks */ + union { + struct radix_head *rnh_masks; /* Storage for our masks */ + struct radix_node *mask_nodes; + } s; }; struct radix_node_head { @@ -140,6 +143,14 @@ struct radix_node_head { #endif }; +/* XXX: Temporarily xported to support external radix users */ +struct radix_mask_head { + struct radix_head head; + struct radix_node mask_nodes[3]; +}; +void rn_inithead_internal(struct radix_head *rh, struct radix_node *base_nodes, + int off); + #ifndef _KERNEL #define R_Malloc(p, t, n) (p = (t) malloc((unsigned int)(n))) #define R_Zalloc(p, t, n) (p = (t) calloc(1,(unsigned int)(n))) @@ -172,5 +183,8 @@ struct radix_node *rn_delete(void *, voi struct radix_node *rn_lookup (void *v_arg, void *m_arg, struct radix_head *head); struct radix_node *rn_match(void *, struct radix_head *); +int rn_walktree_from(struct radix_head *h, void *a, void *m, + walktree_f_t *f, void *w); +int rn_walktree(struct radix_head *, walktree_f_t *, void *); #endif /* _RADIX_H_ */ Modified: projects/routing/sys/net/radix_mpath.c ============================================================================== --- projects/routing/sys/net/radix_mpath.c Sun Aug 23 18:30:44 2015 (r287072) +++ projects/routing/sys/net/radix_mpath.c Sun Aug 23 18:31:26 2015 (r287073) @@ -167,7 +167,7 @@ rt_mpath_conflict(struct radix_node_head struct rtentry *rt1; rn = (struct radix_node *)rt; - rn1 = rnh->rnh_lookup(rt_key(rt), netmask, rnh); + rn1 = rnh->rnh_lookup(rt_key(rt), netmask, &rnh->rh); if (!rn1 || rn1->rn_flags & RNF_ROOT) return (0); Modified: projects/routing/sys/net/route.c ============================================================================== --- projects/routing/sys/net/route.c Sun Aug 23 18:30:44 2015 (r287072) +++ projects/routing/sys/net/route.c Sun Aug 23 18:31:26 2015 (r287073) @@ -115,7 +115,7 @@ SYSCTL_UINT(_net, OID_AUTO, add_addr_all VNET_DEFINE(struct rtstat, rtstat); #define V_rtstat VNET(rtstat) -VNET_DEFINE(struct radix_node_head *, rt_tables); +VNET_DEFINE(struct rib_head *, rt_tables); #define V_rt_tables VNET(rt_tables) VNET_DEFINE(int, rttrash); /* routes not in table but not freed */ @@ -137,7 +137,7 @@ VNET_DEFINE(int, rttrash); /* routes no static VNET_DEFINE(uma_zone_t, rtzone); /* Routing table UMA zone. */ #define V_rtzone VNET(rtzone) -static int rtrequest1_fib_change(struct radix_node_head *, struct rt_addrinfo *, +static int rtrequest1_fib_change(struct rib_head *, struct rt_addrinfo *, struct rtentry **, u_int); static void rt_setmetrics(const struct rt_addrinfo *, struct rtentry *); static int rt_ifdelroute(struct rtentry *rt, void *arg); @@ -148,7 +148,7 @@ struct if_mtuinfo int mtu; }; -static int if_updatemtu_cb(struct radix_node *, void *); +static int if_updatemtu_cb(struct rtentry *, void *); /* * handler for net.my_fibnum @@ -167,25 +167,25 @@ sysctl_my_fibnum(SYSCTL_HANDLER_ARGS) SYSCTL_PROC(_net, OID_AUTO, my_fibnum, CTLTYPE_INT|CTLFLAG_RD, NULL, 0, &sysctl_my_fibnum, "I", "default FIB of caller"); -static __inline struct radix_node_head ** +static __inline struct rib_head ** rt_tables_get_rnh_ptr(int table, int fam) { - struct radix_node_head **rnh; + struct rib_head **rh; KASSERT(table >= 0 && table < rt_numfibs, ("%s: table out of bounds.", __func__)); KASSERT(fam >= 0 && fam < (AF_MAX+1), ("%s: fam out of bounds.", __func__)); - /* rnh is [fib=0][af=0]. */ - rnh = (struct radix_node_head **)V_rt_tables; + /* rh is [fib=0][af=0]. */ + rh = (struct rib_head **)V_rt_tables; /* Get the offset to the requested table and fam. */ - rnh += table * (AF_MAX+1) + fam; + rh += table * (AF_MAX+1) + fam; - return (rnh); + return (rh); } -struct radix_node_head * +struct rib_head * rt_tables_get_rnh(int table, int fam) { @@ -254,12 +254,12 @@ static void vnet_route_init(const void *unused __unused) { struct domain *dom; - struct radix_node_head **rnh; + struct rib_head **rh; int table; int fam; V_rt_tables = malloc(rt_numfibs * (AF_MAX+1) * - sizeof(struct radix_node_head *), M_RTABLE, M_WAITOK|M_ZERO); + sizeof(struct rib_head *), M_RTABLE, M_WAITOK|M_ZERO); V_rtzone = uma_zcreate("rtentry", sizeof(struct rtentry), rtentry_ctor, rtentry_dtor, @@ -273,10 +273,10 @@ vnet_route_init(const void *unused __unu if (table != 0 && fam != AF_INET6 && fam != AF_INET) break; - rnh = rt_tables_get_rnh_ptr(table, fam); - if (rnh == NULL) - panic("%s: rnh NULL", __func__); - dom->dom_rtattach((void **)rnh, 0); + rh = rt_tables_get_rnh_ptr(table, fam); + if (rh == NULL) + panic("%s: rh NULL", __func__); + dom->dom_rtattach((void **)rh, 0); } } } @@ -290,7 +290,7 @@ vnet_route_uninit(const void *unused __u int table; int fam; struct domain *dom; - struct radix_node_head **rnh; + struct rib_head **rh; for (dom = domains; dom; dom = dom->dom_next) { if (dom->dom_rtdetach == NULL) @@ -302,10 +302,10 @@ vnet_route_uninit(const void *unused __u if (table != 0 && fam != AF_INET6 && fam != AF_INET) break; - rnh = rt_tables_get_rnh_ptr(table, fam); - if (rnh == NULL) - panic("%s: rnh NULL", __func__); - dom->dom_rtdetach((void **)rnh, 0); + rh = rt_tables_get_rnh_ptr(table, fam); + if (rh == NULL) + panic("%s: rh NULL", __func__); + dom->dom_rtdetach((void **)rh, 0); } } @@ -316,6 +316,44 @@ VNET_SYSUNINIT(vnet_route_uninit, SI_SUB vnet_route_uninit, 0); #endif +struct rib_head * +rt_table_init(int offset) +{ + struct rib_head *rh; + + rh = malloc(sizeof(struct rib_head), M_RTABLE, M_WAITOK | M_ZERO); + + /* XXX: These details should be hidded inside radix.c */ + /* Init masks tree */ + rn_inithead_internal(&rh->head, rh->rnh_nodes, offset); + rn_inithead_internal(&rh->rmhead.head, rh->rmhead.mask_nodes, 0); + rh->head.s.rnh_masks = &rh->rmhead.head; + rh->rmhead.head.s.mask_nodes = rh->rmhead.mask_nodes; + + /* Init locks */ + rw_init(&rh->rib_lock, "rib head"); + + /* Finally, set base callbacks */ + rh->rnh_addaddr = rn_addroute; + rh->rnh_deladdr = rn_delete; + rh->rnh_matchaddr = rn_match; + rh->rnh_lookup = rn_lookup; + rh->rnh_walktree = rn_walktree; + rh->rnh_walktree_from = rn_walktree_from; + + return (rh); +} + +void +rt_table_destroy(struct rib_head *rh) +{ + + /* Assume table is already empty */ + rw_destroy(&rh->rib_lock); + free(rh, M_RTABLE); +} + + #ifndef _SYS_SYSPROTO_H_ struct setfib_args { int fibnum; @@ -395,7 +433,7 @@ struct rtentry * rtalloc1_fib(struct sockaddr *dst, int report, u_long ignflags, u_int fibnum) { - struct radix_node_head *rnh; + struct rib_head *rh; struct radix_node *rn; struct rtentry *newrt; struct rt_addrinfo info; @@ -403,9 +441,9 @@ rtalloc1_fib(struct sockaddr *dst, int r int needlock; KASSERT((fibnum < rt_numfibs), ("rtalloc1_fib: bad fibnum")); - rnh = rt_tables_get_rnh(fibnum, dst->sa_family); + rh = rt_tables_get_rnh(fibnum, dst->sa_family); newrt = NULL; - if (rnh == NULL) + if (rh == NULL) goto miss; /* @@ -413,22 +451,22 @@ rtalloc1_fib(struct sockaddr *dst, int r */ needlock = !(ignflags & RTF_RNH_LOCKED); if (needlock) - RADIX_NODE_HEAD_RLOCK(rnh); + RIB_RLOCK(rh); #ifdef INVARIANTS else - RADIX_NODE_HEAD_LOCK_ASSERT(rnh); + RIB_LOCK_ASSERT(rh); #endif - rn = rnh->rnh_matchaddr(dst, rnh); + rn = rh->rnh_matchaddr(dst, &rh->head); if (rn && ((rn->rn_flags & RNF_ROOT) == 0)) { newrt = RNTORT(rn); RT_LOCK(newrt); RT_ADDREF(newrt); if (needlock) - RADIX_NODE_HEAD_RUNLOCK(rnh); + RIB_RUNLOCK(rh); goto done; } else if (needlock) - RADIX_NODE_HEAD_RUNLOCK(rnh); + RIB_RUNLOCK(rh); /* * Either we hit the root or couldn't find any match, @@ -461,11 +499,11 @@ done: void rtfree(struct rtentry *rt) { - struct radix_node_head *rnh; + struct rib_head *rh; KASSERT(rt != NULL,("%s: NULL rt", __func__)); - rnh = rt_tables_get_rnh(rt->rt_fibnum, rt_key(rt)->sa_family); - KASSERT(rnh != NULL,("%s: NULL rnh", __func__)); + rh = rt_tables_get_rnh(rt->rt_fibnum, rt_key(rt)->sa_family); + KASSERT(rh != NULL,("%s: NULL rh", __func__)); RT_LOCK_ASSERT(rt); @@ -488,8 +526,8 @@ rtfree(struct rtentry *rt) * typically calls rtexpunge which clears the RTF_UP flag * on the entry so that the code below reclaims the storage. */ - if (rt->rt_refcnt == 0 && rnh->rnh_close) - rnh->rnh_close((struct radix_node *)rt, rnh); + if (rt->rt_refcnt == 0 && rh->rnh_close) + rh->rnh_close((struct radix_node *)rt, &rh->head); /* * If we are no longer "up" (and ref == 0) @@ -564,11 +602,11 @@ rtredirect_fib(struct sockaddr *dst, short *stat = NULL; struct rt_addrinfo info; struct ifaddr *ifa; - struct radix_node_head *rnh; + struct rib_head *rh; ifa = NULL; - rnh = rt_tables_get_rnh(fibnum, dst->sa_family); - if (rnh == NULL) { + rh = rt_tables_get_rnh(fibnum, dst->sa_family); + if (rh == NULL) { error = EAFNOSUPPORT; goto out; } @@ -622,7 +660,7 @@ rtredirect_fib(struct sockaddr *dst, info.rti_ifa = ifa; info.rti_flags = flags; if (rt0 != NULL) - RT_UNLOCK(rt0); /* drop lock to avoid LOR with RNH */ + RT_UNLOCK(rt0); /* drop lock to avoid LOR with rh */ error = rtrequest1_fib(RTM_ADD, &info, &rt, fibnum); if (rt != NULL) { RT_LOCK(rt); @@ -648,11 +686,11 @@ rtredirect_fib(struct sockaddr *dst, * add the key and gateway (in one malloc'd chunk). */ RT_UNLOCK(rt); - RADIX_NODE_HEAD_LOCK(rnh); + RIB_WLOCK(rh); RT_LOCK(rt); rt_setgate(rt, rt_key(rt), gateway); gwrt = rtalloc1(gateway, 1, RTF_RNH_LOCKED); - RADIX_NODE_HEAD_UNLOCK(rnh); + RIB_WUNLOCK(rh); EVENTHANDLER_INVOKE(route_redirect_event, rt, gwrt, dst); RTFREE_LOCKED(gwrt); } @@ -817,35 +855,35 @@ rtrequest_fib(int req, void rt_foreach_fib(int af, rt_setwarg_t *setwa_f, rt_walktree_f_t *wa_f, void *arg) { - struct radix_node_head *rnh; + struct rib_head *rh; uint32_t fibnum; int i; for (fibnum = 0; fibnum < rt_numfibs; fibnum++) { /* Do we want some specific family? */ if (af != AF_UNSPEC) { - rnh = rt_tables_get_rnh(fibnum, af); - if (rnh == NULL) + rh = rt_tables_get_rnh(fibnum, af); + if (rh == NULL) continue; if (setwa_f != NULL) - setwa_f(rnh, fibnum, i, arg); + setwa_f(rh, fibnum, i, arg); - RADIX_NODE_HEAD_LOCK(rnh); - rnh->rnh_walktree(rnh, (walktree_f_t *)wa_f, arg); - RADIX_NODE_HEAD_UNLOCK(rnh); + RIB_WLOCK(rh); + rh->rnh_walktree(&rh->head, (walktree_f_t *)wa_f, arg); + RIB_WUNLOCK(rh); continue; } for (i = 1; i <= AF_MAX; i++) { - rnh = rt_tables_get_rnh(fibnum, i); - if (rnh == NULL) + rh = rt_tables_get_rnh(fibnum, i); + if (rh == NULL) continue; if (setwa_f != NULL) - setwa_f(rnh, fibnum, i, arg); + setwa_f(rh, fibnum, i, arg); - RADIX_NODE_HEAD_LOCK(rnh); - rnh->rnh_walktree(rnh, (walktree_f_t *)wa_f, arg); - RADIX_NODE_HEAD_UNLOCK(rnh); + RIB_WLOCK(rh); + rh->rnh_walktree(&rh->head, (walktree_f_t *)wa_f, arg); + RIB_WUNLOCK(rh); } } } @@ -853,12 +891,12 @@ rt_foreach_fib(int af, rt_setwarg_t *set /* * Delete Routes for a Network Interface * - * Called for each routing entry via the rnh->rnh_walktree() call above + * Called for each routing entry via the rh->rnh_walktree() call above * to delete all route entries referencing a detaching network interface. * * Arguments: * rt pointer to rtentry - * arg argument passed to rnh->rnh_walktree() - detaching interface + * arg argument passed to rh->rnh_walktree() - detaching interface * * Returns: * 0 successful @@ -970,7 +1008,7 @@ rt_getifa_fib(struct rt_addrinfo *info, * The route must be locked. */ int -rt_expunge(struct radix_node_head *rnh, struct rtentry *rt) +rt_expunge(struct rib_head *rh, struct rtentry *rt) { #if !defined(RADIX_MPATH) struct radix_node *rn; @@ -983,7 +1021,7 @@ rt_expunge(struct radix_node_head *rnh, int error = 0; RT_LOCK_ASSERT(rt); - RADIX_NODE_HEAD_LOCK_ASSERT(rnh); + RIB_LOCK_ASSERT(rh); #ifdef RADIX_MPATH fib = rt->rt_fibnum; @@ -1008,7 +1046,7 @@ rt_expunge(struct radix_node_head *rnh, * Remove the item from the tree; it should be there, * but when callers invoke us blindly it may not (sigh). */ - rn = rnh->rnh_deladdr(rt_key(rt), rt_mask(rt), rnh); + rn = rh->rnh_deladdr(rt_key(rt), rt_mask(rt), &rh->head); if (rn == NULL) { error = ESRCH; goto bad; @@ -1047,12 +1085,10 @@ bad: } static int -if_updatemtu_cb(struct radix_node *rn, void *arg) +if_updatemtu_cb(struct rtentry *rt, void *arg) { - struct rtentry *rt; struct if_mtuinfo *ifmtu; - rt = (struct rtentry *)rn; ifmtu = (struct if_mtuinfo *)arg; if (rt->rt_ifp != ifmtu->ifp) @@ -1082,31 +1118,24 @@ if_updatemtu_cb(struct radix_node *rn, v return (0); } +static void +rt_getmtu_fib(struct rib_head *rh, uint32_t fibum, int af, void *_arg) +{ + struct if_mtuinfo *ifmtu = (struct if_mtuinfo *)_arg; + + ifmtu->mtu = if_getmtu_family(ifmtu->ifp, af); +} + void rt_updatemtu(struct ifnet *ifp) { struct if_mtuinfo ifmtu; - struct radix_node_head *rnh; - int i, j; + memset(&ifmtu, 0, sizeof(ifmtu)); ifmtu.ifp = ifp; - /* - * Try to update rt_mtu for all routes using this interface - * Unfortunately the only way to do this is to traverse all - * routing tables in all fibs/domains. - */ - for (i = 1; i <= AF_MAX; i++) { - ifmtu.mtu = if_getmtu_family(ifp, i); - for (j = 0; j < rt_numfibs; j++) { - rnh = rt_tables_get_rnh(j, i); - if (rnh == NULL) - continue; - RADIX_NODE_HEAD_LOCK(rnh); - rnh->rnh_walktree(rnh, if_updatemtu_cb, &ifmtu); - RADIX_NODE_HEAD_UNLOCK(rnh); - } - } + /* Try to update rt_mtu for all routes */ + rt_foreach_fib(AF_UNSPEC, rt_getmtu_fib, if_updatemtu_cb, &ifmtu); } @@ -1164,7 +1193,7 @@ rt_print(char *buf, int buflen, struct r #ifdef RADIX_MPATH static int rn_mpath_update(int req, struct rt_addrinfo *info, - struct radix_node_head *rnh, struct rtentry **ret_nrt) + struct rib_head *rh, struct rtentry **ret_nrt) { /* * if we got multipath routes, we require users to specify @@ -1174,7 +1203,7 @@ rn_mpath_update(int req, struct rt_addri struct radix_node *rn; int error = 0; - rn = rnh->rnh_lookup(dst, netmask, rnh); + rn = rh->rnh_lookup(dst, netmask, rh); if (rn == NULL) return (ESRCH); rto = rt = RNTORT(rn); @@ -1213,7 +1242,7 @@ rn_mpath_update(int req, struct rt_addri * remove from tree before returning it * to the caller */ - rn = rnh->rnh_deladdr(dst, netmask, rnh); + rn = rh->rnh_deladdr(dst, netmask, rh); KASSERT(rt == RNTORT(rn), ("radix node disappeared")); goto gwdelete; } @@ -1278,7 +1307,7 @@ rtrequest1_fib(int req, struct rt_addrin struct rtentry *rt0; #endif struct radix_node *rn; - struct radix_node_head *rnh; + struct rib_head *rh; struct ifaddr *ifa; struct sockaddr *ndst; struct sockaddr_storage mdst; @@ -1298,15 +1327,15 @@ rtrequest1_fib(int req, struct rt_addrin /* * Find the correct routing tree to use for this Address Family */ - rnh = rt_tables_get_rnh(fibnum, dst->sa_family); - if (rnh == NULL) + rh = rt_tables_get_rnh(fibnum, dst->sa_family); + if (rh == NULL) return (EAFNOSUPPORT); needlock = ((flags & RTF_RNH_LOCKED) == 0); flags &= ~RTF_RNH_LOCKED; if (needlock) - RADIX_NODE_HEAD_LOCK(rnh); + RIB_WLOCK(rh); else - RADIX_NODE_HEAD_LOCK_ASSERT(rnh); + RIB_LOCK_ASSERT(rh); /* * If we are adding a host route then we don't want to put * a netmask in the tree, nor do we want to clone it. @@ -1321,8 +1350,8 @@ rtrequest1_fib(int req, struct rt_addrin dst = (struct sockaddr *)&mdst; } #ifdef RADIX_MPATH - if (rn_mpath_capable(rnh)) { - error = rn_mpath_update(req, info, rnh, ret_nrt); + if (rn_mpath_capable(rh)) { + error = rn_mpath_update(req, info, rh, ret_nrt); /* * "bad" holds true for the success case * as well @@ -1334,8 +1363,8 @@ rtrequest1_fib(int req, struct rt_addrin #endif if ((flags & RTF_PINNED) == 0) { /* Check if target route can be deleted */ - rt = (struct rtentry *)rnh->rnh_lookup(dst, - netmask, rnh); + rt = (struct rtentry *)rh->rnh_lookup(dst, + netmask, &rh->head); if ((rt != NULL) && (rt->rt_flags & RTF_PINNED)) senderr(EADDRINUSE); } @@ -1344,7 +1373,7 @@ rtrequest1_fib(int req, struct rt_addrin * Remove the item from the tree and return it. * Complain if it is not there and do no more processing. */ - rn = rnh->rnh_deladdr(dst, netmask, rnh); + rn = rh->rnh_deladdr(dst, netmask, &rh->head); if (rn == NULL) senderr(ESRCH); if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT)) @@ -1430,7 +1459,7 @@ rtrequest1_fib(int req, struct rt_addrin /* * We use the ifa reference returned by rt_getifa_fib(). - * This moved from below so that rnh->rnh_addaddr() can + * This moved from below so that rh->rnh_addaddr() can * examine the ifa and ifa->ifa_ifp if it so desires. */ rt->rt_ifa = ifa; @@ -1441,8 +1470,8 @@ rtrequest1_fib(int req, struct rt_addrin #ifdef RADIX_MPATH /* do not permit exactly the same dst/mask/gw pair */ - if (rn_mpath_capable(rnh) && - rt_mpath_conflict(rnh, rt, netmask)) { + if (rn_mpath_capable(rh) && + rt_mpath_conflict(rh, rt, netmask)) { ifa_free(rt->rt_ifa); R_Free(rt_key(rt)); uma_zfree(V_rtzone, rt); @@ -1461,7 +1490,7 @@ rtrequest1_fib(int req, struct rt_addrin case AF_INET: #endif #if defined(INET6) || defined(INET) - rn = rnh->rnh_matchaddr(dst, rnh); + rn = rh->rnh_matchaddr(dst, rh); if (rn && ((rn->rn_flags & RNF_ROOT) == 0)) { struct sockaddr *mask; u_char *m, *n; @@ -1504,7 +1533,7 @@ rtrequest1_fib(int req, struct rt_addrin #endif /* FLOWTABLE */ /* XXX mtu manipulation will be done in rnh_addaddr -- itojun */ - rn = rnh->rnh_addaddr(ndst, netmask, rnh, rt->rt_nodes); + rn = rh->rnh_addaddr(ndst, netmask, &rh->head, rt->rt_nodes); /* * If it still failed to go into the tree, * then un-make it (this should be a function) @@ -1544,14 +1573,14 @@ rtrequest1_fib(int req, struct rt_addrin RT_UNLOCK(rt); break; case RTM_CHANGE: - error = rtrequest1_fib_change(rnh, info, ret_nrt, fibnum); + error = rtrequest1_fib_change(rh, info, ret_nrt, fibnum); break; default: error = EOPNOTSUPP; } bad: if (needlock) - RADIX_NODE_HEAD_UNLOCK(rnh); + RIB_WUNLOCK(rh); return (error); #undef senderr } @@ -1564,7 +1593,7 @@ bad: #undef flags static int -rtrequest1_fib_change(struct radix_node_head *rnh, struct rt_addrinfo *info, +rtrequest1_fib_change(struct rib_head *rh, struct rt_addrinfo *info, struct rtentry **ret_nrt, u_int fibnum) { struct rtentry *rt = NULL; @@ -1573,8 +1602,8 @@ rtrequest1_fib_change(struct radix_node_ int family, mtu; struct if_mtuinfo ifmtu; - rt = (struct rtentry *)rnh->rnh_lookup(info->rti_info[RTAX_DST], - info->rti_info[RTAX_NETMASK], rnh); + rt = (struct rtentry *)rh->rnh_lookup(info->rti_info[RTAX_DST], + info->rti_info[RTAX_NETMASK], &rh->head); if (rt == NULL) return (ESRCH); @@ -1584,7 +1613,7 @@ rtrequest1_fib_change(struct radix_node_ * If we got multipath routes, * we require users to specify a matching RTAX_GATEWAY. */ - if (rn_mpath_capable(rnh)) { + if (rn_mpath_capable(rh)) { rt = rt_mpath_matchgate(rt, info->rti_info[RTAX_GATEWAY]); if (rt == NULL) return (ESRCH); @@ -1653,7 +1682,7 @@ rtrequest1_fib_change(struct radix_node_ /* Check if we really need to update */ ifmtu.ifp = rt->rt_ifp; ifmtu.mtu = mtu; - if_updatemtu_cb(rt->rt_nodes, &ifmtu); + if_updatemtu_cb(rt, &ifmtu); } } @@ -1704,13 +1733,13 @@ rt_setgate(struct rtentry *rt, struct so /* XXX dst may be overwritten, can we move this to below */ int dlen = SA_SIZE(dst), glen = SA_SIZE(gate); #ifdef INVARIANTS - struct radix_node_head *rnh; + struct rib_head *rh; - rnh = rt_tables_get_rnh(rt->rt_fibnum, dst->sa_family); + rh = rt_tables_get_rnh(rt->rt_fibnum, dst->sa_family); #endif RT_LOCK_ASSERT(rt); - RADIX_NODE_HEAD_LOCK_ASSERT(rnh); + RIB_LOCK_ASSERT(rh); /* * Prepare to store the gateway in rt->rt_gateway. @@ -1783,7 +1812,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int int didwork = 0; int a_failure = 0; static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK}; - struct radix_node_head *rnh; + struct rib_head *rh; if (flags & RTF_HOST) { dst = ifa->ifa_dstaddr; @@ -1847,14 +1876,14 @@ rtinit1(struct ifaddr *ifa, int cmd, int * Look up an rtentry that is in the routing tree and * contains the correct info. */ - rnh = rt_tables_get_rnh(fibnum, dst->sa_family); - if (rnh == NULL) + rh = rt_tables_get_rnh(fibnum, dst->sa_family); + if (rh == NULL) /* this table doesn't exist but others might */ continue; - RADIX_NODE_HEAD_RLOCK(rnh); - rn = rnh->rnh_lookup(dst, netmask, rnh); + RIB_RLOCK(rh); + rn = rh->rnh_lookup(dst, netmask, &rh->head); #ifdef RADIX_MPATH - if (rn_mpath_capable(rnh)) { + if (rn_mpath_capable(rh)) { if (rn == NULL) error = ESRCH; @@ -1877,7 +1906,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int error = (rn == NULL || (rn->rn_flags & RNF_ROOT) || RNTORT(rn)->rt_ifa != ifa); - RADIX_NODE_HEAD_RUNLOCK(rnh); + RIB_RUNLOCK(rh); if (error) { /* this is only an error if bad on ALL tables */ continue; @@ -1909,8 +1938,8 @@ rtinit1(struct ifaddr *ifa, int cmd, int * RTM_DELETE message, and retry adding * interface prefix. */ - rnh = rt_tables_get_rnh(fibnum, dst->sa_family); - RADIX_NODE_HEAD_LOCK(rnh); + rh = rt_tables_get_rnh(fibnum, dst->sa_family); + RIB_WLOCK(rh); /* Delete old prefix */ info.rti_ifa = NULL; @@ -1924,7 +1953,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int error = rtrequest1_fib(cmd, &info, &rt, fibnum); } - RADIX_NODE_HEAD_UNLOCK(rnh); + RIB_WUNLOCK(rh); } Modified: projects/routing/sys/net/route.h ============================================================================== --- projects/routing/sys/net/route.h Sun Aug 23 18:30:44 2015 (r287072) +++ projects/routing/sys/net/route.h Sun Aug 23 18:31:26 2015 (r287073) @@ -107,6 +107,7 @@ VNET_DECLARE(u_int, rt_add_addr_allfibs) #endif #endif *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***