diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/if.c | 15 | ||||
| -rw-r--r-- | lib/if.h | 14 | ||||
| -rw-r--r-- | lib/mpls.h | 3 | ||||
| -rw-r--r-- | lib/netns_linux.c | 38 | ||||
| -rw-r--r-- | lib/ns.h | 16 | ||||
| -rw-r--r-- | lib/prefix.h | 2 | ||||
| -rw-r--r-- | lib/typerb.c | 19 | ||||
| -rw-r--r-- | lib/typerb.h | 39 | ||||
| -rw-r--r-- | lib/typesafe.c | 17 | ||||
| -rw-r--r-- | lib/typesafe.h | 144 | ||||
| -rw-r--r-- | lib/vrf.c | 8 | ||||
| -rw-r--r-- | lib/vrf.h | 2 |
12 files changed, 219 insertions, 98 deletions
@@ -410,7 +410,7 @@ struct interface *if_lookup_by_index_all_vrf(ifindex_t ifindex) } /* Lookup interface by IP address. */ -struct interface *if_lookup_exact_address(void *src, int family, +struct interface *if_lookup_exact_address(const void *src, int family, vrf_id_t vrf_id) { struct vrf *vrf = vrf_lookup_by_id(vrf_id); @@ -442,7 +442,7 @@ struct interface *if_lookup_exact_address(void *src, int family, } /* Lookup interface by IP address. */ -struct connected *if_lookup_address(void *matchaddr, int family, +struct connected *if_lookup_address(const void *matchaddr, int family, vrf_id_t vrf_id) { struct vrf *vrf = vrf_lookup_by_id(vrf_id); @@ -479,7 +479,7 @@ struct connected *if_lookup_address(void *matchaddr, int family, } /* Lookup interface by prefix */ -struct interface *if_lookup_prefix(struct prefix *prefix, vrf_id_t vrf_id) +struct interface *if_lookup_prefix(const struct prefix *prefix, vrf_id_t vrf_id) { struct vrf *vrf = vrf_lookup_by_id(vrf_id); struct listnode *cnode; @@ -982,7 +982,8 @@ nbr_connected_log(struct nbr_connected *connected, char *str) } /* If two connected address has same prefix return 1. */ -static int connected_same_prefix(struct prefix *p1, struct prefix *p2) +static int connected_same_prefix(const struct prefix *p1, + const struct prefix *p2) { if (p1->family == p2->family) { if (p1->family == AF_INET @@ -1010,7 +1011,7 @@ unsigned int connected_count_by_family(struct interface *ifp, int family) } struct connected *connected_lookup_prefix_exact(struct interface *ifp, - struct prefix *p) + const struct prefix *p) { struct listnode *node; struct listnode *next; @@ -1049,7 +1050,7 @@ struct connected *connected_delete_by_prefix(struct interface *ifp, /* Find the address on our side that will be used when packets are sent to dst. */ struct connected *connected_lookup_prefix(struct interface *ifp, - struct prefix *addr) + const struct prefix *addr) { struct listnode *cnode; struct connected *c; @@ -1273,7 +1274,7 @@ struct if_link_params *if_link_params_get(struct interface *ifp) /* Compute default bandwidth based on interface */ iflp->default_bw = ((ifp->bandwidth ? ifp->bandwidth : DEFAULT_BANDWIDTH) - * TE_KILO_BIT / TE_BYTE); + * TE_MEGA_BIT / TE_BYTE); /* Set Max, Reservable and Unreserved Bandwidth */ iflp->max_bw = iflp->default_bw; @@ -143,7 +143,7 @@ struct if_stats { #define TE_EXT_MASK 0x0FFFFFFF #define TE_EXT_ANORMAL 0x80000000 #define LOSS_PRECISION 0.000003 -#define TE_KILO_BIT 1000 +#define TE_MEGA_BIT 1000000 #define TE_BYTE 8 #define DEFAULT_BANDWIDTH 10000 #define MAX_CLASS_TYPE 8 @@ -512,11 +512,11 @@ extern struct interface *if_create_name(const char *name, vrf_id_t vrf_id); extern struct interface *if_create_ifindex(ifindex_t ifindex, vrf_id_t vrf_id); extern struct interface *if_lookup_by_index(ifindex_t, vrf_id_t vrf_id); extern struct interface *if_lookup_by_index_all_vrf(ifindex_t); -extern struct interface *if_lookup_exact_address(void *matchaddr, int family, - vrf_id_t vrf_id); -extern struct connected *if_lookup_address(void *matchaddr, int family, +extern struct interface *if_lookup_exact_address(const void *matchaddr, + int family, vrf_id_t vrf_id); +extern struct connected *if_lookup_address(const void *matchaddr, int family, vrf_id_t vrf_id); -extern struct interface *if_lookup_prefix(struct prefix *prefix, +extern struct interface *if_lookup_prefix(const struct prefix *prefix, vrf_id_t vrf_id); size_t if_lookup_by_hwaddr(const uint8_t *hw_addr, size_t addrsz, struct interface ***result, vrf_id_t vrf_id); @@ -575,9 +575,9 @@ connected_add_by_prefix(struct interface *, struct prefix *, struct prefix *); extern struct connected *connected_delete_by_prefix(struct interface *, struct prefix *); extern struct connected *connected_lookup_prefix(struct interface *, - struct prefix *); + const struct prefix *); extern struct connected *connected_lookup_prefix_exact(struct interface *, - struct prefix *); + const struct prefix *); extern unsigned int connected_count_by_family(struct interface *, int family); extern struct nbr_connected *nbr_connected_new(void); extern void nbr_connected_free(struct nbr_connected *); diff --git a/lib/mpls.h b/lib/mpls.h index 05cf2935e8..126dbf753d 100644 --- a/lib/mpls.h +++ b/lib/mpls.h @@ -127,7 +127,8 @@ enum lsp_types_t { ZEBRA_LSP_LDP = 2, /* LDP LSP. */ ZEBRA_LSP_BGP = 3, /* BGP LSP. */ ZEBRA_LSP_OSPF_SR = 4,/* OSPF Segment Routing LSP. */ - ZEBRA_LSP_SHARP = 5, /* Identifier for test protocol */ + ZEBRA_LSP_ISIS_SR = 5,/* IS-IS Segment Routing LSP. */ + ZEBRA_LSP_SHARP = 6, /* Identifier for test protocol */ }; /* Functions for basic label operations. */ diff --git a/lib/netns_linux.c b/lib/netns_linux.c index 98f359401e..e1c0159fc5 100644 --- a/lib/netns_linux.c +++ b/lib/netns_linux.c @@ -379,12 +379,20 @@ struct ns *ns_lookup(ns_id_t ns_id) return ns_lookup_internal(ns_id); } -void ns_walk_func(int (*func)(struct ns *)) +void ns_walk_func(int (*func)(struct ns *, + void *param_in, + void **param_out), + void *param_in, + void **param_out) { struct ns *ns = NULL; + int ret; - RB_FOREACH (ns, ns_head, &ns_tree) - func(ns); + RB_FOREACH (ns, ns_head, &ns_tree) { + ret = func(ns, param_in, param_out); + if (ret == NS_WALK_STOP) + return; + } } const char *ns_get_name(struct ns *ns) @@ -584,9 +592,33 @@ int ns_socket(int domain, int type, int protocol, ns_id_t ns_id) return ret; } +/* if relative link_nsid matches default netns, + * then return default absolute netns value + * otherwise, return NS_UNKNOWN + */ +ns_id_t ns_id_get_absolute(ns_id_t ns_id_reference, ns_id_t link_nsid) +{ + struct ns *ns; + + ns = ns_lookup(ns_id_reference); + if (!ns) + return NS_UNKNOWN; + if (ns->relative_default_ns != link_nsid) + return NS_UNKNOWN; + ns = ns_get_default(); + assert(ns); + return ns->ns_id; +} + ns_id_t ns_get_default_id(void) { if (default_ns) return default_ns->ns_id; return NS_DEFAULT_INTERNAL; } + +struct ns *ns_get_default(void) +{ + return default_ns; +} + @@ -53,6 +53,11 @@ struct ns { /* Identifier, mapped on the NSID value */ ns_id_t internal_ns_id; + /* Identifier, value of NSID of default netns, + * relative value in that local netns + */ + ns_id_t relative_default_ns; + /* Name */ char *name; @@ -120,7 +125,14 @@ int ns_socket(int domain, int type, int protocol, ns_id_t ns_id); extern char *ns_netns_pathname(struct vty *vty, const char *name); /* Parse and execute a function on all the NETNS */ -extern void ns_walk_func(int (*func)(struct ns *)); +#define NS_WALK_CONTINUE 0 +#define NS_WALK_STOP 1 + +extern void ns_walk_func(int (*func)(struct ns *, + void *, + void **), + void *param_in, + void **param_out); /* API to get the NETNS name, from the ns pointer */ extern const char *ns_get_name(struct ns *ns); @@ -174,7 +186,9 @@ extern struct ns *ns_lookup_name(const char *name); */ extern int ns_enable(struct ns *ns, void (*func)(ns_id_t, void *)); extern struct ns *ns_get_created(struct ns *ns, char *name, ns_id_t ns_id); +extern ns_id_t ns_id_get_absolute(ns_id_t ns_id_reference, ns_id_t link_nsid); extern void ns_disable(struct ns *ns); +extern struct ns *ns_get_default(void); #ifdef __cplusplus } diff --git a/lib/prefix.h b/lib/prefix.h index f2952c38c3..4b2d90d63a 100644 --- a/lib/prefix.h +++ b/lib/prefix.h @@ -522,7 +522,7 @@ static inline int is_default_prefix(const struct prefix *p) return 0; } -static inline int is_host_route(struct prefix *p) +static inline int is_host_route(const struct prefix *p) { if (p->family == AF_INET) return (p->prefixlen == IPV4_MAX_BITLEN); diff --git a/lib/typerb.c b/lib/typerb.c index 7e8cd9d8f7..092faa4cc9 100644 --- a/lib/typerb.c +++ b/lib/typerb.c @@ -377,12 +377,13 @@ struct typed_rb_entry *typed_rb_insert(struct rbt_tree *rbt, } /* Finds the node with the same key as elm */ -struct rb_entry *typed_rb_find(struct rbt_tree *rbt, const struct rb_entry *key, +const struct rb_entry *typed_rb_find(const struct rbt_tree *rbt, + const struct rb_entry *key, int (*cmpfn)( const struct typed_rb_entry *a, const struct typed_rb_entry *b)) { - struct rb_entry *tmp = RBH_ROOT(rbt); + const struct rb_entry *tmp = RBH_ROOT(rbt); int comp; while (tmp != NULL) { @@ -398,13 +399,13 @@ struct rb_entry *typed_rb_find(struct rbt_tree *rbt, const struct rb_entry *key, return NULL; } -struct rb_entry *typed_rb_find_gteq(struct rbt_tree *rbt, +const struct rb_entry *typed_rb_find_gteq(const struct rbt_tree *rbt, const struct rb_entry *key, int (*cmpfn)( const struct typed_rb_entry *a, const struct typed_rb_entry *b)) { - struct rb_entry *tmp = RBH_ROOT(rbt), *best = NULL; + const struct rb_entry *tmp = RBH_ROOT(rbt), *best = NULL; int comp; while (tmp != NULL) { @@ -421,13 +422,13 @@ struct rb_entry *typed_rb_find_gteq(struct rbt_tree *rbt, return best; } -struct rb_entry *typed_rb_find_lt(struct rbt_tree *rbt, +const struct rb_entry *typed_rb_find_lt(const struct rbt_tree *rbt, const struct rb_entry *key, int (*cmpfn)( const struct typed_rb_entry *a, const struct typed_rb_entry *b)) { - struct rb_entry *tmp = RBH_ROOT(rbt), *best = NULL; + const struct rb_entry *tmp = RBH_ROOT(rbt), *best = NULL; int comp; while (tmp != NULL) { @@ -443,8 +444,10 @@ struct rb_entry *typed_rb_find_lt(struct rbt_tree *rbt, return best; } -struct rb_entry *typed_rb_next(struct rb_entry *rbe) +struct rb_entry *typed_rb_next(const struct rb_entry *rbe_const) { + struct rb_entry *rbe = (struct rb_entry *)rbe_const; + if (RBE_RIGHT(rbe) != NULL) { rbe = RBE_RIGHT(rbe); while (RBE_LEFT(rbe) != NULL) @@ -463,7 +466,7 @@ struct rb_entry *typed_rb_next(struct rb_entry *rbe) return rbe; } -struct rb_entry *typed_rb_min(struct rbt_tree *rbt) +struct rb_entry *typed_rb_min(const struct rbt_tree *rbt) { struct rb_entry *rbe = RBH_ROOT(rbt); struct rb_entry *parent = NULL; diff --git a/lib/typerb.h b/lib/typerb.h index 2d7b0ba637..fca45e20d1 100644 --- a/lib/typerb.h +++ b/lib/typerb.h @@ -45,23 +45,23 @@ struct typed_rb_entry *typed_rb_insert(struct typed_rb_root *rbt, const struct typed_rb_entry *b)); struct typed_rb_entry *typed_rb_remove(struct typed_rb_root *rbt, struct typed_rb_entry *rbe); -struct typed_rb_entry *typed_rb_find(struct typed_rb_root *rbt, +const struct typed_rb_entry *typed_rb_find(const struct typed_rb_root *rbt, const struct typed_rb_entry *rbe, int (*cmpfn)( const struct typed_rb_entry *a, const struct typed_rb_entry *b)); -struct typed_rb_entry *typed_rb_find_gteq(struct typed_rb_root *rbt, +const struct typed_rb_entry *typed_rb_find_gteq(const struct typed_rb_root *rbt, const struct typed_rb_entry *rbe, int (*cmpfn)( const struct typed_rb_entry *a, const struct typed_rb_entry *b)); -struct typed_rb_entry *typed_rb_find_lt(struct typed_rb_root *rbt, +const struct typed_rb_entry *typed_rb_find_lt(const struct typed_rb_root *rbt, const struct typed_rb_entry *rbe, int (*cmpfn)( const struct typed_rb_entry *a, const struct typed_rb_entry *b)); -struct typed_rb_entry *typed_rb_min(struct typed_rb_root *rbt); -struct typed_rb_entry *typed_rb_next(struct typed_rb_entry *rbe); +struct typed_rb_entry *typed_rb_min(const struct typed_rb_root *rbt); +struct typed_rb_entry *typed_rb_next(const struct typed_rb_entry *rbe); #define _PREDECL_RBTREE(prefix) \ struct prefix ## _head { struct typed_rb_root rr; }; \ @@ -86,20 +86,21 @@ macro_inline type *prefix ## _add(struct prefix##_head *h, type *item) \ re = typed_rb_insert(&h->rr, &item->field.re, cmpfn_uq); \ return container_of_null(re, type, field.re); \ } \ -macro_inline type *prefix ## _find_gteq(struct prefix##_head *h, \ - const type *item) \ +macro_inline const type *prefix ## _const_find_gteq( \ + const struct prefix##_head *h, const type *item) \ { \ - struct typed_rb_entry *re; \ + const struct typed_rb_entry *re; \ re = typed_rb_find_gteq(&h->rr, &item->field.re, cmpfn_nuq); \ return container_of_null(re, type, field.re); \ } \ -macro_inline type *prefix ## _find_lt(struct prefix##_head *h, \ - const type *item) \ +macro_inline const type *prefix ## _const_find_lt( \ + const struct prefix##_head *h, const type *item) \ { \ - struct typed_rb_entry *re; \ + const struct typed_rb_entry *re; \ re = typed_rb_find_lt(&h->rr, &item->field.re, cmpfn_nuq); \ return container_of_null(re, type, field.re); \ } \ +TYPESAFE_FIND_CMP(prefix, type) \ macro_inline type *prefix ## _del(struct prefix##_head *h, type *item) \ { \ struct typed_rb_entry *re; \ @@ -115,18 +116,20 @@ macro_inline type *prefix ## _pop(struct prefix##_head *h) \ typed_rb_remove(&h->rr, re); \ return container_of(re, type, field.re); \ } \ -macro_pure type *prefix ## _first(struct prefix##_head *h) \ +macro_pure const type *prefix ## _const_first(const struct prefix##_head *h) \ { \ - struct typed_rb_entry *re; \ + const struct typed_rb_entry *re; \ re = typed_rb_min(&h->rr); \ return container_of_null(re, type, field.re); \ } \ -macro_pure type *prefix ## _next(struct prefix##_head *h, type *item) \ +macro_pure const type *prefix ## _const_next(const struct prefix##_head *h, \ + const type *item) \ { \ - struct typed_rb_entry *re; \ + const struct typed_rb_entry *re; \ re = typed_rb_next(&item->field.re); \ return container_of_null(re, type, field.re); \ } \ +TYPESAFE_FIRST_NEXT(prefix, type) \ macro_pure type *prefix ## _next_safe(struct prefix##_head *h, type *item) \ { \ struct typed_rb_entry *re; \ @@ -149,12 +152,14 @@ macro_inline int prefix ## __cmp(const struct typed_rb_entry *a, \ return cmpfn(container_of(a, type, field.re), \ container_of(b, type, field.re)); \ } \ -macro_inline type *prefix ## _find(struct prefix##_head *h, const type *item) \ +macro_inline const type *prefix ## _const_find(const struct prefix##_head *h, \ + const type *item) \ { \ - struct typed_rb_entry *re; \ + const struct typed_rb_entry *re; \ re = typed_rb_find(&h->rr, &item->field.re, &prefix ## __cmp); \ return container_of_null(re, type, field.re); \ } \ +TYPESAFE_FIND(prefix, type) \ \ _DECLARE_RBTREE(prefix, type, field, prefix ## __cmp, prefix ## __cmp) \ /* ... */ diff --git a/lib/typesafe.c b/lib/typesafe.c index a52b55b734..69796e2d81 100644 --- a/lib/typesafe.c +++ b/lib/typesafe.c @@ -158,7 +158,7 @@ void typesafe_hash_shrink(struct thash_head *head) /* skiplist */ -static inline struct sskip_item *sl_level_get(struct sskip_item *item, +static inline struct sskip_item *sl_level_get(const struct sskip_item *item, size_t level) { if (level < SKIPLIST_OVERFLOW) @@ -263,13 +263,14 @@ struct sskip_item *typesafe_skiplist_add(struct sskip_head *head, /* NOTE: level counting below is 1-based since that makes the code simpler! */ -struct sskip_item *typesafe_skiplist_find(struct sskip_head *head, +const struct sskip_item *typesafe_skiplist_find( + const struct sskip_head *head, const struct sskip_item *item, int (*cmpfn)( const struct sskip_item *a, const struct sskip_item *b)) { size_t level = SKIPLIST_MAXDEPTH; - struct sskip_item *prev = &head->hitem, *next; + const struct sskip_item *prev = &head->hitem, *next; int cmpval; while (level) { @@ -290,13 +291,14 @@ struct sskip_item *typesafe_skiplist_find(struct sskip_head *head, return NULL; } -struct sskip_item *typesafe_skiplist_find_gteq(struct sskip_head *head, +const struct sskip_item *typesafe_skiplist_find_gteq( + const struct sskip_head *head, const struct sskip_item *item, int (*cmpfn)( const struct sskip_item *a, const struct sskip_item *b)) { size_t level = SKIPLIST_MAXDEPTH; - struct sskip_item *prev = &head->hitem, *next; + const struct sskip_item *prev = &head->hitem, *next; int cmpval; while (level) { @@ -317,13 +319,14 @@ struct sskip_item *typesafe_skiplist_find_gteq(struct sskip_head *head, return next; } -struct sskip_item *typesafe_skiplist_find_lt(struct sskip_head *head, +const struct sskip_item *typesafe_skiplist_find_lt( + const struct sskip_head *head, const struct sskip_item *item, int (*cmpfn)( const struct sskip_item *a, const struct sskip_item *b)) { size_t level = SKIPLIST_MAXDEPTH; - struct sskip_item *prev = &head->hitem, *next, *best = NULL; + const struct sskip_item *prev = &head->hitem, *next, *best = NULL; int cmpval; while (level) { diff --git a/lib/typesafe.h b/lib/typesafe.h index c30d73d1b3..e134316dd9 100644 --- a/lib/typesafe.h +++ b/lib/typesafe.h @@ -44,6 +44,41 @@ extern "C" { item; \ item = from, from = prefix##_next_safe(head, from)) + +/* non-const variants. these wrappers are the same for all the types, so + * bundle them together here. + */ +#define TYPESAFE_FIRST_NEXT(prefix, type) \ +macro_pure type *prefix ## _first(struct prefix##_head *h) \ +{ \ + return (type *)prefix ## _const_first(h); \ +} \ +macro_pure type *prefix ## _next(struct prefix##_head *h, type *item) \ +{ \ + return (type *)prefix ## _const_next(h, item); \ +} \ +/* ... */ +#define TYPESAFE_FIND(prefix, type) \ +macro_inline type *prefix ## _find(struct prefix##_head *h, \ + const type *item) \ +{ \ + return (type *)prefix ## _const_find(h, item); \ +} \ +/* ... */ +#define TYPESAFE_FIND_CMP(prefix, type) \ +macro_inline type *prefix ## _find_lt(struct prefix##_head *h, \ + const type *item) \ +{ \ + return (type *)prefix ## _const_find_lt(h, item); \ +} \ +macro_inline type *prefix ## _find_gteq(struct prefix##_head *h, \ + const type *item) \ +{ \ + return (type *)prefix ## _const_find_gteq(h, item); \ +} \ +/* ... */ + + /* single-linked list, unsorted/arbitrary. * can be used as queue with add_tail / pop */ @@ -133,15 +168,17 @@ macro_inline type *prefix ## _pop(struct prefix##_head *h) \ h->sh.last_next = &h->sh.first; \ return container_of(sitem, type, field.si); \ } \ -macro_pure type *prefix ## _first(struct prefix##_head *h) \ +macro_pure const type *prefix ## _const_first(const struct prefix##_head *h) \ { \ return container_of_null(h->sh.first, type, field.si); \ } \ -macro_pure type *prefix ## _next(struct prefix##_head * h, type *item) \ +macro_pure const type *prefix ## _const_next(const struct prefix##_head *h, \ + const type *item) \ { \ - struct slist_item *sitem = &item->field.si; \ + const struct slist_item *sitem = &item->field.si; \ return container_of_null(sitem->next, type, field.si); \ } \ +TYPESAFE_FIRST_NEXT(prefix, type) \ macro_pure type *prefix ## _next_safe(struct prefix##_head *h, type *item) \ { \ struct slist_item *sitem; \ @@ -232,20 +269,22 @@ macro_inline type *prefix ## _pop(struct prefix##_head *h) \ h->dh.count--; \ return container_of(ditem, type, field.di); \ } \ -macro_pure type *prefix ## _first(struct prefix##_head *h) \ +macro_pure const type *prefix ## _const_first(const struct prefix##_head *h) \ { \ - struct dlist_item *ditem = h->dh.hitem.next; \ + const struct dlist_item *ditem = h->dh.hitem.next; \ if (ditem == &h->dh.hitem) \ return NULL; \ return container_of(ditem, type, field.di); \ } \ -macro_pure type *prefix ## _next(struct prefix##_head * h, type *item) \ +macro_pure const type *prefix ## _const_next(const struct prefix##_head *h, \ + const type *item) \ { \ - struct dlist_item *ditem = &item->field.di; \ + const struct dlist_item *ditem = &item->field.di; \ if (ditem->next == &h->dh.hitem) \ return NULL; \ return container_of(ditem->next, type, field.di); \ } \ +TYPESAFE_FIRST_NEXT(prefix, type) \ macro_pure type *prefix ## _next_safe(struct prefix##_head *h, type *item) \ { \ if (!item) \ @@ -338,19 +377,21 @@ macro_inline type *prefix ## _pop(struct prefix##_head *h) \ typesafe_heap_resize(&h->hh, false); \ return container_of(hitem, type, field.hi); \ } \ -macro_pure type *prefix ## _first(struct prefix##_head *h) \ +macro_pure const type *prefix ## _const_first(const struct prefix##_head *h) \ { \ if (h->hh.count == 0) \ return NULL; \ return container_of(h->hh.array[0], type, field.hi); \ } \ -macro_pure type *prefix ## _next(struct prefix##_head *h, type *item) \ +macro_pure const type *prefix ## _const_next(const struct prefix##_head *h, \ + const type *item) \ { \ uint32_t idx = item->field.hi.index + 1; \ if (idx >= h->hh.count) \ return NULL; \ return container_of(h->hh.array[idx], type, field.hi); \ } \ +TYPESAFE_FIRST_NEXT(prefix, type) \ macro_pure type *prefix ## _next_safe(struct prefix##_head *h, type *item) \ { \ if (!item) \ @@ -431,26 +472,27 @@ macro_inline type *prefix ## _add(struct prefix##_head *h, type *item) \ h->sh.count++; \ return NULL; \ } \ -macro_inline type *prefix ## _find_gteq(struct prefix##_head *h, \ - const type *item) \ +macro_inline const type *prefix ## _const_find_gteq( \ + const struct prefix##_head *h, const type *item) \ { \ - struct ssort_item *sitem = h->sh.first; \ + const struct ssort_item *sitem = h->sh.first; \ int cmpval = 0; \ while (sitem && (cmpval = cmpfn_nuq( \ container_of(sitem, type, field.si), item)) < 0) \ sitem = sitem->next; \ return container_of_null(sitem, type, field.si); \ } \ -macro_inline type *prefix ## _find_lt(struct prefix##_head *h, \ - const type *item) \ +macro_inline const type *prefix ## _const_find_lt( \ + const struct prefix##_head *h, const type *item) \ { \ - struct ssort_item *prev = NULL, *sitem = h->sh.first; \ + const struct ssort_item *prev = NULL, *sitem = h->sh.first; \ int cmpval = 0; \ while (sitem && (cmpval = cmpfn_nuq( \ container_of(sitem, type, field.si), item)) < 0) \ sitem = (prev = sitem)->next; \ return container_of_null(prev, type, field.si); \ } \ +TYPESAFE_FIND_CMP(prefix, type) \ /* TODO: del_hint */ \ macro_inline type *prefix ## _del(struct prefix##_head *h, type *item) \ { \ @@ -472,15 +514,17 @@ macro_inline type *prefix ## _pop(struct prefix##_head *h) \ h->sh.first = sitem->next; \ return container_of(sitem, type, field.si); \ } \ -macro_pure type *prefix ## _first(struct prefix##_head *h) \ +macro_pure const type *prefix ## _const_first(const struct prefix##_head *h) \ { \ return container_of_null(h->sh.first, type, field.si); \ } \ -macro_pure type *prefix ## _next(struct prefix##_head *h, type *item) \ +macro_pure const type *prefix ## _const_next(const struct prefix##_head *h, \ + const type *item) \ { \ - struct ssort_item *sitem = &item->field.si; \ + const struct ssort_item *sitem = &item->field.si; \ return container_of_null(sitem->next, type, field.si); \ } \ +TYPESAFE_FIRST_NEXT(prefix, type) \ macro_pure type *prefix ## _next_safe(struct prefix##_head *h, type *item) \ { \ struct ssort_item *sitem; \ @@ -497,10 +541,11 @@ macro_pure size_t prefix ## _count(const struct prefix##_head *h) \ #define DECLARE_SORTLIST_UNIQ(prefix, type, field, cmpfn) \ _DECLARE_SORTLIST(prefix, type, field, cmpfn, cmpfn) \ - \ -macro_inline type *prefix ## _find(struct prefix##_head *h, const type *item) \ + \ +macro_inline const type *prefix ## _const_find(const struct prefix##_head *h, \ + const type *item) \ { \ - struct ssort_item *sitem = h->sh.first; \ + const struct ssort_item *sitem = h->sh.first; \ int cmpval = 0; \ while (sitem && (cmpval = cmpfn( \ container_of(sitem, type, field.si), item)) < 0) \ @@ -509,6 +554,7 @@ macro_inline type *prefix ## _find(struct prefix##_head *h, const type *item) \ return NULL; \ return container_of(sitem, type, field.si); \ } \ +TYPESAFE_FIND(prefix, type) \ /* ... */ #define DECLARE_SORTLIST_NONUNIQ(prefix, type, field, cmpfn) \ @@ -606,12 +652,13 @@ macro_inline type *prefix ## _add(struct prefix##_head *h, type *item) \ *np = &item->field.hi; \ return NULL; \ } \ -macro_inline type *prefix ## _find(struct prefix##_head *h, const type *item) \ +macro_inline const type *prefix ## _const_find(const struct prefix##_head *h, \ + const type *item) \ { \ if (!h->hh.tabshift) \ return NULL; \ uint32_t hval = hashfn(item), hbits = HASH_KEY(h->hh, hval); \ - struct thash_item *hitem = h->hh.entries[hbits]; \ + const struct thash_item *hitem = h->hh.entries[hbits]; \ while (hitem && hitem->hashval < hval) \ hitem = hitem->next; \ while (hitem && hitem->hashval == hval) { \ @@ -621,6 +668,7 @@ macro_inline type *prefix ## _find(struct prefix##_head *h, const type *item) \ } \ return NULL; \ } \ +TYPESAFE_FIND(prefix, type) \ macro_inline type *prefix ## _del(struct prefix##_head *h, type *item) \ { \ if (!h->hh.tabshift) \ @@ -655,7 +703,7 @@ macro_inline type *prefix ## _pop(struct prefix##_head *h) \ } \ return NULL; \ } \ -macro_pure type *prefix ## _first(struct prefix##_head *h) \ +macro_pure const type *prefix ## _const_first(const struct prefix##_head *h) \ { \ uint32_t i; \ for (i = 0; i < HASH_SIZE(h->hh); i++) \ @@ -663,17 +711,19 @@ macro_pure type *prefix ## _first(struct prefix##_head *h) \ return container_of(h->hh.entries[i], type, field.hi); \ return NULL; \ } \ -macro_pure type *prefix ## _next(struct prefix##_head *h, type *item) \ +macro_pure const type *prefix ## _const_next(const struct prefix##_head *h, \ + const type *item) \ { \ - struct thash_item *hitem = &item->field.hi; \ + const struct thash_item *hitem = &item->field.hi; \ if (hitem->next) \ return container_of(hitem->next, type, field.hi); \ uint32_t i = HASH_KEY(h->hh, hitem->hashval) + 1; \ - for (; i < HASH_SIZE(h->hh); i++) \ + for (; i < HASH_SIZE(h->hh); i++) \ if (h->hh.entries[i]) \ return container_of(h->hh.entries[i], type, field.hi); \ return NULL; \ } \ +TYPESAFE_FIRST_NEXT(prefix, type) \ macro_pure type *prefix ## _next_safe(struct prefix##_head *h, type *item) \ { \ if (!item) \ @@ -742,20 +792,21 @@ macro_inline type *prefix ## _add(struct prefix##_head *h, type *item) \ si = typesafe_skiplist_add(&h->sh, &item->field.si, cmpfn_uq); \ return container_of_null(si, type, field.si); \ } \ -macro_inline type *prefix ## _find_gteq(struct prefix##_head *h, \ - const type *item) \ +macro_inline const type *prefix ## _const_find_gteq( \ + const struct prefix##_head *h, const type *item) \ { \ - struct sskip_item *sitem = typesafe_skiplist_find_gteq(&h->sh, \ + const struct sskip_item *sitem = typesafe_skiplist_find_gteq(&h->sh, \ &item->field.si, cmpfn_nuq); \ return container_of_null(sitem, type, field.si); \ } \ -macro_inline type *prefix ## _find_lt(struct prefix##_head *h, \ - const type *item) \ +macro_inline const type *prefix ## _const_find_lt( \ + const struct prefix##_head *h, const type *item) \ { \ - struct sskip_item *sitem = typesafe_skiplist_find_lt(&h->sh, \ + const struct sskip_item *sitem = typesafe_skiplist_find_lt(&h->sh, \ &item->field.si, cmpfn_nuq); \ return container_of_null(sitem, type, field.si); \ } \ +TYPESAFE_FIND_CMP(prefix, type) \ macro_inline type *prefix ## _del(struct prefix##_head *h, type *item) \ { \ struct sskip_item *sitem = typesafe_skiplist_del(&h->sh, \ @@ -767,16 +818,18 @@ macro_inline type *prefix ## _pop(struct prefix##_head *h) \ struct sskip_item *sitem = typesafe_skiplist_pop(&h->sh); \ return container_of_null(sitem, type, field.si); \ } \ -macro_pure type *prefix ## _first(struct prefix##_head *h) \ +macro_pure const type *prefix ## _const_first(const struct prefix##_head *h) \ { \ - struct sskip_item *first = h->sh.hitem.next[0]; \ + const struct sskip_item *first = h->sh.hitem.next[0]; \ return container_of_null(first, type, field.si); \ } \ -macro_pure type *prefix ## _next(struct prefix##_head *h, type *item) \ +macro_pure const type *prefix ## _const_next(const struct prefix##_head *h, \ + const type *item) \ { \ - struct sskip_item *next = item->field.si.next[0]; \ + const struct sskip_item *next = item->field.si.next[0]; \ return container_of_null(next, type, field.si); \ } \ +TYPESAFE_FIRST_NEXT(prefix, type) \ macro_pure type *prefix ## _next_safe(struct prefix##_head *h, type *item) \ { \ struct sskip_item *next; \ @@ -792,19 +845,21 @@ macro_pure size_t prefix ## _count(const struct prefix##_head *h) \ #define PREDECL_SKIPLIST_UNIQ(prefix) \ _PREDECL_SKIPLIST(prefix) #define DECLARE_SKIPLIST_UNIQ(prefix, type, field, cmpfn) \ - \ + \ macro_inline int prefix ## __cmp(const struct sskip_item *a, \ const struct sskip_item *b) \ { \ return cmpfn(container_of(a, type, field.si), \ container_of(b, type, field.si)); \ } \ -macro_inline type *prefix ## _find(struct prefix##_head *h, const type *item) \ +macro_inline const type *prefix ## _const_find(const struct prefix##_head *h, \ + const type *item) \ { \ - struct sskip_item *sitem = typesafe_skiplist_find(&h->sh, \ + const struct sskip_item *sitem = typesafe_skiplist_find(&h->sh, \ &item->field.si, &prefix ## __cmp); \ return container_of_null(sitem, type, field.si); \ } \ +TYPESAFE_FIND(prefix, type) \ \ _DECLARE_SKIPLIST(prefix, type, field, \ prefix ## __cmp, prefix ## __cmp) \ @@ -843,15 +898,18 @@ extern struct sskip_item *typesafe_skiplist_add(struct sskip_head *head, struct sskip_item *item, int (*cmpfn)( const struct sskip_item *a, const struct sskip_item *b)); -extern struct sskip_item *typesafe_skiplist_find(struct sskip_head *head, +extern const struct sskip_item *typesafe_skiplist_find( + const struct sskip_head *head, const struct sskip_item *item, int (*cmpfn)( const struct sskip_item *a, const struct sskip_item *b)); -extern struct sskip_item *typesafe_skiplist_find_gteq(struct sskip_head *head, +extern const struct sskip_item *typesafe_skiplist_find_gteq( + const struct sskip_head *head, const struct sskip_item *item, int (*cmpfn)( const struct sskip_item *a, const struct sskip_item *b)); -extern struct sskip_item *typesafe_skiplist_find_lt(struct sskip_head *head, +extern const struct sskip_item *typesafe_skiplist_find_lt( + const struct sskip_head *head, const struct sskip_item *item, int (*cmpfn)( const struct sskip_item *a, const struct sskip_item *b)); @@ -652,7 +652,8 @@ int vrf_handler_create(struct vty *vty, const char *vrfname, } int vrf_netns_handler_create(struct vty *vty, struct vrf *vrf, char *pathname, - ns_id_t ns_id, ns_id_t internal_ns_id) + ns_id_t ns_id, ns_id_t internal_ns_id, + ns_id_t rel_def_ns_id) { struct ns *ns = NULL; @@ -700,6 +701,7 @@ int vrf_netns_handler_create(struct vty *vty, struct vrf *vrf, char *pathname, } ns = ns_get_created(ns, pathname, ns_id); ns->internal_ns_id = internal_ns_id; + ns->relative_default_ns = rel_def_ns_id; ns->vrf_ctxt = (void *)vrf; vrf->ns_ctxt = (void *)ns; /* update VRF netns NAME */ @@ -797,7 +799,9 @@ DEFUN_NOSH (vrf_netns, frr_with_privs(vrf_daemon_privs) { ret = vrf_netns_handler_create(vty, vrf, pathname, - NS_UNKNOWN, NS_UNKNOWN); + NS_UNKNOWN, + NS_UNKNOWN, + NS_UNKNOWN); } return ret; } @@ -315,7 +315,7 @@ extern int vrf_handler_create(struct vty *vty, const char *name, */ extern int vrf_netns_handler_create(struct vty *vty, struct vrf *vrf, char *pathname, ns_id_t ext_ns_id, - ns_id_t ns_id); + ns_id_t ns_id, ns_id_t rel_def_ns_id); /* used internally to enable or disable VRF. * Notify a change in the VRF ID of the VRF |
