Author: melifaro
Date: Mon Jan 25 06:33:15 2016
New Revision: 294706
URL: https://svnweb.freebsd.org/changeset/base/294706

Log:
  MFP r287070,r287073: split radix implementation and route table structure.
  
  There are number of radix consumers in kernel land (pf,ipfw,nfs,route)
    with different requirements. In fact, first 3 don't have _any_ requirements
    and first 2 does not use radix locking. On the other hand, routing
    structure do have these requirements (rnh_gen, multipath, custom
    to-be-added control plane functions, different locking).
  Additionally, radix should not known anything about its consumers internals.
  
  So, radix code now uses tiny 'struct radix_head' structure along with
    internal 'struct radix_mask_head' instead of 'struct radix_node_head'.
    Existing consumers still uses the same 'struct radix_node_head' with
    slight modifications: they need to pass pointer to (embedded)
    'struct radix_head' to all radix callbacks.
  
  Routing code now uses new 'struct rib_head' with different locking macro:
    RADIX_NODE_HEAD prefix was renamed to RIB_ (which stands for routing
    information base).
  
  New net/route_var.h header was added to hold routing subsystem internal
    data. 'struct rib_head' was placed there. 'struct rtentry' will also
    be moved there soon.

Added:
  head/sys/net/route_var.h   (contents, props changed)
Modified:
  head/sys/kern/vfs_export.c
  head/sys/net/radix.c
  head/sys/net/radix.h
  head/sys/net/radix_mpath.c
  head/sys/net/radix_mpath.h
  head/sys/net/route.c
  head/sys/net/route.h
  head/sys/net/rtsock.c
  head/sys/netinet/in_fib.c
  head/sys/netinet/in_rmx.c
  head/sys/netinet/in_var.h
  head/sys/netinet6/in6_fib.c
  head/sys/netinet6/in6_rmx.c
  head/sys/netinet6/nd6_rtr.c
  head/sys/netpfil/ipfw/ip_fw_table_algo.c
  head/sys/netpfil/pf/pf_table.c
  head/sys/nfs/bootp_subr.c

Modified: head/sys/kern/vfs_export.c
==============================================================================
--- head/sys/kern/vfs_export.c  Mon Jan 25 05:33:18 2016        (r294705)
+++ head/sys/kern/vfs_export.c  Mon Jan 25 06:33:15 2016        (r294706)
@@ -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: head/sys/net/radix.c
==============================================================================
--- head/sys/net/radix.c        Mon Jan 25 05:33:18 2016        (r294705)
+++ head/sys/net/radix.c        Mon Jan 25 06:33:15 2016        (r294706)
@@ -56,18 +56,15 @@
 #include <net/radix.h>
 #endif /* !_KERNEL */
 
-static int     rn_walktree_from(struct radix_node_head *h, void *a, void *m,
-                   walktree_f_t *f, void *w);
-static int rn_walktree(struct radix_node_head *, walktree_f_t *, void *);
 static struct radix_node
