From 996c93142d3abfab0f6d6c800474e22a8cfbdbc5 Mon Sep 17 00:00:00 2001 From: Lou Berger Date: Tue, 6 Mar 2018 14:02:52 -0500 Subject: *: conform with COMMUNITY.md formatting rules, via 'make indent' Signed-off-by: Lou Berger --- lib/log.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index 9fc19ff683..6330c53702 100644 --- a/lib/log.c +++ b/lib/log.c @@ -177,9 +177,8 @@ static void time_print(FILE *fp, struct timestamp_control *ctl) static void vzlog_file(struct zlog *zl, struct timestamp_control *tsctl, - const char *proto_str, int record_priority, - int priority, FILE *fp, const char *format, - va_list args) + const char *proto_str, int record_priority, int priority, + FILE *fp, const char *format, va_list args) { va_list ac; @@ -237,8 +236,8 @@ void vzlog(int priority, const char *format, va_list args) /* File output. */ if ((priority <= zl->maxlvl[ZLOG_DEST_FILE]) && zl->fp) - vzlog_file(zl, &tsctl, proto_str, zl->record_priority, - priority, zl->fp, format, args); + vzlog_file(zl, &tsctl, proto_str, zl->record_priority, priority, + zl->fp, format, args); /* fixed-config logging to stderr while we're stating up & haven't * daemonized / reached mainloop yet @@ -246,11 +245,11 @@ void vzlog(int priority, const char *format, va_list args) * note the "else" on stdout output -- we don't want to print the same * message to both stderr and stdout. */ if (zlog_startup_stderr && priority <= LOG_WARNING) - vzlog_file(zl, &tsctl, proto_str, 1, - priority, stderr, format, args); + vzlog_file(zl, &tsctl, proto_str, 1, priority, stderr, format, + args); else if (priority <= zl->maxlvl[ZLOG_DEST_STDOUT]) - vzlog_file(zl, &tsctl, proto_str, zl->record_priority, - priority, stdout, format, args); + vzlog_file(zl, &tsctl, proto_str, zl->record_priority, priority, + stdout, format, args); /* Terminal monitor. */ if (priority <= zl->maxlvl[ZLOG_DEST_MONITOR]) @@ -1114,10 +1113,9 @@ void zlog_hexdump(const void *mem, unsigned int len) printing */ s += sprintf(s, " "); - else if ( - isprint((int)((const char *)mem) - [j])) /* printable char - */ + else if (isprint((int)((const char *)mem) + [j])) /* printable char + */ s += sprintf( s, "%c", 0xFF & ((const char *)mem)[j]); -- cgit v1.2.3 From e16abbb303a4b2ce8d0959729a2c43dcf49ee44c Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 14 Feb 2018 19:52:01 -0500 Subject: lib, zebra: Add rule encoding Add some code to pass the rule we want installed into the kernel. Signed-off-by: Donald Sharp --- lib/log.c | 3 +++ lib/zclient.h | 3 +++ zebra/zserv.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index 6330c53702..9e33ef9102 100644 --- a/lib/log.c +++ b/lib/log.c @@ -961,6 +961,9 @@ static const struct zebra_desc_table command_types[] = { DESC_ENTRY(ZEBRA_PW_SET), DESC_ENTRY(ZEBRA_PW_UNSET), DESC_ENTRY(ZEBRA_PW_STATUS_UPDATE), + DESC_ENTRY(ZEBRA_RULE_ADD), + DESC_ENTRY(ZEBRA_RULE_DELETE), + DESC_ENTRY(ZEBRA_RULE_NOTIFY_OWNER), }; #undef DESC_ENTRY diff --git a/lib/zclient.h b/lib/zclient.h index 39566b1739..a315a7ed5a 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -129,6 +129,9 @@ typedef enum { ZEBRA_PW_SET, ZEBRA_PW_UNSET, ZEBRA_PW_STATUS_UPDATE, + ZEBRA_RULE_ADD, + ZEBRA_RULE_DELETE, + ZEBRA_RULE_NOTIFY_OWNER, } zebra_message_types_t; struct redist_proto { diff --git a/zebra/zserv.c b/zebra/zserv.c index 0485aadde1..13936e5366 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -60,6 +60,7 @@ #include "zebra/label_manager.h" #include "zebra/zebra_vxlan.h" #include "zebra/rt.h" +#include "zebra/zebra_pbr.h" /* Event list of zebra. */ enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE }; @@ -2587,6 +2588,62 @@ stream_failure: return; } +static inline void zread_rule(uint16_t command, struct zserv *client, + uint16_t length, struct zebra_vrf *zvrf) +{ + struct zebra_pbr_rule zpr; + struct interface *ifp; + struct stream *s; + uint32_t total, i; + uint32_t priority; + ifindex_t ifindex; + + s = client->ibuf; + STREAM_GETL(s, total); + + for (i = 0; i < total; i++) { + memset(&zpr, 0, sizeof(zpr)); + + STREAM_GETL(s, zpr.seq); + STREAM_GETL(s, priority); + STREAM_GETC(s, zpr.filter.src_ip.family); + STREAM_GETC(s, zpr.filter.src_ip.prefixlen); + STREAM_GET(&zpr.filter.src_ip.u.prefix, s, + prefix_blen(&zpr.filter.src_ip)); + STREAM_GETW(s, zpr.filter.src_port); + STREAM_GETC(s, zpr.filter.dst_ip.family); + STREAM_GETC(s, zpr.filter.dst_ip.prefixlen); + STREAM_GET(&zpr.filter.dst_ip.u.prefix, s, + prefix_blen(&zpr.filter.dst_ip)); + STREAM_GETW(s, zpr.filter.dst_port); + STREAM_GETL(s, zpr.action.table); + STREAM_GETL(s, ifindex); + + ifp = if_lookup_by_index(ifindex, VRF_UNKNOWN); + if (!ifp) { + zlog_debug("FAiled to lookup ifindex: %u", ifindex); + return; + } + + if (!is_default_prefix(&zpr.filter.src_ip)) + zpr.filter.filter_bm |= PBR_FILTER_SRC_IP; + + if (!is_default_prefix(&zpr.filter.dst_ip)) + zpr.filter.filter_bm |= PBR_FILTER_DST_IP; + + if (zpr.filter.src_port) + zpr.filter.filter_bm |= PBR_FILTER_SRC_PORT; + + if (zpr.filter.dst_port) + zpr.filter.filter_bm |= PBR_FILTER_DST_PORT; + + kernel_add_pbr_rule(&zpr, ifp, priority); + } + +stream_failure: + return; +} + static inline void zserv_handle_commands(struct zserv *client, uint16_t command, uint16_t length, struct zebra_vrf *zvrf) @@ -2731,6 +2788,10 @@ static inline void zserv_handle_commands(struct zserv *client, uint16_t command, case ZEBRA_PW_UNSET: zread_pseudowire(command, client, length, zvrf); break; + case ZEBRA_RULE_ADD: + case ZEBRA_RULE_DELETE: + zread_rule(command, client, length, zvrf); + break; default: zlog_info("Zebra received unknown command %d", command); break; -- cgit v1.2.3 From 51ade3a27f6d25ca97585d5d13780f2959d069de Mon Sep 17 00:00:00 2001 From: "G. Paul Ziemba" Date: Fri, 9 Mar 2018 10:44:56 -0500 Subject: lib: add BGP VPN route type Signed-off-by: G. Paul Ziemba --- lib/log.c | 4 ++++ lib/route_types.txt | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index 9e33ef9102..49335e119b 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1055,6 +1055,8 @@ int proto_redistnum(int afi, const char *s) return ZEBRA_ROUTE_BABEL; else if (strmatch(s, "sharp")) return ZEBRA_ROUTE_SHARP; + else if (strmatch(s, "vpn")) + return ZEBRA_ROUTE_BGP_VPN; } if (afi == AFI_IP6) { if (strmatch(s, "kernel")) @@ -1083,6 +1085,8 @@ int proto_redistnum(int afi, const char *s) return ZEBRA_ROUTE_BABEL; else if (strmatch(s, "sharp")) return ZEBRA_ROUTE_SHARP; + else if (strmatch(s, "vpn")) + return ZEBRA_ROUTE_BGP_VPN; } return -1; } diff --git a/lib/route_types.txt b/lib/route_types.txt index 4e764a14c1..98cada8f89 100644 --- a/lib/route_types.txt +++ b/lib/route_types.txt @@ -40,7 +40,7 @@ # Long description: Full description, but should try fit on a line. #### # -# If you add a new routing protocol here, make sure you go update +# If you add a new routing protocol here, make sure you also update # meta_queue_map in zebra_rib.c # ## type cname daemon C 4 6 short help @@ -76,6 +76,7 @@ ZEBRA_ROUTE_VNC_DIRECT_RH, vnc-rn, NULL, 'V', 0, 0, "VNC-RN" ZEBRA_ROUTE_BGP_DIRECT, bgp-direct, NULL, 'b', 0, 0, "BGP-Direct" # bgp unicast -> vnc ZEBRA_ROUTE_BGP_DIRECT_EXT, bgp-direct-to-nve-groups, NULL, 'e', 0, 0, "BGP2VNC" +ZEBRA_ROUTE_BGP_VPN, vpn, NULL, 'c', 1, 1, "VPN", bgpd ZEBRA_ROUTE_BABEL, babel, babeld, 'A', 1, 1, "Babel" ZEBRA_ROUTE_SHARP, sharp, sharpd, 'D', 1, 1, "SHARP" ZEBRA_ROUTE_ALL, wildcard, none, '-', 0, 0, "-" @@ -101,5 +102,6 @@ ZEBRA_ROUTE_OLSR, "Optimised Link State Routing (OLSR)" ZEBRA_ROUTE_TABLE, "Non-main Kernel Routing Table" ZEBRA_ROUTE_LDP, "Label Distribution Protocol (LDP)" ZEBRA_ROUTE_VNC_DIRECT, "VNC direct (not via zebra) routes" +ZEBRA_ROUTE_BGP_VPN, "BGP VPN routes" ZEBRA_ROUTE_BABEL, "Babel routing protocol (Babel)" ZEBRA_ROUTE_SHARP, "Super Happy Advanced Routing Protocol (sharpd)" -- cgit v1.2.3 From e049c5fcce862e994fc1b79baf8671c0aa25894e Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Mon, 12 Mar 2018 14:01:47 -0400 Subject: lib: fixup zlog_hexdump * Allocate correct amount of memory * Use snprintf() instead of sprintf() Signed-off-by: Quentin Young --- lib/log.c | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index 9e33ef9102..2d856cc777 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1092,41 +1092,50 @@ void zlog_hexdump(const void *mem, unsigned int len) unsigned long i = 0; unsigned int j = 0; unsigned int columns = 8; - char buf[(len * 4) + ((len / 4) * 20) + 30]; + /* 19 bytes for 0xADDRESS: */ + /* 24 bytes for data; 2 chars plus a space per data byte */ + /* 1 byte for space */ + /* 8 bytes for ASCII representation */ + /* 1 byte for a newline */ + /* ===================== */ + /* 53 bytes per 8 bytes of data */ + /* 1 byte for null term */ + size_t bs = ((len / 8) + 1) * 53 + 1; + char buf[bs]; char *s = buf; + memset(buf, 0, sizeof(buf)); + for (i = 0; i < len + ((len % columns) ? (columns - len % columns) : 0); i++) { /* print offset */ if (i % columns == 0) - s += sprintf(s, "0x%016lx: ", (unsigned long)mem + i); + s += snprintf(s, bs - (s - buf), + "0x%016lx: ", (unsigned long)mem + i); /* print hex data */ if (i < len) - s += sprintf(s, "%02x ", 0xFF & ((const char *)mem)[i]); + s += snprintf(s, bs - (s - buf), "%02x ", + 0xFF & ((const char *)mem)[i]); /* end of block, just aligning for ASCII dump */ else - s += sprintf(s, " "); + s += snprintf(s, bs - (s - buf), " "); /* print ASCII dump */ if (i % columns == (columns - 1)) { for (j = i - (columns - 1); j <= i; j++) { - if (j >= len) /* end of block, not really - printing */ - s += sprintf(s, " "); - - else if (isprint((int)((const char *)mem) - [j])) /* printable char - */ - s += sprintf( - s, "%c", + /* end of block not really printing */ + if (j >= len) + s += snprintf(s, bs - (s - buf), " "); + else if (isprint((int)((const char *)mem)[j])) + s += snprintf( + s, bs - (s - buf), "%c", 0xFF & ((const char *)mem)[j]); - else /* other char */ - s += sprintf(s, "."); + s += snprintf(s, bs - (s - buf), "."); } - s += sprintf(s, "\n"); + s += snprintf(s, bs - (s - buf), "\n"); } } zlog_debug("\n%s", buf); -- cgit v1.2.3 From abccc77544f973ad896d31f356ee6fc6df3e2614 Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Mon, 12 Mar 2018 14:04:56 -0400 Subject: tests: add unit test for zlog Just tests zlog_hexdump right now Signed-off-by: Quentin Young --- lib/log.c | 18 ++++++++------- tests/Makefile.am | 6 ++++- tests/lib/test_zlog.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++ tests/lib/test_zlog.py | 4 ++++ 4 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 tests/lib/test_zlog.c create mode 100644 tests/lib/test_zlog.py (limited to 'lib/log.c') diff --git a/lib/log.c b/lib/log.c index 2d856cc777..74e7be7c7d 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1092,14 +1092,16 @@ void zlog_hexdump(const void *mem, unsigned int len) unsigned long i = 0; unsigned int j = 0; unsigned int columns = 8; - /* 19 bytes for 0xADDRESS: */ - /* 24 bytes for data; 2 chars plus a space per data byte */ - /* 1 byte for space */ - /* 8 bytes for ASCII representation */ - /* 1 byte for a newline */ - /* ===================== */ - /* 53 bytes per 8 bytes of data */ - /* 1 byte for null term */ + /* + * 19 bytes for 0xADDRESS: + * 24 bytes for data; 2 chars plus a space per data byte + * 1 byte for space + * 8 bytes for ASCII representation + * 1 byte for a newline + * ===================== + * 53 bytes per 8 bytes of data + * 1 byte for null term + */ size_t bs = ((len / 8) + 1) * 53 + 1; char buf[bs]; char *s = buf; diff --git a/tests/Makefile.am b/tests/Makefile.am index f4ab2a126a..0c9a5684da 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -73,6 +73,7 @@ check_PROGRAMS = \ lib/test_timer_correctness \ lib/test_timer_performance \ lib/test_ttable \ + lib/test_zlog \ lib/cli/test_cli \ lib/cli/test_commands \ $(TESTS_BGPD) \ @@ -115,9 +116,9 @@ lib_test_heavy_SOURCES = lib/test_heavy.c helpers/c/main.c lib_test_memory_SOURCES = lib/test_memory.c lib_test_nexthop_iter_SOURCES = lib/test_nexthop_iter.c helpers/c/prng.c lib_test_privs_SOURCES = lib/test_privs.c +lib_test_ringbuf_SOURCES = lib/test_ringbuf.c lib_test_srcdest_table_SOURCES = lib/test_srcdest_table.c \ helpers/c/prng.c -lib_test_ringbuf_SOURCES = lib/test_ringbuf.c lib_test_segv_SOURCES = lib/test_segv.c lib_test_sig_SOURCES = lib/test_sig.c lib_test_stream_SOURCES = lib/test_stream.c @@ -127,6 +128,7 @@ lib_test_timer_correctness_SOURCES = lib/test_timer_correctness.c \ lib_test_timer_performance_SOURCES = lib/test_timer_performance.c \ helpers/c/prng.c lib_test_ttable_SOURCES = lib/test_ttable.c +lib_test_zlog_SOURCES = lib/test_zlog.c lib_test_zmq_SOURCES = lib/test_zmq.c lib_test_zmq_CFLAGS = $(AM_CFLAGS) $(ZEROMQ_CFLAGS) lib_cli_test_cli_SOURCES = lib/cli/test_cli.c lib/cli/common_cli.c @@ -167,6 +169,7 @@ lib_test_table_LDADD = $(ALL_TESTS_LDADD) -lm lib_test_timer_correctness_LDADD = $(ALL_TESTS_LDADD) lib_test_timer_performance_LDADD = $(ALL_TESTS_LDADD) lib_test_ttable_LDADD = $(ALL_TESTS_LDADD) +lib_test_zlog_LDADD = $(ALL_TESTS_LDADD) lib_test_zmq_LDADD = ../lib/libfrrzmq.la $(ALL_TESTS_LDADD) $(ZEROMQ_LIBS) lib_cli_test_cli_LDADD = $(ALL_TESTS_LDADD) lib_cli_test_commands_LDADD = $(ALL_TESTS_LDADD) @@ -207,6 +210,7 @@ EXTRA_DIST = \ lib/test_timer_correctness.py \ lib/test_ttable.py \ lib/test_ttable.refout \ + lib/test_zlog.py \ ospf6d/test_lsdb.py \ ospf6d/test_lsdb.in \ ospf6d/test_lsdb.refout \ diff --git a/tests/lib/test_zlog.c b/tests/lib/test_zlog.c new file mode 100644 index 0000000000..790e65cfe9 --- /dev/null +++ b/tests/lib/test_zlog.c @@ -0,0 +1,61 @@ +/* + * Zlog tests. + * Copyright (C) 2018 Cumulus Networks, Inc. + * Quentin Young + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include +#include +#include "log.h" + +/* maximum amount of data to hexdump */ +#define MAXDATA 16384 + +/* + * Test hexdump functionality. + * + * At the moment, not crashing is considered success. + */ +static bool test_zlog_hexdump(void) +{ + unsigned int nl = 1; + + do { + long d[nl]; + + for (unsigned int i = 0; i < nl; i++) + d[i] = random(); + zlog_hexdump(d, nl * sizeof(long)); + } while (++nl * sizeof(long) <= MAXDATA); + + return true; +} + +bool (*tests[])(void) = { + test_zlog_hexdump, +}; + +int main(int argc, char **argv) +{ + openzlog("testzlog", "NONE", 0, LOG_CONS | LOG_NDELAY | LOG_PID, + LOG_ERR); + zlog_set_file("test_zlog.log", LOG_DEBUG); + + for (unsigned int i = 0; i < array_size(tests); i++) + if (!tests[i]()) + return 1; + return 0; +} diff --git a/tests/lib/test_zlog.py b/tests/lib/test_zlog.py new file mode 100644 index 0000000000..2ca2585886 --- /dev/null +++ b/tests/lib/test_zlog.py @@ -0,0 +1,4 @@ +import frrtest + +class TestZlog(frrtest.TestMultiOut): + program = './test_zlog' -- cgit v1.2.3 From b9c7bc5ab0ee57f4052b625c0e76663f50c1249f Mon Sep 17 00:00:00 2001 From: "G. Paul Ziemba" Date: Fri, 16 Mar 2018 11:11:37 -0700 Subject: bgpd: new vpn-policy CLI PR #1739 added code to leak routes between (default VRF) VPN safi and unicast RIBs in any VRF. That set of changes included temporary CLI including vpn-policy blocks to specify RD/RT/label/&c. After considerable discussion, we arrived at a consensus CLI shown below. The code of this PR implements the vpn-specific parts of this syntax: router bgp [vrf ] address-family unicast rd (vpn|evpn) export (AS:NN | IP:nn) label (vpn|evpn) export (0..1048575) rt (vpn|evpn) (import|export|both) RTLIST... nexthop vpn (import|export) (A.B.C.D | X:X::X:X) route-map (vpn|evpn|vrf NAME) (import|export) MAP [no] import|export [vpn|evpn|evpn8] [no] import|export vrf NAME User documentation of the vpn-specific parts of the above syntax is in PR #1937 Signed-off-by: G. Paul Ziemba --- bgpd/bgp_mplsvpn.c | 62 ++--- bgpd/bgp_mplsvpn.h | 16 +- bgpd/bgp_vty.c | 725 +++++++++++++++++++++------------------------------- bgpd/bgp_vty.h | 3 +- bgpd/bgp_zebra.c | 29 --- bgpd/bgpd.c | 16 +- bgpd/bgpd.h | 3 +- lib/command.c | 8 - lib/command.h | 2 - lib/log.c | 4 - lib/route_types.txt | 2 - vtysh/vtysh.c | 39 +-- zebra/zebra_rib.c | 1 - 13 files changed, 327 insertions(+), 583 deletions(-) (limited to 'lib/log.c') diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index d87f78a783..4916e95106 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -28,8 +28,8 @@ #include "queue.h" #include "filter.h" #include "mpls.h" -#include "lib/json.h" -#include "lib/zclient.h" +#include "json.h" +#include "zclient.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_debug.h" @@ -824,7 +824,6 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */ struct prefix *p = &info_vpn->net->p; afi_t afi = family2afi(p->family); - struct bgp_redist *red; struct attr static_attr = {0}; struct attr *new_attr = NULL; struct bgp_node *bn; @@ -836,7 +835,7 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */ int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF); - if (!vpn_leak_from_vpn_active(bgp_vrf, afi, &debugmsg, &red)) { + if (!vpn_leak_from_vpn_active(bgp_vrf, afi, &debugmsg)) { if (debug) zlog_debug("%s: skipping: %s", __func__, debugmsg); return; @@ -893,28 +892,7 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */ /* * route map handling - * For now, we apply two route maps: the "redist" route map and the - * vpn-policy route map. Once we finalize CLI syntax, one of these - * route maps will probably go away. */ - if (red->rmap.map) { - struct bgp_info info; - route_map_result_t ret; - - memset(&info, 0, sizeof(info)); - info.peer = bgp_vrf->peer_self; - info.attr = &static_attr; - ret = route_map_apply(red->rmap.map, p, RMAP_BGP, &info); - if (RMAP_DENYMATCH == ret) { - bgp_attr_flush(&static_attr); /* free any added parts */ - if (debug) - zlog_debug( - "%s: vrf %s redist route map \"%s\" says DENY, skipping", - __func__, bgp_vrf->name, - red->rmap.name); - return; - } - } if (bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN]) { struct bgp_info info; route_map_result_t ret; @@ -994,7 +972,6 @@ void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */ safi_t safi = SAFI_UNICAST; struct bgp *bgp; struct listnode *mnode, *mnnode; - struct bgp_redist *red; struct bgp_node *bn; struct bgp_info *bi; const char *debugmsg; @@ -1007,7 +984,7 @@ void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn, /* from */ /* Loop over VRFs */ for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) { - if (!vpn_leak_from_vpn_active(bgp, afi, &debugmsg, &red)) { + if (!vpn_leak_from_vpn_active(bgp, afi, &debugmsg)) { if (debug) zlog_debug("%s: skipping: %s", __func__, debugmsg); @@ -1164,36 +1141,27 @@ static void vpn_policy_routemap_update(struct bgp *bgp, const char *rmap_name) __func__); } - /* - * vpn -> vrf leaking currently can have two route-maps: - * 1. the vpn-policy tovpn route-map - * 2. the (per-afi) redistribute vpn route-map - */ - char *mapname_vpn_policy = - bgp->vpn_policy[afi] - .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]; - struct bgp_redist *red = NULL; - - if (vpn_leak_from_vpn_active(bgp, afi, NULL, &red) - && ((mapname_vpn_policy - && !strcmp(rmap_name, mapname_vpn_policy)) - || (red && red->rmap.name - && !strcmp(red->rmap.name, rmap_name)))) { + char *mapname = bgp->vpn_policy[afi] + .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]; - if (debug) - zlog_debug( - "%s: rmap \"%s\" matches vrf-policy fromvpn" - " for as %d afi %s", + if (vpn_leak_from_vpn_active(bgp, afi, NULL) && + mapname && + !strcmp(rmap_name, mapname)) { + + if (debug) { + zlog_debug("%s: rmap \"%s\" matches vrf-policy fromvpn for as %d afi %s", __func__, rmap_name, bgp->as, afi2str(afi)); + } vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, afi, bgp_get_default(), bgp); - if (!rmap) + if (!rmap) { bgp->vpn_policy[afi] .rmap[BGP_VPN_POLICY_DIR_FROMVPN] = NULL; + } vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, afi, bgp_get_default(), bgp); diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h index d0ad8ac846..4d7a858bec 100644 --- a/bgpd/bgp_mplsvpn.h +++ b/bgpd/bgp_mplsvpn.h @@ -107,11 +107,8 @@ static inline int vpn_leak_to_vpn_active(struct bgp *bgp_vrf, afi_t afi, } static inline int vpn_leak_from_vpn_active(struct bgp *bgp_vrf, afi_t afi, - const char **pmsg, - struct bgp_redist **pred) + const char **pmsg) { - struct bgp_redist *red; - if (bgp_vrf->inst_type != BGP_INSTANCE_TYPE_VRF && bgp_vrf->inst_type != BGP_INSTANCE_TYPE_DEFAULT) { @@ -120,14 +117,11 @@ static inline int vpn_leak_from_vpn_active(struct bgp *bgp_vrf, afi_t afi, return 0; } - /* Hijack zebra redist bits for this route type */ - red = bgp_redist_lookup(bgp_vrf, afi, ZEBRA_ROUTE_BGP_VPN, 0); - if (red) { - if (pred) - *pred = red; - } else { + /* Is vrf configured to import from vpn? */ + if (!CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST], + BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT)) { if (pmsg) - *pmsg = "redist not set"; + *pmsg = "import not set"; return 0; } if (!bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN]) { diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 4a5633c94d..3aa8ceedaf 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -6112,74 +6112,63 @@ ALIAS_HIDDEN(no_neighbor_addpath_tx_bestpath_per_as, NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2 "Use addpath to advertise the bestpath per each neighboring AS\n") - -DEFUN_NOSH (vpn_policy_afi, - vpn_policy_afi_cmd, - "vpn-policy ", - "Enter vpn-policy command mode\n" - BGP_AFI_HELP_STR) +static int set_ecom_list(struct vty *vty, int argc, struct cmd_token **argv, + struct ecommunity **list) { - VTY_DECLVAR_CONTEXT(bgp, bgp); - if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF - && bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT) { + struct ecommunity *ecom = NULL; + struct ecommunity *ecomadd; - vty_out(vty, - "vpn-policy supported only in core or vrf instances.\n"); - return CMD_WARNING_CONFIG_FAILED; - } + for (; argc; --argc, ++argv) { - afi_t afi; - int idx = 0; + ecomadd = ecommunity_str2com(argv[0]->arg, + ECOMMUNITY_ROUTE_TARGET, 0); + if (!ecomadd) { + vty_out(vty, "Malformed community-list value\n"); + if (ecom) + ecommunity_free(&ecom); + return CMD_WARNING_CONFIG_FAILED; + } - if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) { - if (afi == AFI_IP) - vty->node = BGP_VPNPOLICY_IPV4_NODE; - else - vty->node = BGP_VPNPOLICY_IPV6_NODE; - return CMD_SUCCESS; + if (ecom) { + ecommunity_merge(ecom, ecomadd); + ecommunity_free(&ecomadd); + } else { + ecom = ecomadd; + } + } + + if (*list) { + ecommunity_free(&*list); } - return CMD_WARNING_CONFIG_FAILED; + *list = ecom; + + return CMD_SUCCESS; } -static int vpn_policy_afis(struct vty *vty, int *doafi) +static int vpn_policy_getafi(struct vty *vty, int *doafi) { switch (vty->node) { - case BGP_VPNPOLICY_IPV4_NODE: + case BGP_IPV4_NODE: doafi[AFI_IP] = 1; break; - case BGP_VPNPOLICY_IPV6_NODE: + case BGP_IPV6_NODE: doafi[AFI_IP6] = 1; break; default: vty_out(vty, - "%% context error: valid only in vpn-policy block\n"); - return CMD_WARNING_CONFIG_FAILED; - } - return CMD_SUCCESS; -} - -static int argv_find_and_parse_vpn_policy_dirs(struct vty *vty, - struct cmd_token **argv, - int argc, int *idx, int *dodir) -{ - if (argv_find(argv, argc, "fromvpn", idx)) { - dodir[BGP_VPN_POLICY_DIR_FROMVPN] = 1; - } else if (argv_find(argv, argc, "tovpn", idx)) { - dodir[BGP_VPN_POLICY_DIR_TOVPN] = 1; - } else if (argv_find(argv, argc, "both", idx)) { - dodir[BGP_VPN_POLICY_DIR_FROMVPN] = 1; - dodir[BGP_VPN_POLICY_DIR_TOVPN] = 1; - } else { - vty_out(vty, "%% direction parse error\n"); + "%% context error: valid only in address-family unicast block\n"); return CMD_WARNING_CONFIG_FAILED; } return CMD_SUCCESS; } -DEFUN (vpn_policy_rd, - vpn_policy_rd_cmd, - "rd ASN:NN_OR_IP-ADDRESS:NN", +DEFPY (af_rd_vpn_export, + af_rd_vpn_export_cmd, + "[no] rd vpn export ASN:NN_OR_IP-ADDRESS:NN$rd_str", + NO_STR "Specify route distinguisher\n" + "Between current address-family and vpn\n" + "For routes leaked from current address-family to vpn\n" "Route Distinguisher (: | :)\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); @@ -6187,14 +6176,21 @@ DEFUN (vpn_policy_rd, int ret; int doafi[AFI_MAX] = {0}; afi_t afi; + int idx = 0; + int yes = 1; - ret = str2prefix_rd(argv[1]->arg, &prd); - if (!ret) { - vty_out(vty, "%% Malformed rd\n"); - return CMD_WARNING_CONFIG_FAILED; + if (argv_find(argv, argc, "no", &idx)) + yes = 0; + + if (yes) { + ret = str2prefix_rd(rd_str, &prd); + if (!ret) { + vty_out(vty, "%% Malformed rd\n"); + return CMD_WARNING_CONFIG_FAILED; + } } - ret = vpn_policy_afis(vty, doafi); + ret = vpn_policy_getafi(vty, doafi); if (ret != CMD_SUCCESS) return ret; @@ -6208,9 +6204,14 @@ DEFUN (vpn_policy_rd, vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(), bgp); - bgp->vpn_policy[afi].tovpn_rd = prd; - SET_FLAG(bgp->vpn_policy[afi].flags, - BGP_VPN_POLICY_TOVPN_RD_SET); + if (yes) { + bgp->vpn_policy[afi].tovpn_rd = prd; + SET_FLAG(bgp->vpn_policy[afi].flags, + BGP_VPN_POLICY_TOVPN_RD_SET); + } else { + UNSET_FLAG(bgp->vpn_policy[afi].flags, + BGP_VPN_POLICY_TOVPN_RD_SET); + } /* post-change: re-export vpn routes */ vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, @@ -6220,57 +6221,38 @@ DEFUN (vpn_policy_rd, return CMD_SUCCESS; } -DEFUN (vpn_policy_no_rd, - vpn_policy_no_rd_cmd, - "no rd", +ALIAS (af_rd_vpn_export, + af_no_rd_vpn_export_cmd, + "no rd vpn export", NO_STR - "Specify route distinguisher\n") -{ - VTY_DECLVAR_CONTEXT(bgp, bgp); - int ret; - int doafi[AFI_MAX] = {0}; - afi_t afi; - - ret = vpn_policy_afis(vty, doafi); - if (ret != CMD_SUCCESS) - return ret; - - - for (afi = 0; afi < AFI_MAX; ++afi) { - if (!doafi[afi]) - continue; - - /* pre-change: un-export vpn routes (vpn->vrf routes unaffected) - */ - vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, - bgp_get_default(), bgp); - - UNSET_FLAG(bgp->vpn_policy[afi].flags, - BGP_VPN_POLICY_TOVPN_RD_SET); - - /* post-change: re-export vpn routes */ - vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, - bgp_get_default(), bgp); - } - - return CMD_SUCCESS; -} + "Specify route distinguisher\n" + "Between current address-family and vpn\n" + "For routes leaked from current address-family to vpn\n") -DEFUN (vpn_policy_label, - vpn_policy_label_cmd, - "label (0-1048575)", +DEFPY (af_label_vpn_export, + af_label_vpn_export_cmd, + "[no] label vpn export (0-1048575)$label_val", + NO_STR "label value for VRF\n" + "Between current address-family and vpn\n" + "For routes leaked from current address-family to vpn\n" "Label Value <0-1048575>\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); - mpls_label_t label; + mpls_label_t label = MPLS_LABEL_NONE; int doafi[AFI_MAX] = {0}; afi_t afi; int ret; + int idx = 0; + int yes = 1; + + if (argv_find(argv, argc, "no", &idx)) + yes = 0; - label = strtoul(argv[1]->arg, NULL, 10); + if (yes) + label = label_val; /* rely on parser to force unsigned */ - ret = vpn_policy_afis(vty, doafi); + ret = vpn_policy_getafi(vty, doafi); if (ret != CMD_SUCCESS) return ret; @@ -6278,7 +6260,8 @@ DEFUN (vpn_policy_label, if (!doafi[afi]) continue; - /* pre-change: un-export vpn routes (vpn->vrf routes unaffected) + /* + * pre-change: un-export vpn routes (vpn->vrf routes unaffected) */ vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(), bgp); @@ -6293,44 +6276,21 @@ DEFUN (vpn_policy_label, return CMD_SUCCESS; } -DEFUN (vpn_policy_no_label, - vpn_policy_no_label_cmd, - "no label", - "Negate a command or set its defaults\n" - "label value for VRF\n") -{ - VTY_DECLVAR_CONTEXT(bgp, bgp); - int doafi[AFI_MAX] = {0}; - afi_t afi; - int ret; - - ret = vpn_policy_afis(vty, doafi); - if (ret != CMD_SUCCESS) - return ret; - - for (afi = 0; afi < AFI_MAX; ++afi) { - if (!doafi[afi]) - continue; - - /* pre-change: un-export vpn routes (vpn->vrf routes unaffected) - */ - vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, - bgp_get_default(), bgp); - - bgp->vpn_policy[afi].tovpn_label = MPLS_LABEL_NONE; - - /* post-change: re-export vpn routes */ - vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, - bgp_get_default(), bgp); - } - - return CMD_SUCCESS; -} +ALIAS (af_label_vpn_export, + af_no_label_vpn_export_cmd, + "no label vpn export", + NO_STR + "label value for VRF\n" + "Between current address-family and vpn\n" + "For routes leaked from current address-family to vpn\n") -DEFPY (vpn_policy_nexthop, - vpn_policy_nexthop_cmd, - "nexthop $nexthop", +DEFPY (af_nexthop_vpn_export, + af_nexthop_vpn_export_cmd, + "[no] nexthop vpn export $nexthop_str", + NO_STR "Specify next hop to use for VRF advertised prefixes\n" + "Between current address-family and vpn\n" + "For routes leaked from current address-family to vpn\n" "IPv4 prefix\n" "IPv6 prefix\n") { @@ -6339,11 +6299,18 @@ DEFPY (vpn_policy_nexthop, afi_t afi; int ret; struct prefix p; + int idx = 0; + int yes = 1; - if (!sockunion2hostprefix(nexthop, &p)) - return CMD_WARNING_CONFIG_FAILED; + if (argv_find(argv, argc, "no", &idx)) + yes = 0; + + if (yes) { + if (!sockunion2hostprefix(nexthop_str, &p)) + return CMD_WARNING_CONFIG_FAILED; + } - ret = vpn_policy_afis(vty, doafi); + ret = vpn_policy_getafi(vty, doafi); if (ret != CMD_SUCCESS) return ret; @@ -6357,9 +6324,14 @@ DEFPY (vpn_policy_nexthop, vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(), bgp); - bgp->vpn_policy[afi].tovpn_nexthop = p; - SET_FLAG(bgp->vpn_policy[afi].flags, - BGP_VPN_POLICY_TOVPN_NEXTHOP_SET); + if (yes) { + bgp->vpn_policy[afi].tovpn_nexthop = p; + SET_FLAG(bgp->vpn_policy[afi].flags, + BGP_VPN_POLICY_TOVPN_NEXTHOP_SET); + } else { + UNSET_FLAG(bgp->vpn_policy[afi].flags, + BGP_VPN_POLICY_TOVPN_NEXTHOP_SET); + } /* post-change: re-export vpn routes */ vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, @@ -6369,81 +6341,40 @@ DEFPY (vpn_policy_nexthop, return CMD_SUCCESS; } -DEFUN (vpn_policy_no_nexthop, - vpn_policy_no_nexthop_cmd, - "no nexthop", +ALIAS (af_nexthop_vpn_export, + af_no_nexthop_vpn_export_cmd, + "no nexthop vpn export", NO_STR - "Specify next hop to use for VRF advertised prefixes\n") -{ - VTY_DECLVAR_CONTEXT(bgp, bgp); - int doafi[AFI_MAX] = {0}; - afi_t afi; - int ret; - - ret = vpn_policy_afis(vty, doafi); - if (ret != CMD_SUCCESS) - return ret; - - for (afi = 0; afi < AFI_MAX; ++afi) { - if (!doafi[afi]) - continue; - - /* pre-change: un-export vpn routes (vpn->vrf routes unaffected) - */ - vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, - bgp_get_default(), bgp); - - UNSET_FLAG(bgp->vpn_policy[afi].flags, - BGP_VPN_POLICY_TOVPN_NEXTHOP_SET); - - /* post-change: re-export vpn routes */ - vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, - bgp_get_default(), bgp); - } - - return CMD_SUCCESS; -} + "Specify next hop to use for VRF advertised prefixes\n" + "Between current address-family and vpn\n" + "For routes leaked from current address-family to vpn\n") -static int set_ecom_list(struct vty *vty, int argc, struct cmd_token **argv, - struct ecommunity **list) +static int vpn_policy_getdirs(struct vty *vty, const char *dstr, int *dodir) { - struct ecommunity *ecom = NULL; - struct ecommunity *ecomadd; - - for (; argc; --argc, ++argv) { - - ecomadd = ecommunity_str2com(argv[0]->arg, - ECOMMUNITY_ROUTE_TARGET, 0); - if (!ecomadd) { - vty_out(vty, "Malformed community-list value\n"); - if (ecom) - ecommunity_free(&ecom); - return CMD_WARNING_CONFIG_FAILED; - } - - if (ecom) { - ecommunity_merge(ecom, ecomadd); - ecommunity_free(&ecomadd); - } else { - ecom = ecomadd; - } - } - - if (*list) { - ecommunity_free(&*list); + if (!strcmp(dstr, "import")) { + dodir[BGP_VPN_POLICY_DIR_FROMVPN] = 1; + } else if (!strcmp(dstr, "export")) { + dodir[BGP_VPN_POLICY_DIR_TOVPN] = 1; + } else if (!strcmp(dstr, "both")) { + dodir[BGP_VPN_POLICY_DIR_FROMVPN] = 1; + dodir[BGP_VPN_POLICY_DIR_TOVPN] = 1; + } else { + vty_out(vty, "%% direction parse error\n"); + return CMD_WARNING_CONFIG_FAILED; } - *list = ecom; - return CMD_SUCCESS; } -DEFUN (vpn_policy_rt, - vpn_policy_rt_cmd, - "rt RTLIST...", +DEFPY (af_rt_vpn_imexport, + af_rt_vpn_imexport_cmd, + "[no] vpn $direction_str RTLIST...", + NO_STR + "Specify route target list\n" "Specify route target list\n" - "fromvpn: match any\n" - "tovpn: set\n" - "both fromvpn: match any and tovpn: set\n" + "Between current address-family and vpn\n" + "For routes leaked from vpn to current address-family: match any\n" + "For routes leaked from current address-family to vpn: set\n" + "both import: match any and export: set\n" "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); @@ -6454,18 +6385,28 @@ DEFUN (vpn_policy_rt, vpn_policy_direction_t dir; afi_t afi; int idx = 0; + int yes = 1; - ret = vpn_policy_afis(vty, doafi); + if (argv_find(argv, argc, "no", &idx)) + yes = 0; + + ret = vpn_policy_getafi(vty, doafi); if (ret != CMD_SUCCESS) return ret; - ret = argv_find_and_parse_vpn_policy_dirs(vty, argv, argc, &idx, dodir); + ret = vpn_policy_getdirs(vty, direction_str, dodir); if (ret != CMD_SUCCESS) return ret; - ret = set_ecom_list(vty, argc - 2, argv + 2, &ecom); - if (ret != CMD_SUCCESS) { - return ret; + if (yes) { + if (!argv_find(argv, argc, "RTLIST", &idx)) { + vty_out(vty, "%% Missing RTLIST\n"); + return CMD_WARNING_CONFIG_FAILED; + } + ret = set_ecom_list(vty, argc - idx, argv + idx, &ecom); + if (ret != CMD_SUCCESS) { + return ret; + } } for (afi = 0; afi < AFI_MAX; ++afi) { @@ -6477,10 +6418,18 @@ DEFUN (vpn_policy_rt, vpn_leak_prechange(dir, afi, bgp_get_default(), bgp); - if (bgp->vpn_policy[afi].rtlist[dir]) - ecommunity_free( - &bgp->vpn_policy[afi].rtlist[dir]); - bgp->vpn_policy[afi].rtlist[dir] = ecommunity_dup(ecom); + if (yes) { + if (bgp->vpn_policy[afi].rtlist[dir]) + ecommunity_free( + &bgp->vpn_policy[afi].rtlist[dir]); + bgp->vpn_policy[afi].rtlist[dir] = + ecommunity_dup(ecom); + } else { + if (bgp->vpn_policy[afi].rtlist[dir]) + ecommunity_free( + &bgp->vpn_policy[afi].rtlist[dir]); + bgp->vpn_policy[afi].rtlist[dir] = NULL; + } vpn_leak_postchange(dir, afi, bgp_get_default(), bgp); } @@ -6490,58 +6439,26 @@ DEFUN (vpn_policy_rt, return CMD_SUCCESS; } -DEFUN (vpn_policy_no_rt, - vpn_policy_no_rt_cmd, - "no rt ", +ALIAS (af_rt_vpn_imexport, + af_no_rt_vpn_imexport_cmd, + "no vpn $direction_str", NO_STR "Specify route target list\n" - "fromvpn: match any\n" - "tovpn: set\n" - "both fromvpn: match any and tovpn: set\n") -{ - VTY_DECLVAR_CONTEXT(bgp, bgp); - int ret; - int dodir[BGP_VPN_POLICY_DIR_MAX] = {0}; - int doafi[AFI_MAX] = {0}; - vpn_policy_direction_t dir; - afi_t afi; - int idx = 0; - - ret = vpn_policy_afis(vty, doafi); - if (ret != CMD_SUCCESS) - return ret; - - ret = argv_find_and_parse_vpn_policy_dirs(vty, argv, argc, &idx, dodir); - if (ret != CMD_SUCCESS) - return ret; - - for (afi = 0; afi < AFI_MAX; ++afi) { - if (!doafi[afi]) - continue; - for (dir = 0; dir < BGP_VPN_POLICY_DIR_MAX; ++dir) { - if (!dodir[dir]) - continue; - - vpn_leak_prechange(dir, afi, bgp_get_default(), bgp); - - if (bgp->vpn_policy[afi].rtlist[dir]) - ecommunity_free( - &bgp->vpn_policy[afi].rtlist[dir]); - bgp->vpn_policy[afi].rtlist[dir] = NULL; - - vpn_leak_postchange(dir, afi, bgp_get_default(), bgp); - } - } - - return CMD_SUCCESS; -} - -DEFUN (vpn_policy_route_map, - vpn_policy_route_map_cmd, - "route-map WORD", + "Specify route target list\n" + "Between current address-family and vpn\n" + "For routes leaked from vpn to current address-family\n" + "For routes leaked from current address-family to vpn\n" + "both import and export\n") + +DEFPY (af_route_map_vpn_imexport, + af_route_map_vpn_imexport_cmd, +/* future: "route-map RMAP" */ + "[no] route-map vpn $direction_str RMAP$rmap_str", + NO_STR "Specify route map\n" - "fromvpn: core vpn -> this vrf\n" - "tovpn: this vrf -> core vpn\n" + "Between current address-family and vpn\n" + "For routes leaked from vpn to current address-family\n" + "For routes leaked from current address-family to vpn\n" "name of route-map\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); @@ -6550,14 +6467,17 @@ DEFUN (vpn_policy_route_map, int doafi[AFI_MAX] = {0}; vpn_policy_direction_t dir; afi_t afi; - int map_name_arg = 2; int idx = 0; + int yes = 1; - ret = vpn_policy_afis(vty, doafi); + if (argv_find(argv, argc, "no", &idx)) + yes = 0; + + ret = vpn_policy_getafi(vty, doafi); if (ret != CMD_SUCCESS) return ret; - ret = argv_find_and_parse_vpn_policy_dirs(vty, argv, argc, &idx, dodir); + ret = vpn_policy_getdirs(vty, direction_str, dodir); if (ret != CMD_SUCCESS) return ret; @@ -6570,14 +6490,21 @@ DEFUN (vpn_policy_route_map, vpn_leak_prechange(dir, afi, bgp_get_default(), bgp); - if (bgp->vpn_policy[afi].rmap_name[dir]) - XFREE(MTYPE_ROUTE_MAP_NAME, - bgp->vpn_policy[afi].rmap_name[dir]); - bgp->vpn_policy[afi].rmap_name[dir] = XSTRDUP( - MTYPE_ROUTE_MAP_NAME, argv[map_name_arg]->arg); - bgp->vpn_policy[afi].rmap[dir] = - route_map_lookup_by_name( - argv[map_name_arg]->arg); + if (yes) { + if (bgp->vpn_policy[afi].rmap_name[dir]) + XFREE(MTYPE_ROUTE_MAP_NAME, + bgp->vpn_policy[afi].rmap_name[dir]); + bgp->vpn_policy[afi].rmap_name[dir] = XSTRDUP( + MTYPE_ROUTE_MAP_NAME, rmap_str); + bgp->vpn_policy[afi].rmap[dir] = + route_map_lookup_by_name(rmap_str); + } else { + if (bgp->vpn_policy[afi].rmap_name[dir]) + XFREE(MTYPE_ROUTE_MAP_NAME, + bgp->vpn_policy[afi].rmap_name[dir]); + bgp->vpn_policy[afi].rmap_name[dir] = NULL; + bgp->vpn_policy[afi].rmap[dir] = NULL; + } vpn_leak_postchange(dir, afi, bgp_get_default(), bgp); } @@ -6586,47 +6513,73 @@ DEFUN (vpn_policy_route_map, return CMD_SUCCESS; } -DEFUN (vpn_policy_no_route_map, - vpn_policy_no_route_map_cmd, - "no route-map ", +ALIAS (af_route_map_vpn_imexport, + af_no_route_map_vpn_imexport_cmd, + "no route-map vpn $direction_str", NO_STR "Specify route map\n" - "fromvpn: core vpn -> this vrf\n" - "tovpn: this vrf -> core vpn\n") + "Between current address-family and vpn\n" + "For routes leaked from vpn to current address-family\n" + "For routes leaked from current address-family to vpn\n") + +/* This command is valid only in a bgp vrf instance or the default instance */ +DEFPY (bgp_imexport_vpn, + bgp_imexport_vpn_cmd, + "[no] $direction_str vpn", + "Export routes to another routing protocol\n" + "to VPN RIB per vpn-policy") { VTY_DECLVAR_CONTEXT(bgp, bgp); - int ret; - int dodir[BGP_VPN_POLICY_DIR_MAX] = {0}; - int doafi[AFI_MAX] = {0}; - vpn_policy_direction_t dir; + int previous_state; afi_t afi; + safi_t safi; int idx = 0; + int yes = 1; + int flag; + vpn_policy_direction_t dir; - ret = vpn_policy_afis(vty, doafi); - if (ret != CMD_SUCCESS) - return ret; + if (argv_find(argv, argc, "no", &idx)) + yes = 0; - ret = argv_find_and_parse_vpn_policy_dirs(vty, argv, argc, &idx, dodir); - if (ret != CMD_SUCCESS) - return ret; + if (BGP_INSTANCE_TYPE_VRF != bgp->inst_type && + BGP_INSTANCE_TYPE_DEFAULT != bgp->inst_type) { - for (afi = 0; afi < AFI_MAX; ++afi) { - if (!doafi[afi]) - continue; - for (dir = 0; dir < BGP_VPN_POLICY_DIR_MAX; ++dir) { - if (!dodir[dir]) - continue; + vty_out(vty, "%% import|export vpn valid only for bgp vrf or default instance\n"); + return CMD_WARNING_CONFIG_FAILED; + } - vpn_leak_prechange(dir, afi, bgp_get_default(), bgp); + afi = bgp_node_afi(vty); + safi = bgp_node_safi(vty); + if ((SAFI_UNICAST != safi) || ((AFI_IP != afi) && (AFI_IP6 != afi))) { + vty_out(vty, "%% import|export vpn valid only for unicast ipv4|ipv6\n"); + return CMD_WARNING_CONFIG_FAILED; + } - if (bgp->vpn_policy[afi].rmap_name[dir]) - XFREE(MTYPE_ROUTE_MAP_NAME, - bgp->vpn_policy[afi].rmap_name[dir]); - bgp->vpn_policy[afi].rmap_name[dir] = NULL; - bgp->vpn_policy[afi].rmap[dir] = NULL; + if (!strcmp(direction_str, "import")) { + flag = BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT; + dir = BGP_VPN_POLICY_DIR_FROMVPN; + } else if (!strcmp(direction_str, "export")) { + flag = BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT; + dir = BGP_VPN_POLICY_DIR_TOVPN; + } else { + vty_out(vty, "%% unknown direction %s\n", direction_str); + return CMD_WARNING_CONFIG_FAILED; + } + + previous_state = CHECK_FLAG(bgp->af_flags[afi][safi], flag); + if (yes) { + SET_FLAG(bgp->af_flags[afi][safi], flag); + if (!previous_state) { + /* trigger export current vrf */ vpn_leak_postchange(dir, afi, bgp_get_default(), bgp); } + } else { + if (previous_state) { + /* trigger un-export current vrf */ + vpn_leak_prechange(dir, afi, bgp_get_default(), bgp); + } + UNSET_FLAG(bgp->af_flags[afi][safi], flag); } return CMD_SUCCESS; @@ -11659,99 +11612,20 @@ void bgp_config_write_redistribute(struct vty *vty, struct bgp *bgp, afi_t afi, } } -/* This command is valid only in a bgp vrf instance or the default instance */ -DEFUN (bgp_export_vpn, - bgp_export_vpn_cmd, - "export vpn", - "Export routes to another routing protocol\n" - "to VPN RIB per vpn-policy") -{ - VTY_DECLVAR_CONTEXT(bgp, bgp); - int was_off = 0; - afi_t afi; - safi_t safi; - - if (BGP_INSTANCE_TYPE_VRF != bgp->inst_type - && BGP_INSTANCE_TYPE_DEFAULT != bgp->inst_type) { - vty_out(vty, - "%% export vpn valid only for bgp vrf or default instance\n"); - return CMD_WARNING_CONFIG_FAILED; - } - afi = bgp_node_afi(vty); - safi = bgp_node_safi(vty); - if ((SAFI_UNICAST != safi) || ((AFI_IP != afi) && (AFI_IP6 != afi))) { - vty_out(vty, - "%% export vpn valid only for unicast ipv4|ipv6\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (!CHECK_FLAG(bgp->af_flags[afi][safi], - BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT)) { - was_off = 1; - } - SET_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT); - if (was_off) { - /* trigger export current vrf */ - zlog_debug("%s: calling postchange", __func__); - vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, - bgp_get_default(), bgp); - } - return CMD_SUCCESS; -} - -DEFUN (bgp_no_export_vpn, - bgp_no_export_vpn_cmd, - "no export vpn", - NO_STR - "Export routes to another routing protocol\n" - "to VPN RIB per vpn-policy") -{ - VTY_DECLVAR_CONTEXT(bgp, bgp); - int was_on = 0; - afi_t afi; - safi_t safi; - - if (BGP_INSTANCE_TYPE_VRF != bgp->inst_type - && BGP_INSTANCE_TYPE_DEFAULT != bgp->inst_type) { - vty_out(vty, - "%% export vpn valid only for bgp vrf or default instance\n"); - return CMD_WARNING_CONFIG_FAILED; - } - afi = bgp_node_afi(vty); - safi = bgp_node_safi(vty); - if ((SAFI_UNICAST != safi) || ((AFI_IP != afi) && (AFI_IP6 != afi))) { - vty_out(vty, - "%% export vpn valid only for unicast ipv4|ipv6\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (CHECK_FLAG(bgp->af_flags[afi][safi], - BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT)) { - was_on = 1; - } - if (was_on) { - /* trigger un-export current vrf */ - zlog_debug("%s: calling postchange", __func__); - vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, - bgp_get_default(), bgp); - } - UNSET_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT); - return CMD_SUCCESS; -} - -static void bgp_vpn_policy_config_write_afi(struct vty *vty, struct bgp *bgp, +/* This is part of the address-family block (unicast only) */ +void bgp_vpn_policy_config_write_afi(struct vty *vty, struct bgp *bgp, afi_t afi) { - vty_frame(vty, " vpn-policy ipv%d\n", ((afi == AFI_IP) ? 4 : 6)); + int indent = 2; if (bgp->vpn_policy[afi].tovpn_label != MPLS_LABEL_NONE) { - vty_out(vty, " label %u\n", + vty_out(vty, "%*slabel vpn export %u\n", indent, "", bgp->vpn_policy[afi].tovpn_label); } if (CHECK_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_RD_SET)) { char buf[RD_ADDRSTRLEN]; - vty_out(vty, " rd %s\n", + vty_out(vty, "%*srd vpn export %s\n", indent, "", prefix_rd2str(&bgp->vpn_policy[afi].tovpn_rd, buf, sizeof(buf))); } @@ -11763,7 +11637,8 @@ static void bgp_vpn_policy_config_write_afi(struct vty *vty, struct bgp *bgp, &bgp->vpn_policy[afi].tovpn_nexthop.u.prefix, buf, sizeof(buf))) { - vty_out(vty, " nexthop %s\n", buf); + vty_out(vty, "%*snexthop vpn export %s\n", + indent, "", buf); } } if (bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN] @@ -11775,7 +11650,7 @@ static void bgp_vpn_policy_config_write_afi(struct vty *vty, struct bgp *bgp, char *b = ecommunity_ecom2str( bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_TOVPN], ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET); - vty_out(vty, " rt both %s\n", b); + vty_out(vty, "%*srt vpn both %s\n", indent, "", b); XFREE(MTYPE_ECOMMUNITY_STR, b); } else { if (bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN]) { @@ -11784,7 +11659,7 @@ static void bgp_vpn_policy_config_write_afi(struct vty *vty, struct bgp *bgp, .rtlist[BGP_VPN_POLICY_DIR_FROMVPN], ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET); - vty_out(vty, " rt fromvpn %s\n", b); + vty_out(vty, "%*srt vpn import %s\n", indent, "", b); XFREE(MTYPE_ECOMMUNITY_STR, b); } if (bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_TOVPN]) { @@ -11793,28 +11668,21 @@ static void bgp_vpn_policy_config_write_afi(struct vty *vty, struct bgp *bgp, .rtlist[BGP_VPN_POLICY_DIR_TOVPN], ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET); - vty_out(vty, " rt tovpn %s\n", b); + vty_out(vty, "%*srt vpn export %s\n", indent, "", b); XFREE(MTYPE_ECOMMUNITY_STR, b); } } if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]) { - vty_out(vty, " route-map fromvpn %s\n", + vty_out(vty, "%*sroute-map vpn import %s\n", indent, "", bgp->vpn_policy[afi] .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]); } if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN]) { - vty_out(vty, " route-map tovpn %s\n", + vty_out(vty, "%*sroute-map vpn export %s\n", indent, "", bgp->vpn_policy[afi] .rmap_name[BGP_VPN_POLICY_DIR_TOVPN]); } - vty_endframe(vty, " exit\n"); -} - -void bgp_vpn_policy_config_write(struct vty *vty, struct bgp *bgp) -{ - bgp_vpn_policy_config_write_afi(vty, bgp, AFI_IP); - bgp_vpn_policy_config_write_afi(vty, bgp, AFI_IP6); } @@ -11859,12 +11727,6 @@ static struct cmd_node bgp_evpn_node = {BGP_EVPN_NODE, static struct cmd_node bgp_evpn_vni_node = {BGP_EVPN_VNI_NODE, "%s(config-router-af-vni)# ", 1}; -static struct cmd_node bgp_vpn_policy_ipv4_node = { - BGP_VPNPOLICY_IPV4_NODE, "%s(config-router-vpn-policy-ipv4)# ", 1}; - -static struct cmd_node bgp_vpn_policy_ipv6_node = { - BGP_VPNPOLICY_IPV6_NODE, "%s(config-router-vpn-policy-ipv6)# ", 1}; - static void community_list_vty(void); static void bgp_ac_neighbor(vector comps, struct cmd_token *token) @@ -11925,8 +11787,6 @@ void bgp_vty_init(void) install_node(&bgp_vpnv6_node, NULL); install_node(&bgp_evpn_node, NULL); install_node(&bgp_evpn_vni_node, NULL); - install_node(&bgp_vpn_policy_ipv4_node, NULL); - install_node(&bgp_vpn_policy_ipv6_node, NULL); /* Install default VTY commands to new nodes. */ install_default(BGP_NODE); @@ -11940,8 +11800,6 @@ void bgp_vty_init(void) install_default(BGP_VPNV6_NODE); install_default(BGP_EVPN_NODE); install_default(BGP_EVPN_VNI_NODE); - install_default(BGP_VPNPOLICY_IPV4_NODE); - install_default(BGP_VPNPOLICY_IPV6_NODE); /* "bgp multiple-instance" commands. */ install_element(CONFIG_NODE, &bgp_multiple_instance_cmd); @@ -13001,11 +12859,9 @@ void bgp_vty_init(void) install_element(BGP_IPV6_NODE, &bgp_redistribute_ipv6_rmap_metric_cmd); install_element(BGP_IPV6_NODE, &bgp_redistribute_ipv6_metric_rmap_cmd); - /* export vpn [route-map WORD] */ - install_element(BGP_IPV4_NODE, &bgp_export_vpn_cmd); - install_element(BGP_IPV6_NODE, &bgp_export_vpn_cmd); - install_element(BGP_IPV4_NODE, &bgp_no_export_vpn_cmd); - install_element(BGP_IPV6_NODE, &bgp_no_export_vpn_cmd); + /* import|export vpn [route-map WORD] */ + install_element(BGP_IPV4_NODE, &bgp_imexport_vpn_cmd); + install_element(BGP_IPV6_NODE, &bgp_imexport_vpn_cmd); /* ttl_security commands */ install_element(BGP_NODE, &neighbor_ttl_security_cmd); @@ -13027,28 +12883,27 @@ void bgp_vty_init(void) community_list_vty(); /* vpn-policy commands */ - install_element(BGP_NODE, &vpn_policy_afi_cmd); - install_element(BGP_VPNPOLICY_IPV4_NODE, &vpn_policy_rd_cmd); - install_element(BGP_VPNPOLICY_IPV6_NODE, &vpn_policy_rd_cmd); - install_element(BGP_VPNPOLICY_IPV4_NODE, &vpn_policy_label_cmd); - install_element(BGP_VPNPOLICY_IPV6_NODE, &vpn_policy_label_cmd); - install_element(BGP_VPNPOLICY_IPV4_NODE, &vpn_policy_nexthop_cmd); - install_element(BGP_VPNPOLICY_IPV6_NODE, &vpn_policy_nexthop_cmd); - install_element(BGP_VPNPOLICY_IPV4_NODE, &vpn_policy_rt_cmd); - install_element(BGP_VPNPOLICY_IPV6_NODE, &vpn_policy_rt_cmd); - install_element(BGP_VPNPOLICY_IPV4_NODE, &vpn_policy_route_map_cmd); - install_element(BGP_VPNPOLICY_IPV6_NODE, &vpn_policy_route_map_cmd); - - install_element(BGP_VPNPOLICY_IPV4_NODE, &vpn_policy_no_rd_cmd); - install_element(BGP_VPNPOLICY_IPV6_NODE, &vpn_policy_no_rd_cmd); - install_element(BGP_VPNPOLICY_IPV4_NODE, &vpn_policy_no_label_cmd); - install_element(BGP_VPNPOLICY_IPV6_NODE, &vpn_policy_no_label_cmd); - install_element(BGP_VPNPOLICY_IPV4_NODE, &vpn_policy_no_nexthop_cmd); - install_element(BGP_VPNPOLICY_IPV6_NODE, &vpn_policy_no_nexthop_cmd); - install_element(BGP_VPNPOLICY_IPV4_NODE, &vpn_policy_no_rt_cmd); - install_element(BGP_VPNPOLICY_IPV6_NODE, &vpn_policy_no_rt_cmd); - install_element(BGP_VPNPOLICY_IPV4_NODE, &vpn_policy_no_route_map_cmd); - install_element(BGP_VPNPOLICY_IPV6_NODE, &vpn_policy_no_route_map_cmd); + install_element(BGP_IPV4_NODE, &af_rd_vpn_export_cmd); + install_element(BGP_IPV6_NODE, &af_rd_vpn_export_cmd); + install_element(BGP_IPV4_NODE, &af_label_vpn_export_cmd); + install_element(BGP_IPV6_NODE, &af_label_vpn_export_cmd); + install_element(BGP_IPV4_NODE, &af_nexthop_vpn_export_cmd); + install_element(BGP_IPV6_NODE, &af_nexthop_vpn_export_cmd); + install_element(BGP_IPV4_NODE, &af_rt_vpn_imexport_cmd); + install_element(BGP_IPV6_NODE, &af_rt_vpn_imexport_cmd); + install_element(BGP_IPV4_NODE, &af_route_map_vpn_imexport_cmd); + install_element(BGP_IPV6_NODE, &af_route_map_vpn_imexport_cmd); + + install_element(BGP_IPV4_NODE, &af_no_rd_vpn_export_cmd); + install_element(BGP_IPV6_NODE, &af_no_rd_vpn_export_cmd); + install_element(BGP_IPV4_NODE, &af_no_label_vpn_export_cmd); + install_element(BGP_IPV6_NODE, &af_no_label_vpn_export_cmd); + install_element(BGP_IPV4_NODE, &af_no_nexthop_vpn_export_cmd); + install_element(BGP_IPV6_NODE, &af_no_nexthop_vpn_export_cmd); + install_element(BGP_IPV4_NODE, &af_no_rt_vpn_imexport_cmd); + install_element(BGP_IPV6_NODE, &af_no_rt_vpn_imexport_cmd); + install_element(BGP_IPV4_NODE, &af_no_route_map_vpn_imexport_cmd); + install_element(BGP_IPV6_NODE, &af_no_route_map_vpn_imexport_cmd); } #include "memory.h" diff --git a/bgpd/bgp_vty.h b/bgpd/bgp_vty.h index 459c4ffcc3..f77ebb610e 100644 --- a/bgpd/bgp_vty.h +++ b/bgpd/bgp_vty.h @@ -71,5 +71,6 @@ extern int bgp_vty_find_and_parse_afi_safi_bgp(struct vty *vty, safi_t *safi, struct bgp **bgp); extern int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi, safi_t safi, u_char use_json); -extern void bgp_vpn_policy_config_write(struct vty *vty, struct bgp *bgp); +extern void bgp_vpn_policy_config_write_afi(struct vty *vty, struct bgp *bgp, + afi_t afi); #endif /* _QUAGGA_BGP_VTY_H */ diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 22284fd28d..97b4c916d7 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1451,27 +1451,7 @@ int bgp_redistribute_set(struct bgp *bgp, afi_t afi, int type, u_short instance) } #endif - /* vpn -> vrf (happens within bgp but we hijack redist bits */ - if ((bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT - || bgp->inst_type == BGP_INSTANCE_TYPE_VRF) - && type == ZEBRA_ROUTE_BGP_VPN) { - - /* leak update all */ - vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, afi, - bgp_get_default(), bgp); - } - vrf_bitmap_set(zclient->redist[afi][type], bgp->vrf_id); - - /* vpn -> vrf (happens within bgp but we hijack redist bits */ - if ((bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT - || bgp->inst_type == BGP_INSTANCE_TYPE_VRF) - && type == ZEBRA_ROUTE_BGP_VPN) { - - /* leak update all */ - vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, afi, - bgp_get_default(), bgp); - } } /* @@ -1625,15 +1605,6 @@ int bgp_redistribute_unset(struct bgp *bgp, afi_t afi, int type, vnc_export_bgp_disable(bgp, afi); } #endif - /* vpn -> vrf (happend within bgp but we hijack redist bits */ - if ((bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT - || bgp->inst_type == BGP_INSTANCE_TYPE_VRF) - && type == ZEBRA_ROUTE_BGP_VPN) { - - /* leak withdraw all */ - vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, afi, - bgp_get_default(), bgp); - } red = bgp_redist_lookup(bgp, afi, type, instance); if (!red) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 2eae2e5e9e..c178727b54 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -7132,10 +7132,18 @@ static void bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi, if (safi == SAFI_EVPN) bgp_config_write_evpn_info(vty, bgp, afi, safi); - if (CHECK_FLAG(bgp->af_flags[afi][safi], - BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT)) { + if (safi == SAFI_UNICAST) { + bgp_vpn_policy_config_write_afi(vty, bgp, afi); + if (CHECK_FLAG(bgp->af_flags[afi][safi], + BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT)) { - vty_out(vty, " export vpn\n"); + vty_out(vty, " export vpn\n"); + } + if (CHECK_FLAG(bgp->af_flags[afi][safi], + BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT)) { + + vty_out(vty, " import vpn\n"); + } } vty_endframe(vty, " exit-address-family\n"); @@ -7404,8 +7412,6 @@ int bgp_config_write(struct vty *vty) if (bgp_option_check(BGP_OPT_CONFIG_CISCO)) vty_out(vty, " no auto-summary\n"); - bgp_vpn_policy_config_write(vty, bgp); - /* IPv4 unicast configuration. */ bgp_config_write_family(vty, bgp, AFI_IP, SAFI_UNICAST); diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 664f8c9da4..79fe8c8c3b 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -318,6 +318,7 @@ struct bgp { u_int16_t af_flags[AFI_MAX][SAFI_MAX]; #define BGP_CONFIG_DAMPENING (1 << 0) #define BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT (1 << 1) +#define BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT (1 << 2) /* l2vpn evpn flags - 1 << 0 is used for DAMPENNG */ #define BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST (1 << 1) @@ -471,7 +472,7 @@ struct bgp { uint32_t tovpn_label; /* may be MPLS_LABEL_NONE */ uint32_t tovpn_zebra_vrf_label_last_sent; struct prefix_rd tovpn_rd; - struct prefix tovpn_nexthop; /* unset => set to router id */ + struct prefix tovpn_nexthop; /* unset => set to 0 */ uint32_t flags; #define BGP_VPN_POLICY_TOVPN_RD_SET 0x00000004 #define BGP_VPN_POLICY_TOVPN_NEXTHOP_SET 0x00000008 diff --git a/lib/command.c b/lib/command.c index b289cdd7a3..5697c1d812 100644 --- a/lib/command.c +++ b/lib/command.c @@ -87,8 +87,6 @@ const char *node_names[] = { "bgp vnc l2", // BGP_VNC_L2_GROUP_NODE, "rfp defaults", // RFP_DEFAULTS_NODE, "bgp evpn", // BGP_EVPN_NODE, - "bgp vpn policy ipv4", // BGP_VPNPOLICY_IPV4_NODE - "bgp vpn policy ipv6", // BGP_VPNPOLICY_IPV6_NODE "ospf", // OSPF_NODE, "ospf6", // OSPF6_NODE, "ldp", // LDP_NODE, @@ -951,8 +949,6 @@ enum node_type node_parent(enum node_type node) case BGP_VPNV4_NODE: case BGP_VPNV6_NODE: case BGP_VRF_POLICY_NODE: - case BGP_VPNPOLICY_IPV4_NODE: - case BGP_VPNPOLICY_IPV6_NODE: case BGP_VNC_DEFAULTS_NODE: case BGP_VNC_NVE_GROUP_NODE: case BGP_VNC_L2_GROUP_NODE: @@ -1323,8 +1319,6 @@ void cmd_exit(struct vty *vty) case BGP_VPNV4_NODE: case BGP_VPNV6_NODE: case BGP_VRF_POLICY_NODE: - case BGP_VPNPOLICY_IPV4_NODE: - case BGP_VPNPOLICY_IPV6_NODE: case BGP_VNC_DEFAULTS_NODE: case BGP_VNC_NVE_GROUP_NODE: case BGP_VNC_L2_GROUP_NODE: @@ -1395,8 +1389,6 @@ DEFUN (config_end, case BABEL_NODE: case BGP_NODE: case BGP_VRF_POLICY_NODE: - case BGP_VPNPOLICY_IPV4_NODE: - case BGP_VPNPOLICY_IPV6_NODE: case BGP_VNC_DEFAULTS_NODE: case BGP_VNC_NVE_GROUP_NODE: case BGP_VNC_L2_GROUP_NODE: diff --git a/lib/command.h b/lib/command.h index 1e700aaa8f..95d8ee99df 100644 --- a/lib/command.h +++ b/lib/command.h @@ -110,8 +110,6 @@ enum node_type { BGP_VNC_L2_GROUP_NODE, /* BGP VNC L2 group */ RFP_DEFAULTS_NODE, /* RFP defaults node */ BGP_EVPN_NODE, /* BGP EVPN node. */ - BGP_VPNPOLICY_IPV4_NODE, /* BGP VPN IPv6 policy */ - BGP_VPNPOLICY_IPV6_NODE, /* BGP VPN IPv6 policy */ OSPF_NODE, /* OSPF protocol mode */ OSPF6_NODE, /* OSPF protocol for IPv6 mode */ LDP_NODE, /* LDP protocol mode */ diff --git a/lib/log.c b/lib/log.c index a8e7462baa..74e7be7c7d 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1055,8 +1055,6 @@ int proto_redistnum(int afi, const char *s) return ZEBRA_ROUTE_BABEL; else if (strmatch(s, "sharp")) return ZEBRA_ROUTE_SHARP; - else if (strmatch(s, "vpn")) - return ZEBRA_ROUTE_BGP_VPN; } if (afi == AFI_IP6) { if (strmatch(s, "kernel")) @@ -1085,8 +1083,6 @@ int proto_redistnum(int afi, const char *s) return ZEBRA_ROUTE_BABEL; else if (strmatch(s, "sharp")) return ZEBRA_ROUTE_SHARP; - else if (strmatch(s, "vpn")) - return ZEBRA_ROUTE_BGP_VPN; } return -1; } diff --git a/lib/route_types.txt b/lib/route_types.txt index 98cada8f89..310a993c38 100644 --- a/lib/route_types.txt +++ b/lib/route_types.txt @@ -76,7 +76,6 @@ ZEBRA_ROUTE_VNC_DIRECT_RH, vnc-rn, NULL, 'V', 0, 0, "VNC-RN" ZEBRA_ROUTE_BGP_DIRECT, bgp-direct, NULL, 'b', 0, 0, "BGP-Direct" # bgp unicast -> vnc ZEBRA_ROUTE_BGP_DIRECT_EXT, bgp-direct-to-nve-groups, NULL, 'e', 0, 0, "BGP2VNC" -ZEBRA_ROUTE_BGP_VPN, vpn, NULL, 'c', 1, 1, "VPN", bgpd ZEBRA_ROUTE_BABEL, babel, babeld, 'A', 1, 1, "Babel" ZEBRA_ROUTE_SHARP, sharp, sharpd, 'D', 1, 1, "SHARP" ZEBRA_ROUTE_ALL, wildcard, none, '-', 0, 0, "-" @@ -102,6 +101,5 @@ ZEBRA_ROUTE_OLSR, "Optimised Link State Routing (OLSR)" ZEBRA_ROUTE_TABLE, "Non-main Kernel Routing Table" ZEBRA_ROUTE_LDP, "Label Distribution Protocol (LDP)" ZEBRA_ROUTE_VNC_DIRECT, "VNC direct (not via zebra) routes" -ZEBRA_ROUTE_BGP_VPN, "BGP VPN routes" ZEBRA_ROUTE_BABEL, "Babel routing protocol (Babel)" ZEBRA_ROUTE_SHARP, "Super Happy Advanced Routing Protocol (sharpd)" diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 556ce27229..efef106d97 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -360,9 +360,7 @@ static int vtysh_execute_func(const char *line, int pager) } else if ((saved_node == KEYCHAIN_KEY_NODE || saved_node == LDP_PSEUDOWIRE_NODE || saved_node == LDP_IPV4_IFACE_NODE - || saved_node == LDP_IPV6_IFACE_NODE - || saved_node == BGP_VPNPOLICY_IPV4_NODE - || saved_node == BGP_VPNPOLICY_IPV6_NODE) + || saved_node == LDP_IPV6_IFACE_NODE) && (tried == 1)) { vtysh_execute("exit"); } else if (tried) { @@ -634,9 +632,7 @@ int vtysh_mark_file(const char *filename) } else if ((prev_node == BGP_EVPN_VNI_NODE) && (tried == 1)) { fprintf(outputfile, "exit-vni\n"); - } else if ((prev_node == KEYCHAIN_KEY_NODE - || prev_node == BGP_VPNPOLICY_IPV4_NODE - || prev_node == BGP_VPNPOLICY_IPV6_NODE) + } else if ((prev_node == KEYCHAIN_KEY_NODE) && (tried == 1)) { fprintf(outputfile, "exit\n"); } else if (tried) { @@ -1017,12 +1013,6 @@ static struct cmd_node bgp_evpn_node = {BGP_EVPN_NODE, static struct cmd_node bgp_evpn_vni_node = {BGP_EVPN_VNI_NODE, "%s(config-router-af-vni)# "}; -static struct cmd_node bgp_vpn_policy_ipv4_node = { - BGP_VPNPOLICY_IPV4_NODE, "%s(config-router-vpn-policy-ipv4)# ", 1}; - -static struct cmd_node bgp_vpn_policy_ipv6_node = { - BGP_VPNPOLICY_IPV6_NODE, "%s(config-router-vpn-policy-ipv6)# ", 1}; - static struct cmd_node bgp_ipv6l_node = {BGP_IPV6L_NODE, "%s(config-router-af)# "}; @@ -1274,20 +1264,6 @@ DEFUNSH(VTYSH_BGPD, bgp_evpn_vni, bgp_evpn_vni_cmd, "vni (1-16777215)", return CMD_SUCCESS; } -DEFUNSH(VTYSH_BGPD, vpn_policy_afi, vpn_policy_afi_cmd, "vpn-policy ", - "Configure a VPN policy\n" - BGP_AFI_HELP_STR) -{ - int idx = 1; - - if (argv_find(argv, argc, "ipv4", &idx)) - vty->node = BGP_VPNPOLICY_IPV4_NODE; - else - vty->node = BGP_VPNPOLICY_IPV6_NODE; - return CMD_SUCCESS; -} - - #if defined(ENABLE_BGP_VNC) DEFUNSH(VTYSH_BGPD, vnc_defaults, vnc_defaults_cmd, "vnc defaults", "VNC/RFP related configuration\n" @@ -1562,8 +1538,6 @@ static int vtysh_exit(struct vty *vty) case BGP_IPV6M_NODE: case BGP_IPV6L_NODE: case BGP_VRF_POLICY_NODE: - case BGP_VPNPOLICY_IPV4_NODE: - case BGP_VPNPOLICY_IPV6_NODE: case BGP_EVPN_NODE: case BGP_VNC_DEFAULTS_NODE: case BGP_VNC_NVE_GROUP_NODE: @@ -3112,8 +3086,6 @@ void vtysh_init_vty(void) install_node(&bgp_vrf_policy_node, NULL); install_node(&bgp_evpn_node, NULL); install_node(&bgp_evpn_vni_node, NULL); - install_node(&bgp_vpn_policy_ipv4_node, NULL); - install_node(&bgp_vpn_policy_ipv6_node, NULL); install_node(&bgp_vnc_defaults_node, NULL); install_node(&bgp_vnc_nve_group_node, NULL); install_node(&bgp_vnc_l2_group_node, NULL); @@ -3206,10 +3178,6 @@ void vtysh_init_vty(void) install_element(BGP_EVPN_VNI_NODE, &vtysh_quit_bgpd_cmd); install_element(BGP_IPV6L_NODE, &vtysh_exit_bgpd_cmd); install_element(BGP_IPV6L_NODE, &vtysh_quit_bgpd_cmd); - install_element(BGP_VPNPOLICY_IPV4_NODE, &vtysh_exit_bgpd_cmd); - install_element(BGP_VPNPOLICY_IPV4_NODE, &vtysh_quit_bgpd_cmd); - install_element(BGP_VPNPOLICY_IPV6_NODE, &vtysh_exit_bgpd_cmd); - install_element(BGP_VPNPOLICY_IPV6_NODE, &vtysh_quit_bgpd_cmd); #if defined(ENABLE_BGP_VNC) install_element(BGP_VRF_POLICY_NODE, &vtysh_exit_bgpd_cmd); install_element(BGP_VRF_POLICY_NODE, &vtysh_quit_bgpd_cmd); @@ -3262,8 +3230,6 @@ void vtysh_init_vty(void) install_element(BGP_VNC_DEFAULTS_NODE, &vtysh_end_all_cmd); install_element(BGP_VNC_NVE_GROUP_NODE, &vtysh_end_all_cmd); install_element(BGP_VNC_L2_GROUP_NODE, &vtysh_end_all_cmd); - install_element(BGP_VPNPOLICY_IPV4_NODE, &vtysh_end_all_cmd); - install_element(BGP_VPNPOLICY_IPV6_NODE, &vtysh_end_all_cmd); install_element(ISIS_NODE, &vtysh_end_all_cmd); install_element(KEYCHAIN_NODE, &vtysh_end_all_cmd); install_element(KEYCHAIN_KEY_NODE, &vtysh_end_all_cmd); @@ -3313,7 +3279,6 @@ void vtysh_init_vty(void) install_element(CONFIG_NODE, &router_bgp_cmd); install_element(BGP_NODE, &address_family_vpnv4_cmd); install_element(BGP_NODE, &address_family_vpnv6_cmd); - install_element(BGP_NODE, &vpn_policy_afi_cmd); #if defined(ENABLE_BGP_VNC) install_element(BGP_NODE, &vnc_vrf_policy_cmd); install_element(BGP_NODE, &vnc_defaults_cmd); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 26dd48733e..d654579b1c 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -1865,7 +1865,6 @@ static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = { [ZEBRA_ROUTE_VNC_DIRECT_RH] = 3, [ZEBRA_ROUTE_BGP_DIRECT] = 3, [ZEBRA_ROUTE_BGP_DIRECT_EXT] = 3, - [ZEBRA_ROUTE_BGP_VPN] = 3, [ZEBRA_ROUTE_BABEL] = 2, [ZEBRA_ROUTE_ALL] = 4, // Shouldn't happen but for safety }; -- cgit v1.2.3