ospfd: OSPFv2 VRF Changes II

Accomodate review comments

Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
This commit is contained in:
Chirag Shah 2017-09-07 08:08:09 -07:00
parent c0f3f7cdf8
commit 43b8d1d8a1
8 changed files with 516 additions and 489 deletions

1
ospfd/.gitignore vendored
View File

@ -15,3 +15,4 @@ TAGS
*~
*.loT
*.a
*.clippy.c

View File

@ -51,7 +51,7 @@ static void ospf_route_map_update(const char *name)
if (listcount(om->ospf) == 0)
return;
for (ALL_LIST_ELEMENTS_RO (om->ospf, n1, ospf)) {
for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
/* Update route-map */
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
struct list *red_list;

View File

@ -2570,11 +2570,14 @@ DEFUN (show_ip_ospf_mpls_te_link,
}
/* Show All Interfaces. */
if (argc == 5) {
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
for (ALL_LIST_ELEMENTS(vrf_iflist(ospf->vrf_id), node, nnode,
ifp))
for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
if (!ospf->oi_running)
continue;
for (ALL_LIST_ELEMENTS(vrf_iflist(ospf->vrf_id), node,
nnode, ifp))
show_mpls_te_link_sub(vty, ifp);
}
}
/* Interface name is specified. */
else {
ifp = if_lookup_by_name_all_vrf(argv[idx_interface]->arg);

View File

@ -126,36 +126,70 @@ int ospf_oi_count(struct interface *ifp)
return i;
}
#define OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf) \
if (argv_find(argv, argc, "vrf", &idx_vrf)) { \
vrf_name = argv[idx_vrf + 1]->arg; \
all_vrf = strmatch(vrf_name, "all"); \
}
static struct ospf *ospf_cmd_lookup_ospf(struct vty *vty,
struct cmd_token *argv[],
const int argc,
uint32_t enable,
u_short *instance)
{
struct ospf *ospf = NULL;
int idx_vrf = 0;
const char *vrf_name = NULL;
if (argv_find(argv, argc, "vrf", &idx_vrf)) {
vrf_name = argv[idx_vrf + 1]->arg;
if (enable) {
if (argc > 4)
*instance = strtoul(argv[2]->arg, NULL, 10);
/* Allocate VRF aware instance */
ospf = ospf_get(*instance, vrf_name);
} else {
if (argc > 5)
*instance = strtoul(argv[3]->arg, NULL, 10);
ospf = ospf_lookup_by_inst_name(*instance, vrf_name);
}
} else {
if (enable) {
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (!ospf)
vty_out(vty,
"There isn't active ospf instance\n");
if (argc > 2)
*instance = strtoul(argv[2]->arg, NULL, 10);
} else {
if (argc > 3)
*instance = strtoul(argv[3]->arg, NULL, 10);
ospf = ospf_lookup_instance(*instance);
}
}
return ospf;
}
#ifndef VTYSH_EXTRACT_PL
#include "ospf_vty_clippy.c"
#endif
DEFUN_NOSH (router_ospf,
router_ospf_cmd,
"router ospf [(1-65535)] [vrf NAME]",
"router ospf [{(1-65535)|vrf NAME}]",
"Enable a routing process\n"
"Start OSPF configuration\n"
"Instance ID\n"
VRF_CMD_HELP_STR)
{
struct ospf *ospf = NULL;
u_short instance = 0;
int ret = CMD_SUCCESS;
int idx_vrf = 0;
const char *vrf_name = NULL;
u_short instance = 0;
if (argv_find(argv, argc, "vrf", &idx_vrf)) {
if (argc > 4)
instance = strtoul(argv[2]->arg, NULL, 10);
vrf_name = argv[idx_vrf + 1]->arg;
/* Allocate VRF aware instance */
ospf = ospf_get(instance, vrf_name);
} else {
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (!ospf) {
vty_out(vty, "There isn't active ospf instance\n");
ospf = ospf_cmd_lookup_ospf(vty, argv, argc, 1, &instance);
if (!ospf)
return CMD_WARNING_CONFIG_FAILED;
}
if (argc > 2)
instance = strtoul(argv[2]->arg, NULL, 10);
}
/* The following logic to set the vty qobj index is in place to be able
to ignore the commands which dont belong to this instance. */
@ -178,7 +212,7 @@ DEFUN_NOSH (router_ospf,
DEFUN (no_router_ospf,
no_router_ospf_cmd,
"no router ospf [(1-65535)] [vrf NAME]",
"no router ospf [{(1-65535)|vrf NAME}]",
NO_STR
"Enable a routing process\n"
"Start OSPF configuration\n"
@ -187,32 +221,21 @@ DEFUN (no_router_ospf,
{
struct ospf *ospf;
u_short instance = 0;
int idx_vrf = 0;
const char *vrf_name = NULL;
if (argv_find(argv, argc, "vrf", &idx_vrf)) {
if (argc > 5)
instance = strtoul(argv[3]->arg, NULL, 10);
vrf_name = argv[idx_vrf + 1]->arg;
ospf = ospf_lookup_by_inst_name(instance, vrf_name);
if (ospf == NULL)
return CMD_SUCCESS;
} else {
if (argc > 3)
instance = strtoul(argv[3]->arg, NULL, 10);
ospf = ospf_lookup_instance(instance);
if (ospf == NULL)
ospf = ospf_cmd_lookup_ospf(vty, argv, argc, 0, &instance);
if (ospf == NULL) {
if (instance)
return CMD_NOT_MY_INSTANCE;
else
return CMD_WARNING;
}
ospf_finish(ospf);
return CMD_SUCCESS;
}
DEFUN (ospf_router_id,
DEFPY (ospf_router_id,
ospf_router_id_cmd,
"ospf router-id A.B.C.D",
"OSPF specific commands\n"
@ -220,17 +243,9 @@ DEFUN (ospf_router_id,
"OSPF router-id in IP address format\n")
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
int idx_ipv4 = 2;
struct listnode *node;
struct ospf_area *area;
struct in_addr router_id;
int ret;
ret = inet_aton(argv[idx_ipv4]->arg, &router_id);
if (!ret) {
vty_out(vty, "Please specify Router ID by A.B.C.D\n");
return CMD_WARNING_CONFIG_FAILED;
}
ospf->router_id_static = router_id;
@ -281,7 +296,7 @@ DEFUN_HIDDEN (ospf_router_id_old,
return CMD_SUCCESS;
}
DEFUN (no_ospf_router_id,
DEFPY (no_ospf_router_id,
no_ospf_router_id_cmd,
"no ospf router-id [A.B.C.D]",
NO_STR
@ -293,6 +308,13 @@ DEFUN (no_ospf_router_id,
struct listnode *node;
struct ospf_area *area;
if (router_id_str) {
if (!IPV4_ADDR_SAME(&ospf->router_id_static, &router_id)) {
vty_out(vty, "%% OSPF router-id doesn't match\n");
return CMD_WARNING_CONFIG_FAILED;
}
}
ospf->router_id_static.s_addr = 0;
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
@ -3157,10 +3179,7 @@ DEFUN (show_ip_ospf,
if (listcount(om->ospf) == 0)
return CMD_SUCCESS;
if (argv_find(argv, argc, "vrf", &idx_vrf)) {
vrf_name = argv[idx_vrf + 1]->arg;
all_vrf = strmatch(vrf_name, "all");
}
OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
/* vrf input is provided could be all or specific vrf*/
if (vrf_name) {
@ -3606,11 +3625,12 @@ static int show_ip_ospf_interface_common(struct vty *vty, struct ospf *ospf,
DEFUN (show_ip_ospf_interface,
show_ip_ospf_interface_cmd,
"show ip ospf [vrf NAME] interface [INTERFACE] [json]",
"show ip ospf [vrf <NAME|all>] interface [INTERFACE] [json]",
SHOW_STR
IP_STR
"OSPF information\n"
VRF_CMD_HELP_STR
"All VRFs\n"
"Interface information\n"
"Interface name\n"
JSON_STR)
@ -3624,10 +3644,8 @@ DEFUN (show_ip_ospf_interface,
int inst = 0;
int idx_vrf = 0;
if (argv_find(argv, argc, "vrf", &idx_vrf)) {
vrf_name = argv[idx_vrf + 1]->arg;
all_vrf = strmatch(vrf_name, "all");
}
OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
if (uj)
argc--;
@ -3872,10 +3890,7 @@ DEFUN (show_ip_ospf_neighbor,
int inst = 0;
int idx_vrf = 0;
if (argv_find(argv, argc, "vrf", &idx_vrf)) {
vrf_name = argv[idx_vrf + 1]->arg;
all_vrf = strmatch(vrf_name, "all");
}
OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
if (!uj)
show_ip_ospf_neighbour_header(vty);
@ -4051,10 +4066,7 @@ DEFUN (show_ip_ospf_neighbor_all,
int inst = 0;
int idx_vrf = 0;
if (argv_find(argv, argc, "vrf", &idx_vrf)) {
vrf_name = argv[idx_vrf + 1]->arg;
all_vrf = strmatch(vrf_name, "all");
}
OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
if (!uj)
show_ip_ospf_neighbour_header(vty);
@ -4693,10 +4705,7 @@ DEFUN (show_ip_ospf_neighbor_detail,
int inst = 0;
int idx_vrf = 0;
if (argv_find(argv, argc, "vrf", &idx_vrf)) {
vrf_name = argv[idx_vrf + 1]->arg;
all_vrf = strmatch(vrf_name, "all");
}
OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
/* vrf input is provided could be all or specific vrf*/
if (vrf_name) {
@ -4831,10 +4840,7 @@ DEFUN (show_ip_ospf_neighbor_detail_all,
int inst = 0;
int idx_vrf = 0;
if (argv_find(argv, argc, "vrf", &idx_vrf)) {
vrf_name = argv[idx_vrf + 1]->arg;
all_vrf = strmatch(vrf_name, "all");
}
OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
/* vrf input is provided could be all or specific vrf*/
if (vrf_name) {
@ -5670,10 +5676,7 @@ DEFUN (show_ip_ospf_database_max,
int inst = 0;
int idx_vrf = 0;
if (argv_find(argv, argc, "vrf", &idx_vrf)) {
vrf_name = argv[idx_vrf + 1]->arg;
all_vrf = strmatch(vrf_name, "all");
}
OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
if (vrf_name) {
if (all_vrf) {
@ -5705,7 +5708,7 @@ DEFUN (show_ip_ospf_database_max,
DEFUN (show_ip_ospf_instance_database,
show_ip_ospf_instance_database_cmd,
"show ip ospf [(1-65535)] [vrf NAME] database [<asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> [A.B.C.D [<self-originate|adv-router A.B.C.D>]]]",
"show ip ospf [{(1-65535)|vrf NAME}] database [<asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> [A.B.C.D [<self-originate|adv-router A.B.C.D>]]]",
SHOW_STR
IP_STR
"OSPF information\n"
@ -5850,7 +5853,7 @@ static int show_ip_ospf_database_type_adv_router_common(struct vty *vty,
DEFUN (show_ip_ospf_instance_database_type_adv_router,
show_ip_ospf_instance_database_type_adv_router_cmd,
"show ip ospf [(1-65535)] [vrf NAME] database <asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> <adv-router A.B.C.D|self-originate>",
"show ip ospf [{(1-65535)|vrf NAME}] database <asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> <adv-router A.B.C.D|self-originate>",
SHOW_STR
IP_STR
"OSPF information\n"
@ -5869,7 +5872,7 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router,
bool all_vrf = FALSE;
int ret = CMD_SUCCESS;
int inst = 0;
int idx = 0;
int idx = 0, idx_vrf = 0;
if (argv_find(argv, argc, "(1-65535)", &idx)) {
instance = strtoul(argv[idx]->arg, NULL, 10);
@ -5883,10 +5886,9 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router,
argc,
argv));
}
if (argv_find(argv, argc, "vrf", &idx)) {
vrf_name = argv[++idx]->arg;
all_vrf = strmatch(vrf_name, "all");
}
OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
if (vrf_name) {
if (all_vrf) {
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
@ -8397,10 +8399,7 @@ DEFUN (show_ip_ospf_border_routers,
int inst = 0;
int idx_vrf = 0;
if (argv_find(argv, argc, "vrf", &idx_vrf)) {
vrf_name = argv[idx_vrf + 1]->arg;
all_vrf = strmatch(vrf_name, "all");
}
OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
if (vrf_name) {
if (all_vrf) {
@ -8495,10 +8494,7 @@ DEFUN (show_ip_ospf_route,
int inst = 0;
int idx_vrf = 0;
if (argv_find (argv, argc, "vrf", &idx_vrf)) {
vrf_name = argv[idx_vrf + 1]->arg;
all_vrf = strmatch(vrf_name, "all");
}
OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
/* vrf input is provided could be all or specific vrf*/
if (vrf_name) {
@ -8632,20 +8628,14 @@ const char *ospf_int_type_str[] = {"unknown", /* should never be used. */
"virtual-link", /* should never be used. */
"loopback"};
/* Configuration write function for ospfd. */
static int config_write_interface(struct vty *vty)
static int config_write_interface_one(struct vty *vty, struct ospf *ospf)
{
struct listnode *n1, *n2;
struct interface *ifp;
struct crypt_key *ck;
int write = 0;
struct route_node *rn = NULL;
struct ospf_if_params *params;
struct ospf *ospf = NULL;
struct listnode *node = NULL;
/* Traverse all ospf [vrf] instances */
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
int write = 0;
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), n1, ifp)) {
if (memcmp(ifp->name, "VLINK", 5) == 0)
@ -8829,6 +8819,7 @@ static int config_write_interface(struct vty *vty)
size_t buflen = MAX(strlen("4294967295"),
strlen("255.255.255.255"));
char buf[buflen];
area_id2str(buf, sizeof(buf),
&params->if_area,
params->if_area_id_fmt);
@ -8874,7 +8865,20 @@ static int config_write_interface(struct vty *vty)
vty_endframe(vty, NULL);
}
}
return write;
}
/* Configuration write function for ospfd. */
static int config_write_interface(struct vty *vty)
{
int write = 0;
struct ospf *ospf = NULL;
struct listnode *node = NULL;
/* Traverse all ospf [vrf] instances */
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf))
write += config_write_interface_one(vty, ospf);
return write;
}
@ -9214,19 +9218,13 @@ static int config_write_ospf_distance(struct vty *vty, struct ospf *ospf)
return 0;
}
/* OSPF configuration write function. */
static int ospf_config_write(struct vty *vty)
static int ospf_config_write_one(struct vty *vty, struct ospf *ospf)
{
struct ospf *ospf;
struct interface *ifp;
struct ospf_interface *oi;
struct listnode *node, *ospf_node = NULL;
struct listnode *node = NULL;
int write = 0;
if (listcount(om->ospf) == 0)
return write;
for (ALL_LIST_ELEMENTS_RO (om->ospf, ospf_node, ospf)) {
if (ospf->oi_running) {
/* `router ospf' print. */
if (ospf->instance && ospf->name) {
vty_out(vty, "router ospf %d vrf %s\n",
@ -9242,7 +9240,7 @@ static int ospf_config_write(struct vty *vty)
if (!ospf->networks) {
write++;
continue;
return write;
}
/* Router ID print. */
@ -9371,7 +9369,22 @@ static int ospf_config_write(struct vty *vty)
ospf_opaque_config_write_router(vty, ospf);
write++;
}
return write;
}
/* OSPF configuration write function. */
static int ospf_config_write(struct vty *vty)
{
struct ospf *ospf;
struct listnode *ospf_node = NULL;
int write = 0;
if (listcount(om->ospf) == 0)
return write;
for (ALL_LIST_ELEMENTS_RO(om->ospf, ospf_node, ospf)) {
if (ospf->oi_running)
write += ospf_config_write_one(vty, ospf);
}
return write;
}

View File

@ -107,6 +107,8 @@ static int ospf_interface_add(int command, struct zclient *zclient,
struct ospf *ospf = NULL;
ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
if (ifp == NULL)
return 0;
if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
zlog_debug(
@ -123,6 +125,8 @@ static int ospf_interface_add(int command, struct zclient *zclient,
}
ospf = ospf_lookup_by_vrf_id(vrf_id);
if (!ospf)
return 0;
ospf_if_update(ospf, ifp);
@ -282,6 +286,8 @@ static int ospf_interface_address_add(int command, struct zclient *zclient,
}
ospf = ospf_lookup_by_vrf_id(vrf_id);
if (!ospf)
return 0;
ospf_if_update(ospf, c->ifp);
@ -1123,8 +1129,8 @@ void ospf_distribute_list_update(struct ospf *ospf, int type,
{
struct route_table *rt;
struct ospf_external *ext;
void **args = XCALLOC(MTYPE_OSPF_DIST_ARGS, sizeof(void *)*2);
void **args = XCALLOC(MTYPE_OSPF_DIST_ARGS, sizeof (void * )*2);
args[0] = ospf;
args[1] = (void *)((ptrdiff_t) type);
@ -1158,7 +1164,7 @@ static void ospf_filter_update(struct access_list *access)
return;
/* Iterate all ospf [VRF] instances */
for (ALL_LIST_ELEMENTS_RO (om->ospf, n1, ospf)) {
for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
/* Update distribute-list, and apply filter. */
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
struct list *red_list;

View File

@ -447,14 +447,19 @@ struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id)
}
struct ospf *ospf_lookup_by_name(const char *name)
/* It should only be used when processing incoming info update from zebra.
* Other situations, it is not sufficient to lookup the ospf instance by
* vrf_name only without using the instance number.
*/
static struct ospf *ospf_lookup_by_name(const char *vrf_name)
{
struct ospf *ospf = NULL;
struct listnode *node, *nnode;
for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf))
if ((ospf->name == NULL && name == NULL)
|| (ospf->name && name && strcmp(ospf->name, name) == 0))
if ((ospf->name == NULL && vrf_name == NULL)
|| (ospf->name && vrf_name &&
strcmp(ospf->name, vrf_name) == 0))
return ospf;
return NULL;
}
@ -1283,8 +1288,9 @@ void ospf_ls_upd_queue_empty(struct ospf_interface *oi)
void ospf_if_update(struct ospf *ospf, struct interface *ifp)
{
if (!ospf)
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
return;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("%s: interface %s ifp->vrf_id %u ospf vrf %s vrf_id %u router_id %s",

View File

@ -510,11 +510,6 @@ extern const char *ospf_redist_string(u_int route_type);
extern struct ospf *ospf_lookup_instance(u_short);
extern struct ospf *ospf_get(u_short instance, const char *name);
extern struct ospf *ospf_get_instance(u_short);
extern struct ospf *ospf_lookup_by_name(const char *name);
extern struct ospf *ospf_lookup_by_inst_name(u_short instance,
const char *name);
extern struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id);
extern struct ospf *ospf_lookup_by_name(const char *name);
extern struct ospf *ospf_lookup_by_inst_name(u_short instance,
const char *name);
extern struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id);

View File

@ -58,6 +58,9 @@ ospfdheader_HEADERS = \
# end
endif
ospfd/ospf_vty_clippy.c: $(CLIPPY_DEPS)
ospfd/ospf_vty.$(OBJEXT): ospfd/ospf_vty_clippy.c
noinst_HEADERS += \
ospfd/ospf_abr.h \
ospfd/ospf_apiserver.h \