summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_routemap.c24
-rw-r--r--bgpd/bgpd.c13
-rw-r--r--doc/Building_FRR_for_LEDE-OpenWRT.md96
-rw-r--r--doc/cli.md8
-rw-r--r--lib/command_graph.c2
-rw-r--r--lib/command_graph.h10
-rw-r--r--lib/command_lex.l4
-rw-r--r--lib/command_match.c55
-rw-r--r--lib/command_parse.y12
-rw-r--r--lib/command_py.c2
-rw-r--r--lib/grammar_sandbox.c2
-rw-r--r--lib/routemap.c18
-rw-r--r--ospfd/ospf_spf.c6
-rw-r--r--pimd/pim_nht.c20
-rw-r--r--pimd/pim_upstream.c7
-rw-r--r--python/clidef.py8
-rw-r--r--tests/lib/cli/test_cli.c2
-rw-r--r--tests/ospf6d/test_lsdb.c2
-rw-r--r--vtysh/vtysh.c7
-rw-r--r--zebra/connected.c6
-rw-r--r--zebra/kernel_socket.c8
-rw-r--r--zebra/redistribute.c2
-rw-r--r--zebra/rib.h5
-rw-r--r--zebra/rt_netlink.c26
-rw-r--r--zebra/zebra_rib.c9
-rw-r--r--zebra/zserv.c7
26 files changed, 291 insertions, 70 deletions
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index a8e111d361..5a5d2a5d5d 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -3499,26 +3499,38 @@ DEFUN (no_match_origin,
DEFUN (set_ip_nexthop_peer,
set_ip_nexthop_peer_cmd,
- "set ip next-hop peer-address",
+ "[no] set ip next-hop peer-address",
+ NO_STR
SET_STR
IP_STR
"Next hop address\n"
"Use peer address (for BGP only)\n")
{
- return generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
- "ip next-hop", "peer-address");
+ int (*func)(struct vty *, struct route_map_index *, const char *,
+ const char *) = strmatch(argv[0]->text, "no")
+ ? generic_set_delete
+ : generic_set_add;
+
+ return func(vty, VTY_GET_CONTEXT(route_map_index), "ip next-hop",
+ "peer-address");
}
DEFUN (set_ip_nexthop_unchanged,
set_ip_nexthop_unchanged_cmd,
- "set ip next-hop unchanged",
+ "[no] set ip next-hop unchanged",
+ NO_STR
SET_STR
IP_STR
"Next hop address\n"
"Don't modify existing Next hop address\n")
{
- return generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
- "ip next-hop", "unchanged");
+ int (*func)(struct vty *, struct route_map_index *, const char *,
+ const char *) = strmatch(argv[0]->text, "no")
+ ? generic_set_delete
+ : generic_set_add;
+
+ return func(vty, VTY_GET_CONTEXT(route_map_index), "ip next-hop",
+ "unchanged");
}
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index f9dbac2f71..d7733fbacd 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -6190,11 +6190,14 @@ static void bgp_config_write_filter(struct vty *vty, struct peer *peer,
addr, filter->plist[in].name);
}
- if (filter->plist[out].name && !gfilter) {
- afi_header_vty_out(vty, afi, safi, write,
- " neighbor %s prefix-list %s out\n", addr,
- filter->plist[out].name);
- }
+ if (filter->plist[out].name)
+ if (!gfilter || !gfilter->plist[out].name
+ || strcmp(filter->plist[out].name, gfilter->plist[out].name)
+ != 0) {
+ afi_header_vty_out(vty, afi, safi, write,
+ " neighbor %s prefix-list %s out\n",
+ addr, filter->plist[out].name);
+ }
/* route-map. */
if (filter->map[RMAP_IN].name)
diff --git a/doc/Building_FRR_for_LEDE-OpenWRT.md b/doc/Building_FRR_for_LEDE-OpenWRT.md
new file mode 100644
index 0000000000..cde68dbd0b
--- /dev/null
+++ b/doc/Building_FRR_for_LEDE-OpenWRT.md
@@ -0,0 +1,96 @@
+Building FRR for OpenWRT/LEDE from Git Source
+===============================================
+
+- for the moment because of cross compile problems, master is not supported,
+ only upto 3.0
+- LDP can't be built because of missing Perl-XML-LibXML in OpenWRT/LEDE tree
+
+Prepare build environment
+-------------------------
+
+https://lede-project.org/docs/guide-developer/install-buildsystem
+
+for
+
+Ubuntu 12.04LTS:
+
+ sudo apt-get install build-essential subversion git-core \
+ libncurses5-dev zlib1g-dev gawk flex quilt libssl-dev xsltproc \
+ libxml-parser-perl mercurial bzr ecj cvs unzip
+
+Ubuntu 64bit:
+
+ sudo apt-get install build-essential subversion libncurses5-dev zlib1g-dev \
+ gawk gcc-multilib flex git-core gettext libssl-dev
+
+Debian 8 Jessie:
+
+ sudo apt-get install build-essential libncurses5-dev gawk git subversion \
+ libssl-dev gettext unzip zlib1g-dev file python
+
+Debian 9 Stretch:
+
+ sudo apt-get install build-essential libncurses5-dev gawk git subversion \
+ libssl-dev gettext zlib1g-dev
+
+Centos x86-64 (some packages require EPEL):
+
+ yum install subversion binutils bzip2 gcc gcc-c++ gawk gettext flex \
+ ncurses-devel zlib-devel zlib-static make patch unzip glibc glibc-devel \
+ perl-ExtUtils-MakeMaker glibc-static quilt ncurses-libs sed sdcc bison \
+ intltool sharutils wget git-core openssl-devel xz
+
+Fedora 24 - 64Bit:
+
+ dnf install -y subversion binutils bzip2 gcc gcc-c++ gawk gettext git-core \
+ unzip ncurses-devel ncurses-compat-libs zlib-devel zlib-static make \
+ flex patch perl-ExtUtils-MakeMaker perl-Thread-Queue glibc glibc-devel \
+ glibc-static quilt sed sdcc intltool sharutils bison wget openssl-devel
+
+
+Get LEDE Sources (from Git)
+---------------------------
+
+LEDE and OpenWRT is planned to remerge and won't cover the similar OpenWRT build
+As normal user:
+ git clone https://git.lede-project.org/source.git lede
+ cd lede
+ ./scripts/feeds update -a
+ ./scripts/feeds install -a
+ cd feeds/routing
+ git pull origin pull/319/head
+ ln -s ../../../feeds/routing/frr/ ../../package/feeds/routing/
+ cd ../..
+ make menuconfig
+
+Select the needed target then select needed packages in
+Network -> Routing and Redirection -> frr, exit and save
+
+ make or make package/frr/compile
+
+It may be possible that on first build `make package/frr/compile` not to work
+and it may be needed to run a `make` for the entire build envronment, add V=s
+for debugging
+
+Work with sources
+-----------------
+
+To update the rc1 version or add other options, the Makefile is found in
+feeds/routing/frr
+
+edit:
+ PKG_VERSION:=
+ PKG_SOURCE_VERSION:=<git-hash>
+
+Usage
+-----
+
+Edit `/usr/sbin/frr.init` and add/remove the daemons name in section DAEMONS=
+or don't install unneded packages
+For example: zebra bgpd ldpd isisd nhrpd ospfd ospf6d pimd ripd ripngd
+
+### Enable the serivce
+ - service frr enable
+
+### Start the service
+ - service frr start
diff --git a/doc/cli.md b/doc/cli.md
index cfb4d629f9..ef867362c3 100644
--- a/doc/cli.md
+++ b/doc/cli.md
@@ -30,15 +30,17 @@ Characters allowed in each token type:
Tokens
------
* `WORD` -- A token that begins with +, -, or a lowercase letter. It is
- an unchanging part of the command and will only match itself.
- Example: "show ip bgp", every token is a WORD.
+ an unchanging part of the command and will only match itself.
+ Example: "show ip bgp", every token is a WORD.
* `IPV4` -- 'A.B.C.D', matches an IPv4 address.
* `IPV6` -- 'X:X::X:X', matches an IPv6 address.
* `IPV4_PREFIX` -- 'A.B.C.D/M', matches an IPv4 prefix in CIDR notation.
* `IPV6_PREFIX` -- 'X:X::X:X/M', matches an IPv6 prefix in CIDR notation.
+* `MAC` -- 'M:A:C', matches a 48-bit mac address
+* `MAC_PREFIX` -- 'M:A:C/M', matches a 48-bit mac address with a mask
* `VARIABLE` -- Begins with a capital letter. Matches any input.
* `RANGE` -- Numeric range delimited by parentheses, e.g. (-100 - 100) or
- (10-20). Will only match numbers in the range.
+ (10-20). Will only match numbers in the range.
Rules
-----
diff --git a/lib/command_graph.c b/lib/command_graph.c
index dc7233c1fe..fce11a70cc 100644
--- a/lib/command_graph.c
+++ b/lib/command_graph.c
@@ -379,6 +379,8 @@ static void cmd_node_names(struct graph_node *gn, struct graph_node *join,
case IPV4_PREFIX_TKN:
case IPV6_TKN:
case IPV6_PREFIX_TKN:
+ case MAC_TKN:
+ case MAC_PREFIX_TKN:
if (!tok->varname && prevname)
cmd_token_varname_set(tok, prevname);
prevname = NULL;
diff --git a/lib/command_graph.h b/lib/command_graph.h
index 879148844c..ec68e284ed 100644
--- a/lib/command_graph.h
+++ b/lib/command_graph.h
@@ -42,14 +42,17 @@ struct vty;
* The type determines what kind of data the token can match (in the
* matching use case) or hold (in the argv use case).
*/
+/* clang-format off */
enum cmd_token_type {
- WORD_TKN, // words
+ WORD_TKN, // words
VARIABLE_TKN, // almost anything
RANGE_TKN, // integer range
- IPV4_TKN, // IPV4 addresses
+ IPV4_TKN, // IPV4 addresses
IPV4_PREFIX_TKN, // IPV4 network prefixes
- IPV6_TKN, // IPV6 prefixes
+ IPV6_TKN, // IPV6 prefixes
IPV6_PREFIX_TKN, // IPV6 network prefixes
+ MAC_TKN, // Ethernet address
+ MAC_PREFIX_TKN, // Ethernet address w/ CIDR mask
/* plumbing types */
FORK_TKN, // marks subgraph beginning
@@ -59,6 +62,7 @@ enum cmd_token_type {
SPECIAL_TKN = FORK_TKN,
};
+/* clang-format on */
#define IS_VARYING_TOKEN(x) ((x) >= VARIABLE_TKN && (x) < FORK_TKN)
diff --git a/lib/command_lex.l b/lib/command_lex.l
index fddbf7b287..59d0d840a8 100644
--- a/lib/command_lex.l
+++ b/lib/command_lex.l
@@ -40,6 +40,8 @@ IPV4 A\.B\.C\.D
IPV4_PREFIX A\.B\.C\.D\/M
IPV6 X:X::X:X
IPV6_PREFIX X:X::X:X\/M
+MAC M:A:C
+MAC_PREFIX M:A:C\/M
VARIABLE [A-Z][-_a-zA-Z:0-9]+
NUMBER (\-|\+)?[0-9]{1,20}
RANGE \({NUMBER}[ ]?\-[ ]?{NUMBER}\)
@@ -67,6 +69,8 @@ RANGE \({NUMBER}[ ]?\-[ ]?{NUMBER}\)
{IPV4_PREFIX} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return IPV4_PREFIX;}
{IPV6} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return IPV6;}
{IPV6_PREFIX} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return IPV6_PREFIX;}
+{MAC} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return MAC;}
+{MAC_PREFIX} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return MAC_PREFIX;}
{VARIABLE} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return VARIABLE;}
{RANGE} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return RANGE;}
. {return yytext[0];}
diff --git a/lib/command_match.c b/lib/command_match.c
index bc54f1bb09..f07448d716 100644
--- a/lib/command_match.c
+++ b/lib/command_match.c
@@ -78,6 +78,8 @@ static enum match_type match_word(struct cmd_token *, const char *);
static enum match_type match_variable(struct cmd_token *, const char *);
+static enum match_type match_mac(const char *, bool);
+
/* matching functions */
static enum matcher_rv matcher_rv;
@@ -537,6 +539,8 @@ static int score_precedence(enum cmd_token_type type)
case IPV4_PREFIX_TKN:
case IPV6_TKN:
case IPV6_PREFIX_TKN:
+ case MAC_TKN:
+ case MAC_PREFIX_TKN:
case RANGE_TKN:
return 2;
case WORD_TKN:
@@ -658,6 +662,10 @@ static enum match_type match_token(struct cmd_token *token, char *input_token)
return match_range(token, input_token);
case VARIABLE_TKN:
return match_variable(token, input_token);
+ case MAC_TKN:
+ return match_mac(input_token, false);
+ case MAC_PREFIX_TKN:
+ return match_mac(input_token, true);
case END_TKN:
default:
return no_match;
@@ -964,3 +972,50 @@ static enum match_type match_variable(struct cmd_token *token, const char *word)
assert(token->type == VARIABLE_TKN);
return exact_match;
}
+
+#define MAC_CHARS "ABCDEFabcdef0123456789:"
+
+static enum match_type match_mac(const char *word, bool prefix)
+{
+ /* 6 2-digit hex numbers separated by 5 colons */
+ size_t mac_explen = 6 * 2 + 5;
+ /* '/' + 2-digit integer */
+ size_t mask_len = 1 + 2;
+ unsigned int i;
+ char *eptr;
+ unsigned int maskval;
+
+ /* length check */
+ if (strlen(word) > mac_explen + (prefix ? mask_len : 0))
+ return no_match;
+
+ /* address check */
+ for (i = 0; i < mac_explen; i++) {
+ if (word[i] == '\0' || !strchr(MAC_CHARS, word[i]))
+ break;
+ if (((i + 1) % 3 == 0) != (word[i] == ':'))
+ return no_match;
+ }
+
+ /* incomplete address */
+ if (i < mac_explen && word[i] == '\0')
+ return partly_match;
+ else if (i < mac_explen)
+ return no_match;
+
+ /* mask check */
+ if (prefix && word[i] == '/') {
+ if (word[++i] == '\0')
+ return partly_match;
+
+ maskval = strtoul(&word[i], &eptr, 10);
+ if (*eptr != '\0' || maskval > 48)
+ return no_match;
+ } else if (prefix && word[i] == '\0') {
+ return partly_match;
+ } else if (prefix) {
+ return no_match;
+ }
+
+ return exact_match;
+}
diff --git a/lib/command_parse.y b/lib/command_parse.y
index 1bc8ea1a44..0f3e42219e 100644
--- a/lib/command_parse.y
+++ b/lib/command_parse.y
@@ -101,6 +101,8 @@
%token <string> IPV6_PREFIX
%token <string> VARIABLE
%token <string> RANGE
+%token <string> MAC
+%token <string> MAC_PREFIX
/* union types for parsed rules */
%type <node> start
@@ -273,6 +275,16 @@ placeholder_token_real:
XFREE (MTYPE_LEX, $1);
}
+| MAC
+{
+ $$ = new_token_node (ctx, MAC_TKN, $1, doc_next(ctx));
+ XFREE (MTYPE_LEX, $1);
+}
+| MAC_PREFIX
+{
+ $$ = new_token_node (ctx, MAC_PREFIX_TKN, $1, doc_next(ctx));
+ XFREE (MTYPE_LEX, $1);
+}
placeholder_token:
placeholder_token_real varname_token
diff --git a/lib/command_py.c b/lib/command_py.c
index 785d2ffa70..755cfb55ce 100644
--- a/lib/command_py.c
+++ b/lib/command_py.c
@@ -199,6 +199,8 @@ static PyObject *graph_to_pyobj(struct wrap_graph *wgraph,
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)
diff --git a/lib/grammar_sandbox.c b/lib/grammar_sandbox.c
index 8dd8d2e2bb..96ecfa44d3 100644
--- a/lib/grammar_sandbox.c
+++ b/lib/grammar_sandbox.c
@@ -498,6 +498,8 @@ struct message tokennames[] = {item(WORD_TKN), // words
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 w/ mask
/* plumbing types */
item(FORK_TKN),
diff --git a/lib/routemap.c b/lib/routemap.c
index 3d1add25dc..a70248633c 100644
--- a/lib/routemap.c
+++ b/lib/routemap.c
@@ -2194,24 +2194,24 @@ DEFUN (set_ip_nexthop,
DEFUN (no_set_ip_nexthop,
no_set_ip_nexthop_cmd,
- "no set ip next-hop [<peer-address|A.B.C.D>]",
+ "no set ip next-hop [A.B.C.D]",
NO_STR
SET_STR
IP_STR
"Next hop address\n"
- "Use peer address (for BGP only)\n"
"IP address of next hop\n")
{
- int idx_peer = 4;
+ int idx;
VTY_DECLVAR_CONTEXT(route_map_index, index);
+ const char *arg = NULL;
- if (rmap_match_set_hook.no_set_ip_nexthop) {
- if (argc <= idx_peer)
- return rmap_match_set_hook.no_set_ip_nexthop(
- vty, index, "ip next-hop", NULL);
+ if (argv_find(argv, argc, "A.B.C.D", &idx))
+ arg = argv[idx]->arg;
+
+ if (rmap_match_set_hook.no_set_ip_nexthop)
return rmap_match_set_hook.no_set_ip_nexthop(
- vty, index, "ip next-hop", argv[idx_peer]->arg);
- }
+ vty, index, "ip next-hop", arg);
+
return CMD_SUCCESS;
}
diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c
index 7437d26da3..891088ecc2 100644
--- a/ospfd/ospf_spf.c
+++ b/ospfd/ospf_spf.c
@@ -136,8 +136,10 @@ static void ospf_canonical_nexthops_free(struct vertex *root)
/* Free child nexthops pointing back to this root vertex */
for (ALL_LIST_ELEMENTS(child->parents, n2, nn2, vp))
- if (vp->parent == root && vp->nexthop)
+ if (vp->parent == root && vp->nexthop) {
vertex_nexthop_free(vp->nexthop);
+ vp->nexthop = NULL;
+ }
}
}
@@ -401,8 +403,6 @@ static void ospf_spf_flush_parents(struct vertex *w)
/* delete the existing nexthops */
for (ALL_LIST_ELEMENTS(w->parents, ln, nn, vp)) {
list_delete_node(w->parents, ln);
- if (vp->nexthop)
- vertex_nexthop_free(vp->nexthop);
vertex_parent_free(vp);
}
}
diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c
index f7fa9993ad..1e88ff13ff 100644
--- a/pimd/pim_nht.c
+++ b/pimd/pim_nht.c
@@ -248,12 +248,11 @@ void pim_delete_tracked_nexthop(struct pim_instance *pim, struct prefix *addr,
}
/* Update RP nexthop info based on Nexthop update received from Zebra.*/
-static int pim_update_rp_nh(struct pim_instance *pim,
- struct pim_nexthop_cache *pnc)
+static void pim_update_rp_nh(struct pim_instance *pim,
+ struct pim_nexthop_cache *pnc)
{
struct listnode *node = NULL;
struct rp_info *rp_info = NULL;
- int ret = 0;
/*Traverse RP list and update each RP Nexthop info */
for (ALL_LIST_ELEMENTS_RO(pnc->rp_list, node, rp_info)) {
@@ -261,12 +260,11 @@ static int pim_update_rp_nh(struct pim_instance *pim,
continue;
// Compute PIM RPF using cached nexthop
- ret = pim_ecmp_nexthop_search(
- pim, pnc, &rp_info->rp.source_nexthop,
- &rp_info->rp.rpf_addr, &rp_info->group, 1);
+ pim_ecmp_nexthop_search(pim, pnc,
+ &rp_info->rp.source_nexthop,
+ &rp_info->rp.rpf_addr,
+ &rp_info->group, 1);
}
-
- return !ret;
}
/* This API is used to traverse nexthop cache of RPF addr
@@ -320,8 +318,10 @@ static int pim_update_upstream_nh_helper(struct hash_backet *backet, void *arg)
old.source_nexthop.interface = up->rpf.source_nexthop.interface;
rpf_result = pim_rpf_update(pim, up, &old, 0);
- if (rpf_result == PIM_RPF_FAILURE)
+ if (rpf_result == PIM_RPF_FAILURE) {
+ pim_mroute_del(up->channel_oil, __PRETTY_FUNCTION__);
return HASHWALK_CONTINUE;
+ }
/* update kernel multicast forwarding cache (MFC) */
if (up->channel_oil) {
@@ -525,7 +525,7 @@ int pim_ecmp_nexthop_search(struct pim_instance *pim,
pim->vrf->name,
nexthop->interface->name);
}
- return 0;
+ return 1;
}
}
}
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index 95d1a840ff..cc90cef3ae 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.c
@@ -1111,8 +1111,15 @@ static int pim_upstream_keep_alive_timer(struct thread *t)
PIM_UPSTREAM_FLAG_UNSET_SRC_STREAM(up->flags);
pim_upstream_del(pim, up, __PRETTY_FUNCTION__);
} else if (PIM_UPSTREAM_FLAG_TEST_SRC_LHR(up->flags)) {
+ struct pim_upstream *parent = up->parent;
+
PIM_UPSTREAM_FLAG_UNSET_SRC_LHR(up->flags);
pim_upstream_del(pim, up, __PRETTY_FUNCTION__);
+
+ if (parent) {
+ pim_jp_agg_single_upstream_send(&parent->rpf,
+ parent, true);
+ }
}
return 0;
diff --git a/python/clidef.py b/python/clidef.py
index 069d80fb70..8e3c7595b7 100644
--- a/python/clidef.py
+++ b/python/clidef.py
@@ -59,7 +59,7 @@ class PrefixBase(RenderHandler):
def combine(self, other):
if type(self) == type(other):
return other
- if type(other) in [Prefix4Handler, Prefix6Handler, PrefixGenHandler]:
+ if isinstance(other, PrefixBase):
return PrefixGenHandler(None)
return StringHandler(None)
deref = '&'
@@ -71,6 +71,10 @@ class Prefix6Handler(PrefixBase):
argtype = 'const struct prefix_ipv6 *'
decl = Template('struct prefix_ipv6 $varname = { };')
code = Template('_fail = !str2prefix_ipv6(argv[_i]->arg, &$varname);')
+class PrefixEthHandler(PrefixBase):
+ argtype = 'struct prefix_eth *'
+ decl = Template('struct prefix_eth $varname = { };')
+ code = Template('_fail = !str2prefix_eth(argv[_i]->arg, &$varname);')
class PrefixGenHandler(PrefixBase):
argtype = 'const struct prefix *'
decl = Template('struct prefix $varname = { };')
@@ -121,6 +125,8 @@ handlers = {
'IPV4_PREFIX_TKN': Prefix4Handler,
'IPV6_TKN': IP6Handler,
'IPV6_PREFIX_TKN': Prefix6Handler,
+ 'MAC_TKN': PrefixEthHandler,
+ 'MAC_PREFIX_TKN': PrefixEthHandler,
}
# core template invoked for each occurence of DEFPY.
diff --git a/tests/lib/cli/test_cli.c b/tests/lib/cli/test_cli.c
index 8f062d8b5e..4cc15ba23f 100644
--- a/tests/lib/cli/test_cli.c
+++ b/tests/lib/cli/test_cli.c
@@ -41,7 +41,7 @@ DUMMY_DEFUN(cmd13, "alt a X:X::X:X");
DUMMY_DEFUN(cmd14,
"pat g { foo A.B.C.D$foo|foo|bar X:X::X:X$bar| baz } [final]");
-#include "tests/lib/cli/test_cli_clippy.c"
+#include "lib/cli/test_cli_clippy.c"
DEFPY(magic_test, magic_test_cmd,
"magic (0-100) {ipv4net A.B.C.D/M|X:X::X:X$ipv6}",
diff --git a/tests/ospf6d/test_lsdb.c b/tests/ospf6d/test_lsdb.c
index 310c4a7323..633e88e769 100644
--- a/tests/ospf6d/test_lsdb.c
+++ b/tests/ospf6d/test_lsdb.c
@@ -29,7 +29,7 @@
#include "ospf6d/ospf6_lsdb.h"
#include "tests/lib/cli/common_cli.h"
-#include "tests/ospf6d/test_lsdb_clippy.c"
+#include "ospf6d/test_lsdb_clippy.c"
static struct ospf6_lsdb *lsdb;
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 6255726c47..f971c171bc 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -250,6 +250,13 @@ static int vtysh_client_execute(struct vtysh_client *head_client,
static void vtysh_client_config(struct vtysh_client *head_client, char *line)
{
+ /* watchfrr currently doesn't load any config, and has some hardcoded
+ * settings that show up in "show run". skip it here (for now at
+ * least) so we don't get that mangled up in config-write.
+ */
+ if (head_client->flag == VTYSH_WATCHFRR)
+ return;
+
vtysh_client_run_all(head_client, line, 1, NULL,
vtysh_config_parse_line, NULL);
}
diff --git a/zebra/connected.c b/zebra/connected.c
index 80f9ebe5ea..701314f246 100644
--- a/zebra/connected.c
+++ b/zebra/connected.c
@@ -323,10 +323,10 @@ void connected_down_ipv4(struct interface *ifp, struct connected *ifc)
/* Same logic as for connected_up_ipv4(): push the changes into the
* head. */
rib_delete(AFI_IP, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0,
- &p, NULL, NULL, ifp->ifindex, 0);
+ &p, NULL, NULL, ifp->ifindex, 0, 0);
rib_delete(AFI_IP, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0,
- 0, &p, NULL, NULL, ifp->ifindex, 0);
+ 0, &p, NULL, NULL, ifp->ifindex, 0, 0);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
zlog_debug(
@@ -501,7 +501,7 @@ void connected_down_ipv6(struct interface *ifp, struct connected *ifc)
return;
rib_delete(AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0,
- 0, &p, NULL, NULL, ifp->ifindex, 0);
+ 0, &p, NULL, NULL, ifp->ifindex, 0, 0);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
zlog_debug(
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index 5ca6a488c3..84d01bca6f 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -1019,7 +1019,7 @@ void rtm_read(struct rt_msghdr *rtm)
if (rtm->rtm_type == RTM_CHANGE)
rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
- NULL, 0, 0);
+ NULL, 0, 0, 0);
union g_addr ggate = {.ipv4 = gate.sin.sin_addr};
if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
@@ -1030,7 +1030,7 @@ void rtm_read(struct rt_msghdr *rtm)
else
rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
- &ggate, 0, 0);
+ &ggate, 0, 0, 0);
}
if (dest.sa.sa_family == AF_INET6) {
/* One day we might have a debug section here like one in the
@@ -1061,7 +1061,7 @@ void rtm_read(struct rt_msghdr *rtm)
if (rtm->rtm_type == RTM_CHANGE)
rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
- NULL, 0, 0);
+ NULL, 0, 0, 0);
union g_addr ggate = {.ipv6 = gate.sin6.sin6_addr};
if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
@@ -1072,7 +1072,7 @@ void rtm_read(struct rt_msghdr *rtm)
else
rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
- &ggate, ifindex, 0);
+ &ggate, ifindex, 0, 0);
}
}
diff --git a/zebra/redistribute.c b/zebra/redistribute.c
index 92da5fe0ce..ed27dc3e83 100644
--- a/zebra/redistribute.c
+++ b/zebra/redistribute.c
@@ -578,7 +578,7 @@ int zebra_del_import_table_entry(struct route_node *rn, struct route_entry *re)
rib_delete(AFI_IP, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE,
re->table, re->flags, &p, NULL, NULL, 0,
- zebrad.rtm_table_default);
+ zebrad.rtm_table_default, re->metric);
}
/* DD: Add IPv6 code */
diff --git a/zebra/rib.h b/zebra/rib.h
index de941bcbbe..495b731e88 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -296,7 +296,7 @@ extern int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
u_short instance, int flags, struct prefix *p,
struct prefix_ipv6 *src_p, union g_addr *gate,
union g_addr *src, ifindex_t ifindex, u_int32_t table_id,
- u_int32_t, u_int32_t, u_char);
+ u_int32_t metric, u_int32_t mtu, u_char distance);
extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *,
struct prefix_ipv6 *src_p, struct route_entry *);
@@ -304,7 +304,8 @@ extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *,
extern void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
u_short instance, int flags, struct prefix *p,
struct prefix_ipv6 *src_p, union g_addr *gate,
- ifindex_t ifindex, u_int32_t table_id);
+ ifindex_t ifindex, u_int32_t table_id,
+ u_int32_t metric);
extern struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t,
union g_addr *,
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 192fffd29c..e28fe5630a 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -308,21 +308,19 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
if (tb[RTA_GATEWAY])
gate = RTA_DATA(tb[RTA_GATEWAY]);
- if (h->nlmsg_type == RTM_NEWROUTE) {
- if (tb[RTA_PRIORITY])
- metric = *(int *)RTA_DATA(tb[RTA_PRIORITY]);
+ if (tb[RTA_PRIORITY])
+ metric = *(int *)RTA_DATA(tb[RTA_PRIORITY]);
- if (tb[RTA_METRICS]) {
- struct rtattr *mxrta[RTAX_MAX + 1];
+ if (tb[RTA_METRICS]) {
+ struct rtattr *mxrta[RTAX_MAX + 1];
- memset(mxrta, 0, sizeof mxrta);
- netlink_parse_rtattr(mxrta, RTAX_MAX,
- RTA_DATA(tb[RTA_METRICS]),
- RTA_PAYLOAD(tb[RTA_METRICS]));
+ memset(mxrta, 0, sizeof mxrta);
+ netlink_parse_rtattr(mxrta, RTAX_MAX,
+ RTA_DATA(tb[RTA_METRICS]),
+ RTA_PAYLOAD(tb[RTA_METRICS]));
- if (mxrta[RTAX_MTU])
- mtu = *(u_int32_t *)RTA_DATA(mxrta[RTAX_MTU]);
- }
+ if (mxrta[RTAX_MTU])
+ mtu = *(u_int32_t *)RTA_DATA(mxrta[RTAX_MTU]);
}
if (rtm->rtm_family == AF_INET) {
@@ -449,7 +447,7 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
if (!tb[RTA_MULTIPATH])
rib_delete(afi, SAFI_UNICAST, vrf_id,
ZEBRA_ROUTE_KERNEL, 0, flags, &p, NULL, gate,
- index, table);
+ index, table, metric);
else {
struct rtnexthop *rtnh =
(struct rtnexthop *)RTA_DATA(tb[RTA_MULTIPATH]);
@@ -476,7 +474,7 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
rib_delete(afi, SAFI_UNICAST, vrf_id,
ZEBRA_ROUTE_KERNEL, 0, flags,
&p, NULL, gate, index,
- table);
+ table, metric);
len -= NLMSG_ALIGN(rtnh->rtnh_len);
rtnh = RTNH_NEXT(rtnh);
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index e61c2e7b0e..ed53554265 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -2274,7 +2274,8 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
u_short instance, int flags, struct prefix *p,
struct prefix_ipv6 *src_p, union g_addr *gate,
- ifindex_t ifindex, u_int32_t table_id)
+ ifindex_t ifindex, u_int32_t table_id,
+ u_int32_t metric)
{
struct route_table *table;
struct route_node *rn;
@@ -2328,6 +2329,9 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
continue;
if (re->instance != instance)
continue;
+ if (re->type == ZEBRA_ROUTE_KERNEL &&
+ re->metric != metric)
+ continue;
if (re->type == ZEBRA_ROUTE_CONNECT && (nexthop = re->nexthop)
&& nexthop->type == NEXTHOP_TYPE_IFINDEX) {
if (nexthop->ifindex != ifindex)
@@ -2468,6 +2472,9 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
continue;
if (re->instance != instance)
continue;
+ if (re->type == ZEBRA_ROUTE_KERNEL &&
+ re->metric != metric)
+ continue;
if (!RIB_SYSTEM_ROUTE(re)) {
same = re;
break;
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 5a62cc3e81..cd893b5670 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -1365,7 +1365,8 @@ static int zread_ipv4_delete(struct zserv *client, u_short length,
table_id = zvrf->table_id;
rib_delete(AFI_IP, api.safi, zvrf_id(zvrf), api.type, api.instance,
- api.flags, &p, NULL, nexthop_p, ifindex, table_id);
+ api.flags, &p, NULL, nexthop_p, ifindex, table_id,
+ api.metric);
client->v4_route_del_cnt++;
return 0;
}
@@ -1763,11 +1764,11 @@ static int zread_ipv6_delete(struct zserv *client, u_short length,
if (IN6_IS_ADDR_UNSPECIFIED(&nexthop))
rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type,
api.instance, api.flags, &p, src_pp, NULL, ifindex,
- client->rtm_table);
+ client->rtm_table, api.metric);
else
rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type,
api.instance, api.flags, &p, src_pp, pnexthop,
- ifindex, client->rtm_table);
+ ifindex, client->rtm_table, api.metric);
client->v6_route_del_cnt++;
return 0;