-        *rn_insert(void *, struct radix_node_head *, int *,
+        *rn_insert(void *, struct radix_head *, int *,
             struct radix_node [2]),
         *rn_newpair(void *, int, struct radix_node[2]),
         *rn_search(void *, struct radix_node *),
         *rn_search_m(void *, struct radix_node *, void *);
+static struct radix_node *rn_addmask(void *, struct radix_mask_head *, 
int,int);
 
-static void rn_detachhead_internal(void **head);
-static int rn_inithead_internal(void **head, int off);
+static void rn_detachhead_internal(struct radix_head *);
 
 #define        RADIX_MAX_KEY_LEN       32
 
@@ -215,7 +212,7 @@ rn_refines(void *m_arg, void *n_arg)
  * from host routes.
  */
 struct radix_node *
-rn_lookup(void *v_arg, void *m_arg, struct radix_node_head *head)
+rn_lookup(void *v_arg, void *m_arg, struct radix_head *head)
 {
        struct radix_node *x;
        caddr_t netmask;
@@ -277,7 +274,7 @@ rn_satisfies_leaf(char *trial, struct ra
  * Search for longest-prefix match in given @head
  */
 struct radix_node *
-rn_match(void *v_arg, struct radix_node_head *head)
+rn_match(void *v_arg, struct radix_head *head)
 {
        caddr_t v = v_arg;
        struct radix_node *t = head->rnh_treetop, *x;
@@ -426,7 +423,7 @@ rn_newpair(void *v, int b, struct radix_
 }
 
 static struct radix_node *
-rn_insert(void *v_arg, struct radix_node_head *head, int *dupentry,
+rn_insert(void *v_arg, struct radix_head *head, int *dupentry,
     struct radix_node nodes[2])
 {
        caddr_t v = v_arg;
@@ -490,7 +487,7 @@ on1:
 }
 
 struct radix_node *
-rn_addmask(void *n_arg, struct radix_node_head *maskhead, int search, int skip)
+rn_addmask(void *n_arg, struct radix_mask_head *maskhead, int search, int skip)
 {
        unsigned char *netmask = n_arg;
        unsigned char *cp, *cplim;
@@ -505,7 +502,7 @@ rn_addmask(void *n_arg, struct radix_nod
        if (skip == 0)
                skip = 1;
        if (mlen <= skip)
-               return (maskhead->rnh_nodes);
+               return (maskhead->mask_nodes);
 
        bzero(addmask_key, RADIX_MAX_KEY_LEN);
        if (skip > 1)
@@ -518,9 +515,9 @@ rn_addmask(void *n_arg, struct radix_nod
                cp--;
        mlen = cp - addmask_key;
        if (mlen <= skip)
-               return (maskhead->rnh_nodes);
+               return (maskhead->mask_nodes);
        *addmask_key = mlen;
-       x = rn_search(addmask_key, maskhead->rnh_treetop);
+       x = rn_search(addmask_key, maskhead->head.rnh_treetop);
        if (bcmp(addmask_key, x->rn_key, mlen) != 0)
                x = 0;
        if (x || search)
@@ -530,7 +527,7 @@ rn_addmask(void *n_arg, struct radix_nod
                return (0);
        netmask = cp = (unsigned char *)(x + 2);
        bcopy(addmask_key, cp, mlen);
-       x = rn_insert(cp, maskhead, &maskduplicated, x);
+       x = rn_insert(cp, &maskhead->head, &maskduplicated, x);
        if (maskduplicated) {
                log(LOG_ERR, "rn_addmask: mask impossibly already in tree");
                R_Free(saved_x);
@@ -598,7 +595,7 @@ rn_new_radix_mask(struct radix_node *tt,
 }
 
 struct radix_node *
-rn_addroute(void *v_arg, void *n_arg, struct radix_node_head *head,
+rn_addroute(void *v_arg, void *n_arg, struct radix_head *head,
     struct radix_node treenodes[2])
 {
        caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg;
@@ -772,7 +769,7 @@ on2:
 }
 
 struct radix_node *
-rn_delete(void *v_arg, void *netmask_arg, struct radix_node_head *head)
+rn_delete(void *v_arg, void *netmask_arg, struct radix_head *head)
 {
        struct radix_node *t, *p, *x, *tt;
        struct radix_mask *m, *saved_m, **mp;
@@ -959,8 +956,8 @@ out:
  * This is the same as rn_walktree() except for the parameters and the
  * exit.
  */
-static int
-rn_walktree_from(struct radix_node_head *h, void *a, void *m,
+int
+rn_walktree_from(struct radix_head *h, void *a, void *m,
     walktree_f_t *f, void *w)
 {
        int error;
@@ -1065,8 +1062,8 @@ rn_walktree_from(struct radix_node_head 
        return (0);
 }
 
-static int
-rn_walktree(struct radix_node_head *h, walktree_f_t *f, void *w)
+int
+rn_walktree(struct radix_head *h, walktree_f_t *f, void *w)
 {
        int error;
        struct radix_node *base, *next;
@@ -1105,75 +1102,76 @@ rn_walktree(struct radix_node_head *h, w
 }
 
 /*
- * 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_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;
-       rnh->rnh_treetop = t;
-       return (1);
+
+       rh->rnh_treetop = t;
 }
 
 static void
-rn_detachhead_internal(void **head)
+rn_detachhead_internal(struct radix_head *head)
 {
-       struct radix_node_head *rnh;
 
-       KASSERT((head != NULL && *head != NULL),
+       KASSERT((head != NULL),
            ("%s: head already freed", __func__));
-       rnh = *head;
        
        /* Free <left,root,right> nodes. */
-       R_Free(rnh);
-
-       *head = NULL;
+       R_Free(head);
 }
 
+/* Functions used by 'struct radix_node_head' users */
+
 int
 rn_inithead(void **head, int off)
 {
        struct radix_node_head *rnh;
+       struct radix_mask_head *rmh;
+
+       rnh = *head;
+       rmh = NULL;
 
        if (*head != NULL)
                return (1);
 
-       if (rn_inithead_internal(head, off) == 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 (0);
+       }
 
-       rnh = (struct radix_node_head *)(*head);
+       /* Init trees */
+       rn_inithead_internal(&rnh->rh, rnh->rnh_nodes, off);
+       rn_inithead_internal(&rmh->head, rmh->mask_nodes, 0);
+       *head = rnh;
+       rnh->rh.rnh_masks = rmh;
 
-       if (rn_inithead_internal((void **)&rnh->rnh_masks, 0) == 0) {
-               rn_detachhead_internal(head);
-               return (0);
-       }
+       /* 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);
 }
@@ -1181,7 +1179,7 @@ rn_inithead(void **head, int off)
 static int
 rn_freeentry(struct radix_node *rn, void *arg)
 {
-       struct radix_node_head * const rnh = arg;
+       struct radix_head * const rnh = arg;
        struct radix_node *x;
 
        x = (struct radix_node *)rn_delete(rn + 2, NULL, rnh);
@@ -1198,11 +1196,14 @@ rn_detachhead(void **head)
        KASSERT((head != NULL && *head != NULL),
            ("%s: head already freed", __func__));
 
-       rnh = *head;
+       rnh = (struct radix_node_head *)(*head);
+
+       rn_walktree(&rnh->rh.rnh_masks->head, rn_freeentry, rnh->rh.rnh_masks);
+       rn_detachhead_internal(&rnh->rh.rnh_masks->head);
+       rn_detachhead_internal(&rnh->rh);
+
+       *head = NULL;
 
-       rn_walktree(rnh->rnh_masks, rn_freeentry, rnh->rnh_masks);
-       rn_detachhead_internal((void **)&rnh->rnh_masks);
-       rn_detachhead_internal(head);
        return (1);
 }
 

Modified: head/sys/net/radix.h
==============================================================================
--- head/sys/net/radix.h        Mon Jan 25 05:33:18 2016        (r294705)
+++ head/sys/net/radix.h        Mon Jan 25 06:33:15 2016        (r294706)
@@ -101,35 +101,53 @@ 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_head;
+
 typedef int walktree_f_t(struct radix_node *, void *);
+typedef struct radix_node *rn_matchaddr_f_t(void *v,
+    struct radix_head *head);
+typedef struct radix_node *rn_addaddr_f_t(void *v, void *mask,
+    struct radix_head *head, struct radix_node nodes[]);
+typedef struct radix_node *rn_deladdr_f_t(void *v, void *mask,
+    struct radix_head *head);
+typedef struct radix_node *rn_lookup_f_t(void *v, void *mask,
+    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_head *head,
+    void *a, void *m, walktree_f_t *f, void *w);
+typedef void rn_close_t(struct radix_node *rn, struct radix_head *head);
 
-struct radix_node_head {
+struct radix_mask_head;
+
+struct radix_head {
        struct  radix_node *rnh_treetop;
-       u_int   rnh_gen;                /* generation counter */
-       int     rnh_multipath;          /* multipath capable ? */
-       struct  radix_node *(*rnh_addaddr)      /* add based on sockaddr */
-               (void *v, void *mask,
-                    struct radix_node_head *head, struct radix_node nodes[]);
-       struct  radix_node *(*rnh_deladdr)      /* remove based on sockaddr */
-               (void *v, void *mask, struct radix_node_head *head);
-       struct  radix_node *(*rnh_matchaddr)    /* longest match for sockaddr */
-               (void *v, struct radix_node_head *head);
-       struct  radix_node *(*rnh_lookup)       /*exact match for sockaddr*/
-               (void *v, void *mask, struct radix_node_head *head);
-       int     (*rnh_walktree)                 /* traverse tree */
-               (struct radix_node_head *head, walktree_f_t *f, void *w);
-       int     (*rnh_walktree_from)            /* traverse tree below a */
-               (struct radix_node_head *head, void *a, void *m,
-                    walktree_f_t *f, void *w);
-       void    (*rnh_close)    /* do something when the last ref drops */
-               (struct radix_node *rn, struct radix_node_head *head);
+       struct  radix_mask_head *rnh_masks;     /* Storage for our masks */
+};
+
+struct radix_node_head {
+       struct radix_head rh;
+       rn_matchaddr_f_t        *rnh_matchaddr; /* longest match for sockaddr */
+       rn_addaddr_f_t  *rnh_addaddr;   /* add based on sockaddr*/
+       rn_deladdr_f_t  *rnh_deladdr;   /* remove based on sockaddr */
+       rn_lookup_f_t   *rnh_lookup;    /* exact match for sockaddr */
+       rn_walktree_t   *rnh_walktree;  /* traverse tree */
+       rn_walktree_from_t      *rnh_walktree_from; /* traverse tree below a */
+       rn_close_t      *rnh_close;     /*do something when the last ref drops*/
        struct  radix_node rnh_nodes[3];        /* empty tree for common case */
-       struct  radix_node_head *rnh_masks;     /* Storage for our masks */
 #ifdef _KERNEL
        struct  rwlock rnh_lock;                /* locks entire radix tree */
 #endif
 };
 
+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)))
@@ -156,13 +174,14 @@ struct radix_node_head {
 int     rn_inithead(void **, int);
 int     rn_detachhead(void **);
 int     rn_refines(void *, void *);
-struct radix_node
-        *rn_addmask(void *, struct radix_node_head *, int, int),
-        *rn_addroute (void *, void *, struct radix_node_head *,
-                       struct radix_node [2]),
-        *rn_delete(void *, void *, struct radix_node_head *),
-        *rn_lookup (void *v_arg, void *m_arg,
-                       struct radix_node_head *head),
-        *rn_match(void *, struct radix_node_head *);
+struct radix_node *rn_addroute(void *, void *, struct radix_head *,
+    struct radix_node[2]);
+struct radix_node *rn_delete(void *, void *, struct radix_head *);
+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: head/sys/net/radix_mpath.c
==============================================================================
--- head/sys/net/radix_mpath.c  Mon Jan 25 05:33:18 2016        (r294705)
+++ head/sys/net/radix_mpath.c  Mon Jan 25 06:33:15 2016        (r294706)
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
 #include <net/radix.h>
 #include <net/radix_mpath.h>
 #include <net/route.h>
+#include <net/route_var.h>
 #include <net/if.h>
 #include <net/if_var.h>
 
@@ -57,12 +58,19 @@ __FBSDID("$FreeBSD$");
 static uint32_t hashjitter;
 
 int
-rn_mpath_capable(struct radix_node_head *rnh)
+rt_mpath_capable(struct rib_head *rnh)
 {
 
        return rnh->rnh_multipath;
 }
 
+int
+rn_mpath_capable(struct radix_head *rh)
+{
+
+       return (rt_mpath_capable((struct rib_head *)rh));
+}
+
 struct radix_node *
 rn_mpath_next(struct radix_node *rn)
 {
@@ -159,14 +167,14 @@ rt_mpath_deldup(struct rtentry *headrt, 
  * Assume @rt rt_key host bits are cleared according to @netmask
  */
 int
-rt_mpath_conflict(struct radix_node_head *rnh, struct rtentry *rt,
+rt_mpath_conflict(struct rib_head *rnh, struct rtentry *rt,
     struct sockaddr *netmask)
 {
        struct radix_node *rn, *rn1;
        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->head);
        if (!rn1 || rn1->rn_flags & RNF_ROOT)
                return (0);
 
@@ -284,11 +292,11 @@ extern int        in_inithead(void **head, int 
 int
 rn4_mpath_inithead(void **head, int off)
 {
-       struct radix_node_head *rnh;
+       struct rib_head *rnh;
 
        hashjitter = arc4random();
        if (in_inithead(head, off) == 1) {
-               rnh = (struct radix_node_head *)*head;
+               rnh = (struct rib_head *)*head;
                rnh->rnh_multipath = 1;
                return 1;
        } else
@@ -300,11 +308,11 @@ rn4_mpath_inithead(void **head, int off)
 int
 rn6_mpath_inithead(void **head, int off)
 {
-       struct radix_node_head *rnh;
+       struct rib_head *rnh;
 
        hashjitter = arc4random();
        if (in6_inithead(head, off) == 1) {
-               rnh = (struct radix_node_head *)*head;
+               rnh = (struct rib_head *)*head;
                rnh->rnh_multipath = 1;
                return 1;
        } else

Modified: head/sys/net/radix_mpath.h
==============================================================================
--- head/sys/net/radix_mpath.h  Mon Jan 25 05:33:18 2016        (r294705)
+++ head/sys/net/radix_mpath.h  Mon Jan 25 06:33:15 2016        (r294706)
@@ -44,11 +44,13 @@
 struct route;
 struct rtentry;
 struct sockaddr;
-int    rn_mpath_capable(struct radix_node_head *);
+struct rib_head;
+int    rt_mpath_capable(struct rib_head *);
+int    rn_mpath_capable(struct radix_head *);
 struct radix_node *rn_mpath_next(struct radix_node *);
 u_int32_t rn_mpath_count(struct radix_node *);
 struct rtentry *rt_mpath_matchgate(struct rtentry *, struct sockaddr *);
-int rt_mpath_conflict(struct radix_node_head *, struct rtentry *,
+int rt_mpath_conflict(struct rib_head *, struct rtentry *,
     struct sockaddr *);
 void rtalloc_mpath_fib(struct route *, u_int32_t, u_int);
 struct rtentry *rt_mpath_select(struct rtentry *, uint32_t);

Modified: head/sys/net/route.c
==============================================================================
--- head/sys/net/route.c        Mon Jan 25 05:33:18 2016        (r294705)
+++ head/sys/net/route.c        Mon Jan 25 06:33:15 2016        (r294706)
@@ -57,6 +57,7 @@
 #include <net/if_var.h>
 #include <net/if_dl.h>
 #include <net/route.h>
+#include <net/route_var.h>
 #include <net/vnet.h>
 #include <net/flowtable.h>
 
@@ -114,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 */
@@ -136,15 +137,15 @@ 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(const struct rtentry *rt, void *arg);
-static struct rtentry *rt_unlinkrte(struct radix_node_head *rnh,
+static struct rtentry *rt_unlinkrte(struct rib_head *rnh,
     struct rt_addrinfo *info, int *perror);
 static void rt_notifydelete(struct rtentry *rt, struct rt_addrinfo *info);
 #ifdef RADIX_MPATH
-static struct radix_node *rt_mpath_unlink(struct radix_node_head *rnh,
+static struct radix_node *rt_mpath_unlink(struct rib_head *rnh,
     struct rt_addrinfo *info, struct rtentry *rto, int *perror);
 #endif
 static int rt_exportinfo(struct rtentry *rt, struct rt_addrinfo *info,
@@ -175,10 +176,10 @@ 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 **rnh;
 
        KASSERT(table >= 0 && table < rt_numfibs, ("%s: table out of bounds.",
            __func__));
@@ -186,14 +187,14 @@ rt_tables_get_rnh_ptr(int table, int fam
            __func__));
 
        /* rnh is [fib=0][af=0]. */
-       rnh = (struct radix_node_head **)V_rt_tables;
+       rnh = (struct rib_head **)V_rt_tables;
        /* Get the offset to the requested table and fam. */
        rnh += table * (AF_MAX+1) + fam;
 
        return (rnh);
 }
 
-struct radix_node_head *
+struct rib_head *
 rt_tables_get_rnh(int table, int fam)
 {
 
@@ -263,12 +264,12 @@ static void
 vnet_route_init(const void *unused __unused)
 {
        struct domain *dom;
-       struct radix_node_head **rnh;
+       struct rib_head **rnh;
        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,
@@ -299,7 +300,7 @@ vnet_route_uninit(const void *unused __u
        int table;
        int fam;
        struct domain *dom;
-       struct radix_node_head **rnh;
+       struct rib_head **rnh;
 
        for (dom = domains; dom; dom = dom->dom_next) {
                if (dom->dom_rtdetach == NULL)
@@ -325,6 +326,43 @@ 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);
+
+       /* TODO: 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.rnh_masks = &rh->rmhead;
+
+       /* Init locks */
+       rw_init(&rh->rib_lock, "rib head lock");
+
+       /* 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;
@@ -375,32 +413,32 @@ 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;
        int err = 0, msgtype = RTM_MISS;
 
        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;
 
        /*
         * Look up the address in the table for that Address Family
         */
-       RADIX_NODE_HEAD_RLOCK(rnh);
-       rn = rnh->rnh_matchaddr(dst, rnh);
+       RIB_RLOCK(rh);
+       rn = rh->rnh_matchaddr(dst, &rh->head);
        if (rn && ((rn->rn_flags & RNF_ROOT) == 0)) {
                newrt = RNTORT(rn);
                RT_LOCK(newrt);
                RT_ADDREF(newrt);
-               RADIX_NODE_HEAD_RUNLOCK(rnh);
+               RIB_RUNLOCK(rh);
                return (newrt);
 
        } else
-               RADIX_NODE_HEAD_RUNLOCK(rnh);
+               RIB_RUNLOCK(rh);
        
        /*
         * Either we hit the root or couldn't find any match,
@@ -430,7 +468,7 @@ miss:
 void
 rtfree(struct rtentry *rt)
 {
-       struct radix_node_head *rnh;
+       struct rib_head *rnh;
 
        KASSERT(rt != NULL,("%s: NULL rt", __func__));
        rnh = rt_tables_get_rnh(rt->rt_fibnum, rt_key(rt)->sa_family);
@@ -458,7 +496,7 @@ rtfree(struct rtentry *rt)
         * 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);
+               rnh->rnh_close((struct radix_node *)rt, &rnh->head);
 
        /*
         * If we are no longer "up" (and ref == 0)
@@ -522,7 +560,7 @@ rtredirect_fib(struct sockaddr *dst,
        short *stat = NULL;
        struct rt_addrinfo info;
        struct ifaddr *ifa;
-       struct radix_node_head *rnh;
+       struct rib_head *rnh;
 
        ifa = NULL;
        rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
@@ -608,10 +646,10 @@ 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(rnh);
                        RT_LOCK(rt);
                        rt_setgate(rt, rt_key(rt), gateway);
-                       RADIX_NODE_HEAD_UNLOCK(rnh);
+                       RIB_WUNLOCK(rnh);
                }
        } else
                error = EHOSTUNREACH;
@@ -853,7 +891,7 @@ int
 rib_lookup_info(uint32_t fibnum, const struct sockaddr *dst, uint32_t flags,
     uint32_t flowid, struct rt_addrinfo *info)
 {
-       struct radix_node_head *rh;
+       struct rib_head *rh;
        struct radix_node *rn;
        struct rtentry *rt;
        int error;
@@ -863,20 +901,20 @@ rib_lookup_info(uint32_t fibnum, const s
        if (rh == NULL)
                return (ENOENT);
 
-       RADIX_NODE_HEAD_RLOCK(rh);
-       rn = rh->rnh_matchaddr(__DECONST(void *, dst), rh);
+       RIB_RLOCK(rh);
+       rn = rh->rnh_matchaddr(__DECONST(void *, dst), &rh->head);
        if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) {
                rt = RNTORT(rn);
                /* Ensure route & ifp is UP */
                if (RT_LINK_IS_UP(rt->rt_ifp)) {
                        flags = (flags & NHR_REF) | NHR_COPY;
                        error = rt_exportinfo(rt, info, flags);
-                       RADIX_NODE_HEAD_RUNLOCK(rh);
+                       RIB_RUNLOCK(rh);
 
                        return (error);
                }
        }
-       RADIX_NODE_HEAD_RUNLOCK(rh);
+       RIB_RUNLOCK(rh);
 
        return (ENOENT);
 }
@@ -903,7 +941,7 @@ void
 rt_foreach_fib_walk(int af, rt_setwarg_t *setwa_f, rt_walktree_f_t *wa_f,
     void *arg)
 {
-       struct radix_node_head *rnh;
+       struct rib_head *rnh;
        uint32_t fibnum;
        int i;
 
@@ -916,9 +954,9 @@ rt_foreach_fib_walk(int af, rt_setwarg_t
                        if (setwa_f != NULL)
                                setwa_f(rnh, fibnum, af, arg);
 
-                       RADIX_NODE_HEAD_LOCK(rnh);
-                       rnh->rnh_walktree(rnh, (walktree_f_t *)wa_f, arg);
-                       RADIX_NODE_HEAD_UNLOCK(rnh);
+                       RIB_WLOCK(rnh);
+                       rnh->rnh_walktree(&rnh->head, (walktree_f_t *)wa_f,arg);
+                       RIB_WUNLOCK(rnh);
                        continue;
                }
 
@@ -929,9 +967,9 @@ rt_foreach_fib_walk(int af, rt_setwarg_t
                        if (setwa_f != NULL)
                                setwa_f(rnh, 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(rnh);
+                       rnh->rnh_walktree(&rnh->head, (walktree_f_t *)wa_f,arg);
+                       RIB_WUNLOCK(rnh);
                }
        }
 }
@@ -939,7 +977,7 @@ rt_foreach_fib_walk(int af, rt_setwarg_t
 struct rt_delinfo
 {
        struct rt_addrinfo info;
-       struct radix_node_head *rnh;
+       struct rib_head *rnh;
        struct rtentry *head;
 };
 
@@ -987,7 +1025,7 @@ rt_checkdelroute(struct radix_node *rn, 
 void
 rt_foreach_fib_walk_del(int af, rt_filter_f_t *filter_f, void *arg)
 {
-       struct radix_node_head *rnh;
+       struct rib_head *rnh;
        struct rt_delinfo di;
        struct rtentry *rt;
        uint32_t fibnum;
@@ -1013,9 +1051,9 @@ rt_foreach_fib_walk_del(int af, rt_filte
                                continue;
                        di.rnh = rnh;
 
-                       RADIX_NODE_HEAD_LOCK(rnh);
-                       rnh->rnh_walktree(rnh, rt_checkdelroute, &di);
-                       RADIX_NODE_HEAD_UNLOCK(rnh);
+                       RIB_WLOCK(rnh);
+                       rnh->rnh_walktree(&rnh->head, rt_checkdelroute, &di);
+                       RIB_WUNLOCK(rnh);
 
                        if (di.head == NULL)
                                continue;
@@ -1092,7 +1130,7 @@ rt_flushifroutes(struct ifnet *ifp)
  * ENOENT - if supplied filter function returned 0 (not matched).
  */
 static struct rtentry *
-rt_unlinkrte(struct radix_node_head *rnh, struct rt_addrinfo *info, int 
*perror)
+rt_unlinkrte(struct rib_head *rnh, struct rt_addrinfo *info, int *perror)
 {
        struct sockaddr *dst, *netmask;
        struct rtentry *rt;
@@ -1101,7 +1139,7 @@ rt_unlinkrte(struct radix_node_head *rnh
        dst = info->rti_info[RTAX_DST];
        netmask = info->rti_info[RTAX_NETMASK];
 
-       rt = (struct rtentry *)rnh->rnh_lookup(dst, netmask, rnh);
+       rt = (struct rtentry *)rnh->rnh_lookup(dst, netmask, &rnh->head);
        if (rt == NULL) {
                *perror = ESRCH;
                return (NULL);
@@ -1136,11 +1174,11 @@ rt_unlinkrte(struct radix_node_head *rnh
         */
        *perror = ESRCH;
 #ifdef RADIX_MPATH
-       if (rn_mpath_capable(rnh))
+       if (rt_mpath_capable(rnh))
                rn = rt_mpath_unlink(rnh, info, rt, perror);
        else
 #endif
-       rn = rnh->rnh_deladdr(dst, netmask, rnh);
+       rn = rnh->rnh_deladdr(dst, netmask, &rnh->head);
        if (rn == NULL)
                return (NULL);
 
@@ -1273,7 +1311,7 @@ void
 rt_updatemtu(struct ifnet *ifp)
 {
        struct if_mtuinfo ifmtu;
-       struct radix_node_head *rnh;
+       struct rib_head *rnh;
        int i, j;
 
        ifmtu.ifp = ifp;
@@ -1289,9 +1327,9 @@ rt_updatemtu(struct ifnet *ifp)
                        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);
+                       RIB_WLOCK(rnh);
+                       rnh->rnh_walktree(&rnh->head, if_updatemtu_cb, &ifmtu);
+                       RIB_WUNLOCK(rnh);
                }
        }
 }
@@ -1357,7 +1395,7 @@ rt_print(char *buf, int buflen, struct r
  * and sets @perror to ESRCH.
  */
 static struct radix_node *
-rt_mpath_unlink(struct radix_node_head *rnh, struct rt_addrinfo *info,
+rt_mpath_unlink(struct rib_head *rnh, struct rt_addrinfo *info,
     struct rtentry *rto, int *perror)
 {
        /*
@@ -1409,7 +1447,7 @@ rt_mpath_unlink(struct radix_node_head *
                 * use the normal delete code to remove
                 * the first entry
                 */
-               rn = rnh->rnh_deladdr(dst, netmask, rnh);
+               rn = rnh->rnh_deladdr(dst, netmask, &rnh->head);
                *perror = 0;
                return (rn);
        }
@@ -1427,7 +1465,7 @@ rt_mpath_unlink(struct radix_node_head *
 
 #ifdef FLOWTABLE
 static struct rtentry *
-rt_flowtable_check_route(struct radix_node_head *rnh, struct rt_addrinfo *info)
+rt_flowtable_check_route(struct rib_head *rnh, struct rt_addrinfo *info)
 {
 #if defined(INET6) || defined(INET)
        struct radix_node *rn;
@@ -1499,7 +1537,7 @@ rtrequest1_fib(int req, struct rt_addrin
        struct rtentry *rt0;
 #endif
        struct radix_node *rn;
-       struct radix_node_head *rnh;
+       struct rib_head *rnh;
        struct ifaddr *ifa;
        struct sockaddr *ndst;
        struct sockaddr_storage mdst;
@@ -1537,9 +1575,9 @@ rtrequest1_fib(int req, struct rt_addrin
                        dst = (struct sockaddr *)&mdst;
                }
 
-               RADIX_NODE_HEAD_LOCK(rnh);
+               RIB_WLOCK(rnh);
                rt = rt_unlinkrte(rnh, info, &error);
-               RADIX_NODE_HEAD_UNLOCK(rnh);
+               RIB_WUNLOCK(rnh);
                if (error != 0)
                        return (error);
 
@@ -1616,13 +1654,13 @@ rtrequest1_fib(int req, struct rt_addrin
 
                rt_setmetrics(info, rt);
 
-               RADIX_NODE_HEAD_LOCK(rnh);
+               RIB_WLOCK(rnh);
                RT_LOCK(rt);
 #ifdef RADIX_MPATH
                /* do not permit exactly the same dst/mask/gw pair */
-               if (rn_mpath_capable(rnh) &&
+               if (rt_mpath_capable(rnh) &&
                        rt_mpath_conflict(rnh, rt, netmask)) {
-                       RADIX_NODE_HEAD_UNLOCK(rnh);
+                       RIB_WUNLOCK(rnh);
 
                        ifa_free(rt->rt_ifa);
                        R_Free(rt_key(rt));
@@ -1636,7 +1674,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 = rnh->rnh_addaddr(ndst, netmask, &rnh->head, rt->rt_nodes);
 
                rt_old = NULL;
                if (rn == NULL && (info->rti_flags & RTF_PINNED) != 0) {
@@ -1653,10 +1691,10 @@ rtrequest1_fib(int req, struct rt_addrin
                        info->rti_flags |= RTF_PINNED;
                        info->rti_info[RTAX_DST] = info_dst;
                        if (rt_old != NULL)
-                               rn = rnh->rnh_addaddr(ndst, netmask, rnh,
+                               rn = rnh->rnh_addaddr(ndst, netmask, &rnh->head,
                                    rt->rt_nodes);
                }
-               RADIX_NODE_HEAD_UNLOCK(rnh);
+               RIB_WUNLOCK(rnh);
 
                if (rt_old != NULL)
                        RT_UNLOCK(rt_old);
@@ -1705,9 +1743,9 @@ rtrequest1_fib(int req, struct rt_addrin
                RT_UNLOCK(rt);
                break;
        case RTM_CHANGE:
-               RADIX_NODE_HEAD_LOCK(rnh);
+               RIB_WLOCK(rnh);
                error = rtrequest1_fib_change(rnh, info, ret_nrt, fibnum);
-               RADIX_NODE_HEAD_UNLOCK(rnh);
+               RIB_WUNLOCK(rnh);
                break;
        default:
                error = EOPNOTSUPP;
@@ -1724,7 +1762,7 @@ rtrequest1_fib(int req, struct rt_addrin
 #undef flags
 
 static int
-rtrequest1_fib_change(struct radix_node_head *rnh, struct rt_addrinfo *info,
+rtrequest1_fib_change(struct rib_head *rnh, struct rt_addrinfo *info,
     struct rtentry **ret_nrt, u_int fibnum)
 {
        struct rtentry *rt = NULL;
@@ -1734,7 +1772,7 @@ rtrequest1_fib_change(struct radix_node_
        struct if_mtuinfo ifmtu;
 
        rt = (struct rtentry *)rnh->rnh_lookup(info->rti_info[RTAX_DST],
-           info->rti_info[RTAX_NETMASK], rnh);
+           info->rti_info[RTAX_NETMASK], &rnh->head);
 
        if (rt == NULL)
                return (ESRCH);
@@ -1744,7 +1782,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 (rt_mpath_capable(rnh)) {
                rt = rt_mpath_matchgate(rt, info->rti_info[RTAX_GATEWAY]);
                if (rt == NULL)
                        return (ESRCH);
@@ -1935,7 +1973,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int
        int didwork = 0;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to