summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/if.c15
-rw-r--r--lib/if.h14
-rw-r--r--lib/mpls.h3
-rw-r--r--lib/netns_linux.c38
-rw-r--r--lib/ns.h16
-rw-r--r--lib/prefix.h2
-rw-r--r--lib/typerb.c19
-rw-r--r--lib/typerb.h39
-rw-r--r--lib/typesafe.c17
-rw-r--r--lib/typesafe.h144
-rw-r--r--lib/vrf.c8
-rw-r--r--lib/vrf.h2
12 files changed, 219 insertions, 98 deletions
diff --git a/lib/if.c b/lib/if.c
index ff95cd9043..a1e02f4f30 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -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;
diff --git a/lib/if.h b/lib/if.h
index ac8d8e70ba..8dc418f20b 100644
--- a/lib/if.h
+++ b/lib/if.h
@@ -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;
+}
+
diff --git a/lib/ns.h b/lib/ns.h
index 20e0a38e3b..286ff5b295 100644
--- a/lib/ns.h
+++ b/lib/ns.h
@@ -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));
diff --git a/lib/vrf.c b/lib/vrf.c
index 6bd577fce1..9df5d19516 100644
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -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;
}
diff --git a/lib/vrf.h b/lib/vrf.h
index 83ed16b48e..a8514d74ed 100644
--- a/lib/vrf.h
+++ b/lib/vrf.h
@@ -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