forked from Mirror/frr
Merge pull request #9644 from opensourcerouting/ospf-opaque-attrs
OSPF opaque route attributes
This commit is contained in:
commit
05786ac774
|
@ -65,6 +65,8 @@
|
|||
#include "bgpd/bgp_evpn_mh.h"
|
||||
#include "bgpd/bgp_mac.h"
|
||||
#include "bgpd/bgp_trace.h"
|
||||
#include "bgpd/bgp_community.h"
|
||||
#include "bgpd/bgp_lcommunity.h"
|
||||
|
||||
/* All information about zebra. */
|
||||
struct zclient *zclient = NULL;
|
||||
|
|
|
@ -24,9 +24,12 @@
|
|||
#include "assert.h"
|
||||
#include "zclient.h"
|
||||
|
||||
#include "bgpd/bgp_aspath.h"
|
||||
#include "bgpd/bgp_community.h"
|
||||
#include "bgpd/bgp_lcommunity.h"
|
||||
/* copied from bgpd/bgp_community.h */
|
||||
#define COMMUNITY_SIZE 4
|
||||
/* copied from bgpd/bgp_lcommunity.h */
|
||||
#define LCOMMUNITY_SIZE 12
|
||||
/* copied from bgpd/bgp_route.h */
|
||||
#define BGP_MAX_SELECTION_REASON_STR_BUF 32
|
||||
|
||||
struct bgp_zebra_opaque {
|
||||
char aspath[256];
|
||||
|
@ -44,7 +47,15 @@ struct bgp_zebra_opaque {
|
|||
char selection_reason[BGP_MAX_SELECTION_REASON_STR_BUF];
|
||||
};
|
||||
|
||||
struct ospf_zebra_opaque {
|
||||
char path_type[32];
|
||||
char area_id[INET_ADDRSTRLEN];
|
||||
char tag[16];
|
||||
};
|
||||
|
||||
static_assert(sizeof(struct bgp_zebra_opaque) <= ZAPI_MESSAGE_OPAQUE_LENGTH,
|
||||
"BGP opaque data shouldn't be larger than zebra's buffer");
|
||||
static_assert(sizeof(struct ospf_zebra_opaque) <= ZAPI_MESSAGE_OPAQUE_LENGTH,
|
||||
"OSPF opaque data shouldn't be larger than zebra's buffer");
|
||||
|
||||
#endif /* FRR_ROUTE_OPAQUE_H */
|
||||
|
|
|
@ -124,7 +124,6 @@ struct ospf6_area {
|
|||
#define OSPF6_NSSA_TRANSLATE_ENABLED 1
|
||||
};
|
||||
|
||||
#define OSPF6_AREA_DEFAULT 0x00
|
||||
#define OSPF6_AREA_ENABLE 0x01
|
||||
#define OSPF6_AREA_ACTIVE 0x02
|
||||
#define OSPF6_AREA_TRANSIT 0x04 /* TransitCapability */
|
||||
|
|
|
@ -148,8 +148,7 @@ struct ospf6_path {
|
|||
#define OSPF6_PATH_TYPE_INTER 2
|
||||
#define OSPF6_PATH_TYPE_EXTERNAL1 3
|
||||
#define OSPF6_PATH_TYPE_EXTERNAL2 4
|
||||
#define OSPF6_PATH_TYPE_REDISTRIBUTE 5
|
||||
#define OSPF6_PATH_TYPE_MAX 6
|
||||
#define OSPF6_PATH_TYPE_MAX 5
|
||||
|
||||
#define OSPF6_PATH_SUBTYPE_DEFAULT_RT 1
|
||||
|
||||
|
|
|
@ -436,6 +436,7 @@ static struct ospf6 *ospf6_create(const char *name)
|
|||
o->fd = -1;
|
||||
|
||||
o->max_multipath = MULTIPATH_NUM;
|
||||
SET_FLAG(o->config_flags, OSPF6_SEND_EXTRA_DATA_TO_ZEBRA);
|
||||
|
||||
o->oi_write_q = list_new();
|
||||
|
||||
|
@ -885,6 +886,39 @@ DEFUN (no_ospf6_log_adjacency_changes_detail,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static void ospf6_reinstall_routes(struct ospf6 *ospf6)
|
||||
{
|
||||
struct ospf6_route *route;
|
||||
|
||||
for (route = ospf6_route_head(ospf6->route_table); route;
|
||||
route = ospf6_route_next(route))
|
||||
ospf6_zebra_route_update_add(route, ospf6);
|
||||
}
|
||||
|
||||
DEFPY (ospf6_send_extra_data,
|
||||
ospf6_send_extra_data_cmd,
|
||||
"[no] ospf6 send-extra-data zebra",
|
||||
NO_STR
|
||||
OSPF6_STR
|
||||
"Extra data to Zebra for display/use\n"
|
||||
"To zebra\n")
|
||||
{
|
||||
VTY_DECLVAR_CONTEXT(ospf6, ospf6);
|
||||
|
||||
if (no
|
||||
&& CHECK_FLAG(ospf6->config_flags,
|
||||
OSPF6_SEND_EXTRA_DATA_TO_ZEBRA)) {
|
||||
UNSET_FLAG(ospf6->config_flags, OSPF6_SEND_EXTRA_DATA_TO_ZEBRA);
|
||||
ospf6_reinstall_routes(ospf6);
|
||||
} else if (!CHECK_FLAG(ospf6->config_flags,
|
||||
OSPF6_SEND_EXTRA_DATA_TO_ZEBRA)) {
|
||||
SET_FLAG(ospf6->config_flags, OSPF6_SEND_EXTRA_DATA_TO_ZEBRA);
|
||||
ospf6_reinstall_routes(ospf6);
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (ospf6_timers_lsa,
|
||||
ospf6_timers_lsa_cmd,
|
||||
"timers lsa min-arrival (0-600000)",
|
||||
|
@ -2202,6 +2236,10 @@ static int config_write_ospf6(struct vty *vty)
|
|||
vty_out(vty, " ospf6 router-id %pI4\n",
|
||||
&ospf6->router_id_static);
|
||||
|
||||
if (!CHECK_FLAG(ospf6->config_flags,
|
||||
OSPF6_SEND_EXTRA_DATA_TO_ZEBRA))
|
||||
vty_out(vty, " no ospf6 send-extra-data zebra\n");
|
||||
|
||||
/* log-adjacency-changes flag print. */
|
||||
if (CHECK_FLAG(ospf6->config_flags,
|
||||
OSPF6_LOG_ADJACENCY_CHANGES)) {
|
||||
|
@ -2287,6 +2325,7 @@ void ospf6_top_init(void)
|
|||
install_element(OSPF6_NODE, &ospf6_log_adjacency_changes_detail_cmd);
|
||||
install_element(OSPF6_NODE, &no_ospf6_log_adjacency_changes_cmd);
|
||||
install_element(OSPF6_NODE, &no_ospf6_log_adjacency_changes_detail_cmd);
|
||||
install_element(OSPF6_NODE, &ospf6_send_extra_data_cmd);
|
||||
|
||||
/* LSA timers commands */
|
||||
install_element(OSPF6_NODE, &ospf6_timers_lsa_cmd);
|
||||
|
|
|
@ -32,9 +32,9 @@ struct ospf6_master {
|
|||
};
|
||||
|
||||
/* ospf6->config_flags */
|
||||
enum {
|
||||
OSPF6_LOG_ADJACENCY_CHANGES = (1 << 0),
|
||||
OSPF6_LOG_ADJACENCY_DETAIL = (1 << 1),
|
||||
enum { OSPF6_LOG_ADJACENCY_CHANGES = (1 << 0),
|
||||
OSPF6_LOG_ADJACENCY_DETAIL = (1 << 1),
|
||||
OSPF6_SEND_EXTRA_DATA_TO_ZEBRA = (1 << 2),
|
||||
};
|
||||
|
||||
/* For processing route-map change update in the callback */
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "stream.h"
|
||||
#include "zclient.h"
|
||||
#include "memory.h"
|
||||
#include "route_opaque.h"
|
||||
#include "lib/bfd.h"
|
||||
#include "lib_errors.h"
|
||||
|
||||
|
@ -371,6 +372,38 @@ DEFUN(show_zebra,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static void ospf6_zebra_append_opaque_attr(struct ospf6_route *request,
|
||||
struct zapi_route *api)
|
||||
{
|
||||
struct ospf_zebra_opaque ospf_opaque = {};
|
||||
|
||||
/* OSPF path type */
|
||||
snprintf(ospf_opaque.path_type, sizeof(ospf_opaque.path_type), "%s",
|
||||
OSPF6_PATH_TYPE_NAME(request->path.type));
|
||||
|
||||
switch (request->path.type) {
|
||||
case OSPF6_PATH_TYPE_INTRA:
|
||||
case OSPF6_PATH_TYPE_INTER:
|
||||
/* OSPF area ID */
|
||||
(void)inet_ntop(AF_INET, &request->path.area_id,
|
||||
ospf_opaque.area_id,
|
||||
sizeof(ospf_opaque.area_id));
|
||||
break;
|
||||
case OSPF6_PATH_TYPE_EXTERNAL1:
|
||||
case OSPF6_PATH_TYPE_EXTERNAL2:
|
||||
/* OSPF route tag */
|
||||
snprintf(ospf_opaque.tag, sizeof(ospf_opaque.tag), "%u",
|
||||
request->path.tag);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
SET_FLAG(api->message, ZAPI_MESSAGE_OPAQUE);
|
||||
api->opaque.length = sizeof(struct ospf_zebra_opaque);
|
||||
memcpy(api->opaque.data, &ospf_opaque, api->opaque.length);
|
||||
}
|
||||
|
||||
#define ADD 0
|
||||
#define REM 1
|
||||
static void ospf6_zebra_route_update(int type, struct ospf6_route *request,
|
||||
|
@ -455,6 +488,10 @@ static void ospf6_zebra_route_update(int type, struct ospf6_route *request,
|
|||
api.distance = ospf6_distance_apply((struct prefix_ipv6 *)dest, request,
|
||||
ospf6);
|
||||
|
||||
if (type == ADD
|
||||
&& CHECK_FLAG(ospf6->config_flags, OSPF6_SEND_EXTRA_DATA_TO_ZEBRA))
|
||||
ospf6_zebra_append_opaque_attr(request, &api);
|
||||
|
||||
if (type == REM)
|
||||
ret = zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
|
||||
else
|
||||
|
|
|
@ -39,6 +39,22 @@
|
|||
#include "ospfd/ospf_zebra.h"
|
||||
#include "ospfd/ospf_dump.h"
|
||||
|
||||
const char *ospf_path_type_name(int path_type)
|
||||
{
|
||||
switch (path_type) {
|
||||
case OSPF_PATH_INTRA_AREA:
|
||||
return "Intra-Area";
|
||||
case OSPF_PATH_INTER_AREA:
|
||||
return "Inter-Area";
|
||||
case OSPF_PATH_TYPE1_EXTERNAL:
|
||||
return "External-1";
|
||||
case OSPF_PATH_TYPE2_EXTERNAL:
|
||||
return "External-2";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
struct ospf_route *ospf_route_new(void)
|
||||
{
|
||||
struct ospf_route *new;
|
||||
|
|
|
@ -128,6 +128,7 @@ struct ospf_route {
|
|||
bool changed;
|
||||
};
|
||||
|
||||
extern const char *ospf_path_type_name(int path_type);
|
||||
extern struct ospf_path *ospf_path_new(void);
|
||||
extern void ospf_path_free(struct ospf_path *);
|
||||
extern struct ospf_path *ospf_path_lookup(struct list *, struct ospf_path *);
|
||||
|
|
|
@ -2218,6 +2218,53 @@ ALIAS(no_ospf_compatible_rfc1583, no_ospf_rfc1583_flag_cmd,
|
|||
"OSPF specific commands\n"
|
||||
"Disable the RFC1583Compatibility flag\n")
|
||||
|
||||
static void ospf_table_reinstall_routes(struct ospf *ospf,
|
||||
struct route_table *rt)
|
||||
{
|
||||
struct route_node *rn;
|
||||
|
||||
for (rn = route_top(rt); rn; rn = route_next(rn)) {
|
||||
struct ospf_route *or;
|
||||
|
||||
or = rn->info;
|
||||
if (!or)
|
||||
continue;
|
||||
|
||||
if (or->type == OSPF_DESTINATION_NETWORK)
|
||||
ospf_zebra_add(ospf, (struct prefix_ipv4 *)&rn->p, or);
|
||||
else if (or->type == OSPF_DESTINATION_DISCARD)
|
||||
ospf_zebra_add_discard(ospf,
|
||||
(struct prefix_ipv4 *)&rn->p);
|
||||
}
|
||||
}
|
||||
|
||||
static void ospf_reinstall_routes(struct ospf *ospf)
|
||||
{
|
||||
ospf_table_reinstall_routes(ospf, ospf->new_table);
|
||||
ospf_table_reinstall_routes(ospf, ospf->new_external_route);
|
||||
}
|
||||
|
||||
DEFPY (ospf_send_extra_data,
|
||||
ospf_send_extra_data_cmd,
|
||||
"[no] ospf send-extra-data zebra",
|
||||
NO_STR
|
||||
OSPF_STR
|
||||
"Extra data to Zebra for display/use\n"
|
||||
"To zebra\n")
|
||||
{
|
||||
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
||||
|
||||
if (no && CHECK_FLAG(ospf->config, OSPF_SEND_EXTRA_DATA_TO_ZEBRA)) {
|
||||
UNSET_FLAG(ospf->config, OSPF_SEND_EXTRA_DATA_TO_ZEBRA);
|
||||
ospf_reinstall_routes(ospf);
|
||||
} else if (!CHECK_FLAG(ospf->config, OSPF_SEND_EXTRA_DATA_TO_ZEBRA)) {
|
||||
SET_FLAG(ospf->config, OSPF_SEND_EXTRA_DATA_TO_ZEBRA);
|
||||
ospf_reinstall_routes(ospf);
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static int ospf_timers_spf_set(struct vty *vty, unsigned int delay,
|
||||
unsigned int hold, unsigned int max)
|
||||
{
|
||||
|
@ -12212,6 +12259,10 @@ static int ospf_config_write_one(struct vty *vty, struct ospf *ospf)
|
|||
vty_out(vty, " ospf router-id %pI4\n",
|
||||
&ospf->router_id_static);
|
||||
|
||||
/* zebra opaque attributes configuration. */
|
||||
if (!CHECK_FLAG(ospf->config, OSPF_SEND_EXTRA_DATA_TO_ZEBRA))
|
||||
vty_out(vty, " no ospf send-extra-data zebra\n");
|
||||
|
||||
/* ABR type print. */
|
||||
if (ospf->abr_type != OSPF_ABR_DEFAULT)
|
||||
vty_out(vty, " ospf abr-type %s\n",
|
||||
|
@ -12663,6 +12714,9 @@ void ospf_vty_init(void)
|
|||
install_element(OSPF_NODE, &ospf_rfc1583_flag_cmd);
|
||||
install_element(OSPF_NODE, &no_ospf_rfc1583_flag_cmd);
|
||||
|
||||
/* "ospf send-extra-data zebra" commands. */
|
||||
install_element(OSPF_NODE, &ospf_send_extra_data_cmd);
|
||||
|
||||
/* "network area" commands. */
|
||||
install_element(OSPF_NODE, &ospf_network_area_cmd);
|
||||
install_element(OSPF_NODE, &no_ospf_network_area_cmd);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "filter.h"
|
||||
#include "plist.h"
|
||||
#include "log.h"
|
||||
#include "route_opaque.h"
|
||||
#include "lib/bfd.h"
|
||||
#include "nexthop.h"
|
||||
|
||||
|
@ -255,6 +256,38 @@ static void ospf_zebra_add_nexthop(struct ospf *ospf, struct ospf_path *path,
|
|||
api->nexthop_num++;
|
||||
}
|
||||
|
||||
static void ospf_zebra_append_opaque_attr(struct ospf_route *or,
|
||||
struct zapi_route *api)
|
||||
{
|
||||
struct ospf_zebra_opaque ospf_opaque = {};
|
||||
|
||||
/* OSPF path type */
|
||||
snprintf(ospf_opaque.path_type, sizeof(ospf_opaque.path_type), "%s",
|
||||
ospf_path_type_name(or->path_type));
|
||||
|
||||
switch (or->path_type) {
|
||||
case OSPF_PATH_INTRA_AREA:
|
||||
case OSPF_PATH_INTER_AREA:
|
||||
/* OSPF area ID */
|
||||
(void)inet_ntop(AF_INET, &or->u.std.area_id,
|
||||
ospf_opaque.area_id,
|
||||
sizeof(ospf_opaque.area_id));
|
||||
break;
|
||||
case OSPF_PATH_TYPE1_EXTERNAL:
|
||||
case OSPF_PATH_TYPE2_EXTERNAL:
|
||||
/* OSPF route tag */
|
||||
snprintf(ospf_opaque.tag, sizeof(ospf_opaque.tag), "%u",
|
||||
or->u.ext.tag);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
SET_FLAG(api->message, ZAPI_MESSAGE_OPAQUE);
|
||||
api->opaque.length = sizeof(struct ospf_zebra_opaque);
|
||||
memcpy(api->opaque.data, &ospf_opaque, api->opaque.length);
|
||||
}
|
||||
|
||||
void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *p,
|
||||
struct ospf_route * or)
|
||||
{
|
||||
|
@ -322,6 +355,9 @@ void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *p,
|
|||
}
|
||||
}
|
||||
|
||||
if (CHECK_FLAG(ospf->config, OSPF_SEND_EXTRA_DATA_TO_ZEBRA))
|
||||
ospf_zebra_append_opaque_attr(or, &api);
|
||||
|
||||
zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
|
||||
}
|
||||
|
||||
|
|
|
@ -406,6 +406,8 @@ struct ospf *ospf_new_alloc(unsigned short instance, const char *name)
|
|||
|
||||
ospf_opaque_type11_lsa_init(new);
|
||||
|
||||
SET_FLAG(new->config, OSPF_SEND_EXTRA_DATA_TO_ZEBRA);
|
||||
|
||||
QOBJ_REG(new, ospf);
|
||||
|
||||
new->fd = -1;
|
||||
|
|
|
@ -125,6 +125,7 @@ enum {
|
|||
OSPF_OPAQUE_CAPABLE = (1 << 2),
|
||||
OSPF_LOG_ADJACENCY_CHANGES = (1 << 3),
|
||||
OSPF_LOG_ADJACENCY_DETAIL = (1 << 4),
|
||||
OSPF_SEND_EXTRA_DATA_TO_ZEBRA = (1 << 5),
|
||||
};
|
||||
|
||||
/* TI-LFA */
|
||||
|
|
8
tests/topotests/zebra_opaque/r3/ospf6d.conf
Normal file
8
tests/topotests/zebra_opaque/r3/ospf6d.conf
Normal file
|
@ -0,0 +1,8 @@
|
|||
!
|
||||
interface r3-eth0
|
||||
ipv6 ospf6 area 0
|
||||
ipv6 ospf6 hello-interval 2
|
||||
ipv6 ospf6 dead-interval 10
|
||||
!
|
||||
router ospf6
|
||||
!
|
8
tests/topotests/zebra_opaque/r3/ospfd.conf
Normal file
8
tests/topotests/zebra_opaque/r3/ospfd.conf
Normal file
|
@ -0,0 +1,8 @@
|
|||
!
|
||||
interface r3-eth0
|
||||
ip ospf area 0
|
||||
ip ospf hello-interval 2
|
||||
ip ospf dead-interval 10
|
||||
!
|
||||
router ospf
|
||||
!
|
5
tests/topotests/zebra_opaque/r3/zebra.conf
Normal file
5
tests/topotests/zebra_opaque/r3/zebra.conf
Normal file
|
@ -0,0 +1,5 @@
|
|||
!
|
||||
int r3-eth0
|
||||
ip address 192.168.1.1/24
|
||||
ipv6 address 2001:db8:1::1/64
|
||||
!
|
8
tests/topotests/zebra_opaque/r4/ospf6d.conf
Normal file
8
tests/topotests/zebra_opaque/r4/ospf6d.conf
Normal file
|
@ -0,0 +1,8 @@
|
|||
!
|
||||
interface r4-eth0
|
||||
ipv6 ospf6 area 0
|
||||
ipv6 ospf6 hello-interval 2
|
||||
ipv6 ospf6 dead-interval 10
|
||||
!
|
||||
router ospf6
|
||||
!
|
8
tests/topotests/zebra_opaque/r4/ospfd.conf
Normal file
8
tests/topotests/zebra_opaque/r4/ospfd.conf
Normal file
|
@ -0,0 +1,8 @@
|
|||
!
|
||||
interface r4-eth0
|
||||
ip ospf area 0
|
||||
ip ospf hello-interval 2
|
||||
ip ospf dead-interval 10
|
||||
!
|
||||
router ospf
|
||||
!
|
5
tests/topotests/zebra_opaque/r4/zebra.conf
Normal file
5
tests/topotests/zebra_opaque/r4/zebra.conf
Normal file
|
@ -0,0 +1,5 @@
|
|||
!
|
||||
int r4-eth0
|
||||
ip address 192.168.1.2/24
|
||||
ipv6 address 2001:db8:1::2/64
|
||||
!
|
|
@ -35,11 +35,11 @@ sys.path.append(os.path.join(CWD, "../"))
|
|||
from lib import topotest
|
||||
from lib.topogen import Topogen, TopoRouter, get_topogen
|
||||
|
||||
pytestmark = [pytest.mark.bgpd]
|
||||
pytestmark = [pytest.mark.bgpd, pytest.mark.ospfd, pytest.mark.ospf6d]
|
||||
|
||||
|
||||
def setup_module(mod):
|
||||
topodef = {"s1": ("r1", "r2")}
|
||||
topodef = {"s1": ("r1", "r2"), "s2": ("r3", "r4")}
|
||||
tgen = Topogen(topodef, mod.__name__)
|
||||
tgen.start_topology()
|
||||
|
||||
|
@ -52,6 +52,12 @@ def setup_module(mod):
|
|||
router.load_config(
|
||||
TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
|
||||
)
|
||||
router.load_config(
|
||||
TopoRouter.RD_OSPF, os.path.join(CWD, "{}/ospfd.conf".format(rname))
|
||||
)
|
||||
router.load_config(
|
||||
TopoRouter.RD_OSPF6, os.path.join(CWD, "{}/ospf6d.conf".format(rname))
|
||||
)
|
||||
|
||||
tgen.start_router()
|
||||
|
||||
|
@ -67,8 +73,6 @@ def test_zebra_opaque():
|
|||
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 = {
|
||||
|
@ -81,11 +85,45 @@ def test_zebra_opaque():
|
|||
}
|
||||
return topotest.json_cmp(output, expected)
|
||||
|
||||
def _ospf_converge(router):
|
||||
output = json.loads(router.vtysh_cmd("show ip route 192.168.1.0/24 json"))
|
||||
expected = {
|
||||
"192.168.1.0/24": [
|
||||
{
|
||||
"ospfPathType": "Intra-Area",
|
||||
"ospfAreaId": "0.0.0.0",
|
||||
}
|
||||
]
|
||||
}
|
||||
return topotest.json_cmp(output, expected)
|
||||
|
||||
def _ospf6_converge(router):
|
||||
output = json.loads(router.vtysh_cmd("show ipv6 route 2001:db8:1::/64 json"))
|
||||
expected = {
|
||||
"2001:db8:1::/64": [
|
||||
{
|
||||
"ospfPathType": "Intra-Area",
|
||||
"ospfAreaId": "0.0.0.0",
|
||||
}
|
||||
]
|
||||
}
|
||||
return topotest.json_cmp(output, expected)
|
||||
|
||||
router = tgen.gears["r1"]
|
||||
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)
|
||||
|
||||
router = tgen.gears["r3"]
|
||||
test_func = functools.partial(_ospf_converge, router)
|
||||
success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
|
||||
assert result is None, 'Cannot see OSPFv2 opaque attributes "{}"'.format(router)
|
||||
|
||||
router = tgen.gears["r3"]
|
||||
test_func = functools.partial(_ospf6_converge, router)
|
||||
success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
|
||||
assert result is None, 'Cannot see OSPFv3 opaque attributes "{}"'.format(router)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = ["-s"] + sys.argv[1:]
|
||||
|
|
|
@ -429,6 +429,7 @@ static void zebra_show_ip_route_opaque(struct vty *vty, struct route_entry *re,
|
|||
struct json_object *json)
|
||||
{
|
||||
struct bgp_zebra_opaque bzo = {};
|
||||
struct ospf_zebra_opaque ozo = {};
|
||||
|
||||
if (!re->opaque)
|
||||
return;
|
||||
|
@ -442,7 +443,7 @@ 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: {
|
||||
case ZEBRA_ROUTE_BGP:
|
||||
memcpy(&bzo, re->opaque->data, re->opaque->length);
|
||||
|
||||
if (json) {
|
||||
|
@ -467,7 +468,31 @@ static void zebra_show_ip_route_opaque(struct vty *vty, struct route_entry *re,
|
|||
vty_out(vty, " Selection reason : %s\n",
|
||||
bzo.selection_reason);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZEBRA_ROUTE_OSPF:
|
||||
case ZEBRA_ROUTE_OSPF6:
|
||||
memcpy(&ozo, re->opaque->data, re->opaque->length);
|
||||
|
||||
if (json) {
|
||||
json_object_string_add(json, "ospfPathType",
|
||||
ozo.path_type);
|
||||
if (ozo.area_id[0] != '\0')
|
||||
json_object_string_add(json, "ospfAreaId",
|
||||
ozo.area_id);
|
||||
if (ozo.tag[0] != '\0')
|
||||
json_object_string_add(json, "ospfTag",
|
||||
ozo.tag);
|
||||
} else {
|
||||
vty_out(vty, " OSPF path type : %s\n",
|
||||
ozo.path_type);
|
||||
if (ozo.area_id[0] != '\0')
|
||||
vty_out(vty, " OSPF area ID : %s\n",
|
||||
ozo.area_id);
|
||||
if (ozo.tag[0] != '\0')
|
||||
vty_out(vty, " OSPF tag : %s\n",
|
||||
ozo.tag);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue