diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/command.c | 1 | ||||
| -rw-r--r-- | lib/command.h | 1 | ||||
| -rw-r--r-- | lib/command_graph.c | 4 | ||||
| -rw-r--r-- | lib/command_graph.h | 1 | ||||
| -rw-r--r-- | lib/command_lex.l | 1 | ||||
| -rw-r--r-- | lib/command_match.c | 25 | ||||
| -rw-r--r-- | lib/command_parse.y | 16 | ||||
| -rw-r--r-- | lib/command_py.c | 39 | ||||
| -rw-r--r-- | lib/getopt.c | 5 | ||||
| -rw-r--r-- | lib/hook.h | 19 | ||||
| -rw-r--r-- | lib/nexthop.c | 69 | ||||
| -rw-r--r-- | lib/nexthop.h | 3 | ||||
| -rw-r--r-- | lib/northbound_cli.c | 18 | ||||
| -rw-r--r-- | lib/prefix.h | 4 | ||||
| -rw-r--r-- | lib/routemap.c | 17 | ||||
| -rw-r--r-- | lib/routemap.h | 9 | ||||
| -rw-r--r-- | lib/skiplist.c | 43 | ||||
| -rw-r--r-- | lib/skiplist.h | 3 | ||||
| -rw-r--r-- | lib/vrf.c | 15 | ||||
| -rw-r--r-- | lib/vrf.h | 1 | ||||
| -rw-r--r-- | lib/zclient.c | 27 | ||||
| -rw-r--r-- | lib/zclient.h | 3 |
22 files changed, 231 insertions, 93 deletions
diff --git a/lib/command.c b/lib/command.c index fcaf466c65..53aa064705 100644 --- a/lib/command.c +++ b/lib/command.c @@ -74,6 +74,7 @@ const struct message tokennames[] = { item(JOIN_TKN), item(START_TKN), item(END_TKN), + item(NEG_ONLY_TKN), {0}, }; /* clang-format on */ diff --git a/lib/command.h b/lib/command.h index c76fc1e8eb..8a7c9a2048 100644 --- a/lib/command.h +++ b/lib/command.h @@ -229,6 +229,7 @@ struct cmd_node { #define CMD_WARNING_CONFIG_FAILED 13 #define CMD_NOT_MY_INSTANCE 14 #define CMD_NO_LEVEL_UP 15 +#define CMD_ERR_NO_DAEMON 16 /* Argc max counts. */ #define CMD_ARGC_MAX 256 diff --git a/lib/command_graph.c b/lib/command_graph.c index c6c3840455..15c8302e63 100644 --- a/lib/command_graph.c +++ b/lib/command_graph.c @@ -388,6 +388,7 @@ static void cmd_node_names(struct graph_node *gn, struct graph_node *join, case START_TKN: case JOIN_TKN: + case NEG_ONLY_TKN: /* "<foo|bar> WORD" -> word is not "bar" or "foo" */ prevname = NULL; break; @@ -511,6 +512,9 @@ void cmd_graph_node_print_cb(struct graph_node *gn, struct buffer *buf) case JOIN_TKN: color = "#ddaaff"; break; + case NEG_ONLY_TKN: + color = "#ffddaa"; + break; case WORD_TKN: color = "#ffffff"; break; diff --git a/lib/command_graph.h b/lib/command_graph.h index 2754dca67d..c20c9874c2 100644 --- a/lib/command_graph.h +++ b/lib/command_graph.h @@ -64,6 +64,7 @@ enum cmd_token_type { JOIN_TKN, // marks subgraph end START_TKN, // first token in line END_TKN, // last token in line + NEG_ONLY_TKN, // filter token, match if "no ..." command SPECIAL_TKN = FORK_TKN, }; diff --git a/lib/command_lex.l b/lib/command_lex.l index 9c096995f5..ec366ce7e1 100644 --- a/lib/command_lex.l +++ b/lib/command_lex.l @@ -82,6 +82,7 @@ RANGE \({NUMBER}[ ]?\-[ ]?{NUMBER}\) {VARIABLE} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return VARIABLE;} {WORD} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return WORD;} {RANGE} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return RANGE;} +!\[ {yylval->string = NULL; return EXCL_BRACKET;} . {return yytext[0];} %% diff --git a/lib/command_match.c b/lib/command_match.c index 5703510148..f221e0a02c 100644 --- a/lib/command_match.c +++ b/lib/command_match.c @@ -42,7 +42,7 @@ DEFINE_MTYPE_STATIC(LIB, CMD_MATCHSTACK, "Command Match Stack"); /* matcher helper prototypes */ static int add_nexthops(struct list *, struct graph_node *, - struct graph_node **, size_t); + struct graph_node **, size_t, bool); static enum matcher_rv command_match_r(struct graph_node *, vector, unsigned int, struct graph_node **, @@ -79,6 +79,13 @@ static enum match_type match_variable(struct cmd_token *, const char *); static enum match_type match_mac(const char *, bool); +static bool is_neg(vector vline, size_t idx) +{ + if (idx >= vector_active(vline) || !vector_slot(vline, idx)) + return false; + return !strcmp(vector_slot(vline, idx), "no"); +} + enum matcher_rv command_match(struct graph *cmdgraph, vector vline, struct list **argv, const struct cmd_element **el) { @@ -248,7 +255,7 @@ static enum matcher_rv command_match_r(struct graph_node *start, vector vline, // get all possible nexthops struct list *next = list_new(); - add_nexthops(next, start, NULL, 0); + add_nexthops(next, start, NULL, 0, is_neg(vline, 1)); // determine the best match for (ALL_LIST_ELEMENTS_RO(next, ln, gn)) { @@ -349,6 +356,7 @@ enum matcher_rv command_complete(struct graph *graph, vector vline, { // pointer to next input token to match char *input_token; + bool neg = is_neg(vline, 0); struct list * current = @@ -363,7 +371,7 @@ enum matcher_rv command_complete(struct graph *graph, vector vline, // add all children of start node to list struct graph_node *start = vector_slot(graph->nodes, 0); - add_nexthops(next, start, &start, 0); + add_nexthops(next, start, &start, 0, neg); unsigned int idx; for (idx = 0; idx < vector_active(vline) && next->count > 0; idx++) { @@ -428,7 +436,7 @@ enum matcher_rv command_complete(struct graph *graph, vector vline, listnode_add(next, newstack); } else if (matchtype >= minmatch) add_nexthops(next, gstack[0], gstack, - idx + 1); + idx + 1, neg); break; default: trace_matcher("no_match\n"); @@ -478,7 +486,7 @@ enum matcher_rv command_complete(struct graph *graph, vector vline, * output, instead of direct node pointers! */ static int add_nexthops(struct list *list, struct graph_node *node, - struct graph_node **stack, size_t stackpos) + struct graph_node **stack, size_t stackpos, bool neg) { int added = 0; struct graph_node *child; @@ -494,8 +502,13 @@ static int add_nexthops(struct list *list, struct graph_node *node, if (j != stackpos) continue; } + + if (token->type == NEG_ONLY_TKN && !neg) + continue; + if (token->type >= SPECIAL_TKN && token->type != END_TKN) { - added += add_nexthops(list, child, stack, stackpos); + added += + add_nexthops(list, child, stack, stackpos, neg); } else { if (stack) { nextstack = XMALLOC( diff --git a/lib/command_parse.y b/lib/command_parse.y index f5e42cc304..3e2cdc79af 100644 --- a/lib/command_parse.y +++ b/lib/command_parse.y @@ -105,6 +105,9 @@ %token <string> MAC %token <string> MAC_PREFIX +/* special syntax, value is irrelevant */ +%token <string> EXCL_BRACKET + /* union types for parsed rules */ %type <node> start %type <node> literal_token @@ -372,6 +375,19 @@ selector: '[' selector_seq_seq ']' varname_token } ; +/* ![option] productions */ +selector: EXCL_BRACKET selector_seq_seq ']' varname_token +{ + struct graph_node *neg_only = new_token_node (ctx, NEG_ONLY_TKN, NULL, NULL); + + $$ = $2; + graph_add_edge ($$.start, neg_only); + graph_add_edge (neg_only, $$.end); + cmd_token_varname_set ($2.end->data, $4); + XFREE (MTYPE_LEX, $4); +} +; + %% #undef scanner diff --git a/lib/command_py.c b/lib/command_py.c index 7f19008fbf..90344ae1e5 100644 --- a/lib/command_py.c +++ b/lib/command_py.c @@ -197,21 +197,30 @@ static PyObject *graph_to_pyobj(struct wrap_graph *wgraph, if (gn->data) { struct cmd_token *tok = gn->data; switch (tok->type) { -#define item(x) case x: wrap->type = #x; break; - item(WORD_TKN) // words - item(VARIABLE_TKN) // almost anything - item(RANGE_TKN) // integer range - item(IPV4_TKN) // IPV4 addresses - item(IPV4_PREFIX_TKN) // IPV4 network prefixes - item(IPV6_TKN) // IPV6 prefixes - item(IPV6_PREFIX_TKN) // IPV6 network prefixes - item(MAC_TKN) // MAC address - item(MAC_PREFIX_TKN) // MAC address with mask - - /* plumbing types */ - item(FORK_TKN) item(JOIN_TKN) item(START_TKN) - item(END_TKN) default - : wrap->type = "???"; +#define item(x) \ + case x: \ + wrap->type = #x; \ + break /* no semicolon */ + + item(WORD_TKN); // words + item(VARIABLE_TKN); // almost anything + item(RANGE_TKN); // integer range + item(IPV4_TKN); // IPV4 addresses + item(IPV4_PREFIX_TKN); // IPV4 network prefixes + item(IPV6_TKN); // IPV6 prefixes + item(IPV6_PREFIX_TKN); // IPV6 network prefixes + item(MAC_TKN); // MAC address + item(MAC_PREFIX_TKN); // MAC address with mask + + /* plumbing types */ + item(FORK_TKN); + item(JOIN_TKN); + item(START_TKN); + item(END_TKN); + item(NEG_ONLY_TKN); +#undef item + default: + wrap->type = "???"; } wrap->deprecated = (tok->attr == CMD_ATTR_DEPRECATED); diff --git a/lib/getopt.c b/lib/getopt.c index 71799c9b6d..a33d196015 100644 --- a/lib/getopt.c +++ b/lib/getopt.c @@ -206,11 +206,10 @@ static char *posixly_correct; whose names are inconsistent. */ #ifndef getenv -extern char *getenv(); +extern char *getenv(const char *); #endif -static char *my_index(str, chr) const char *str; -int chr; +static char *my_index(const char *str, int chr) { while (*str) { if (*str == chr) diff --git a/lib/hook.h b/lib/hook.h index ff3ef29fa3..3a0db6009b 100644 --- a/lib/hook.h +++ b/lib/hook.h @@ -183,6 +183,12 @@ extern void _hook_unregister(struct hook *hook, void *funcptr, void *arg, #define HOOK_ADDDEF(...) (void *hookarg , ## __VA_ARGS__) #define HOOK_ADDARG(...) (hookarg , ## __VA_ARGS__) +/* and another helper to convert () into (void) to get a proper prototype */ +#define _SKIP_10(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, ret, ...) ret +#define _MAKE_VOID(...) _SKIP_10(, ##__VA_ARGS__, , , , , , , , , , void) + +#define HOOK_VOIDIFY(...) (_MAKE_VOID(__VA_ARGS__) __VA_ARGS__) + /* use in header file - declares the hook and its arguments * usage: DECLARE_HOOK(my_hook, (int arg1, struct foo *arg2), (arg1, arg2)); * as above, "passlist" must use the same order and same names as "arglist" @@ -192,13 +198,14 @@ extern void _hook_unregister(struct hook *hook, void *funcptr, void *arg, */ #define DECLARE_HOOK(hookname, arglist, passlist) \ extern struct hook _hook_##hookname; \ - __attribute__((unused)) static void *_hook_typecheck_##hookname( \ - int(*funcptr) arglist) \ + __attribute__((unused)) static inline void * \ + _hook_typecheck_##hookname(int(*funcptr) HOOK_VOIDIFY arglist) \ { \ return (void *)funcptr; \ } \ - __attribute__((unused)) static void *_hook_typecheck_arg_##hookname( \ - int(*funcptr) HOOK_ADDDEF arglist) \ + __attribute__((unused)) static inline void \ + *_hook_typecheck_arg_##hookname(int(*funcptr) \ + HOOK_ADDDEF arglist) \ { \ return (void *)funcptr; \ } \ @@ -213,14 +220,14 @@ extern void _hook_unregister(struct hook *hook, void *funcptr, void *arg, struct hook _hook_##hookname = { \ .name = #hookname, .entries = NULL, .reverse = rev, \ }; \ - static int hook_call_##hookname arglist \ + static int hook_call_##hookname HOOK_VOIDIFY arglist \ { \ int hooksum = 0; \ struct hookent *he = _hook_##hookname.entries; \ void *hookarg; \ union { \ void *voidptr; \ - int(*fptr) arglist; \ + int(*fptr) HOOK_VOIDIFY arglist; \ int(*farg) HOOK_ADDDEF arglist; \ } hookp; \ for (; he; he = he->next) { \ diff --git a/lib/nexthop.c b/lib/nexthop.c index 23e3a2b733..2e09cb4bcc 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -519,12 +519,13 @@ struct nexthop *nexthop_from_ipv6_ifindex(const struct in6_addr *ipv6, return nexthop; } -struct nexthop *nexthop_from_blackhole(enum blackhole_type bh_type) +struct nexthop *nexthop_from_blackhole(enum blackhole_type bh_type, + vrf_id_t nh_vrf_id) { struct nexthop *nexthop; nexthop = nexthop_new(); - nexthop->vrf_id = VRF_DEFAULT; + nexthop->vrf_id = nh_vrf_id; nexthop->type = NEXTHOP_TYPE_BLACKHOLE; nexthop->bh_type = bh_type; @@ -633,9 +634,6 @@ const char *nexthop2str(const struct nexthop *nexthop, char *str, int size) case NEXTHOP_TYPE_BLACKHOLE: snprintf(str, size, "blackhole"); break; - default: - snprintf(str, size, "unknown"); - break; } return str; @@ -938,6 +936,12 @@ int nexthop_str2backups(const char *str, int *num_backups, * unreachable (blackhole) * %pNHs * nexthop2str() + * %pNHcg + * 1.2.3.4 + * (0-length if no IP address present) + * %pNHci + * eth0 + * (0-length if no interface present) */ printfrr_ext_autoreg_p("NH", printfrr_nh) static ssize_t printfrr_nh(struct fbuf *buf, struct printfrr_eargs *ea, @@ -992,12 +996,10 @@ static ssize_t printfrr_nh(struct fbuf *buf, struct printfrr_eargs *ea, case BLACKHOLE_NULL: ret += bputs(buf, " (blackhole)"); break; - default: + case BLACKHOLE_UNSPEC: break; } break; - default: - break; } if (do_ifi && nexthop->ifindex) ret += bprintfrr(buf, ", %s%s", v_viaif, @@ -1028,9 +1030,54 @@ static ssize_t printfrr_nh(struct fbuf *buf, struct printfrr_eargs *ea, case NEXTHOP_TYPE_BLACKHOLE: ret += bputs(buf, "blackhole"); break; - default: - ret += bputs(buf, "unknown"); - break; + } + return ret; + case 'c': + ea->fmt++; + if (*ea->fmt == 'g') { + ea->fmt++; + if (!nexthop) + return bputs(buf, "(null)"); + switch (nexthop->type) { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + ret += bprintfrr(buf, "%pI4", + &nexthop->gate.ipv4); + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + ret += bprintfrr(buf, "%pI6", + &nexthop->gate.ipv6); + break; + case NEXTHOP_TYPE_IFINDEX: + case NEXTHOP_TYPE_BLACKHOLE: + break; + } + } else if (*ea->fmt == 'i') { + ea->fmt++; + if (!nexthop) + return bputs(buf, "(null)"); + switch (nexthop->type) { + case NEXTHOP_TYPE_IFINDEX: + ret += bprintfrr( + buf, "%s", + ifindex2ifname(nexthop->ifindex, + nexthop->vrf_id)); + break; + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + if (nexthop->ifindex) + ret += bprintfrr( + buf, "%s", + ifindex2ifname( + nexthop->ifindex, + nexthop->vrf_id)); + break; + case NEXTHOP_TYPE_BLACKHOLE: + break; + } } return ret; } diff --git a/lib/nexthop.h b/lib/nexthop.h index dd65509aec..320b46315e 100644 --- a/lib/nexthop.h +++ b/lib/nexthop.h @@ -182,7 +182,8 @@ struct nexthop *nexthop_from_ipv6(const struct in6_addr *ipv6, vrf_id_t vrf_id); struct nexthop *nexthop_from_ipv6_ifindex(const struct in6_addr *ipv6, ifindex_t ifindex, vrf_id_t vrf_id); -struct nexthop *nexthop_from_blackhole(enum blackhole_type bh_type); +struct nexthop *nexthop_from_blackhole(enum blackhole_type bh_type, + vrf_id_t nh_vrf_id); /* * Hash a nexthop. Suitable for use with hash tables. diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c index b74a0e6c23..6676c0b072 100644 --- a/lib/northbound_cli.c +++ b/lib/northbound_cli.c @@ -550,6 +550,13 @@ void nb_cli_show_config_prepare(struct nb_config *config, bool with_defaults) LYD_VALIDATE_NO_STATE, NULL); } +static int lyd_node_cmp(struct lyd_node **dnode1, struct lyd_node **dnode2) +{ + struct nb_node *nb_node = (*dnode1)->schema->priv; + + return nb_node->cbs.cli_cmp(*dnode1, *dnode2); +} + static void show_dnode_children_cmds(struct vty *vty, struct lyd_node *root, bool with_defaults) { @@ -567,6 +574,10 @@ static void show_dnode_children_cmds(struct vty *vty, struct lyd_node *root, * it's time to print the config. */ if (sort_node && nb_node != sort_node) { + list_sort(sort_list, + (int (*)(const void **, + const void **))lyd_node_cmp); + for (ALL_LIST_ELEMENTS_RO(sort_list, listnode, data)) nb_cli_show_dnode_cmds(vty, data, with_defaults); @@ -584,11 +595,9 @@ static void show_dnode_children_cmds(struct vty *vty, struct lyd_node *root, if (!sort_node) { sort_node = nb_node; sort_list = list_new(); - sort_list->cmp = (int (*)(void *, void *)) - nb_node->cbs.cli_cmp; } - listnode_add_sort(sort_list, child); + listnode_add(sort_list, child); continue; } @@ -596,6 +605,9 @@ static void show_dnode_children_cmds(struct vty *vty, struct lyd_node *root, } if (sort_node) { + list_sort(sort_list, + (int (*)(const void **, const void **))lyd_node_cmp); + for (ALL_LIST_ELEMENTS_RO(sort_list, listnode, data)) nb_cli_show_dnode_cmds(vty, data, with_defaults); diff --git a/lib/prefix.h b/lib/prefix.h index 944c94f57f..c92f5cec5a 100644 --- a/lib/prefix.h +++ b/lib/prefix.h @@ -512,7 +512,7 @@ extern char *esi_to_str(const esi_t *esi, char *buf, int size); extern char *evpn_es_df_alg2str(uint8_t df_alg, char *buf, int buf_len); extern void prefix_evpn_hexdump(const struct prefix_evpn *p); -static inline int ipv6_martian(struct in6_addr *addr) +static inline int ipv6_martian(const struct in6_addr *addr) { struct in6_addr localhost_addr; @@ -527,7 +527,7 @@ static inline int ipv6_martian(struct in6_addr *addr) extern int macstr2prefix_evpn(const char *str, struct prefix_evpn *p); /* NOTE: This routine expects the address argument in network byte order. */ -static inline int ipv4_martian(struct in_addr *addr) +static inline int ipv4_martian(const struct in_addr *addr) { in_addr_t ip = ntohl(addr->s_addr); diff --git a/lib/routemap.c b/lib/routemap.c index 594dcf97cb..5c60b7d1c6 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -2488,8 +2488,9 @@ void route_map_notify_pentry_dependencies(const char *affected_name, We need to make sure our route-map processing matches the above */ -route_map_result_t route_map_apply(struct route_map *map, - const struct prefix *prefix, void *object) +route_map_result_t route_map_apply_ext(struct route_map *map, + const struct prefix *prefix, + void *match_object, void *set_object) { static int recursion = 0; enum route_map_cmd_result_t match_ret = RMAP_NOMATCH; @@ -2516,7 +2517,7 @@ route_map_result_t route_map_apply(struct route_map *map, if ((!map->optimization_disabled) && (map->ipv4_prefix_table || map->ipv6_prefix_table)) { - index = route_map_get_index(map, prefix, object, + index = route_map_get_index(map, prefix, match_object, (uint8_t *)&match_ret); if (index) { index->applied++; @@ -2551,7 +2552,7 @@ route_map_result_t route_map_apply(struct route_map *map, index->applied++; /* Apply this index. */ match_ret = route_map_apply_match(&index->match_list, - prefix, object); + prefix, match_object); if (rmap_debug) { zlog_debug( "Route-map: %s, sequence: %d, prefix: %pFX, result: %s", @@ -2610,7 +2611,7 @@ route_map_result_t route_map_apply(struct route_map *map, * return code. */ (void)(*set->cmd->func_apply)( - set->value, prefix, object); + set->value, prefix, set_object); /* Call another route-map if available */ if (index->nextrm) { @@ -2622,8 +2623,10 @@ route_map_result_t route_map_apply(struct route_map *map, jump to it */ { recursion++; - ret = route_map_apply( - nextrm, prefix, object); + ret = route_map_apply_ext( + nextrm, prefix, + match_object, + set_object); recursion--; } diff --git a/lib/routemap.h b/lib/routemap.h index b356dbf52e..2c8eb24537 100644 --- a/lib/routemap.h +++ b/lib/routemap.h @@ -443,9 +443,12 @@ extern struct route_map *route_map_lookup_by_name(const char *name); struct route_map *route_map_lookup_warn_noexist(struct vty *vty, const char *name); /* Apply route map to the object. */ -extern route_map_result_t route_map_apply(struct route_map *map, - const struct prefix *prefix, - void *object); +extern route_map_result_t route_map_apply_ext(struct route_map *map, + const struct prefix *prefix, + void *match_object, + void *set_object); +#define route_map_apply(map, prefix, object) \ + route_map_apply_ext(map, prefix, object, object) extern void route_map_add_hook(void (*func)(const char *)); extern void route_map_delete_hook(void (*func)(const char *)); diff --git a/lib/skiplist.c b/lib/skiplist.c index fc42857418..c5219f7381 100644 --- a/lib/skiplist.c +++ b/lib/skiplist.c @@ -65,17 +65,25 @@ DEFINE_MTYPE_STATIC(LIB, SKIP_LIST, "Skip List"); DEFINE_MTYPE_STATIC(LIB, SKIP_LIST_NODE, "Skip Node"); +DEFINE_MTYPE_STATIC(LIB, SKIP_LIST_STATS, "Skiplist Counters"); #define BitsInRandom 31 #define MaxNumberOfLevels 16 #define MaxLevel (MaxNumberOfLevels-1) -#define newNodeOfLevel(l) XCALLOC(MTYPE_SKIP_LIST_NODE, sizeof(struct skiplistnode)+(l)*sizeof(struct skiplistnode *)) +#define newNodeOfLevel(l) \ + XCALLOC(MTYPE_SKIP_LIST_NODE, \ + sizeof(struct skiplistnode) \ + + (l) * sizeof(struct skiplistnode *)) + +/* XXX must match type of (struct skiplist).level_stats */ +#define newStatsOfLevel(l) \ + XCALLOC(MTYPE_SKIP_LIST_STATS, ((l) + 1) * sizeof(int)) static int randomsLeft; static int randomBits; -#if 1 +#ifdef SKIPLIST_DEBUG #define CHECKLAST(sl) \ do { \ if ((sl)->header->forward[0] && !(sl)->last) \ @@ -138,7 +146,7 @@ struct skiplist *skiplist_new(int flags, new->level = 0; new->count = 0; new->header = newNodeOfLevel(MaxNumberOfLevels); - new->stats = newNodeOfLevel(MaxNumberOfLevels); + new->level_stats = newStatsOfLevel(MaxNumberOfLevels); new->flags = flags; if (cmp) @@ -166,7 +174,7 @@ void skiplist_free(struct skiplist *l) p = q; } while (p); - XFREE(MTYPE_SKIP_LIST_NODE, l->stats); + XFREE(MTYPE_SKIP_LIST_STATS, l->level_stats); XFREE(MTYPE_SKIP_LIST, l); } @@ -180,11 +188,13 @@ int skiplist_insert(register struct skiplist *l, register void *key, CHECKLAST(l); +#ifdef SKIPLIST_DEBUG /* DEBUG */ if (!key) { flog_err(EC_LIB_DEVELOPMENT, "%s: key is 0, value is %p", __func__, value); } +#endif p = l->header; k = l->level; @@ -214,10 +224,10 @@ int skiplist_insert(register struct skiplist *l, register void *key, q->flags = SKIPLIST_NODE_FLAG_INSERTED; /* debug */ #endif - ++(l->stats->forward[k]); + ++(l->level_stats[k]); #ifdef SKIPLIST_DEBUG - zlog_debug("%s: incremented stats @%p:%d, now %ld", __func__, l, k, - l->stats->forward[k] - (struct skiplistnode *)NULL); + zlog_debug("%s: incremented level_stats @%p:%d, now %d", __func__, l, k, + l->level_stats[k]); #endif do { @@ -298,12 +308,10 @@ int skiplist_delete(register struct skiplist *l, register void *key, k++) { p->forward[k] = q->forward[k]; } - --(l->stats->forward[k - 1]); + --(l->level_stats[k - 1]); #ifdef SKIPLIST_DEBUG - zlog_debug("%s: decremented stats @%p:%d, now %ld", - __func__, l, k - 1, - l->stats->forward[k - 1] - - (struct skiplistnode *)NULL); + zlog_debug("%s: decremented level_stats @%p:%d, now %d", + __func__, l, k - 1, l->level_stats[k - 1]); #endif if (l->del) (*l->del)(q->value); @@ -559,11 +567,10 @@ int skiplist_delete_first(register struct skiplist *l) l->last = NULL; } - --(l->stats->forward[nodelevel]); + --(l->level_stats[nodelevel]); #ifdef SKIPLIST_DEBUG - zlog_debug("%s: decremented stats @%p:%d, now %ld", __func__, l, - nodelevel, - l->stats->forward[nodelevel] - (struct skiplistnode *)NULL); + zlog_debug("%s: decremented level_stats @%p:%d, now %d", __func__, l, + nodelevel, l->level_stats[nodelevel]); #endif if (l->del) @@ -587,9 +594,7 @@ void skiplist_debug(struct vty *vty, struct skiplist *l) vty_out(vty, "Skiplist %p has max level %d\n", l, l->level); for (i = l->level; i >= 0; --i) - vty_out(vty, " @%d: %ld\n", i, - (long)((l->stats->forward[i]) - - (struct skiplistnode *)NULL)); + vty_out(vty, " @%d: %d\n", i, l->level_stats[i]); } static void *scramble(int i) diff --git a/lib/skiplist.h b/lib/skiplist.h index a106a455d6..00950e13bb 100644 --- a/lib/skiplist.h +++ b/lib/skiplist.h @@ -60,7 +60,7 @@ struct skiplist { int level; /* max lvl (1 + current # of levels in list) */ unsigned int count; struct skiplistnode *header; - struct skiplistnode *stats; + int *level_stats; struct skiplistnode *last; /* last real list item (NULL if empty list) */ @@ -123,6 +123,7 @@ extern int skiplist_empty(register struct skiplist *l); /* in */ extern unsigned int skiplist_count(register struct skiplist *l); /* in */ +struct vty; extern void skiplist_debug(struct vty *vty, struct skiplist *l); extern void skiplist_test(struct vty *vty); @@ -384,21 +384,6 @@ const char *vrf_id_to_name(vrf_id_t vrf_id) return VRF_LOGNAME(vrf); } -vrf_id_t vrf_name_to_id(const char *name) -{ - struct vrf *vrf; - vrf_id_t vrf_id = VRF_DEFAULT; // Pending: need a way to return invalid - // id/ routine not used. - - if (!name) - return vrf_id; - vrf = vrf_lookup_by_name(name); - if (vrf) - vrf_id = vrf->vrf_id; - - return vrf_id; -} - /* Get the data pointer of the specified VRF. If not found, create one. */ void *vrf_info_get(vrf_id_t vrf_id) { @@ -119,7 +119,6 @@ extern struct vrf *vrf_lookup_by_name(const char *); extern struct vrf *vrf_get(vrf_id_t, const char *); extern struct vrf *vrf_update(vrf_id_t new_vrf_id, const char *name); extern const char *vrf_id_to_name(vrf_id_t vrf_id); -extern vrf_id_t vrf_name_to_id(const char *); #define VRF_LOGNAME(V) V ? V->name : "Unknown" diff --git a/lib/zclient.c b/lib/zclient.c index a1e7194890..dde60a6c90 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -1105,6 +1105,33 @@ stream_failure: return -1; } +int zapi_srv6_locator_encode(struct stream *s, const struct srv6_locator *l) +{ + stream_putw(s, strlen(l->name)); + stream_put(s, l->name, strlen(l->name)); + stream_putw(s, l->prefix.prefixlen); + stream_put(s, &l->prefix.prefix, sizeof(l->prefix.prefix)); + return 0; +} + +int zapi_srv6_locator_decode(struct stream *s, struct srv6_locator *l) +{ + uint16_t len = 0; + + STREAM_GETW(s, len); + if (len > SRV6_LOCNAME_SIZE) + goto stream_failure; + + STREAM_GET(l->name, s, len); + STREAM_GETW(s, l->prefix.prefixlen); + STREAM_GET(&l->prefix.prefix, s, sizeof(l->prefix.prefix)); + l->prefix.family = AF_INET6; + return 0; + +stream_failure: + return -1; +} + static int zapi_nhg_encode(struct stream *s, int cmd, struct zapi_nhg *api_nhg) { int i; diff --git a/lib/zclient.h b/lib/zclient.h index 71187ccae7..f9438d5db7 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -1090,6 +1090,9 @@ extern int zapi_labels_encode(struct stream *s, int cmd, struct zapi_labels *zl); extern int zapi_labels_decode(struct stream *s, struct zapi_labels *zl); +extern int zapi_srv6_locator_encode(struct stream *s, + const struct srv6_locator *l); +extern int zapi_srv6_locator_decode(struct stream *s, struct srv6_locator *l); extern int zapi_srv6_locator_chunk_encode(struct stream *s, const struct srv6_locator_chunk *c); extern int zapi_srv6_locator_chunk_decode(struct stream *s, |
