summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/Makefile.am2
-rw-r--r--bgpd/bgp_attr.c3
-rw-r--r--bgpd/bgp_network.c4
-rw-r--r--bgpd/bgp_vty.c50
-rw-r--r--bgpd/bgpd.c97
-rw-r--r--bgpd/bgpd.h7
-rw-r--r--doc/user/overview.rst28
-rw-r--r--lib/subdir.am2
-rw-r--r--lib/vrf.c2
-rw-r--r--ospf6d/subdir.am2
-rw-r--r--ospfd/subdir.am2
-rw-r--r--ripd/subdir.am2
-rw-r--r--zebra/redistribute.c33
-rw-r--r--zebra/subdir.am2
-rw-r--r--zebra/zebra_ns.c35
-rw-r--r--zebra/zebra_ns.h1
-rw-r--r--zebra/zebra_static.c32
-rw-r--r--zebra/zebra_static.h9
-rw-r--r--zebra/zebra_vrf.c25
-rw-r--r--zebra/zebra_vty.c255
20 files changed, 450 insertions, 143 deletions
diff --git a/bgpd/Makefile.am b/bgpd/Makefile.am
index 8a410adca1..6761389100 100644
--- a/bgpd/Makefile.am
+++ b/bgpd/Makefile.am
@@ -116,7 +116,7 @@ module_LTLIBRARIES += bgpd_snmp.la
endif
bgpd_snmp_la_SOURCES = bgp_snmp.c
-bgpd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS)
+bgpd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99
bgpd_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
bgpd_snmp_la_LIBADD = ../lib/libfrrsnmp.la
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index e714e17bde..2c52b57b36 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -1177,7 +1177,6 @@ static bgp_attr_parse_ret_t bgp_attr_aspath_check(struct peer *const peer,
* not right.
* So do the checks later, i.e. here
*/
- struct bgp *bgp = peer->bgp;
struct aspath *aspath;
/* Confederation sanity check. */
@@ -1192,7 +1191,7 @@ static bgp_attr_parse_ret_t bgp_attr_aspath_check(struct peer *const peer,
}
/* First AS check for EBGP. */
- if (bgp != NULL && bgp_flag_check(bgp, BGP_FLAG_ENFORCE_FIRST_AS)) {
+ if (CHECK_FLAG(peer->flags, PEER_FLAG_ENFORCE_FIRST_AS)) {
if (peer->sort == BGP_PEER_EBGP
&& !aspath_firstas_check(attr->aspath, peer->as)) {
zlog_err("%s incorrect first AS (must be %u)",
diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c
index 37d06c1e53..84a959d0e8 100644
--- a/bgpd/bgp_network.c
+++ b/bgpd/bgp_network.c
@@ -723,7 +723,9 @@ int bgp_socket(struct bgp *bgp, unsigned short port, const char *address)
if (bgpd_privs.change(ZPRIVS_RAISE))
zlog_err("Can't raise privileges");
sock = vrf_socket(ainfo->ai_family, ainfo->ai_socktype,
- ainfo->ai_protocol, bgp->vrf_id, NULL);
+ ainfo->ai_protocol, bgp->vrf_id,
+ (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ?
+ bgp->name : NULL));
if (bgpd_privs.change(ZPRIVS_LOWER))
zlog_err("Can't lower privileges");
if (sock < 0) {
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 257adda3f3..833de64c94 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -1991,7 +1991,11 @@ DEFUN (no_bgp_fast_external_failover,
}
/* "bgp enforce-first-as" configuration. */
-DEFUN (bgp_enforce_first_as,
+#if defined(VERSION_TYPE_DEV) && CONFDATE > 20180517
+CPP_NOTICE("bgpd: remove deprecated '[no] bgp enforce-first-as' commands")
+#endif
+
+DEFUN_DEPRECATED (bgp_enforce_first_as,
bgp_enforce_first_as_cmd,
"bgp enforce-first-as",
BGP_STR
@@ -1999,12 +2003,11 @@ DEFUN (bgp_enforce_first_as,
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_set(bgp, BGP_FLAG_ENFORCE_FIRST_AS);
- bgp_clear_star_soft_in(vty, bgp->name);
return CMD_SUCCESS;
}
-DEFUN (no_bgp_enforce_first_as,
+DEFUN_DEPRECATED (no_bgp_enforce_first_as,
no_bgp_enforce_first_as_cmd,
"no bgp enforce-first-as",
NO_STR
@@ -2013,7 +2016,6 @@ DEFUN (no_bgp_enforce_first_as,
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_unset(bgp, BGP_FLAG_ENFORCE_FIRST_AS);
- bgp_clear_star_soft_in(vty, bgp->name);
return CMD_SUCCESS;
}
@@ -3449,7 +3451,7 @@ ALIAS_HIDDEN(no_neighbor_set_peer_group, no_neighbor_set_peer_group_hidden_cmd,
"Peer-group name\n")
static int peer_flag_modify_vty(struct vty *vty, const char *ip_str,
- uint16_t flag, int set)
+ uint32_t flag, int set)
{
int ret;
struct peer *peer;
@@ -3481,13 +3483,13 @@ static int peer_flag_modify_vty(struct vty *vty, const char *ip_str,
return bgp_vty_return(vty, ret);
}
-static int peer_flag_set_vty(struct vty *vty, const char *ip_str, uint16_t flag)
+static int peer_flag_set_vty(struct vty *vty, const char *ip_str, uint32_t flag)
{
return peer_flag_modify_vty(vty, ip_str, flag, 1);
}
static int peer_flag_unset_vty(struct vty *vty, const char *ip_str,
- uint16_t flag)
+ uint32_t flag)
{
return peer_flag_modify_vty(vty, ip_str, flag, 0);
}
@@ -4584,6 +4586,36 @@ DEFUN (no_neighbor_disable_connected_check,
PEER_FLAG_DISABLE_CONNECTED_CHECK);
}
+
+/* enforce-first-as */
+DEFUN (neighbor_enforce_first_as,
+ neighbor_enforce_first_as_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> enforce-first-as",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Enforce the first AS for EBGP routes\n")
+{
+ int idx_peer = 1;
+
+ return peer_flag_set_vty(vty, argv[idx_peer]->arg,
+ PEER_FLAG_ENFORCE_FIRST_AS);
+}
+
+DEFUN (no_neighbor_enforce_first_as,
+ no_neighbor_enforce_first_as_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> enforce-first-as",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Enforce the first AS for EBGP routes\n")
+{
+ int idx_peer = 2;
+
+ return peer_flag_unset_vty(vty, argv[idx_peer]->arg,
+ PEER_FLAG_ENFORCE_FIRST_AS);
+}
+
+
DEFUN (neighbor_description,
neighbor_description_cmd,
"neighbor <A.B.C.D|X:X::X:X|WORD> description LINE...",
@@ -12984,6 +13016,10 @@ void bgp_vty_init(void)
install_element(BGP_NODE, &neighbor_disable_connected_check_cmd);
install_element(BGP_NODE, &no_neighbor_disable_connected_check_cmd);
+ /* "neighbor enforce-first-as" commands. */
+ install_element(BGP_NODE, &neighbor_enforce_first_as_cmd);
+ install_element(BGP_NODE, &no_neighbor_enforce_first_as_cmd);
+
/* "neighbor description" commands. */
install_element(BGP_NODE, &neighbor_description_cmd);
install_element(BGP_NODE, &no_neighbor_description_cmd);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 69297cd3e4..cc09d4991d 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -109,12 +109,7 @@ extern struct zclient *zclient;
static int bgp_check_main_socket(bool create, struct bgp *bgp)
{
static int bgp_server_main_created;
- struct listnode *bgpnode, *nbgpnode;
- struct bgp *bgp_temp;
- if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF &&
- vrf_is_mapped_on_netns(bgp->vrf_id))
- return 0;
if (create == true) {
if (bgp_server_main_created)
return 0;
@@ -125,18 +120,6 @@ static int bgp_check_main_socket(bool create, struct bgp *bgp)
}
if (!bgp_server_main_created)
return 0;
- /* only delete socket on some cases */
- for (ALL_LIST_ELEMENTS(bm->bgp, bgpnode, nbgpnode, bgp_temp)) {
- /* do not count with current bgp */
- if (bgp_temp == bgp)
- continue;
- /* if other instance non VRF, do not delete socket */
- if (bgp_temp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
- return 0;
- /* vrf lite, do not delete socket */
- if (!vrf_is_mapped_on_netns(bgp_temp->vrf_id))
- return 0;
- }
bgp_close();
bgp_server_main_created = 0;
return 0;
@@ -1391,6 +1374,12 @@ void bgp_peer_conf_if_to_su_update(struct peer *peer)
if (!peer->conf_if)
return;
+ /*
+ * Our peer structure is stored in the bgp->peerhash
+ * release it before we modify anything.
+ */
+ hash_release(peer->bgp->peerhash, peer);
+
prev_family = peer->su.sa.sa_family;
if ((ifp = if_lookup_by_name(peer->conf_if, peer->bgp->vrf_id))) {
peer->ifp = ifp;
@@ -1429,8 +1418,9 @@ void bgp_peer_conf_if_to_su_update(struct peer *peer)
memset(&peer->su.sin6.sin6_addr, 0, sizeof(struct in6_addr));
}
- /* Since our su changed we need to del/add peer to the peerhash */
- hash_release(peer->bgp->peerhash, peer);
+ /*
+ * Since our su changed we need to del/add peer to the peerhash
+ */
hash_get(peer->bgp->peerhash, peer, hash_alloc_intern);
}
@@ -3079,17 +3069,16 @@ int bgp_handle_socket(struct bgp *bgp, struct vrf *vrf, vrf_id_t old_vrf_id,
/* Create BGP server socket, if listen mode not disabled */
if (!bgp || bgp_option_check(BGP_OPT_NO_LISTEN))
return 0;
- if (bgp->name && bgp->inst_type == BGP_INSTANCE_TYPE_VRF && vrf) {
+ if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF) {
/*
* suppress vrf socket
*/
if (create == FALSE) {
- if (vrf_is_mapped_on_netns(vrf->vrf_id))
- bgp_close_vrf_socket(bgp);
- else
- ret = bgp_check_main_socket(create, bgp);
- return ret;
+ bgp_close_vrf_socket(bgp);
+ return 0;
}
+ if (vrf == NULL)
+ return BGP_ERR_INVALID_VALUE;
/* do nothing
* if vrf_id did not change
*/
@@ -3104,21 +3093,12 @@ int bgp_handle_socket(struct bgp *bgp, struct vrf *vrf, vrf_id_t old_vrf_id,
*/
if (vrf->vrf_id == VRF_UNKNOWN)
return 0;
- /* if BGP VRF instance requested
- * if backend is NETNS, create BGP server socket in the NETNS
- */
- if (vrf_is_mapped_on_netns(bgp->vrf_id)) {
- ret = bgp_socket(bgp, bm->port, bm->address);
- if (ret < 0)
- return BGP_ERR_INVALID_VALUE;
- return 0;
- }
- }
- /* if BGP VRF instance requested or VRF lite backend
- * if BGP non VRF instance, create it
- * if not already done
- */
- return bgp_check_main_socket(create, bgp);
+ ret = bgp_socket(bgp, bm->port, bm->address);
+ if (ret < 0)
+ return BGP_ERR_INVALID_VALUE;
+ return 0;
+ } else
+ return bgp_check_main_socket(create, bgp);
}
/* Called from VTY commands. */
@@ -3495,16 +3475,7 @@ struct peer *peer_lookup(struct bgp *bgp, union sockunion *su)
struct listnode *bgpnode, *nbgpnode;
for (ALL_LIST_ELEMENTS(bm->bgp, bgpnode, nbgpnode, bgp)) {
- /* Skip VRFs Lite only, this function will not be
- * invoked without an instance
- * when examining VRFs.
- */
- if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
- && !vrf_is_mapped_on_netns(bgp->vrf_id))
- continue;
-
peer = hash_lookup(bgp->peerhash, &tmp_peer);
-
if (peer)
break;
}
@@ -3805,6 +3776,7 @@ static const struct peer_flag_action peer_flag_action_list[] = {
{PEER_FLAG_DYNAMIC_CAPABILITY, 0, peer_change_reset},
{PEER_FLAG_DISABLE_CONNECTED_CHECK, 0, peer_change_reset},
{PEER_FLAG_CAPABILITY_ENHE, 0, peer_change_reset},
+ {PEER_FLAG_ENFORCE_FIRST_AS, 0, peer_change_reset_in},
{0, 0, 0}};
static const struct peer_flag_action peer_af_flag_action_list[] = {
@@ -6747,6 +6719,14 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
}
}
+ /* enforce-first-as */
+ if (CHECK_FLAG(peer->flags, PEER_FLAG_ENFORCE_FIRST_AS)) {
+ if (!peer_group_active(peer)
+ || !CHECK_FLAG(g_peer->flags, PEER_FLAG_ENFORCE_FIRST_AS)) {
+ vty_out(vty, " neighbor %s enforce-first-as\n", addr);
+ }
+ }
+
/* update-source */
if (peer->update_if) {
if (!peer_group_active(peer) || !g_peer->update_if
@@ -7296,6 +7276,12 @@ static void bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi,
vty_endframe(vty, " exit-address-family\n");
}
+/* clang-format off */
+#if defined(VERSION_TYPE_DEV) && CONFDATE > 20180517
+CPP_NOTICE("bgpd: remove 'bgp enforce-first-as' config migration from bgp_config_write")
+#endif
+/* clang-format on */
+
int bgp_config_write(struct vty *vty)
{
int write = 0;
@@ -7331,6 +7317,15 @@ int bgp_config_write(struct vty *vty)
if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO))
continue;
+ /* Migrate deprecated 'bgp enforce-first-as'
+ * config to 'neighbor * enforce-first-as' configs
+ */
+ if (bgp_flag_check(bgp, BGP_FLAG_ENFORCE_FIRST_AS)) {
+ for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
+ peer_flag_set(peer, PEER_FLAG_ENFORCE_FIRST_AS);
+ bgp_flag_unset(bgp, BGP_FLAG_ENFORCE_FIRST_AS);
+ }
+
/* Router bgp ASN */
vty_out(vty, "router bgp %u", bgp->as);
@@ -7429,10 +7424,6 @@ int bgp_config_write(struct vty *vty)
vty_out(vty, "\n");
}
- /* BGP enforce-first-as. */
- if (bgp_flag_check(bgp, BGP_FLAG_ENFORCE_FIRST_AS))
- vty_out(vty, " bgp enforce-first-as\n");
-
/* BGP deterministic-med. */
if (!!bgp_flag_check(bgp, BGP_FLAG_DETERMINISTIC_MED)
!= DFLT_BGP_DETERMINISTIC_MED)
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 4c87ac0b6f..a685411f6e 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -832,13 +832,14 @@ struct peer {
#define PEER_FLAG_DISABLE_CONNECTED_CHECK (1 << 6) /* disable-connected-check */
#define PEER_FLAG_LOCAL_AS_NO_PREPEND (1 << 7) /* local-as no-prepend */
#define PEER_FLAG_LOCAL_AS_REPLACE_AS (1 << 8) /* local-as no-prepend replace-as */
-#define PEER_FLAG_DELETE (1 << 9) /* mark the peer for deleting */
-#define PEER_FLAG_CONFIG_NODE (1 << 10) /* the node to update configs on */
+#define PEER_FLAG_DELETE (1 << 9) /* mark the peer for deleting */
+#define PEER_FLAG_CONFIG_NODE (1 << 10) /* the node to update configs on */
#define PEER_FLAG_LONESOUL (1 << 11)
#define PEER_FLAG_DYNAMIC_NEIGHBOR (1 << 12) /* dynamic neighbor */
#define PEER_FLAG_CAPABILITY_ENHE (1 << 13) /* Extended next-hop (rfc 5549)*/
#define PEER_FLAG_IFPEER_V6ONLY (1 << 14) /* if-based peer is v6 only */
-#define PEER_FLAG_IS_RFAPI_HD (1 << 15) /* attached to rfapi HD */
+#define PEER_FLAG_IS_RFAPI_HD (1 << 15) /* attached to rfapi HD */
+#define PEER_FLAG_ENFORCE_FIRST_AS (1 << 16) /* enforce-first-as */
/* outgoing message sent in CEASE_ADMIN_SHUTDOWN notify */
char *tx_shutdown_message;
diff --git a/doc/user/overview.rst b/doc/user/overview.rst
index eb24970bee..0d630ce1a8 100644
--- a/doc/user/overview.rst
+++ b/doc/user/overview.rst
@@ -214,6 +214,34 @@ FRR implements the following RFCs:
- :rfc:`3137`
:t:`OSPF Stub Router Advertisement, A. Retana, L. Nguyen, R. White, A. Zinin,
D. McPherson. June 2001`
+- :rfc:`4447`
+ :t:`Pseudowire Setup and Maintenance Using the Label Distribution Protocol
+ (LDP), L. Martini, E. Rosen, N. El-Aawar, T. Smith, and G. Heron. April
+ 2006.`
+- :rfc:`4762`
+ :t:`Virtual Private LAN Service (VPLS) Using Label Distribution Protocol
+ (LDP) Signaling, M. Lasserre and V. Kompella. January 2007.`
+- :rfc:`5036`
+ :t:`LDP Specification, L. Andersson, I. Minei, and B. Thomas. October 2007.`
+- :rfc:`5561`
+ :t:`LDP Capabilities, B. Thomas, K. Raza, S. Aggarwal, R. Aggarwal, and
+ JL. Le Roux. July 2009.`
+- :rfc:`5918`
+ :t:`Label Distribution Protocol (LDP) 'Typed Wildcard' Forward Equivalence
+ Class (FEC), R. Asati, I. Minei, and B. Thomas. August 2010.`
+- :rfc:`5919`
+ :t:`Signaling LDP Label Advertisement Completion, R. Asati, P. Mohapatra,
+ E. Chen, and B. Thomas. August 2010.`
+- :rfc:`6667`
+ :t:`LDP 'Typed Wildcard' Forwarding Equivalence Class (FEC) for PWid and
+ Generalized PWid FEC Elements, K. Raza, S. Boutros, and C. Pignataro. July
+ 2012.`
+- :rfc:`6720`
+ :t:`The Generalized TTL Security Mechanism (GTSM) for the Label Distribution
+ Protocol (LDP), C. Pignataro and R. Asati. August 2012.`
+- :rfc:`7552`
+ :t:`Updates to LDP for IPv6, R. Asati, C. Pignataro, K. Raza, V. Manral,
+ and R. Papneja. June 2015.`
**When SNMP support is enabled, the following RFCs are also supported:**
diff --git a/lib/subdir.am b/lib/subdir.am
index c5719786d6..1c3d31b927 100644
--- a/lib/subdir.am
+++ b/lib/subdir.am
@@ -190,7 +190,7 @@ if SNMP
lib_LTLIBRARIES += lib/libfrrsnmp.la
endif
-lib_libfrrsnmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS)
+lib_libfrrsnmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99
lib_libfrrsnmp_la_LDFLAGS = -version-info 0:0:0
lib_libfrrsnmp_la_LIBADD = lib/libfrr.la $(SNMP_LIBS)
lib_libfrrsnmp_la_SOURCES = \
diff --git a/lib/vrf.c b/lib/vrf.c
index db539d375d..e1176d1526 100644
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -856,7 +856,7 @@ int vrf_bind(vrf_id_t vrf_id, int fd, char *name)
if (vrf_is_mapped_on_netns(vrf_id))
return fd;
#ifdef SO_BINDTODEVICE
- ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, name, strlen(name));
+ ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, name, strlen(name)+1);
if (ret < 0)
zlog_debug("bind to interface %s failed, errno=%d", name,
errno);
diff --git a/ospf6d/subdir.am b/ospf6d/subdir.am
index 76a64cd637..8a6c4a5ccf 100644
--- a/ospf6d/subdir.am
+++ b/ospf6d/subdir.am
@@ -61,6 +61,6 @@ ospf6d_ospf6d_SOURCES = \
# end
ospf6d_ospf6d_snmp_la_SOURCES = ospf6d/ospf6_snmp.c
-ospf6d_ospf6d_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS)
+ospf6d_ospf6d_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99
ospf6d_ospf6d_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
ospf6d_ospf6d_snmp_la_LIBADD = lib/libfrrsnmp.la
diff --git a/ospfd/subdir.am b/ospfd/subdir.am
index 9f04260366..f2e292e186 100644
--- a/ospfd/subdir.am
+++ b/ospfd/subdir.am
@@ -89,7 +89,7 @@ ospfd_ospfd_LDADD = ospfd/libfrrospf.a lib/libfrr.la @LIBCAP@ @LIBM@
ospfd_ospfd_SOURCES = ospfd/ospf_main.c
ospfd_ospfd_snmp_la_SOURCES = ospfd/ospf_snmp.c
-ospfd_ospfd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS)
+ospfd_ospfd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99
ospfd_ospfd_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
ospfd_ospfd_snmp_la_LIBADD = lib/libfrrsnmp.la
diff --git a/ripd/subdir.am b/ripd/subdir.am
index 7a8f2185ba..1c5167ef4a 100644
--- a/ripd/subdir.am
+++ b/ripd/subdir.am
@@ -35,7 +35,7 @@ ripd_ripd_SOURCES = \
# end
ripd_ripd_snmp_la_SOURCES = ripd/rip_snmp.c
-ripd_ripd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS)
+ripd_ripd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99
ripd_ripd_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
ripd_ripd_snmp_la_LIBADD = lib/libfrrsnmp.la
diff --git a/zebra/redistribute.c b/zebra/redistribute.c
index b1387815ba..be53b74b3f 100644
--- a/zebra/redistribute.c
+++ b/zebra/redistribute.c
@@ -120,7 +120,7 @@ static void zebra_redistribute(struct zserv *client, int type,
if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug(
- "%s: client %s %s(%d) checking: selected=%d, type=%d, distance=%d, metric=%d zebra_check_addr=%d",
+ "%s: client %s %s(%u) checking: selected=%d, type=%d, distance=%d, metric=%d zebra_check_addr=%d",
__func__,
zebra_route_string(client->proto),
prefix2str(dst_p, buf, sizeof(buf)),
@@ -192,7 +192,7 @@ void redistribute_update(struct prefix *p, struct prefix *src_p,
if (send_redistribute) {
if (IS_ZEBRA_DEBUG_EVENT) {
zlog_debug(
- "%s: client %s %s(%d), type=%d, distance=%d, metric=%d",
+ "%s: client %s %s(%u), type=%d, distance=%d, metric=%d",
__func__,
zebra_route_string(client->proto),
prefix2str(p, buf, sizeof(buf)),
@@ -270,7 +270,7 @@ void zebra_redistribute_add(ZAPI_HANDLER_ARGS)
if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug(
- "%s: client proto %s afi=%d, wants %s, vrf %d, instance=%d",
+ "%s: client proto %s afi=%d, wants %s, vrf %u, instance=%d",
__func__, zebra_route_string(client->proto), afi,
zebra_route_string(type), zvrf_id(zvrf), instance);
@@ -298,7 +298,7 @@ void zebra_redistribute_add(ZAPI_HANDLER_ARGS)
if (!vrf_bitmap_check(client->redist[afi][type],
zvrf_id(zvrf))) {
if (IS_ZEBRA_DEBUG_EVENT)
- zlog_debug("%s: setting vrf %d redist bitmap",
+ zlog_debug("%s: setting vrf %u redist bitmap",
__func__, zvrf_id(zvrf));
vrf_bitmap_set(client->redist[afi][type],
zvrf_id(zvrf));
@@ -365,7 +365,8 @@ void zebra_interface_up_update(struct interface *ifp)
struct zserv *client;
if (IS_ZEBRA_DEBUG_EVENT)
- zlog_debug("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name);
+ zlog_debug("MESSAGE: ZEBRA_INTERFACE_UP %s(%u)",
+ ifp->name, ifp->vrf_id);
if (ifp->ptm_status || !ifp->ptm_enable) {
for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
@@ -384,7 +385,8 @@ void zebra_interface_down_update(struct interface *ifp)
struct zserv *client;
if (IS_ZEBRA_DEBUG_EVENT)
- zlog_debug("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name);
+ zlog_debug("MESSAGE: ZEBRA_INTERFACE_DOWN %s(%u)",
+ ifp->name, ifp->vrf_id);
for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
@@ -398,7 +400,7 @@ void zebra_interface_add_update(struct interface *ifp)
struct zserv *client;
if (IS_ZEBRA_DEBUG_EVENT)
- zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADD %s[%d]", ifp->name,
+ zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADD %s(%u)", ifp->name,
ifp->vrf_id);
for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
@@ -415,7 +417,8 @@ void zebra_interface_delete_update(struct interface *ifp)
struct zserv *client;
if (IS_ZEBRA_DEBUG_EVENT)
- zlog_debug("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name);
+ zlog_debug("MESSAGE: ZEBRA_INTERFACE_DELETE %s(%u)",
+ ifp->name, ifp->vrf_id);
for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
client->ifdel_cnt++;
@@ -435,8 +438,9 @@ void zebra_interface_address_add_update(struct interface *ifp,
char buf[PREFIX_STRLEN];
p = ifc->address;
- zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s on %s",
- prefix2str(p, buf, sizeof(buf)), ifc->ifp->name);
+ zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s on %s(%u)",
+ prefix2str(p, buf, sizeof(buf)), ifp->name,
+ ifp->vrf_id);
}
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
@@ -467,8 +471,9 @@ void zebra_interface_address_delete_update(struct interface *ifp,
char buf[PREFIX_STRLEN];
p = ifc->address;
- zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s on %s",
- prefix2str(p, buf, sizeof(buf)), ifc->ifp->name);
+ zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s on %s(%u)",
+ prefix2str(p, buf, sizeof(buf)),
+ ifp->name, ifp->vrf_id);
}
zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 0);
@@ -768,8 +773,8 @@ void zebra_interface_parameters_update(struct interface *ifp)
struct zserv *client;
if (IS_ZEBRA_DEBUG_EVENT)
- zlog_debug("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s",
- ifp->name);
+ zlog_debug("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s(%u)",
+ ifp->name, ifp->vrf_id);
for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
if (client->ifinfo)
diff --git a/zebra/subdir.am b/zebra/subdir.am
index 45e285a9e7..d3abcef6d5 100644
--- a/zebra/subdir.am
+++ b/zebra/subdir.am
@@ -127,7 +127,7 @@ zebra_zebra_irdp_la_SOURCES = \
zebra_zebra_irdp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
zebra_zebra_snmp_la_SOURCES = zebra/zebra_snmp.c
-zebra_zebra_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS)
+zebra_zebra_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99
zebra_zebra_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
zebra_zebra_snmp_la_LIBADD = lib/libfrrsnmp.la
diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c
index 4526a14870..25e68cc081 100644
--- a/zebra/zebra_ns.c
+++ b/zebra/zebra_ns.c
@@ -55,10 +55,15 @@ static struct zebra_ns *dzns;
static inline int zebra_ns_table_entry_compare(const struct zebra_ns_table *e1,
const struct zebra_ns_table *e2)
{
- if (e1->tableid == e2->tableid)
- return (e1->afi - e2->afi);
-
- return e1->tableid - e2->tableid;
+ if (e1->tableid < e2->tableid)
+ return -1;
+ if (e1->tableid > e2->tableid)
+ return 1;
+ if (e1->ns_id < e2->ns_id)
+ return -1;
+ if (e1->ns_id > e2->ns_id)
+ return 1;
+ return (e1->afi - e2->afi);
}
static int logicalrouter_config_write(struct vty *vty);
@@ -177,6 +182,7 @@ struct route_table *zebra_ns_find_table(struct zebra_ns *zns, uint32_t tableid,
memset(&finder, 0, sizeof(finder));
finder.afi = afi;
finder.tableid = tableid;
+ finder.ns_id = zns->ns_id;
znst = RB_FIND(zebra_ns_table_head, &zns->ns_tables, &finder);
if (znst)
@@ -193,9 +199,11 @@ unsigned long zebra_ns_score_proto(uint8_t proto, unsigned short instance)
zns = zebra_ns_lookup(NS_DEFAULT);
- RB_FOREACH (znst, zebra_ns_table_head, &zns->ns_tables)
+ RB_FOREACH (znst, zebra_ns_table_head, &zns->ns_tables) {
+ if (znst->ns_id != NS_DEFAULT)
+ continue;
cnt += rib_score_proto_table(proto, instance, znst->table);
-
+ }
return cnt;
}
@@ -206,8 +214,11 @@ void zebra_ns_sweep_route(void)
zns = zebra_ns_lookup(NS_DEFAULT);
- RB_FOREACH (znst, zebra_ns_table_head, &zns->ns_tables)
+ RB_FOREACH (znst, zebra_ns_table_head, &zns->ns_tables) {
+ if (znst->ns_id != NS_DEFAULT)
+ continue;
rib_sweep_table(znst->table);
+ }
}
struct route_table *zebra_ns_get_table(struct zebra_ns *zns,
@@ -221,6 +232,7 @@ struct route_table *zebra_ns_get_table(struct zebra_ns *zns,
memset(&finder, 0, sizeof(finder));
finder.afi = afi;
finder.tableid = tableid;
+ finder.ns_id = zns->ns_id;
znst = RB_FIND(zebra_ns_table_head, &zns->ns_tables, &finder);
if (znst)
@@ -229,6 +241,7 @@ struct route_table *zebra_ns_get_table(struct zebra_ns *zns,
znst = XCALLOC(MTYPE_ZEBRA_NS, sizeof(*znst));
znst->tableid = tableid;
znst->afi = afi;
+ znst->ns_id = zns->ns_id;
znst->table =
(afi == AFI_IP6) ? srcdest_table_init() : route_table_init();
@@ -257,7 +270,7 @@ static void zebra_ns_free_table(struct zebra_ns_table *znst)
int zebra_ns_disable(ns_id_t ns_id, void **info)
{
- struct zebra_ns_table *znst;
+ struct zebra_ns_table *znst, *tmp;
struct zebra_ns *zns = (struct zebra_ns *)(*info);
hash_clean(zns->rules_hash, zebra_pbr_rules_free);
@@ -271,9 +284,9 @@ int zebra_ns_disable(ns_id_t ns_id, void **info)
zebra_pbr_iptable_free);
hash_free(zns->iptable_hash);
- while (!RB_EMPTY(zebra_ns_table_head, &zns->ns_tables)) {
- znst = RB_ROOT(zebra_ns_table_head, &zns->ns_tables);
-
+ RB_FOREACH_SAFE (znst, zebra_ns_table_head, &zns->ns_tables, tmp) {
+ if (znst->ns_id != ns_id)
+ continue;
RB_REMOVE(zebra_ns_table_head, &zns->ns_tables, znst);
zebra_ns_free_table(znst);
}
diff --git a/zebra/zebra_ns.h b/zebra/zebra_ns.h
index c93db2a764..ed70a34c0b 100644
--- a/zebra/zebra_ns.h
+++ b/zebra/zebra_ns.h
@@ -43,6 +43,7 @@ struct zebra_ns_table {
uint32_t tableid;
afi_t afi;
+ ns_id_t ns_id;
struct route_table *table;
};
diff --git a/zebra/zebra_static.c b/zebra/zebra_static.c
index 24160655d7..67b2954f35 100644
--- a/zebra/zebra_static.c
+++ b/zebra/zebra_static.c
@@ -49,7 +49,9 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
struct vrf *nh_vrf;
/* Lookup table. */
- table = zebra_vrf_table(afi, safi, si->vrf_id);
+ table = zebra_vrf_table_with_table_id(afi, safi,
+ si->vrf_id,
+ si->table_id);
if (!table)
return;
@@ -170,10 +172,20 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
re->metric = 0;
re->mtu = 0;
re->vrf_id = si->vrf_id;
- re->table =
- (si->vrf_id != VRF_DEFAULT)
+ if (!vrf_is_backend_netns()) {
+ re->table =
+ (si->vrf_id != VRF_DEFAULT)
? (zebra_vrf_lookup_by_id(si->vrf_id))->table_id
: zebrad.rtm_table_default;
+ } else {
+ struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(si->vrf_id);
+
+ if (zvrf->table_id != RT_TABLE_MAIN ||
+ zvrf->table_id != zebrad.rtm_table_default)
+ re->table = zvrf->table_id;
+ else
+ re->table = zebrad.rtm_table_default;
+ }
re->nexthop_num = 0;
re->tag = si->tag;
@@ -290,7 +302,9 @@ void static_uninstall_route(afi_t afi, safi_t safi, struct prefix *p,
struct prefix nh_p;
/* Lookup table. */
- table = zebra_vrf_table(afi, safi, si->vrf_id);
+ table = zebra_vrf_table_with_table_id(afi, safi,
+ si->vrf_id,
+ si->table_id);
if (!table)
return;
@@ -395,7 +409,8 @@ int static_add_route(afi_t afi, safi_t safi, uint8_t type, struct prefix *p,
const char *ifname, enum static_blackhole_type bh_type,
route_tag_t tag, uint8_t distance, struct zebra_vrf *zvrf,
struct zebra_vrf *nh_zvrf,
- struct static_nh_label *snh_label)
+ struct static_nh_label *snh_label,
+ uint32_t table_id)
{
struct route_node *rn;
struct static_route *si;
@@ -445,7 +460,7 @@ int static_add_route(afi_t afi, safi_t safi, uint8_t type, struct prefix *p,
if (update)
static_delete_route(afi, safi, type, p, src_p, gate, ifname,
update->tag, update->distance, zvrf,
- &update->snh_label);
+ &update->snh_label, table_id);
/* Make new static route structure. */
si = XCALLOC(MTYPE_STATIC_ROUTE, sizeof(struct static_route));
@@ -457,6 +472,7 @@ int static_add_route(afi_t afi, safi_t safi, uint8_t type, struct prefix *p,
si->vrf_id = zvrf_id(zvrf);
si->nh_vrf_id = zvrf_id(nh_zvrf);
strcpy(si->nh_vrfname, nh_zvrf->vrf->name);
+ si->table_id = table_id;
if (ifname)
strlcpy(si->ifname, ifname, sizeof(si->ifname));
@@ -528,7 +544,8 @@ int static_delete_route(afi_t afi, safi_t safi, uint8_t type, struct prefix *p,
struct prefix_ipv6 *src_p, union g_addr *gate,
const char *ifname, route_tag_t tag, uint8_t distance,
struct zebra_vrf *zvrf,
- struct static_nh_label *snh_label)
+ struct static_nh_label *snh_label,
+ uint32_t table_id)
{
struct route_node *rn;
struct static_route *si;
@@ -554,6 +571,7 @@ int static_delete_route(afi_t afi, safi_t safi, uint8_t type, struct prefix *p,
&& IPV6_ADDR_SAME(gate, &si->addr.ipv6))))
&& (!strcmp(ifname ? ifname : "", si->ifname))
&& (!tag || (tag == si->tag))
+ && (table_id == si->table_id)
&& (!snh_label->num_labels
|| !memcmp(&si->snh_label, snh_label,
sizeof(struct static_nh_label))))
diff --git a/zebra/zebra_static.h b/zebra/zebra_static.h
index 341905f422..7dc47d6190 100644
--- a/zebra/zebra_static.h
+++ b/zebra/zebra_static.h
@@ -77,6 +77,9 @@ struct static_route {
/* Label information */
struct static_nh_label snh_label;
+
+ /* Table Information */
+ uint32_t table_id;
};
extern void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
@@ -92,14 +95,16 @@ extern int static_add_route(afi_t, safi_t safi, uint8_t type, struct prefix *p,
enum static_blackhole_type bh_type, route_tag_t tag,
uint8_t distance, struct zebra_vrf *zvrf,
struct zebra_vrf *nh_zvrf,
- struct static_nh_label *snh_label);
+ struct static_nh_label *snh_label,
+ uint32_t table_id);
extern int static_delete_route(afi_t, safi_t safi, uint8_t type,
struct prefix *p, struct prefix_ipv6 *src_p,
union g_addr *gate, const char *ifname,
route_tag_t tag, uint8_t distance,
struct zebra_vrf *zvrf,
- struct static_nh_label *snh_label);
+ struct static_nh_label *snh_label,
+ uint32_t table_id);
extern void static_ifindex_update(struct interface *ifp, bool up);
diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c
index 46443dec4f..d443f725b0 100644
--- a/zebra/zebra_vrf.c
+++ b/zebra/zebra_vrf.c
@@ -328,7 +328,9 @@ int zebra_vrf_has_config(struct zebra_vrf *zvrf)
}
/* Lookup the routing table in a VRF based on both VRF-Id and table-id.
- * NOTE: Table-id is relevant only in the Default VRF.
+ * NOTE: Table-id is relevant on two modes:
+ * - case VRF backend is default : on default VRF only
+ * - case VRF backend is netns : on all VRFs
*/
struct route_table *zebra_vrf_table_with_table_id(afi_t afi, safi_t safi,
vrf_id_t vrf_id,
@@ -346,6 +348,13 @@ struct route_table *zebra_vrf_table_with_table_id(afi_t afi, safi_t safi,
else
table = zebra_vrf_other_route_table(afi, table_id,
vrf_id);
+ } else if (vrf_is_backend_netns()) {
+ if (table_id == RT_TABLE_MAIN
+ || table_id == zebrad.rtm_table_default)
+ table = zebra_vrf_table(afi, safi, vrf_id);
+ else
+ table = zebra_vrf_other_route_table(afi, table_id,
+ vrf_id);
} else
table = zebra_vrf_table(afi, safi, vrf_id);
@@ -434,7 +443,8 @@ struct zebra_vrf *zebra_vrf_alloc(void)
zebra_vxlan_init_tables(zvrf);
zebra_mpls_init_tables(zvrf);
zebra_pw_init(zvrf);
-
+ zvrf->table_id = RT_TABLE_MAIN;
+ /* by default table ID is default one */
return zvrf;
}
@@ -501,9 +511,16 @@ struct route_table *zebra_vrf_other_route_table(afi_t afi, uint32_t table_id,
if (afi >= AFI_MAX)
return NULL;
- if ((vrf_id == VRF_DEFAULT) && (table_id != RT_TABLE_MAIN)
+ if ((table_id != RT_TABLE_MAIN)
&& (table_id != zebrad.rtm_table_default)) {
- return zebra_ns_get_table(zns, zvrf, table_id, afi);
+ if (zvrf->table_id == RT_TABLE_MAIN ||
+ zvrf->table_id == zebrad.rtm_table_default) {
+ /* this VRF use default table
+ * so in all cases, it does not use specific table
+ * so it is possible to configure tables in this VRF
+ */
+ return zebra_ns_get_table(zns, zvrf, table_id, afi);
+ }
}
return zvrf->table[afi][SAFI_UNICAST];
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index a094ca585e..f7548f618f 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -92,6 +92,7 @@ struct static_hold_route {
char *tag_str;
char *distance_str;
char *label_str;
+ char *table_str;
/* processed & masked destination, used for config display */
struct prefix dest;
@@ -193,6 +194,11 @@ static int static_list_compare(void *arg1, void *arg2)
if (ret)
return ret;
+ ret = static_list_compare_helper(shr1->table_str,
+ shr2->table_str);
+ if (ret)
+ return ret;
+
return static_list_compare_helper(shr1->label_str, shr2->label_str);
}
@@ -203,7 +209,8 @@ static int zebra_static_route_holdem(
safi_t safi, const char *negate, struct prefix *dest,
const char *dest_str, const char *mask_str, const char *src_str,
const char *gate_str, const char *ifname, const char *flag_str,
- const char *tag_str, const char *distance_str, const char *label_str)
+ const char *tag_str, const char *distance_str, const char *label_str,
+ const char *table_str)
{
struct static_hold_route *shr, *lookup;
struct listnode *node;
@@ -236,6 +243,8 @@ static int zebra_static_route_holdem(
shr->distance_str = XSTRDUP(MTYPE_STATIC_ROUTE, distance_str);
if (label_str)
shr->label_str = XSTRDUP(MTYPE_STATIC_ROUTE, label_str);
+ if (table_str)
+ shr->table_str = XSTRDUP(MTYPE_STATIC_ROUTE, table_str);
for (ALL_LIST_ELEMENTS_RO(static_list, node, lookup)) {
if (static_list_compare(shr, lookup) == 0)
@@ -272,7 +281,7 @@ static int zebra_static_route_leak(
afi_t afi, safi_t safi, const char *negate, const char *dest_str,
const char *mask_str, const char *src_str, const char *gate_str,
const char *ifname, const char *flag_str, const char *tag_str,
- const char *distance_str, const char *label_str)
+ const char *distance_str, const char *label_str, const char *table_str)
{
int ret;
uint8_t distance;
@@ -285,6 +294,7 @@ static int zebra_static_route_leak(
route_tag_t tag = 0;
uint8_t type;
struct static_nh_label snh_label;
+ uint32_t table_id = 0;
ret = str2prefix(dest_str, &p);
if (ret <= 0) {
@@ -343,7 +353,24 @@ static int zebra_static_route_leak(
return zebra_static_route_holdem(
zvrf, nh_zvrf, afi, safi, negate, &p, dest_str,
mask_str, src_str, gate_str, ifname, flag_str, tag_str,
- distance_str, label_str);
+ distance_str, label_str, table_str);
+ }
+ if (table_str) {
+ /* table configured. check consistent with vrf config
+ */
+ if (zvrf->table_id != RT_TABLE_MAIN &&
+ zvrf->table_id != zebrad.rtm_table_default) {
+ if (vty)
+ vty_out(vty,
+ "%% Table %s overlaps vrf table %u\n",
+ table_str, zvrf->table_id);
+ else
+ zlog_warn(
+ "%s: Table %s overlaps vrf table %u",
+ __PRETTY_FUNCTION__,
+ table_str, zvrf->table_id);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
}
/* Administrative distance. */
@@ -410,6 +437,9 @@ static int zebra_static_route_leak(
return CMD_WARNING_CONFIG_FAILED;
}
}
+ /* TableID */
+ if (table_str)
+ table_id = atol(table_str);
/* Null0 static route. */
if (ifname != NULL) {
@@ -486,12 +516,12 @@ static int zebra_static_route_leak(
if (!negate) {
static_add_route(afi, safi, type, &p, src_p, gatep, ifname,
bh_type, tag, distance, zvrf, nh_zvrf,
- &snh_label);
+ &snh_label, table_id);
/* Mark as having FRR configuration */
vrf_set_user_cfged(zvrf->vrf);
} else {
static_delete_route(afi, safi, type, &p, src_p, gatep, ifname,
- tag, distance, zvrf, &snh_label);
+ tag, distance, zvrf, &snh_label, table_id);
/* If no other FRR config for this VRF, mark accordingly. */
if (!zebra_vrf_has_config(zvrf))
vrf_reset_user_cfged(zvrf->vrf);
@@ -534,7 +564,7 @@ static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi,
const char *gate_str, const char *ifname,
const char *flag_str, const char *tag_str,
const char *distance_str, const char *vrf_name,
- const char *label_str)
+ const char *label_str, const char *table_str)
{
struct zebra_vrf *zvrf;
@@ -557,7 +587,8 @@ static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi,
}
return zebra_static_route_leak(
vty, zvrf, zvrf, afi, safi, negate, dest_str, mask_str, src_str,
- gate_str, ifname, flag_str, tag_str, distance_str, label_str);
+ gate_str, ifname, flag_str, tag_str, distance_str, label_str,
+ table_str);
}
void static_config_install_delayed_routes(struct zebra_vrf *zvrf)
@@ -582,7 +613,7 @@ void static_config_install_delayed_routes(struct zebra_vrf *zvrf)
NULL, ozvrf, nh_zvrf, shr->afi, shr->safi, NULL,
shr->dest_str, shr->mask_str, shr->src_str,
shr->gate_str, shr->ifname, shr->flag_str, shr->tag_str,
- shr->distance_str, shr->label_str);
+ shr->distance_str, shr->label_str, shr->table_str);
if (installed != CMD_SUCCESS)
zlog_debug(
@@ -606,7 +637,7 @@ DEFPY (ip_mroute_dist,
{
return zebra_static_route(vty, AFI_IP, SAFI_MULTICAST, no, prefix_str,
NULL, NULL, gate_str, ifname, NULL, NULL,
- distance_str, NULL, NULL);
+ distance_str, NULL, NULL, NULL);
}
DEFUN (ip_multicast_mode,
@@ -713,6 +744,7 @@ DEFPY(ip_route_blackhole,
|(1-255)$distance \
|vrf NAME \
|label WORD \
+ |table (1-4294967295) \
}]",
NO_STR IP_STR
"Establish static routes\n"
@@ -725,11 +757,18 @@ DEFPY(ip_route_blackhole,
"Tag value\n"
"Distance value for this route\n"
VRF_CMD_HELP_STR
- MPLS_LABEL_HELPSTR)
+ MPLS_LABEL_HELPSTR
+ "Table to configure\n"
+ "The table number to configure\n")
{
+ if (table_str && !vrf_is_backend_netns()) {
+ vty_out(vty,
+ "%% table param only available when running on netns-based vrfs\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
return zebra_static_route(vty, AFI_IP, SAFI_UNICAST, no, prefix,
mask_str, NULL, NULL, NULL, flag, tag_str,
- distance_str, vrf, label);
+ distance_str, vrf, label, table_str);
}
DEFPY(ip_route_blackhole_vrf,
@@ -741,6 +780,7 @@ DEFPY(ip_route_blackhole_vrf,
tag (1-4294967295) \
|(1-255)$distance \
|label WORD \
+ |table (1-4294967295) \
}]",
NO_STR IP_STR
"Establish static routes\n"
@@ -752,11 +792,18 @@ DEFPY(ip_route_blackhole_vrf,
"Set tag for this route\n"
"Tag value\n"
"Distance value for this route\n"
- MPLS_LABEL_HELPSTR)
+ MPLS_LABEL_HELPSTR
+ "Table to configure\n"
+ "The table number to configure\n")
{
VTY_DECLVAR_CONTEXT(vrf, vrf);
struct zebra_vrf *zvrf = vrf->info;
+ if (table_str && !vrf_is_backend_netns()) {
+ vty_out(vty,
+ "%% table param only available when running on netns-based vrfs\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
/*
* Coverity is complaining that prefix could
* be dereferenced, but we know that prefix will
@@ -765,7 +812,7 @@ DEFPY(ip_route_blackhole_vrf,
assert(prefix);
return zebra_static_route_leak(vty, zvrf, zvrf, AFI_IP, SAFI_UNICAST,
no, prefix, mask_str, NULL, NULL, NULL,
- flag, tag_str, distance_str, label);
+ flag, tag_str, distance_str, label, table_str);
}
DEFPY(ip_route_address_interface,
@@ -779,6 +826,7 @@ DEFPY(ip_route_address_interface,
|(1-255)$distance \
|vrf NAME \
|label WORD \
+ |table (1-4294967295) \
|nexthop-vrf NAME \
}]",
NO_STR IP_STR
@@ -794,6 +842,8 @@ DEFPY(ip_route_address_interface,
"Distance value for this route\n"
VRF_CMD_HELP_STR
MPLS_LABEL_HELPSTR
+ "Table to configure\n"
+ "The table number to configure\n"
VRF_CMD_HELP_STR)
{
struct zebra_vrf *zvrf;
@@ -811,6 +861,12 @@ DEFPY(ip_route_address_interface,
return CMD_WARNING_CONFIG_FAILED;
}
+ if (table_str && !vrf_is_backend_netns()) {
+ vty_out(vty,
+ "%% table param only available when running on netns-based vrfs\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
if (nexthop_vrf)
nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf);
else
@@ -823,7 +879,8 @@ DEFPY(ip_route_address_interface,
return zebra_static_route_leak(
vty, zvrf, nh_zvrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str,
- NULL, gate_str, ifname, flag, tag_str, distance_str, label);
+ NULL, gate_str, ifname, flag, tag_str, distance_str, label,
+ table_str);
}
DEFPY(ip_route_address_interface_vrf,
@@ -836,6 +893,7 @@ DEFPY(ip_route_address_interface_vrf,
tag (1-4294967295) \
|(1-255)$distance \
|label WORD \
+ |table (1-4294967295) \
|nexthop-vrf NAME \
}]",
NO_STR IP_STR
@@ -850,6 +908,8 @@ DEFPY(ip_route_address_interface_vrf,
"Tag value\n"
"Distance value for this route\n"
MPLS_LABEL_HELPSTR
+ "Table to configure\n"
+ "The table number to configure\n"
VRF_CMD_HELP_STR)
{
VTY_DECLVAR_CONTEXT(vrf, vrf);
@@ -857,6 +917,12 @@ DEFPY(ip_route_address_interface_vrf,
struct zebra_vrf *zvrf = vrf->info;
struct zebra_vrf *nh_zvrf;
+ if (table_str && !vrf_is_backend_netns()) {
+ vty_out(vty,
+ "%% table param only available when running on netns-based vrfs\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
if (ifname && !strncasecmp(ifname, "Null0", 5)) {
flag = "Null0";
ifname = NULL;
@@ -874,7 +940,8 @@ DEFPY(ip_route_address_interface_vrf,
return zebra_static_route_leak(
vty, zvrf, nh_zvrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str,
- NULL, gate_str, ifname, flag, tag_str, distance_str, label);
+ NULL, gate_str, ifname, flag, tag_str, distance_str, label,
+ table_str);
}
DEFPY(ip_route,
@@ -887,6 +954,7 @@ DEFPY(ip_route,
|(1-255)$distance \
|vrf NAME \
|label WORD \
+ |table (1-4294967295) \
|nexthop-vrf NAME \
}]",
NO_STR IP_STR
@@ -901,12 +969,20 @@ DEFPY(ip_route,
"Distance value for this route\n"
VRF_CMD_HELP_STR
MPLS_LABEL_HELPSTR
+ "Table to configure\n"
+ "The table number to configure\n"
VRF_CMD_HELP_STR)
{
struct zebra_vrf *zvrf;
struct zebra_vrf *nh_zvrf;
const char *flag = NULL;
+ if (table_str && !vrf_is_backend_netns()) {
+ vty_out(vty,
+ "%% table param only available when running on netns-based vrfs\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
if (ifname && !strncasecmp(ifname, "Null0", 5)) {
flag = "Null0";
ifname = NULL;
@@ -931,7 +1007,8 @@ DEFPY(ip_route,
return zebra_static_route_leak(
vty, zvrf, nh_zvrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str,
- NULL, gate_str, ifname, flag, tag_str, distance_str, label);
+ NULL, gate_str, ifname, flag, tag_str, distance_str, label,
+ table_str);
}
DEFPY(ip_route_vrf,
@@ -943,6 +1020,7 @@ DEFPY(ip_route_vrf,
tag (1-4294967295) \
|(1-255)$distance \
|label WORD \
+ |table (1-4294967295) \
|nexthop-vrf NAME \
}]",
NO_STR IP_STR
@@ -956,13 +1034,21 @@ DEFPY(ip_route_vrf,
"Tag value\n"
"Distance value for this route\n"
MPLS_LABEL_HELPSTR
+ "Table to configure\n"
+ "The table number to configure\n"
VRF_CMD_HELP_STR)
{
VTY_DECLVAR_CONTEXT(vrf, vrf);
struct zebra_vrf *zvrf = vrf->info;
struct zebra_vrf *nh_zvrf;
-
const char *flag = NULL;
+
+ if (table_str && !vrf_is_backend_netns()) {
+ vty_out(vty,
+ "%% table param only available when running on netns-based vrfs\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
if (ifname && !strncasecmp(ifname, "Null0", 5)) {
flag = "Null0";
ifname = NULL;
@@ -980,7 +1066,8 @@ DEFPY(ip_route_vrf,
return zebra_static_route_leak(
vty, zvrf, nh_zvrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str,
- NULL, gate_str, ifname, flag, tag_str, distance_str, label);
+ NULL, gate_str, ifname, flag, tag_str, distance_str, label,
+ NULL);
}
/* New RIB. Detailed information for IPv4 route. */
@@ -1696,6 +1783,35 @@ DEFPY (show_route_table,
return CMD_SUCCESS;
}
+DEFPY (show_route_table_vrf,
+ show_route_table_vrf_cmd,
+ "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table vrf NAME$vrf_name [json$json]",
+ SHOW_STR
+ IP_STR
+ IP6_STR
+ "IP routing table\n"
+ "Table to display\n"
+ "The table number to display, if available\n"
+ VRF_CMD_HELP_STR
+ JSON_STR)
+{
+ afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
+ struct zebra_vrf *zvrf;
+ struct route_table *t;
+ vrf_id_t vrf_id = VRF_DEFAULT;
+
+ if (vrf_name)
+ VRF_GET_ID(vrf_id, vrf_name);
+ zvrf = zebra_vrf_lookup_by_id(vrf_id);
+
+ t = zebra_ns_find_table(zvrf->zns, table, afi);
+ if (t)
+ do_show_route_helper(vty, zvrf, t, afi, false, 0, false, false,
+ 0, 0, !!json);
+
+ return CMD_SUCCESS;
+}
+
DEFUN (show_ip_nht,
show_ip_nht_cmd,
"show ip nht [vrf NAME]",
@@ -2258,6 +2374,8 @@ int static_config(struct vty *vty, struct zebra_vrf *zvrf, afi_t afi,
vty_out(vty, "%s ", shr->distance_str);
if (shr->label_str)
vty_out(vty, "label %s ", shr->label_str);
+ if (shr->table_str)
+ vty_out(vty, "table %s ", shr->table_str);
if (strcmp(shr->vrf_name, shr->nhvrf_name) != 0)
vty_out(vty, "nexthop-vrf %s", shr->nhvrf_name);
vty_out(vty, "\n");
@@ -2324,6 +2442,11 @@ int static_config(struct vty *vty, struct zebra_vrf *zvrf, afi_t afi,
vty_out(vty, " nexthop-vrf %s", si->nh_vrfname);
}
+ /* table ID from VRF overrides configured
+ */
+ if (si->table_id && zvrf->table_id == RT_TABLE_MAIN)
+ vty_out(vty, " table %u", si->table_id);
+
vty_out(vty, "\n");
write = 1;
@@ -2340,6 +2463,7 @@ DEFPY(ipv6_route_blackhole,
|(1-255)$distance \
|vrf NAME \
|label WORD \
+ |table (1-4294967295) \
}]",
NO_STR
IPV6_STR
@@ -2354,11 +2478,19 @@ DEFPY(ipv6_route_blackhole,
"Tag value\n"
"Distance value for this prefix\n"
VRF_CMD_HELP_STR
- MPLS_LABEL_HELPSTR)
+ MPLS_LABEL_HELPSTR
+ "Table to configure\n"
+ "The table number to configure\n")
{
+ if (table_str && !vrf_is_backend_netns()) {
+ vty_out(vty,
+ "%% table param only available when running on netns-based vrfs\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
return zebra_static_route(vty, AFI_IP6, SAFI_UNICAST, no, prefix_str,
NULL, from_str, NULL, NULL, flag, tag_str,
- distance_str, vrf, label);
+ distance_str, vrf, label, table_str);
}
DEFPY(ipv6_route_blackhole_vrf,
@@ -2369,6 +2501,7 @@ DEFPY(ipv6_route_blackhole_vrf,
tag (1-4294967295) \
|(1-255)$distance \
|label WORD \
+ |table (1-4294967295) \
}]",
NO_STR
IPV6_STR
@@ -2382,11 +2515,18 @@ DEFPY(ipv6_route_blackhole_vrf,
"Set tag for this route\n"
"Tag value\n"
"Distance value for this prefix\n"
- MPLS_LABEL_HELPSTR)
+ MPLS_LABEL_HELPSTR
+ "Table to configure\n"
+ "The table number to configure\n")
{
VTY_DECLVAR_CONTEXT(vrf, vrf);
struct zebra_vrf *zvrf = vrf->info;
+ if (table_str && !vrf_is_backend_netns()) {
+ vty_out(vty,
+ "%% table param only available when running on netns-based vrfs\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
/*
* Coverity is complaining that prefix could
* be dereferenced, but we know that prefix will
@@ -2395,7 +2535,8 @@ DEFPY(ipv6_route_blackhole_vrf,
assert(prefix);
return zebra_static_route_leak(
vty, zvrf, zvrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
- from_str, NULL, NULL, flag, tag_str, distance_str, label);
+ from_str, NULL, NULL, flag, tag_str, distance_str, label,
+ table_str);
}
DEFPY(ipv6_route_address_interface,
@@ -2408,6 +2549,7 @@ DEFPY(ipv6_route_address_interface,
|(1-255)$distance \
|vrf NAME \
|label WORD \
+ |table (1-4294967295) \
|nexthop-vrf NAME \
}]",
NO_STR
@@ -2423,11 +2565,19 @@ DEFPY(ipv6_route_address_interface,
"Distance value for this prefix\n"
VRF_CMD_HELP_STR
MPLS_LABEL_HELPSTR
+ "Table to configure\n"
+ "The table number to configure\n"
VRF_CMD_HELP_STR)
{
struct zebra_vrf *zvrf;
struct zebra_vrf *nh_zvrf;
+ if (table_str && !vrf_is_backend_netns()) {
+ vty_out(vty,
+ "%% table param only available when running on netns-based vrfs\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
zvrf = zebra_vty_get_unknown_vrf(vty, vrf);
if (!zvrf) {
vty_out(vty, "%% vrf %s is not defined\n", vrf);
@@ -2446,7 +2596,8 @@ DEFPY(ipv6_route_address_interface,
return zebra_static_route_leak(
vty, zvrf, nh_zvrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
- from_str, gate_str, ifname, NULL, tag_str, distance_str, label);
+ from_str, gate_str, ifname, NULL, tag_str, distance_str, label,
+ table_str);
}
DEFPY(ipv6_route_address_interface_vrf,
@@ -2458,6 +2609,7 @@ DEFPY(ipv6_route_address_interface_vrf,
tag (1-4294967295) \
|(1-255)$distance \
|label WORD \
+ |table (1-4294967295) \
|nexthop-vrf NAME \
}]",
NO_STR
@@ -2472,12 +2624,20 @@ DEFPY(ipv6_route_address_interface_vrf,
"Tag value\n"
"Distance value for this prefix\n"
MPLS_LABEL_HELPSTR
+ "Table to configure\n"
+ "The table number to configure\n"
VRF_CMD_HELP_STR)
{
VTY_DECLVAR_CONTEXT(vrf, vrf);
struct zebra_vrf *zvrf = vrf->info;
struct zebra_vrf *nh_zvrf;
+ if (table_str && !vrf_is_backend_netns()) {
+ vty_out(vty,
+ "%% table param only available when running on netns-based vrfs\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
if (nexthop_vrf)
nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf);
else
@@ -2490,7 +2650,8 @@ DEFPY(ipv6_route_address_interface_vrf,
return zebra_static_route_leak(
vty, zvrf, nh_zvrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
- from_str, gate_str, ifname, NULL, tag_str, distance_str, label);
+ from_str, gate_str, ifname, NULL, tag_str, distance_str, label,
+ table_str);
}
DEFPY(ipv6_route,
@@ -2502,6 +2663,7 @@ DEFPY(ipv6_route,
|(1-255)$distance \
|vrf NAME \
|label WORD \
+ |table (1-4294967295) \
|nexthop-vrf NAME \
}]",
NO_STR
@@ -2517,11 +2679,19 @@ DEFPY(ipv6_route,
"Distance value for this prefix\n"
VRF_CMD_HELP_STR
MPLS_LABEL_HELPSTR
+ "Table to configure\n"
+ "The table number to configure\n"
VRF_CMD_HELP_STR)
{
struct zebra_vrf *zvrf;
struct zebra_vrf *nh_zvrf;
+ if (table_str && !vrf_is_backend_netns()) {
+ vty_out(vty,
+ "%% table param only available when running on netns-based vrfs\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
zvrf = zebra_vty_get_unknown_vrf(vty, vrf);
if (!zvrf) {
vty_out(vty, "%% vrf %s is not defined\n", vrf);
@@ -2540,7 +2710,8 @@ DEFPY(ipv6_route,
return zebra_static_route_leak(
vty, zvrf, nh_zvrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
- from_str, gate_str, ifname, NULL, tag_str, distance_str, label);
+ from_str, gate_str, ifname, NULL, tag_str, distance_str, label,
+ table_str);
}
DEFPY(ipv6_route_vrf,
@@ -2551,6 +2722,7 @@ DEFPY(ipv6_route_vrf,
tag (1-4294967295) \
|(1-255)$distance \
|label WORD \
+ |table (1-4294967295) \
|nexthop-vrf NAME \
}]",
NO_STR
@@ -2565,12 +2737,20 @@ DEFPY(ipv6_route_vrf,
"Tag value\n"
"Distance value for this prefix\n"
MPLS_LABEL_HELPSTR
+ "Table to configure\n"
+ "The table number to configure\n"
VRF_CMD_HELP_STR)
{
VTY_DECLVAR_CONTEXT(vrf, vrf);
struct zebra_vrf *zvrf = vrf->info;
struct zebra_vrf *nh_zvrf;
+ if (table_str && !vrf_is_backend_netns()) {
+ vty_out(vty,
+ "%% table param only available when running on netns-based vrfs\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
if (nexthop_vrf)
nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf);
else
@@ -2583,7 +2763,8 @@ DEFPY(ipv6_route_vrf,
return zebra_static_route_leak(
vty, zvrf, nh_zvrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
- from_str, gate_str, ifname, NULL, tag_str, distance_str, label);
+ from_str, gate_str, ifname, NULL, tag_str, distance_str, label,
+ table_str);
}
/*
@@ -2687,6 +2868,9 @@ DEFUN (show_vrf,
struct vrf *vrf;
struct zebra_vrf *zvrf;
+ if (vrf_is_backend_netns())
+ vty_out(vty, "netns-based vrfs\n");
+
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
if (!(zvrf = vrf->info))
continue;
@@ -3734,11 +3918,13 @@ void zebra_vty_init(void)
install_element(CONFIG_NODE, &ip_multicast_mode_cmd);
install_element(CONFIG_NODE, &no_ip_multicast_mode_cmd);
install_element(CONFIG_NODE, &ip_route_blackhole_cmd);
+ install_element(CONFIG_NODE,
+ &ip_route_address_interface_cmd);
+ install_element(CONFIG_NODE, &ip_route_cmd);
install_element(VRF_NODE, &ip_route_blackhole_vrf_cmd);
- install_element(CONFIG_NODE, &ip_route_address_interface_cmd);
install_element(VRF_NODE, &ip_route_address_interface_vrf_cmd);
- install_element(CONFIG_NODE, &ip_route_cmd);
install_element(VRF_NODE, &ip_route_vrf_cmd);
+
install_element(CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
install_element(CONFIG_NODE, &no_ip_zebra_import_table_cmd);
install_element(CONFIG_NODE, &zebra_workqueue_timer_cmd);
@@ -3750,6 +3936,8 @@ void zebra_vty_init(void)
install_element(VIEW_NODE, &show_vrf_vni_cmd);
install_element(VIEW_NODE, &show_route_cmd);
install_element(VIEW_NODE, &show_route_table_cmd);
+ if (vrf_is_backend_netns())
+ install_element(VIEW_NODE, &show_route_table_vrf_cmd);
install_element(VIEW_NODE, &show_route_detail_cmd);
install_element(VIEW_NODE, &show_route_summary_cmd);
install_element(VIEW_NODE, &show_ip_nht_cmd);
@@ -3760,11 +3948,14 @@ void zebra_vty_init(void)
install_element(VIEW_NODE, &show_ip_rpf_cmd);
install_element(VIEW_NODE, &show_ip_rpf_addr_cmd);
- install_element(CONFIG_NODE, &ipv6_route_blackhole_cmd);
- install_element(VRF_NODE, &ipv6_route_blackhole_vrf_cmd);
- install_element(CONFIG_NODE, &ipv6_route_address_interface_cmd);
- install_element(VRF_NODE, &ipv6_route_address_interface_vrf_cmd);
+ install_element(CONFIG_NODE,
+ &ipv6_route_blackhole_cmd);
+ install_element(CONFIG_NODE,
+ &ipv6_route_address_interface_cmd);
install_element(CONFIG_NODE, &ipv6_route_cmd);
+ install_element(VRF_NODE, &ipv6_route_blackhole_vrf_cmd);
+ install_element(VRF_NODE,
+ &ipv6_route_address_interface_vrf_cmd);
install_element(VRF_NODE, &ipv6_route_vrf_cmd);
install_element(CONFIG_NODE, &ip_nht_default_route_cmd);
install_element(CONFIG_NODE, &no_ip_nht_default_route_cmd);