summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/command.c1
-rw-r--r--lib/command_graph.c4
-rw-r--r--lib/command_graph.h1
-rw-r--r--lib/command_lex.l1
-rw-r--r--lib/command_match.c25
-rw-r--r--lib/command_parse.y16
-rw-r--r--lib/command_py.c39
-rw-r--r--lib/elf_py.c4
-rw-r--r--lib/getopt.c5
-rw-r--r--lib/hook.h19
-rw-r--r--lib/nexthop.c5
-rw-r--r--lib/nexthop.h3
-rw-r--r--lib/routemap.c17
-rw-r--r--lib/routemap.h11
-rw-r--r--lib/routemap_cli.c5
-rw-r--r--lib/vrf.c22
-rw-r--r--lib/vrf.h2
-rw-r--r--lib/zclient.c27
-rw-r--r--lib/zclient.h3
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(
diff --git a/lib/vrf.c b/lib/vrf.c
index 79313d66d9..198d5253c8 100644
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -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 ------- */
/*
diff --git a/lib/vrf.h b/lib/vrf.h
index f8b0148eb8..dab83d42da 100644
--- a/lib/vrf.h
+++ b/lib/vrf.h
@@ -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,