diff options
| -rw-r--r-- | bgpd/bgp_routemap.c | 24 | ||||
| -rw-r--r-- | bgpd/bgpd.c | 13 | ||||
| -rw-r--r-- | doc/Building_FRR_for_LEDE-OpenWRT.md | 96 | ||||
| -rw-r--r-- | doc/cli.md | 8 | ||||
| -rw-r--r-- | lib/command_graph.c | 2 | ||||
| -rw-r--r-- | lib/command_graph.h | 10 | ||||
| -rw-r--r-- | lib/command_lex.l | 4 | ||||
| -rw-r--r-- | lib/command_match.c | 55 | ||||
| -rw-r--r-- | lib/command_parse.y | 12 | ||||
| -rw-r--r-- | lib/command_py.c | 2 | ||||
| -rw-r--r-- | lib/grammar_sandbox.c | 2 | ||||
| -rw-r--r-- | lib/routemap.c | 18 | ||||
| -rw-r--r-- | ospfd/ospf_spf.c | 6 | ||||
| -rw-r--r-- | pimd/pim_nht.c | 20 | ||||
| -rw-r--r-- | pimd/pim_upstream.c | 7 | ||||
| -rw-r--r-- | python/clidef.py | 8 | ||||
| -rw-r--r-- | tests/lib/cli/test_cli.c | 2 | ||||
| -rw-r--r-- | tests/ospf6d/test_lsdb.c | 2 | ||||
| -rw-r--r-- | vtysh/vtysh.c | 7 | ||||
| -rw-r--r-- | zebra/connected.c | 6 | ||||
| -rw-r--r-- | zebra/kernel_socket.c | 8 | ||||
| -rw-r--r-- | zebra/redistribute.c | 2 | ||||
| -rw-r--r-- | zebra/rib.h | 5 | ||||
| -rw-r--r-- | zebra/rt_netlink.c | 26 | ||||
| -rw-r--r-- | zebra/zebra_rib.c | 9 | ||||
| -rw-r--r-- | zebra/zserv.c | 7 |
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; |
