svn commit: r287073 - in projects/routing/sys: kern net netinet netinet6 netpfil/ipfw netpfil/pf nfs
Alexander V. Chernikov
melifaro at FreeBSD.org
Sun Aug 23 18:31:29 UTC 2015
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 <net/radix.h>
#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 <left,root,right>) and are
+ * Initialize an empty tree. This has 3 nodes, which are passed
+ * via base_nodes (in the order <left,root,right>) 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 <left,root,right> 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 ***
More information about the svn-src-projects
mailing list