diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/command.c | 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/elf_py.c | 4 | ||||
| -rw-r--r-- | lib/getopt.c | 5 | ||||
| -rw-r--r-- | lib/hook.h | 19 | ||||
| -rw-r--r-- | lib/nexthop.c | 5 | ||||
| -rw-r--r-- | lib/nexthop.h | 3 | ||||
| -rw-r--r-- | lib/routemap.c | 17 | ||||
| -rw-r--r-- | lib/routemap.h | 11 | ||||
| -rw-r--r-- | lib/routemap_cli.c | 5 | ||||
| -rw-r--r-- | lib/vrf.c | 22 | ||||
| -rw-r--r-- | lib/vrf.h | 2 | ||||
| -rw-r--r-- | lib/zclient.c | 27 | ||||
| -rw-r--r-- | lib/zclient.h | 3 |
19 files changed, 143 insertions, 67 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_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..56a7ae422b 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)) + 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/elf_py.c b/lib/elf_py.c index b47aa3d795..1c306893ad 100644 --- a/lib/elf_py.c +++ b/lib/elf_py.c @@ -860,6 +860,7 @@ static PyObject *elffile_find_note(PyObject *self, PyObject *args) Py_RETURN_NONE; } +#ifdef HAVE_ELF_GETDATA_RAWCHUNK static bool elffile_virt2file(struct elffile *w, GElf_Addr virt, GElf_Addr *offs) { @@ -884,6 +885,7 @@ static bool elffile_virt2file(struct elffile *w, GElf_Addr virt, return false; } +#endif /* HAVE_ELF_GETDATA_RAWCHUNK */ static PyObject *elffile_subscript(PyObject *self, PyObject *key) { @@ -1016,6 +1018,7 @@ static PyTypeObject typeobj_elffile = { .tp_methods = methods_elffile, }; +#ifdef HAVE_ELF_GETDATA_RAWCHUNK static char *elfdata_strptr(Elf_Data *data, size_t offset) { char *p; @@ -1124,6 +1127,7 @@ static void elffile_add_dynreloc(struct elffile *w, Elf_Data *reldata, } } +#endif /* HAVE_ELF_GETDATA_RAWCHUNK */ /* primary (only, really) entry point to anything in this module */ static PyObject *elffile_load(PyTypeObject *type, PyObject *args, 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..98409c76c5 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; 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/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 1fbd142ad2..2c8eb24537 100644 --- a/lib/routemap.h +++ b/lib/routemap.h @@ -350,6 +350,8 @@ DECLARE_QOBJ_TYPE(route_map); (strmatch(A, "frr-bgp-route-map:set-large-community")) #define IS_SET_COMMUNITY(A) \ (strmatch(A, "frr-bgp-route-map:set-community")) +#define IS_SET_EXTCOMMUNITY_NONE(A) \ + (strmatch(A, "frr-bgp-route-map:set-extcommunity-none")) #define IS_SET_EXTCOMMUNITY_RT(A) \ (strmatch(A, "frr-bgp-route-map:set-extcommunity-rt")) #define IS_SET_EXTCOMMUNITY_SOO(A) \ @@ -441,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/routemap_cli.c b/lib/routemap_cli.c index 045a8cddd8..cadad15fa7 100644 --- a/lib/routemap_cli.c +++ b/lib/routemap_cli.c @@ -1223,6 +1223,11 @@ void route_map_action_show(struct vty *vty, struct lyd_node *dnode, strlcat(str, " non-transitive", sizeof(str)); vty_out(vty, " set extcommunity bandwidth %s\n", str); + } else if (IS_SET_EXTCOMMUNITY_NONE(action)) { + if (yang_dnode_get_bool( + dnode, + "./rmap-set-action/frr-bgp-route-map:extcommunity-none")) + vty_out(vty, " set extcommunity none\n"); } else if (IS_SET_AGGREGATOR(action)) { vty_out(vty, " set aggregator as %s %s\n", yang_dnode_get_string( @@ -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) { @@ -1068,13 +1053,6 @@ int vrf_sockunion_socket(const union sockunion *su, vrf_id_t vrf_id, return ret; } -vrf_id_t vrf_generate_id(void) -{ - static int vrf_id_local; - - return ++vrf_id_local; -} - /* ------- Northbound callbacks ------- */ /* @@ -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" @@ -323,7 +322,6 @@ extern int vrf_netns_handler_create(struct vty *vty, struct vrf *vrf, extern void vrf_disable(struct vrf *vrf); extern int vrf_enable(struct vrf *vrf); extern void vrf_delete(struct vrf *vrf); -extern vrf_id_t vrf_generate_id(void); extern const struct frr_yang_module_info frr_vrf_info; 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, |
