summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_route.c8
-rw-r--r--bgpd/bgp_zebra.c20
-rw-r--r--doc/user/ospfd.rst2
-rw-r--r--doc/user/pathd.rst4
-rw-r--r--isisd/isisd.c6
-rw-r--r--lib/route_opaque.h38
-rw-r--r--lib/subdir.am1
-rw-r--r--lib/vrf.c2
-rw-r--r--ospf6d/ospf6_asbr.c2
-rw-r--r--tests/topotests/zebra_opaque/__init__.py0
-rw-r--r--tests/topotests/zebra_opaque/r1/bgpd.conf5
-rw-r--r--tests/topotests/zebra_opaque/r1/zebra.conf4
-rw-r--r--tests/topotests/zebra_opaque/r2/bgpd.conf12
-rw-r--r--tests/topotests/zebra_opaque/r2/zebra.conf4
-rw-r--r--tests/topotests/zebra_opaque/test_zebra_opaque.py104
-rw-r--r--zebra/zebra_vty.c35
16 files changed, 223 insertions, 24 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index dd1e8471e6..c61aedb560 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -7807,14 +7807,14 @@ int bgp_aggregate_set(struct bgp *bgp, struct prefix *prefix, afi_t afi,
DEFPY_YANG(
aggregate_addressv4, aggregate_addressv4_cmd,
- "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> {"
+ "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
"as-set$as_set_s"
"|summary-only$summary_only"
"|route-map WORD$rmap_name"
"|origin <egp|igp|incomplete>$origin_s"
"|matching-MED-only$match_med"
"|suppress-map WORD$suppress_map"
- "}",
+ "}]",
NO_STR
"Configure BGP aggregate entries\n"
"Aggregate prefix\n"
@@ -7897,14 +7897,14 @@ DEFPY_YANG(
}
DEFPY_YANG(aggregate_addressv6, aggregate_addressv6_cmd,
- "[no] aggregate-address X:X::X:X/M$prefix {"
+ "[no] aggregate-address X:X::X:X/M$prefix [{"
"as-set$as_set_s"
"|summary-only$summary_only"
"|route-map WORD$rmap_name"
"|origin <egp|igp|incomplete>$origin_s"
"|matching-MED-only$match_med"
"|suppress-map WORD$suppress_map"
- "}",
+ "}]",
NO_STR
"Configure BGP aggregate entries\n"
"Aggregate prefix\n"
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 2bf57130be..97f781b2bf 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -33,6 +33,7 @@
#include "memory.h"
#include "lib/json.h"
#include "lib/bfd.h"
+#include "lib/route_opaque.h"
#include "filter.h"
#include "mpls.h"
#include "vxlan.h"
@@ -1400,11 +1401,24 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
is_add = (valid_nh_count || nhg_id) ? true : false;
if (is_add && CHECK_FLAG(bm->flags, BM_FLAG_SEND_EXTRA_DATA_TO_ZEBRA)) {
- struct aspath *aspath = info->attr->aspath;
+ struct bgp_zebra_opaque bzo = {};
+
+ strlcpy(bzo.aspath, info->attr->aspath->str,
+ sizeof(bzo.aspath));
+
+ if (info->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
+ strlcpy(bzo.community, info->attr->community->str,
+ sizeof(bzo.community));
+
+ if (info->attr->flag
+ & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES))
+ strlcpy(bzo.lcommunity, info->attr->lcommunity->str,
+ sizeof(bzo.lcommunity));
SET_FLAG(api.message, ZAPI_MESSAGE_OPAQUE);
- api.opaque.length = strlen(aspath->str) + 1;
- memcpy(api.opaque.data, aspath->str, api.opaque.length);
+ api.opaque.length = MIN(sizeof(struct bgp_zebra_opaque),
+ ZAPI_MESSAGE_OPAQUE_LENGTH);
+ memcpy(api.opaque.data, &bzo, api.opaque.length);
}
if (allow_recursion)
diff --git a/doc/user/ospfd.rst b/doc/user/ospfd.rst
index b321d99ad8..c8b25db8af 100644
--- a/doc/user/ospfd.rst
+++ b/doc/user/ospfd.rst
@@ -855,7 +855,7 @@ Traffic Engineering
flood in AREA <area-id> with Opaque Type-10, respectively in AS with Opaque
Type-11. In all case, Opaque-LSA TLV=6.
-.. clicmd:: no mpls-te export
+.. clicmd:: mpls-te export
Export Traffic Engineering Data Base to other daemons through the ZAPI
Opaque Link State messages.
diff --git a/doc/user/pathd.rst b/doc/user/pathd.rst
index 4c7611bc04..f27360cca7 100644
--- a/doc/user/pathd.rst
+++ b/doc/user/pathd.rst
@@ -104,11 +104,11 @@ Configuration Commands
Configure segment routing traffic engineering.
-.. clicmd:: [no] mpls-te <on|off>
+.. clicmd:: mpls-te <on|off>
Activate/Deactivate use of internal Traffic Engineering Database
-.. clicmd:: [no] mpls-te import <ospfv2|ospfv3|isis>
+.. clicmd:: mpls-te import <ospfv2|ospfv3|isis>
Load data from the selected igp
diff --git a/isisd/isisd.c b/isisd/isisd.c
index bda2295ae1..77b18f9cf7 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -1920,9 +1920,9 @@ DEFUN(no_debug_isis_ldp_sync, no_debug_isis_ldp_sync_cmd,
DEFUN (show_hostname,
show_hostname_cmd,
- "show " PROTO_NAME " hostname",
- SHOW_STR
- PROTO_HELP
+ "show " PROTO_NAME " [vrf <NAME|all>] hostname",
+ SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
+ "All VRFs\n"
"IS-IS Dynamic hostname mapping\n")
{
struct listnode *node;
diff --git a/lib/route_opaque.h b/lib/route_opaque.h
new file mode 100644
index 0000000000..599a0363eb
--- /dev/null
+++ b/lib/route_opaque.h
@@ -0,0 +1,38 @@
+/* Opaque data for Zebra from other daemons.
+ *
+ * Copyright (C) 2021 Donatas Abraitis <donatas.abraitis@gmail.com>
+ *
+ * This file is part of FRRouting (FRR).
+ *
+ * FRR 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, or (at your option) any later version.
+ *
+ * FRR 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
+ */
+
+#ifndef FRR_ROUTE_OPAQUE_H
+#define FRR_ROUTE_OPAQUE_H
+
+#include "bgpd/bgp_aspath.h"
+#include "bgpd/bgp_community.h"
+#include "bgpd/bgp_lcommunity.h"
+
+struct bgp_zebra_opaque {
+ char aspath[ASPATH_STR_DEFAULT_LEN];
+
+ /* Show at least 10 communities AA:BB */
+ char community[COMMUNITY_SIZE * 20];
+
+ /* Show at least 10 large-communities AA:BB:CC */
+ char lcommunity[LCOMMUNITY_SIZE * 30];
+};
+
+#endif /* FRR_ROUTE_OPAQUE_H */
diff --git a/lib/subdir.am b/lib/subdir.am
index 480c2938d0..4015c67ea8 100644
--- a/lib/subdir.am
+++ b/lib/subdir.am
@@ -247,6 +247,7 @@ pkginclude_HEADERS += \
lib/queue.h \
lib/ringbuf.h \
lib/routemap.h \
+ lib/route_opaque.h \
lib/sbuf.h \
lib/seqlock.h \
lib/sha256.h \
diff --git a/lib/vrf.c b/lib/vrf.c
index b6a53839cf..d99ec12ba8 100644
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -675,7 +675,7 @@ int vrf_handler_create(struct vty *vty, const char *vrfname,
if (strlen(vrfname) > VRF_NAMSIZ) {
if (vty)
vty_out(vty,
- "%% VRF name %s invalid: length exceeds %d bytes",
+ "%% VRF name %s invalid: length exceeds %d bytes\n",
vrfname, VRF_NAMSIZ);
else
flog_warn(
diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c
index 96dcdba68f..245e5dcd3d 100644
--- a/ospf6d/ospf6_asbr.c
+++ b/ospf6d/ospf6_asbr.c
@@ -1282,7 +1282,7 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
/* create new entry */
route = ospf6_route_create();
route->type = OSPF6_DEST_TYPE_NETWORK;
- memcpy(&route->prefix, prefix, sizeof(struct prefix));
+ prefix_copy(&route->prefix, prefix);
info = (struct ospf6_external_info *)XCALLOC(
MTYPE_OSPF6_EXTERNAL_INFO, sizeof(struct ospf6_external_info));
diff --git a/tests/topotests/zebra_opaque/__init__.py b/tests/topotests/zebra_opaque/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/zebra_opaque/__init__.py
diff --git a/tests/topotests/zebra_opaque/r1/bgpd.conf b/tests/topotests/zebra_opaque/r1/bgpd.conf
new file mode 100644
index 0000000000..b0eac45bba
--- /dev/null
+++ b/tests/topotests/zebra_opaque/r1/bgpd.conf
@@ -0,0 +1,5 @@
+!
+router bgp 65001
+ no bgp ebgp-requires-policy
+ neighbor 192.168.1.2 remote-as external
+!
diff --git a/tests/topotests/zebra_opaque/r1/zebra.conf b/tests/topotests/zebra_opaque/r1/zebra.conf
new file mode 100644
index 0000000000..b29940f46a
--- /dev/null
+++ b/tests/topotests/zebra_opaque/r1/zebra.conf
@@ -0,0 +1,4 @@
+!
+int r1-eth0
+ ip address 192.168.1.1/24
+!
diff --git a/tests/topotests/zebra_opaque/r2/bgpd.conf b/tests/topotests/zebra_opaque/r2/bgpd.conf
new file mode 100644
index 0000000000..517ef70f2a
--- /dev/null
+++ b/tests/topotests/zebra_opaque/r2/bgpd.conf
@@ -0,0 +1,12 @@
+router bgp 65002
+ no bgp ebgp-requires-policy
+ neighbor 192.168.1.1 remote-as external
+ address-family ipv4 unicast
+ redistribute connected
+ neighbor 192.168.1.1 route-map r1 out
+ exit-address-family
+!
+route-map r1 permit 10
+ set community 65002:1 65002:2
+ set large-community 65002:1:1 65002:2:1
+!
diff --git a/tests/topotests/zebra_opaque/r2/zebra.conf b/tests/topotests/zebra_opaque/r2/zebra.conf
new file mode 100644
index 0000000000..cffe827363
--- /dev/null
+++ b/tests/topotests/zebra_opaque/r2/zebra.conf
@@ -0,0 +1,4 @@
+!
+int r2-eth0
+ ip address 192.168.1.2/24
+!
diff --git a/tests/topotests/zebra_opaque/test_zebra_opaque.py b/tests/topotests/zebra_opaque/test_zebra_opaque.py
new file mode 100644
index 0000000000..cc52fbd1a7
--- /dev/null
+++ b/tests/topotests/zebra_opaque/test_zebra_opaque.py
@@ -0,0 +1,104 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2021 by
+# Donatas Abraitis <donatas.abraitis@gmail.com>
+#
+# Permission to use, copy, modify, and/or distribute this software
+# for any purpose with or without fee is hereby granted, provided
+# that the above copyright notice and this permission notice appear
+# in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+#
+
+"""
+Test if Opaque Data is accessable from other daemons in Zebra
+"""
+
+import os
+import sys
+import json
+import time
+import pytest
+import functools
+
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# pylint: disable=C0413
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.topolog import logger
+from mininet.topo import Topo
+
+
+class TemplateTopo(Topo):
+ def build(self, *_args, **_opts):
+ tgen = get_topogen(self)
+
+ for routern in range(1, 3):
+ tgen.add_router("r{}".format(routern))
+
+ switch = tgen.add_switch("s1")
+ switch.add_link(tgen.gears["r1"])
+ switch.add_link(tgen.gears["r2"])
+
+
+def setup_module(mod):
+ tgen = Topogen(TemplateTopo, mod.__name__)
+ tgen.start_topology()
+
+ router_list = tgen.routers()
+
+ for i, (rname, router) in enumerate(router_list.items(), 1):
+ router.load_config(
+ TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+ )
+ router.load_config(
+ TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
+ )
+
+ tgen.start_router()
+
+
+def teardown_module(mod):
+ tgen = get_topogen()
+ tgen.stop_topology()
+
+
+def test_zebra_opaque():
+ tgen = get_topogen()
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ router = tgen.gears["r1"]
+
+ def _bgp_converge(router):
+ output = json.loads(router.vtysh_cmd("show ip route 192.168.1.0/24 json"))
+ expected = {
+ "192.168.1.0/24": [
+ {
+ "communities": "65002:1 65002:2",
+ "largeCommunities": "65002:1:1 65002:2:1",
+ }
+ ]
+ }
+ return topotest.json_cmp(output, expected)
+
+ test_func = functools.partial(_bgp_converge, router)
+ success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+
+ assert result is None, 'Cannot see BGP community aliases "{}"'.format(router)
+
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 8061f34d2b..861600596e 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -42,6 +42,7 @@
#include "zebra/redistribute.h"
#include "zebra/zebra_routemap.h"
#include "lib/json.h"
+#include "lib/route_opaque.h"
#include "zebra/zebra_vxlan.h"
#include "zebra/zebra_evpn_mh.h"
#ifndef VTYSH_EXTRACT_PL
@@ -421,6 +422,8 @@ static void show_nexthop_detail_helper(struct vty *vty,
static void zebra_show_ip_route_opaque(struct vty *vty, struct route_entry *re,
struct json_object *json)
{
+ struct bgp_zebra_opaque bzo = {};
+
if (!re->opaque)
return;
@@ -433,13 +436,27 @@ static void zebra_show_ip_route_opaque(struct vty *vty, struct route_entry *re,
vty_out(vty, " Opaque Data: %s",
(char *)re->opaque->data);
break;
- case ZEBRA_ROUTE_BGP:
- if (json)
- json_object_string_add(json, "asPath",
- (char *)re->opaque->data);
- else
- vty_out(vty, " AS-Path: %s",
- (char *)re->opaque->data);
+ case ZEBRA_ROUTE_BGP: {
+ memcpy(&bzo, re->opaque->data, re->opaque->length);
+
+ if (json) {
+ json_object_string_add(json, "asPath", bzo.aspath);
+ json_object_string_add(json, "communities",
+ bzo.community);
+ json_object_string_add(json, "largeCommunities",
+ bzo.lcommunity);
+ } else {
+ vty_out(vty, " AS-Path : %s\n", bzo.aspath);
+
+ if (bzo.community[0] != '\0')
+ vty_out(vty, " Communities : %s\n",
+ bzo.community);
+
+ if (bzo.lcommunity[0] != '\0')
+ vty_out(vty, " Large-Communities: %s\n",
+ bzo.lcommunity);
+ }
+ }
default:
break;
}
@@ -2530,8 +2547,8 @@ DEFPY (evpn_mh_neigh_holdtime,
"Duration in seconds\n")
{
- return zebra_evpn_mh_neigh_holdtime_update(vty, duration,
- no ? true : false);
+ return zebra_evpn_mh_neigh_holdtime_update(vty, duration,
+ no ? true : false);
}
DEFPY (evpn_mh_startup_delay,