summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--babeld/babel_main.c10
-rw-r--r--babeld/neighbour.c1
-rw-r--r--bgpd/bgp_aspath.c3
-rw-r--r--bgpd/bgp_attr.c4
-rw-r--r--bgpd/bgp_evpn.c8
-rw-r--r--bgpd/bgp_evpn_vty.c20
-rw-r--r--bgpd/bgp_filter.c4
-rw-r--r--bgpd/bgp_label.c1
-rw-r--r--bgpd/bgp_main.c2
-rw-r--r--bgpd/bgp_mplsvpn.c291
-rw-r--r--bgpd/bgp_route.c917
-rw-r--r--bgpd/bgp_route.h4
-rw-r--r--bgpd/bgp_vty.c6
-rw-r--r--bgpd/bgp_zebra.c50
-rw-r--r--bgpd/bgpd.c11
-rw-r--r--bgpd/rfapi/bgp_rfapi_cfg.c15
-rw-r--r--bgpd/rfapi/rfapi.c3
-rw-r--r--bgpd/rfapi/rfapi_import.c16
-rw-r--r--bgpd/rfapi/rfapi_monitor.c2
-rw-r--r--bgpd/rfapi/rfapi_rib.c15
-rw-r--r--bgpd/rfapi/rfapi_vty.c2
-rw-r--r--bgpd/rfapi/vnc_export_bgp.c2
-rw-r--r--bgpd/rfapi/vnc_import_bgp.c2
-rw-r--r--bgpd/rfapi/vnc_zebra.c4
-rw-r--r--debian/control2
-rw-r--r--debian/frr.logrotate2
-rw-r--r--doc/Building_FRR_on_Ubuntu1604.md4
-rw-r--r--eigrpd/eigrp_dump.c10
-rw-r--r--eigrpd/eigrp_filter.c1
-rw-r--r--eigrpd/eigrp_fsm.c14
-rw-r--r--eigrpd/eigrp_hello.c22
-rw-r--r--eigrpd/eigrp_interface.c266
-rw-r--r--eigrpd/eigrp_interface.h8
-rw-r--r--eigrpd/eigrp_macros.h44
-rw-r--r--eigrpd/eigrp_network.c19
-rw-r--r--eigrpd/eigrp_packet.c47
-rw-r--r--eigrpd/eigrp_query.c8
-rw-r--r--eigrpd/eigrp_reply.c10
-rw-r--r--eigrpd/eigrp_siaquery.c8
-rw-r--r--eigrpd/eigrp_siareply.c8
-rw-r--r--eigrpd/eigrp_structs.h59
-rw-r--r--eigrpd/eigrp_topology.c16
-rw-r--r--eigrpd/eigrp_update.c42
-rw-r--r--eigrpd/eigrp_vty.c179
-rw-r--r--eigrpd/eigrp_zebra.c53
-rw-r--r--eigrpd/eigrpd.c8
-rw-r--r--isisd/isis_adjacency.c19
-rw-r--r--isisd/isis_circuit.c81
-rw-r--r--isisd/isis_circuit.h12
-rw-r--r--isisd/isis_constants.h2
-rw-r--r--isisd/isis_dr.c6
-rw-r--r--isisd/isis_events.c6
-rw-r--r--isisd/isis_lsp.c57
-rw-r--r--isisd/isis_lsp_hash.c89
-rw-r--r--isisd/isis_lsp_hash.h34
-rw-r--r--isisd/isis_mt.c6
-rw-r--r--isisd/isis_pdu.c38
-rw-r--r--isisd/isis_route.c4
-rw-r--r--isisd/isis_spf.c18
-rw-r--r--isisd/isis_te.c3
-rw-r--r--isisd/isis_tlvs.c3
-rw-r--r--isisd/isisd.c3
-rw-r--r--isisd/subdir.am2
-rw-r--r--ldpd/address.c4
-rw-r--r--ldpd/adjacency.c8
-rw-r--r--ldpd/interface.c3
-rw-r--r--ldpd/l2vpn.c4
-rw-r--r--ldpd/labelmapping.c2
-rw-r--r--ldpd/lde.c11
-rw-r--r--ldpd/lde_lib.c4
-rw-r--r--ldpd/ldp_vty.h15
-rw-r--r--ldpd/ldp_vty_cmds.c134
-rw-r--r--ldpd/ldp_vty_conf.c20
-rw-r--r--ldpd/ldp_vty_exec.c432
-rw-r--r--ldpd/ldpd.c16
-rw-r--r--ldpd/ldpe.c15
-rw-r--r--ldpd/packet.c2
-rw-r--r--lib/bfd.c2
-rw-r--r--lib/command.c8
-rw-r--r--lib/command.h7
-rw-r--r--lib/command_match.c10
-rw-r--r--lib/csv.c24
-rw-r--r--lib/ferr.c1
-rw-r--r--lib/grammar_sandbox.c6
-rw-r--r--lib/hash.c3
-rw-r--r--lib/if.c7
-rw-r--r--lib/keychain.c2
-rw-r--r--lib/libfrr.c32
-rw-r--r--lib/linklist.c18
-rw-r--r--lib/linklist.h25
-rw-r--r--lib/nexthop.c2
-rw-r--r--lib/ptm_lib.c2
-rw-r--r--lib/sha256.c3
-rw-r--r--lib/thread.c5
-rw-r--r--lib/wheel.c2
-rw-r--r--lib/zclient.c5
-rw-r--r--ospf6d/ospf6_abr.c22
-rw-r--r--ospf6d/ospf6_area.c2
-rw-r--r--ospf6d/ospf6_asbr.c14
-rw-r--r--ospf6d/ospf6_interface.c2
-rw-r--r--ospf6d/ospf6_intra.c46
-rw-r--r--ospf6d/ospf6_lsa.c68
-rw-r--r--ospf6d/ospf6_lsa.h29
-rw-r--r--ospf6d/ospf6_route.c21
-rw-r--r--ospf6d/ospf6_spf.c4
-rw-r--r--ospf6d/ospf6_top.c2
-rw-r--r--ospfd/.gitignore1
-rw-r--r--ospfd/ospf_abr.c6
-rw-r--r--ospfd/ospf_apiserver.c43
-rw-r--r--ospfd/ospf_asbr.c3
-rw-r--r--ospfd/ospf_ase.c19
-rw-r--r--ospfd/ospf_bfd.c9
-rw-r--r--ospfd/ospf_dump.c9
-rw-r--r--ospfd/ospf_flood.c9
-rw-r--r--ospfd/ospf_flood.h3
-rw-r--r--ospfd/ospf_interface.c31
-rw-r--r--ospfd/ospf_ism.c8
-rw-r--r--ospfd/ospf_lsa.c58
-rw-r--r--ospfd/ospf_lsa.h8
-rw-r--r--ospfd/ospf_main.c2
-rw-r--r--ospfd/ospf_network.c68
-rw-r--r--ospfd/ospf_network.h3
-rw-r--r--ospfd/ospf_opaque.c40
-rw-r--r--ospfd/ospf_packet.c88
-rw-r--r--ospfd/ospf_ri.c32
-rw-r--r--ospfd/ospf_route.c41
-rw-r--r--ospfd/ospf_route.h8
-rw-r--r--ospfd/ospf_routemap.c98
-rw-r--r--ospfd/ospf_snmp.c38
-rw-r--r--ospfd/ospf_spf.c28
-rw-r--r--ospfd/ospf_te.c89
-rw-r--r--ospfd/ospf_vty.c1458
-rw-r--r--ospfd/ospf_zebra.c423
-rw-r--r--ospfd/ospf_zebra.h19
-rw-r--r--ospfd/ospfd.c290
-rw-r--r--ospfd/ospfd.h22
-rw-r--r--ospfd/subdir.am3
-rw-r--r--pimd/pim_cmd.c220
-rw-r--r--pimd/pim_hello.c6
-rw-r--r--pimd/pim_iface.c20
-rw-r--r--pimd/pim_ifchannel.c4
-rw-r--r--pimd/pim_igmp.c4
-rw-r--r--pimd/pim_instance.c2
-rw-r--r--pimd/pim_jp_agg.c8
-rw-r--r--pimd/pim_msdp.c8
-rw-r--r--pimd/pim_neighbor.c5
-rw-r--r--pimd/pim_nht.c4
-rw-r--r--pimd/pim_oil.c3
-rw-r--r--pimd/pim_rp.c14
-rw-r--r--pimd/pim_ssmpingd.c6
-rw-r--r--pimd/pim_tlv.c12
-rw-r--r--pimd/pim_upstream.c17
-rw-r--r--pimd/pim_vty.c2
-rw-r--r--ripd/rip_debug.c16
-rw-r--r--ripd/rip_offset.c2
-rw-r--r--ripd/ripd.c5
-rw-r--r--ripngd/ripng_debug.c16
-rw-r--r--ripngd/ripng_nexthop.c2
-rw-r--r--ripngd/ripng_offset.c2
-rw-r--r--ripngd/ripngd.c11
-rw-r--r--tests/isisd/test_fuzz_isis_tlv.c2
-rw-r--r--tests/isisd/test_isis_vertex_queue.c2
-rw-r--r--tools/etc/iproute2/rt_protos.d/frr.conf1
-rwxr-xr-xtools/frr24
-rwxr-xr-xtools/frr-reload.py30
-rw-r--r--vtysh/vtysh.c24
-rw-r--r--vtysh/vtysh_config.c22
-rw-r--r--vtysh/vtysh_main.c8
-rw-r--r--zebra/interface.c8
-rw-r--r--zebra/irdp.h2
-rw-r--r--zebra/irdp_interface.c45
-rw-r--r--zebra/kernel_netlink.c19
-rw-r--r--zebra/label_manager.c2
-rw-r--r--zebra/main.c4
-rw-r--r--zebra/redistribute.c42
-rw-r--r--zebra/rib.h6
-rw-r--r--zebra/rt_netlink.c85
-rw-r--r--zebra/rt_netlink.h16
-rw-r--r--zebra/rtadv.c6
-rw-r--r--zebra/zebra_mpls.c6
-rw-r--r--zebra/zebra_rib.c52
-rw-r--r--zebra/zebra_rnh.c7
-rw-r--r--zebra/zebra_vrf.h4
-rw-r--r--zebra/zebra_vty.c4
-rw-r--r--zebra/zebra_vxlan.c803
-rw-r--r--zebra/zebra_vxlan.h8
-rw-r--r--zebra/zserv.c2
187 files changed, 4800 insertions, 3430 deletions
diff --git a/babeld/babel_main.c b/babeld/babel_main.c
index 6a8f9bb75f..239ab71f06 100644
--- a/babeld/babel_main.c
+++ b/babeld/babel_main.c
@@ -279,8 +279,7 @@ babel_load_state_file(void)
if(fd >= 0 && rc < 0) {
zlog_err("unlink(babel-state): %s", safe_strerror(errno));
/* If we couldn't unlink it, it's probably stale. */
- close(fd);
- fd = -1;
+ goto fini;
}
if(fd >= 0) {
char buf[100];
@@ -315,9 +314,12 @@ babel_load_state_file(void)
zlog_err("Couldn't parse babel-state.");
}
}
- close(fd);
- fd = -1;
+ goto fini;
}
+fini:
+ if (fd >= 0)
+ close(fd);
+ return ;
}
static void
diff --git a/babeld/neighbour.c b/babeld/neighbour.c
index 5bf7e06fae..48a32c4a9c 100644
--- a/babeld/neighbour.c
+++ b/babeld/neighbour.c
@@ -165,7 +165,6 @@ update_neighbour(struct neighbour *neigh, int hello, int hello_interval)
if(missed_hellos > 0) {
neigh->reach >>= missed_hellos;
neigh->hello_seqno = seqno_plus(neigh->hello_seqno, missed_hellos);
- missed_hellos = 0;
rc = 1;
}
diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c
index 2b776d2182..6c03ba3059 100644
--- a/bgpd/bgp_aspath.c
+++ b/bgpd/bgp_aspath.c
@@ -1914,7 +1914,8 @@ static const char *aspath_gettoken(const char *buf, enum as_token *token,
/* There is no match then return unknown token. */
*token = as_token_unknown;
- return p++;
+ p++;
+ return p;
}
struct aspath *aspath_str2aspath(const char *str)
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 97b6273cb4..c178089af7 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -1849,7 +1849,6 @@ static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */
u_char *startp)
{
bgp_size_t total;
- struct bgp_attr_encap_subtlv *stlv_last = NULL;
uint16_t tunneltype = 0;
total = length + (CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3);
@@ -1926,6 +1925,7 @@ static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */
/* attach tlv to encap chain */
if (BGP_ATTR_ENCAP == type) {
+ struct bgp_attr_encap_subtlv *stlv_last;
for (stlv_last = attr->encap_subtlvs;
stlv_last && stlv_last->next;
stlv_last = stlv_last->next)
@@ -1937,6 +1937,7 @@ static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */
}
#if ENABLE_BGP_VNC
} else {
+ struct bgp_attr_encap_subtlv *stlv_last;
for (stlv_last = attr->vnc_subtlvs;
stlv_last && stlv_last->next;
stlv_last = stlv_last->next)
@@ -1948,7 +1949,6 @@ static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */
}
#endif
}
- stlv_last = tlv;
}
if (BGP_ATTR_ENCAP == type) {
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index 6923479cb2..a09d966d7b 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -288,7 +288,7 @@ static void unmap_vni_from_rt(struct bgp *bgp, struct bgpevpn *vpn,
/* Delete VNI from hash list for this RT. */
listnode_delete(irt->vnis, vpn);
if (!listnode_head(irt->vnis)) {
- list_free(irt->vnis);
+ list_delete_and_null(&irt->vnis);
import_rt_free(bgp, irt);
}
}
@@ -2609,10 +2609,8 @@ void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn)
{
bgp_table_unlock(vpn->route_table);
bgp_evpn_unmap_vni_from_its_rts(bgp, vpn);
- list_delete(vpn->import_rtl);
- list_delete(vpn->export_rtl);
- vpn->import_rtl = NULL;
- vpn->export_rtl = NULL;
+ list_delete_and_null(&vpn->import_rtl);
+ list_delete_and_null(&vpn->export_rtl);
bf_release_index(bgp->rd_idspace, vpn->rd_id);
hash_release(bgp->vnihash, vpn);
QOBJ_UNREG(vpn);
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index 7454aec892..07b86c05d6 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -2144,7 +2144,7 @@ static void write_vni_config_for_entry(struct hash_backet *backet,
DEFUN (bgp_evpn_advertise_default_gw_vni,
bgp_evpn_advertise_default_gw_vni_cmd,
"advertise-default-gw",
- "Advertise defualt g/w mac-ip routes in EVPN for a VNI\n")
+ "Advertise default g/w mac-ip routes in EVPN for a VNI\n")
{
struct bgp *bgp = VTY_GET_CONTEXT(bgp);
VTY_DECLVAR_CONTEXT_SUB(bgpevpn, vpn);
@@ -2184,7 +2184,7 @@ DEFUN (no_bgp_evpn_advertise_default_vni_gw,
DEFUN (bgp_evpn_advertise_default_gw,
bgp_evpn_advertise_default_gw_cmd,
"advertise-default-gw",
- "Advertise All defualt g/w mac-ip routes in EVPN\n")
+ "Advertise All default g/w mac-ip routes in EVPN\n")
{
struct bgp *bgp = VTY_GET_CONTEXT(bgp);
@@ -3102,11 +3102,11 @@ DEFUN (bgp_evpn_vni_rt,
if (!bgp || !vpn)
return CMD_WARNING;
- if (!strcmp(argv[1]->arg, "import"))
+ if (!strcmp(argv[1]->text, "import"))
rt_type = RT_TYPE_IMPORT;
- else if (!strcmp(argv[1]->arg, "export"))
+ else if (!strcmp(argv[1]->text, "export"))
rt_type = RT_TYPE_EXPORT;
- else if (!strcmp(argv[1]->arg, "both"))
+ else if (!strcmp(argv[1]->text, "both"))
rt_type = RT_TYPE_BOTH;
else {
vty_out(vty, "%% Invalid Route Target type\n");
@@ -3164,11 +3164,11 @@ DEFUN (no_bgp_evpn_vni_rt,
if (!bgp || !vpn)
return CMD_WARNING;
- if (!strcmp(argv[2]->arg, "import"))
+ if (!strcmp(argv[2]->text, "import"))
rt_type = RT_TYPE_IMPORT;
- else if (!strcmp(argv[2]->arg, "export"))
+ else if (!strcmp(argv[2]->text, "export"))
rt_type = RT_TYPE_EXPORT;
- else if (!strcmp(argv[2]->arg, "both"))
+ else if (!strcmp(argv[2]->text, "both"))
rt_type = RT_TYPE_BOTH;
else {
vty_out(vty, "%% Invalid Route Target type\n");
@@ -3257,9 +3257,9 @@ DEFUN (no_bgp_evpn_vni_rt_without_val,
if (!bgp || !vpn)
return CMD_WARNING;
- if (!strcmp(argv[2]->arg, "import")) {
+ if (!strcmp(argv[2]->text, "import")) {
rt_type = RT_TYPE_IMPORT;
- } else if (!strcmp(argv[2]->arg, "export")) {
+ } else if (!strcmp(argv[2]->text, "export")) {
rt_type = RT_TYPE_EXPORT;
} else {
vty_out(vty, "%% Invalid Route Target type\n");
diff --git a/bgpd/bgp_filter.c b/bgpd/bgp_filter.c
index 6e1a1b6d62..ae9d805b05 100644
--- a/bgpd/bgp_filter.c
+++ b/bgpd/bgp_filter.c
@@ -410,8 +410,8 @@ DEFUN (ip_as_path,
char *regstr;
/* Retrieve access list name */
- char *alname =
- argv_find(argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
+ argv_find(argv, argc, "WORD", &idx);
+ char *alname = argv[idx]->arg;
/* Check the filter type. */
type = argv_find(argv, argc, "deny", &idx) ? AS_FILTER_DENY
diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c
index ad7411990e..06c314de03 100644
--- a/bgpd/bgp_label.c
+++ b/bgpd/bgp_label.c
@@ -225,7 +225,6 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr,
for (; pnt < lim; pnt += psize) {
/* Clear prefix structure. */
memset(&p, 0, sizeof(struct prefix));
- llen = 0;
if (addpath_encoded) {
diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index dfd639c92c..1fac2936eb 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -215,7 +215,7 @@ static __attribute__((__noreturn__)) void bgp_exit(int status)
#endif
bgp_zebra_destroy();
- list_delete(bm->bgp);
+ list_delete_and_null(&bm->bgp);
memset(bm, 0, sizeof(*bm));
frr_fini();
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index 694cb14790..472b9d200a 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -356,19 +356,6 @@ int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
{
struct bgp *bgp;
struct bgp_table *table;
- struct bgp_node *rn;
- struct bgp_node *rm;
- struct bgp_info *ri;
- int rd_header;
- int header = 1;
- unsigned long output_count = 0;
- unsigned long total_count = 0;
- json_object *json = NULL;
- json_object *json_mroute = NULL;
- json_object *json_nroute = NULL;
- json_object *json_array = NULL;
- json_object *json_scode = NULL;
- json_object *json_ocode = NULL;
bgp = bgp_get_default();
if (bgp == NULL) {
@@ -378,279 +365,31 @@ int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
vty_out(vty, "{}\n");
return CMD_WARNING;
}
-
- if (use_json) {
- json_scode = json_object_new_object();
- json_ocode = json_object_new_object();
- json = json_object_new_object();
- json_mroute = json_object_new_object();
- json_nroute = json_object_new_object();
-
- json_object_string_add(json_scode, "suppressed", "s");
- json_object_string_add(json_scode, "damped", "d");
- json_object_string_add(json_scode, "history", "h");
- json_object_string_add(json_scode, "valid", "*");
- json_object_string_add(json_scode, "best", ">");
- json_object_string_add(json_scode, "internal", "i");
-
- json_object_string_add(json_ocode, "igp", "i");
- json_object_string_add(json_ocode, "egp", "e");
- json_object_string_add(json_ocode, "incomplete", "?");
- }
-
- if ((afi != AFI_IP) && (afi != AFI_IP6)) {
- vty_out(vty, "Afi %d not supported\n", afi);
- return CMD_WARNING;
- }
-
- for (rn = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); rn;
- rn = bgp_route_next(rn)) {
- if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
- continue;
-
- if ((table = rn->info) != NULL) {
- rd_header = 1;
-
- for (rm = bgp_table_top(table); rm;
- rm = bgp_route_next(rm)) {
- total_count++;
- if (use_json)
- json_array = json_object_new_array();
- else
- json_array = NULL;
-
- for (ri = rm->info; ri; ri = ri->next) {
- if (type == bgp_show_type_neighbor) {
- union sockunion *su =
- output_arg;
-
- if (ri->peer->su_remote == NULL
- || !sockunion_same(
- ri->peer->su_remote,
- su))
- continue;
- }
- if (header) {
- if (use_json) {
- if (!tags) {
- json_object_int_add(
- json,
- "bgpTableVersion",
- 0);
- json_object_string_add(
- json,
- "bgpLocalRouterId",
- inet_ntoa(
- bgp->router_id));
- json_object_object_add(
- json,
- "bgpStatusCodes",
- json_scode);
- json_object_object_add(
- json,
- "bgpOriginCodes",
- json_ocode);
- }
- } else {
- if (tags)
- vty_out(vty,
- V4_HEADER_TAG);
- else {
- vty_out(vty,
- "BGP table version is 0, local router ID is %s\n",
- inet_ntoa(
- bgp->router_id));
- vty_out(vty,
- "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal\n");
- vty_out(vty,
- "Origin codes: i - IGP, e - EGP, ? - incomplete\n\n");
- vty_out(vty,
- V4_HEADER);
- }
- }
- header = 0;
- }
-
- if (rd_header) {
- u_int16_t type;
- struct rd_as rd_as;
- struct rd_ip rd_ip = {0};
-#if ENABLE_BGP_VNC
- struct rd_vnc_eth rd_vnc_eth = {
- 0};
-#endif
- u_char *pnt;
-
- pnt = rn->p.u.val;
-
- /* Decode RD type. */
- type = decode_rd_type(pnt);
- /* Decode RD value. */
- if (type == RD_TYPE_AS)
- decode_rd_as(pnt + 2,
- &rd_as);
- else if (type == RD_TYPE_AS4)
- decode_rd_as4(pnt + 2,
- &rd_as);
- else if (type == RD_TYPE_IP)
- decode_rd_ip(pnt + 2,
- &rd_ip);
-#if ENABLE_BGP_VNC
- else if (type
- == RD_TYPE_VNC_ETH)
- decode_rd_vnc_eth(
- pnt,
- &rd_vnc_eth);
-#endif
-
- if (use_json) {
- char buffer[BUFSIZ];
- if (type == RD_TYPE_AS
- || type == RD_TYPE_AS4)
- sprintf(buffer,
- "%u:%d",
- rd_as.as,
- rd_as.val);
- else if (type
- == RD_TYPE_IP)
- sprintf(buffer,
- "%s:%d",
- inet_ntoa(
- rd_ip.ip),
- rd_ip.val);
- json_object_string_add(
- json_nroute,
- "routeDistinguisher",
- buffer);
- } else {
- vty_out(vty,
- "Route Distinguisher: ");
-
- if (type == RD_TYPE_AS
- || type == RD_TYPE_AS4)
- vty_out(vty,
- "%u:%d",
- rd_as.as,
- rd_as.val);
- else if (type
- == RD_TYPE_IP)
- vty_out(vty,
- "%s:%d",
- inet_ntoa(
- rd_ip.ip),
- rd_ip.val);
-#if ENABLE_BGP_VNC
- else if (
- type
- == RD_TYPE_VNC_ETH)
- vty_out(vty,
- "%u:%02x:%02x:%02x:%02x:%02x:%02x",
- rd_vnc_eth
- .local_nve_id,
- rd_vnc_eth
- .macaddr
- .octet[0],
- rd_vnc_eth
- .macaddr
- .octet[1],
- rd_vnc_eth
- .macaddr
- .octet[2],
- rd_vnc_eth
- .macaddr
- .octet[3],
- rd_vnc_eth
- .macaddr
- .octet[4],
- rd_vnc_eth
- .macaddr
- .octet[5]);
-#endif
- vty_out(vty, "\n");
- }
- rd_header = 0;
- }
- if (tags)
- route_vty_out_tag(vty, &rm->p,
- ri, 0,
- SAFI_MPLS_VPN,
- json_array);
- else
- route_vty_out(vty, &rm->p, ri,
- 0, SAFI_MPLS_VPN,
- json_array);
- output_count++;
- }
-
- if (use_json) {
- struct prefix *p;
- char buf_a[BUFSIZ];
- char buf_b[BUFSIZ];
- p = &rm->p;
- sprintf(buf_a, "%s/%d",
- inet_ntop(p->family,
- &p->u.prefix, buf_b,
- BUFSIZ),
- p->prefixlen);
- json_object_object_add(
- json_mroute, buf_a, json_array);
- }
- }
-
- if (use_json) {
- struct prefix *p;
- char buf_a[BUFSIZ];
- char buf_b[BUFSIZ];
- p = &rn->p;
- sprintf(buf_a, "%s/%d",
- inet_ntop(p->family, &p->u.prefix,
- buf_b, BUFSIZ),
- p->prefixlen);
- json_object_object_add(json_nroute, buf_a,
- json_mroute);
- }
- }
- }
-
- if (use_json) {
- json_object_object_add(json, "routes", json_nroute);
- vty_out(vty, "%s\n", json_object_to_json_string_ext(
- json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- } else {
- if (output_count == 0)
- vty_out(vty, "No prefixes displayed, %ld exist\n",
- total_count);
- else
- vty_out(vty,
- "\nDisplayed %ld routes and %ld total paths\n",
- output_count, total_count);
- }
-
- return CMD_SUCCESS;
+ table = bgp->rib[afi][SAFI_MPLS_VPN];
+ return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN,
+ table, prd, type, output_arg, use_json);
}
DEFUN (show_bgp_ip_vpn_all_rd,
show_bgp_ip_vpn_all_rd_cmd,
"show bgp "BGP_AFI_CMD_STR" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
SHOW_STR
- IP_STR
BGP_STR
BGP_VPNVX_HELP_STR
"Display VPN NLRI specific information\n"
+ "Display VPN NLRI specific information\n"
"Display information for a route distinguisher\n"
"VPN Route Distinguisher\n"
JSON_STR)
{
- int idx_rd = 5;
int ret;
struct prefix_rd prd;
afi_t afi;
int idx = 0;
if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
- if (argc >= 7 && argv[idx_rd]->arg) {
- ret = str2prefix_rd(argv[idx_rd]->arg, &prd);
+ if (argv_find(argv, argc, "rd", &idx)) {
+ ret = str2prefix_rd(argv[idx+1]->arg, &prd);
if (!ret) {
vty_out(vty,
"%% Malformed Route Distinguisher\n");
@@ -668,9 +407,21 @@ DEFUN (show_bgp_ip_vpn_all_rd,
return CMD_SUCCESS;
}
+ALIAS(show_bgp_ip_vpn_all_rd,
+ show_bgp_ip_vpn_rd_cmd,
+ "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
+ SHOW_STR
+ BGP_STR
+ BGP_VPNVX_HELP_STR
+ "Display VPN NLRI specific information\n"
+ "Display information for a route distinguisher\n"
+ "VPN Route Distinguisher\n"
+ JSON_STR)
+
+#ifdef KEEP_OLD_VPN_COMMANDS
DEFUN (show_ip_bgp_vpn_rd,
show_ip_bgp_vpn_rd_cmd,
- "show [ip] bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
+ "show ip bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
SHOW_STR
IP_STR
BGP_STR
@@ -697,7 +448,6 @@ DEFUN (show_ip_bgp_vpn_rd,
return CMD_SUCCESS;
}
-#ifdef KEEP_OLD_VPN_COMMANDS
DEFUN (show_ip_bgp_vpn_all,
show_ip_bgp_vpn_all_cmd,
"show [ip] bgp <vpnv4|vpnv6>",
@@ -1055,8 +805,9 @@ void bgp_mplsvpn_init(void)
install_element(BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
install_element(VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
- install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
+ install_element(VIEW_NODE, &show_bgp_ip_vpn_rd_cmd);
#ifdef KEEP_OLD_VPN_COMMANDS
+ install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
install_element(VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
install_element(VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
install_element(VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd);
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index b9f23a387e..0c2a2f6fe9 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -391,7 +391,7 @@ static int bgp_info_cmp(struct bgp *bgp, struct bgp_info *new,
int exist_cluster;
int internal_as_route;
int confed_as_route;
- int ret;
+ int ret = 0;
char new_buf[PATH_ADDPATH_STR_BUFFER];
char exist_buf[PATH_ADDPATH_STR_BUFFER];
u_int32_t new_mm_seq;
@@ -488,8 +488,6 @@ static int bgp_info_cmp(struct bgp *bgp, struct bgp_info *new,
}
/* 1. Weight check. */
- new_weight = exist_weight = 0;
-
new_weight = newattr->weight;
exist_weight = existattr->weight;
@@ -6502,246 +6500,258 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
/* Print attribute */
attr = binfo->attr;
- if (attr) {
- /*
- * For ENCAP and EVPN routes, nexthop address family is not
- * neccessarily the same as the prefix address family.
- * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
- * EVPN routes are also exchanged with a MP nexthop. Currently,
- * this
- * is only IPv4, the value will be present in either
- * attr->nexthop or
- * attr->mp_nexthop_global_in
- */
- if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
- char buf[BUFSIZ];
- int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
-
- switch (af) {
- case AF_INET:
- vty_out(vty, "%s",
- inet_ntop(af,
- &attr->mp_nexthop_global_in,
- buf, BUFSIZ));
- break;
- case AF_INET6:
- vty_out(vty, "%s",
- inet_ntop(af, &attr->mp_nexthop_global,
- buf, BUFSIZ));
- break;
- default:
- vty_out(vty, "?");
- break;
- }
- } else if (safi == SAFI_EVPN) {
- if (json_paths) {
- json_nexthop_global = json_object_new_object();
+ if (!attr) {
+ if (json_paths)
+ json_object_array_add(json_paths, json_path);
+ else
+ vty_out(vty, "\n");
- json_object_string_add(
- json_nexthop_global, "ip",
- inet_ntoa(attr->nexthop));
- json_object_string_add(json_nexthop_global,
- "afi", "ipv4");
- json_object_boolean_true_add(
- json_nexthop_global, "used");
- } else
- vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
+ return;
+ }
+
+ /*
+ * For ENCAP and EVPN routes, nexthop address family is not
+ * neccessarily the same as the prefix address family.
+ * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
+ * EVPN routes are also exchanged with a MP nexthop. Currently,
+ * this
+ * is only IPv4, the value will be present in either
+ * attr->nexthop or
+ * attr->mp_nexthop_global_in
+ */
+ if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
+ char buf[BUFSIZ];
+ char nexthop[128];
+ int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
+
+ switch (af) {
+ case AF_INET:
+ sprintf(nexthop, "%s",
+ inet_ntop(af, &attr->mp_nexthop_global_in,
+ buf, BUFSIZ));
+ break;
+ case AF_INET6:
+ sprintf(nexthop, "%s",
+ inet_ntop(af, &attr->mp_nexthop_global,
+ buf, BUFSIZ));
+ break;
+ default:
+ sprintf(nexthop, "?");
+ break;
}
- /* IPv4 Next Hop */
- else if (p->family == AF_INET
- && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
- if (json_paths) {
- json_nexthop_global = json_object_new_object();
- if ((safi == SAFI_MPLS_VPN)
- || (safi == SAFI_EVPN))
- json_object_string_add(
- json_nexthop_global, "ip",
- inet_ntoa(
- attr->mp_nexthop_global_in));
- else
- json_object_string_add(
- json_nexthop_global, "ip",
- inet_ntoa(attr->nexthop));
+ if (json_paths) {
+ json_nexthop_global = json_object_new_object();
+
+ json_object_string_add(json_nexthop_global,
+ "afi",
+ (af == AF_INET) ?
+ "ip" : "ipv6");
+ json_object_string_add(json_nexthop_global,
+ (af == AF_INET) ?
+ "ip" : "ipv6",
+ nexthop);
+ json_object_boolean_true_add(json_nexthop_global,
+ "used");
+ } else
+ vty_out(vty, "%s", nexthop);
+ } else if (safi == SAFI_EVPN) {
+ if (json_paths) {
+ json_nexthop_global = json_object_new_object();
+
+ json_object_string_add(json_nexthop_global, "ip",
+ inet_ntoa(attr->nexthop));
+ json_object_string_add(json_nexthop_global,
+ "afi", "ipv4");
+ json_object_boolean_true_add(json_nexthop_global,
+ "used");
+ } else
+ vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
+ }
+ /* IPv4 Next Hop */
+ else if (p->family == AF_INET
+ && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
+ if (json_paths) {
+ json_nexthop_global = json_object_new_object();
+ if ((safi == SAFI_MPLS_VPN)
+ || (safi == SAFI_EVPN))
json_object_string_add(json_nexthop_global,
- "afi", "ipv4");
- json_object_boolean_true_add(
- json_nexthop_global, "used");
- } else {
- if ((safi == SAFI_MPLS_VPN)
- || (safi == SAFI_EVPN))
- vty_out(vty, "%-16s",
- inet_ntoa(
- attr->mp_nexthop_global_in));
- else
- vty_out(vty, "%-16s",
- inet_ntoa(attr->nexthop));
- }
+ "ip",
+ inet_ntoa(attr->mp_nexthop_global_in));
+ else
+ json_object_string_add(json_nexthop_global,
+ "ip",
+ inet_ntoa(attr->nexthop));
+
+ json_object_string_add(json_nexthop_global,
+ "afi", "ipv4");
+ json_object_boolean_true_add(json_nexthop_global,
+ "used");
+ } else {
+ if ((safi == SAFI_MPLS_VPN)
+ || (safi == SAFI_EVPN))
+ vty_out(vty, "%-16s",
+ inet_ntoa(
+ attr->mp_nexthop_global_in));
+ else
+ vty_out(vty, "%-16s",
+ inet_ntoa(attr->nexthop));
}
+ }
- /* IPv6 Next Hop */
- else if (p->family == AF_INET6
- || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
- int len;
- char buf[BUFSIZ];
+ /* IPv6 Next Hop */
+ else if (p->family == AF_INET6
+ || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
+ int len;
+ char buf[BUFSIZ];
- if (json_paths) {
- json_nexthop_global = json_object_new_object();
+ if (json_paths) {
+ json_nexthop_global = json_object_new_object();
+ json_object_string_add(json_nexthop_global, "ip",
+ inet_ntop(AF_INET6,
+ &attr->mp_nexthop_global, buf,
+ BUFSIZ));
+ json_object_string_add(json_nexthop_global,
+ "afi", "ipv6");
+ json_object_string_add(json_nexthop_global,
+ "scope", "global");
+
+ /* We display both LL & GL if both have been
+ * received */
+ if ((attr->mp_nexthop_len == 32)
+ || (binfo->peer->conf_if)) {
+ json_nexthop_ll =
+ json_object_new_object();
json_object_string_add(
- json_nexthop_global, "ip",
- inet_ntop(AF_INET6,
- &attr->mp_nexthop_global, buf,
- BUFSIZ));
- json_object_string_add(json_nexthop_global,
+ json_nexthop_ll, "ip",
+ inet_ntop(
+ AF_INET6,
+ &attr->mp_nexthop_local,
+ buf, BUFSIZ));
+ json_object_string_add(json_nexthop_ll,
"afi", "ipv6");
- json_object_string_add(json_nexthop_global,
- "scope", "global");
+ json_object_string_add(json_nexthop_ll,
+ "scope",
+ "link-local");
- /* We display both LL & GL if both have been
- * received */
- if ((attr->mp_nexthop_len == 32)
- || (binfo->peer->conf_if)) {
- json_nexthop_ll =
- json_object_new_object();
- json_object_string_add(
- json_nexthop_ll, "ip",
- inet_ntop(
- AF_INET6,
- &attr->mp_nexthop_local,
- buf, BUFSIZ));
- json_object_string_add(json_nexthop_ll,
- "afi", "ipv6");
- json_object_string_add(json_nexthop_ll,
- "scope",
- "link-local");
-
- if ((IPV6_ADDR_CMP(
- &attr->mp_nexthop_global,
- &attr->mp_nexthop_local)
- != 0)
- && !attr->mp_nexthop_prefer_global)
- json_object_boolean_true_add(
- json_nexthop_ll,
- "used");
- else
- json_object_boolean_true_add(
- json_nexthop_global,
- "used");
- } else
+ if ((IPV6_ADDR_CMP(
+ &attr->mp_nexthop_global,
+ &attr->mp_nexthop_local)
+ != 0)
+ && !attr->mp_nexthop_prefer_global)
json_object_boolean_true_add(
- json_nexthop_global, "used");
- } else {
- /* Display LL if LL/Global both in table unless
- * prefer-global is set */
- if (((attr->mp_nexthop_len == 32)
- && !attr->mp_nexthop_prefer_global)
- || (binfo->peer->conf_if)) {
- if (binfo->peer->conf_if) {
- len = vty_out(
- vty, "%s",
- binfo->peer->conf_if);
- len = 16 - len; /* len of IPv6
- addr + max
- len of def
- ifname */
-
- if (len < 1)
- vty_out(vty, "\n%*s",
- 36, " ");
- else
- vty_out(vty, "%*s", len,
- " ");
- } else {
- len = vty_out(
- vty, "%s",
- inet_ntop(
- AF_INET6,
- &attr->mp_nexthop_local,
- buf, BUFSIZ));
- len = 16 - len;
-
- if (len < 1)
- vty_out(vty, "\n%*s",
- 36, " ");
- else
- vty_out(vty, "%*s", len,
- " ");
- }
+ json_nexthop_ll,
+ "used");
+ else
+ json_object_boolean_true_add(
+ json_nexthop_global,
+ "used");
+ } else
+ json_object_boolean_true_add(
+ json_nexthop_global, "used");
+ } else {
+ /* Display LL if LL/Global both in table unless
+ * prefer-global is set */
+ if (((attr->mp_nexthop_len == 32)
+ && !attr->mp_nexthop_prefer_global)
+ || (binfo->peer->conf_if)) {
+ if (binfo->peer->conf_if) {
+ len = vty_out(
+ vty, "%s",
+ binfo->peer->conf_if);
+ len = 16 - len; /* len of IPv6
+ addr + max
+ len of def
+ ifname */
+
+ if (len < 1)
+ vty_out(vty, "\n%*s",
+ 36, " ");
+ else
+ vty_out(vty, "%*s", len,
+ " ");
} else {
len = vty_out(
vty, "%s",
inet_ntop(
AF_INET6,
- &attr->mp_nexthop_global,
+ &attr->mp_nexthop_local,
buf, BUFSIZ));
len = 16 - len;
if (len < 1)
- vty_out(vty, "\n%*s", 36, " ");
+ vty_out(vty, "\n%*s",
+ 36, " ");
else
- vty_out(vty, "%*s", len, " ");
+ vty_out(vty, "%*s", len,
+ " ");
}
+ } else {
+ len = vty_out(vty, "%s",
+ inet_ntop(AF_INET6,
+ &attr->mp_nexthop_global,
+ buf, BUFSIZ));
+ len = 16 - len;
+
+ if (len < 1)
+ vty_out(vty, "\n%*s", 36, " ");
+ else
+ vty_out(vty, "%*s", len, " ");
}
}
+ }
- /* MED/Metric */
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
- if (json_paths)
- json_object_int_add(json_path, "med",
- attr->med);
- else
- vty_out(vty, "%10u", attr->med);
- else if (!json_paths)
- vty_out(vty, " ");
-
- /* Local Pref */
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
- if (json_paths)
- json_object_int_add(json_path, "localpref",
- attr->local_pref);
- else
- vty_out(vty, "%7u", attr->local_pref);
- else if (!json_paths)
- vty_out(vty, " ");
+ /* MED/Metric */
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
+ if (json_paths)
+ json_object_int_add(json_path, "med",
+ attr->med);
+ else
+ vty_out(vty, "%10u", attr->med);
+ else if (!json_paths)
+ vty_out(vty, " ");
+ /* Local Pref */
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
if (json_paths)
- json_object_int_add(json_path, "weight", attr->weight);
+ json_object_int_add(json_path, "localpref",
+ attr->local_pref);
else
- vty_out(vty, "%7u ", attr->weight);
+ vty_out(vty, "%7u", attr->local_pref);
+ else if (!json_paths)
+ vty_out(vty, " ");
- if (json_paths) {
- char buf[BUFSIZ];
- json_object_string_add(json_path, "peerId",
- sockunion2str(&binfo->peer->su,
- buf,
- SU_ADDRSTRLEN));
- }
+ if (json_paths)
+ json_object_int_add(json_path, "weight", attr->weight);
+ else
+ vty_out(vty, "%7u ", attr->weight);
- /* Print aspath */
- if (attr->aspath) {
- if (json_paths)
- json_object_string_add(json_path, "aspath",
- attr->aspath->str);
- else
- aspath_print_vty(vty, "%s", attr->aspath, " ");
- }
+ if (json_paths) {
+ char buf[BUFSIZ];
+ json_object_string_add(json_path, "peerId",
+ sockunion2str(&binfo->peer->su,
+ buf,
+ SU_ADDRSTRLEN));
+ }
- /* Print origin */
- if (json_paths)
- json_object_string_add(
- json_path, "origin",
- bgp_origin_long_str[attr->origin]);
- else
- vty_out(vty, "%s", bgp_origin_str[attr->origin]);
- } else {
+ /* Print aspath */
+ if (attr->aspath) {
if (json_paths)
- json_object_string_add(json_path, "alert",
- "No attributes");
+ json_object_string_add(json_path, "aspath",
+ attr->aspath->str);
else
- vty_out(vty, "No attributes to print\n");
+ aspath_print_vty(vty, "%s", attr->aspath, " ");
}
+ /* Print origin */
+ if (json_paths)
+ json_object_string_add(
+ json_path, "origin",
+ bgp_origin_long_str[attr->origin]);
+ else
+ vty_out(vty, "%s", bgp_origin_str[attr->origin]);
+
if (json_paths) {
if (json_nexthop_global || json_nexthop_ll) {
json_nexthops = json_object_new_array();
@@ -8124,23 +8134,29 @@ static int bgp_show_community(struct vty *vty, struct bgp *bgp,
const char *comstr, int exact, afi_t afi,
safi_t safi);
-static int bgp_show_table(struct vty *vty, struct bgp *bgp,
+
+static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
struct bgp_table *table, enum bgp_show_type type,
- void *output_arg, u_char use_json)
+ void *output_arg, u_char use_json,
+ char *rd, int is_last,
+ unsigned long *output_cum, unsigned long *total_cum)
{
struct bgp_info *ri;
struct bgp_node *rn;
int header = 1;
int display;
- unsigned long output_count;
- unsigned long total_count;
+ unsigned long output_count = 0;
+ unsigned long total_count = 0;
struct prefix *p;
char buf[BUFSIZ];
char buf2[BUFSIZ];
json_object *json_paths = NULL;
int first = 1;
- if (use_json) {
+ if (output_cum && *output_cum != 0)
+ header = 0;
+
+ if (use_json && header) {
vty_out(vty,
"{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64
", \"routerId\": \"%s\", \"routes\": { ",
@@ -8148,252 +8164,290 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp,
bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT ? "Default"
: bgp->name,
table->version, inet_ntoa(bgp->router_id));
+ if (rd)
+ vty_out(vty, " \"routeDistinguishers\" : {");
json_paths = json_object_new_object();
}
- /* This is first entry point, so reset total line. */
- output_count = 0;
- total_count = 0;
+ if (use_json && rd) {
+ vty_out(vty, " \"%s\" : { ", rd);
+ }
/* Start processing of routes. */
- for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
- if (rn->info != NULL) {
- display = 0;
- if (!first && use_json) {
- vty_out(vty, ",");
- }
- if (use_json)
- json_paths = json_object_new_array();
- else
- json_paths = NULL;
+ for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
+ if (rn->info == NULL)
+ continue;
- for (ri = rn->info; ri; ri = ri->next) {
- total_count++;
- if (type == bgp_show_type_flap_statistics
- || type == bgp_show_type_flap_neighbor
- || type == bgp_show_type_dampend_paths
- || type == bgp_show_type_damp_neighbor) {
- if (!(ri->extra
- && ri->extra->damp_info))
- continue;
- }
- if (type == bgp_show_type_regexp) {
- regex_t *regex = output_arg;
+ display = 0;
+ if (!first && use_json)
+ vty_out(vty, ",");
+ if (use_json)
+ json_paths = json_object_new_array();
+ else
+ json_paths = NULL;
- if (bgp_regexec(regex, ri->attr->aspath)
- == REG_NOMATCH)
- continue;
- }
- if (type == bgp_show_type_prefix_list) {
- struct prefix_list *plist = output_arg;
+ for (ri = rn->info; ri; ri = ri->next) {
+ total_count++;
+ if (type == bgp_show_type_flap_statistics
+ || type == bgp_show_type_flap_neighbor
+ || type == bgp_show_type_dampend_paths
+ || type == bgp_show_type_damp_neighbor) {
+ if (!(ri->extra
+ && ri->extra->damp_info))
+ continue;
+ }
+ if (type == bgp_show_type_regexp) {
+ regex_t *regex = output_arg;
- if (prefix_list_apply(plist, &rn->p)
- != PREFIX_PERMIT)
- continue;
- }
- if (type == bgp_show_type_filter_list) {
- struct as_list *as_list = output_arg;
+ if (bgp_regexec(regex, ri->attr->aspath)
+ == REG_NOMATCH)
+ continue;
+ }
+ if (type == bgp_show_type_prefix_list) {
+ struct prefix_list *plist = output_arg;
- if (as_list_apply(as_list,
- ri->attr->aspath)
- != AS_FILTER_PERMIT)
- continue;
- }
- if (type == bgp_show_type_route_map) {
- struct route_map *rmap = output_arg;
- struct bgp_info binfo;
- struct attr dummy_attr;
- int ret;
+ if (prefix_list_apply(plist, &rn->p)
+ != PREFIX_PERMIT)
+ continue;
+ }
+ if (type == bgp_show_type_filter_list) {
+ struct as_list *as_list = output_arg;
- bgp_attr_dup(&dummy_attr, ri->attr);
+ if (as_list_apply(as_list, ri->attr->aspath)
+ != AS_FILTER_PERMIT)
+ continue;
+ }
+ if (type == bgp_show_type_route_map) {
+ struct route_map *rmap = output_arg;
+ struct bgp_info binfo;
+ struct attr dummy_attr;
+ int ret;
- binfo.peer = ri->peer;
- binfo.attr = &dummy_attr;
+ bgp_attr_dup(&dummy_attr, ri->attr);
- ret = route_map_apply(rmap, &rn->p,
- RMAP_BGP, &binfo);
- if (ret == RMAP_DENYMATCH)
- continue;
- }
- if (type == bgp_show_type_neighbor
- || type == bgp_show_type_flap_neighbor
- || type == bgp_show_type_damp_neighbor) {
- union sockunion *su = output_arg;
-
- if (ri->peer == NULL
- || ri->peer->su_remote == NULL
- || !sockunion_same(
- ri->peer->su_remote, su))
- continue;
- }
- if (type == bgp_show_type_cidr_only) {
- u_int32_t destination;
+ binfo.peer = ri->peer;
+ binfo.attr = &dummy_attr;
- destination =
- ntohl(rn->p.u.prefix4.s_addr);
- if (IN_CLASSC(destination)
- && rn->p.prefixlen == 24)
- continue;
- if (IN_CLASSB(destination)
- && rn->p.prefixlen == 16)
- continue;
- if (IN_CLASSA(destination)
- && rn->p.prefixlen == 8)
- continue;
- }
- if (type == bgp_show_type_prefix_longer) {
- struct prefix *p = output_arg;
+ ret = route_map_apply(rmap, &rn->p,
+ RMAP_BGP, &binfo);
+ if (ret == RMAP_DENYMATCH)
+ continue;
+ }
+ if (type == bgp_show_type_neighbor
+ || type == bgp_show_type_flap_neighbor
+ || type == bgp_show_type_damp_neighbor) {
+ union sockunion *su = output_arg;
+
+ if (ri->peer == NULL
+ || ri->peer->su_remote == NULL
+ || !sockunion_same(ri->peer->su_remote,
+ su))
+ continue;
+ }
+ if (type == bgp_show_type_cidr_only) {
+ u_int32_t destination;
- if (!prefix_match(p, &rn->p))
- continue;
- }
- if (type == bgp_show_type_community_all) {
- if (!ri->attr->community)
- continue;
- }
- if (type == bgp_show_type_community) {
- struct community *com = output_arg;
+ destination = ntohl(rn->p.u.prefix4.s_addr);
+ if (IN_CLASSC(destination)
+ && rn->p.prefixlen == 24)
+ continue;
+ if (IN_CLASSB(destination)
+ && rn->p.prefixlen == 16)
+ continue;
+ if (IN_CLASSA(destination)
+ && rn->p.prefixlen == 8)
+ continue;
+ }
+ if (type == bgp_show_type_prefix_longer) {
+ struct prefix *p = output_arg;
- if (!ri->attr->community
- || !community_match(
- ri->attr->community,
- com))
- continue;
- }
- if (type == bgp_show_type_community_exact) {
- struct community *com = output_arg;
+ if (!prefix_match(p, &rn->p))
+ continue;
+ }
+ if (type == bgp_show_type_community_all) {
+ if (!ri->attr->community)
+ continue;
+ }
+ if (type == bgp_show_type_community) {
+ struct community *com = output_arg;
- if (!ri->attr->community
- || !community_cmp(
- ri->attr->community,
- com))
- continue;
- }
- if (type == bgp_show_type_community_list) {
- struct community_list *list =
- output_arg;
+ if (!ri->attr->community
+ || !community_match(ri->attr->community,
+ com))
+ continue;
+ }
+ if (type == bgp_show_type_community_exact) {
+ struct community *com = output_arg;
- if (!community_list_match(
- ri->attr->community, list))
- continue;
- }
- if (type
- == bgp_show_type_community_list_exact) {
- struct community_list *list =
- output_arg;
+ if (!ri->attr->community
+ || !community_cmp(ri->attr->community,
+ com))
+ continue;
+ }
+ if (type == bgp_show_type_community_list) {
+ struct community_list *list = output_arg;
- if (!community_list_exact_match(
- ri->attr->community, list))
- continue;
- }
- if (type == bgp_show_type_lcommunity) {
- struct lcommunity *lcom = output_arg;
+ if (!community_list_match(
+ ri->attr->community, list))
+ continue;
+ }
+ if (type
+ == bgp_show_type_community_list_exact) {
+ struct community_list *list = output_arg;
- if (!ri->attr->lcommunity
- || !lcommunity_match(
- ri->attr->lcommunity,
- lcom))
- continue;
- }
- if (type == bgp_show_type_lcommunity_list) {
- struct community_list *list =
- output_arg;
+ if (!community_list_exact_match(
+ ri->attr->community, list))
+ continue;
+ }
+ if (type == bgp_show_type_lcommunity) {
+ struct lcommunity *lcom = output_arg;
- if (!lcommunity_list_match(
- ri->attr->lcommunity, list))
- continue;
- }
- if (type == bgp_show_type_lcommunity_all) {
- if (!ri->attr->lcommunity)
- continue;
- }
- if (type == bgp_show_type_dampend_paths
- || type == bgp_show_type_damp_neighbor) {
- if (!CHECK_FLAG(ri->flags,
- BGP_INFO_DAMPED)
- || CHECK_FLAG(ri->flags,
- BGP_INFO_HISTORY))
- continue;
- }
+ if (!ri->attr->lcommunity
+ || !lcommunity_match(ri->attr->lcommunity,
+ lcom))
+ continue;
+ }
+ if (type == bgp_show_type_lcommunity_list) {
+ struct community_list *list = output_arg;
- if (!use_json && header) {
- vty_out(vty,
- "BGP table version is %" PRIu64
- ", local router ID is %s\n",
- table->version,
- inet_ntoa(bgp->router_id));
- vty_out(vty, BGP_SHOW_SCODE_HEADER);
- vty_out(vty, BGP_SHOW_OCODE_HEADER);
- if (type == bgp_show_type_dampend_paths
- || type == bgp_show_type_damp_neighbor)
- vty_out(vty,
- BGP_SHOW_DAMP_HEADER);
- else if (
- type == bgp_show_type_flap_statistics
- || type == bgp_show_type_flap_neighbor)
- vty_out(vty,
- BGP_SHOW_FLAP_HEADER);
- else
- vty_out(vty, BGP_SHOW_HEADER);
- header = 0;
- }
+ if (!lcommunity_list_match(
+ ri->attr->lcommunity, list))
+ continue;
+ }
+ if (type == bgp_show_type_lcommunity_all) {
+ if (!ri->attr->lcommunity)
+ continue;
+ }
+ if (type == bgp_show_type_dampend_paths
+ || type == bgp_show_type_damp_neighbor) {
+ if (!CHECK_FLAG(ri->flags, BGP_INFO_DAMPED)
+ || CHECK_FLAG(ri->flags, BGP_INFO_HISTORY))
+ continue;
+ }
+ if (!use_json && header) {
+ vty_out(vty,
+ "BGP table version is %" PRIu64
+ ", local router ID is %s\n",
+ table->version,
+ inet_ntoa(bgp->router_id));
+ vty_out(vty, BGP_SHOW_SCODE_HEADER);
+ vty_out(vty, BGP_SHOW_OCODE_HEADER);
if (type == bgp_show_type_dampend_paths
|| type == bgp_show_type_damp_neighbor)
- damp_route_vty_out(
- vty, &rn->p, ri, display,
- SAFI_UNICAST, use_json,
- json_paths);
- else if (type == bgp_show_type_flap_statistics
- || type == bgp_show_type_flap_neighbor)
- flap_route_vty_out(
- vty, &rn->p, ri, display,
- SAFI_UNICAST, use_json,
- json_paths);
+ vty_out(vty, BGP_SHOW_DAMP_HEADER);
+ else if (
+ type == bgp_show_type_flap_statistics
+ || type == bgp_show_type_flap_neighbor)
+ vty_out(vty, BGP_SHOW_FLAP_HEADER);
else
- route_vty_out(vty, &rn->p, ri, display,
- SAFI_UNICAST, json_paths);
- display++;
+ vty_out(vty, BGP_SHOW_HEADER);
+ header = 0;
}
-
- if (display) {
- output_count++;
- if (use_json) {
- p = &rn->p;
- sprintf(buf2, "%s/%d",
- inet_ntop(p->family,
- &p->u.prefix, buf,
- BUFSIZ),
- p->prefixlen);
- vty_out(vty, "\"%s\": ", buf2);
- vty_out(vty, "%s",
- json_object_to_json_string(
- json_paths));
- json_object_free(json_paths);
- first = 0;
- }
+ if (rd != NULL && !display && !output_count) {
+ if (!use_json)
+ vty_out(vty,
+ "Route Distinguisher: %s\n",
+ rd);
}
+ if (type == bgp_show_type_dampend_paths
+ || type == bgp_show_type_damp_neighbor)
+ damp_route_vty_out(vty, &rn->p, ri, display,
+ safi, use_json,
+ json_paths);
+ else if (type == bgp_show_type_flap_statistics
+ || type == bgp_show_type_flap_neighbor)
+ flap_route_vty_out(vty, &rn->p, ri, display,
+ safi, use_json,
+ json_paths);
+ else
+ route_vty_out(vty, &rn->p, ri, display,
+ safi, json_paths);
+ display++;
}
+ if (display) {
+ output_count++;
+ if (!use_json)
+ continue;
+
+ p = &rn->p;
+ sprintf(buf2, "%s/%d",
+ inet_ntop(p->family, &p->u.prefix,
+ buf, BUFSIZ),
+ p->prefixlen);
+ vty_out(vty, "\"%s\": ", buf2);
+ vty_out(vty, "%s",
+ json_object_to_json_string(json_paths));
+ json_object_free(json_paths);
+ first = 0;
+ }
+ }
+
+ if (output_cum) {
+ output_count += *output_cum;
+ *output_cum = output_count;
+ }
+ if (total_cum) {
+ total_count += *total_cum;
+ *total_cum = total_count;
+ }
if (use_json) {
json_object_free(json_paths);
- vty_out(vty, " } }\n");
+ if (is_last)
+ vty_out(vty, " } }\n");
+ else
+ vty_out(vty, " }, ");
} else {
- /* No route is displayed */
- if (output_count == 0) {
- if (type == bgp_show_type_normal)
+ if (is_last) {
+ /* No route is displayed */
+ if (output_count == 0) {
+ if (type == bgp_show_type_normal)
+ vty_out(vty,
+ "No BGP prefixes displayed, %ld exist\n",
+ total_count);
+ } else
vty_out(vty,
- "No BGP prefixes displayed, %ld exist\n",
- total_count);
- } else
- vty_out(vty,
- "\nDisplayed %ld routes and %ld total paths\n",
- output_count, total_count);
+ "\nDisplayed %ld routes and %ld total paths\n",
+ output_count, total_count);
+ }
}
return CMD_SUCCESS;
}
+int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
+ struct bgp_table *table, struct prefix_rd *prd_match,
+ enum bgp_show_type type, void *output_arg,
+ u_char use_json)
+{
+ struct bgp_node *rn, *next;
+ unsigned long output_cum = 0;
+ unsigned long total_cum = 0;
+
+ for (rn = bgp_table_top(table); rn; rn = next) {
+ next = bgp_route_next(rn);
+ if (prd_match && memcmp(rn->p.u.val, prd_match->val, 8) != 0)
+ continue;
+ if (rn->info != NULL) {
+ struct prefix_rd prd;
+ char rd[BUFSIZ];
+
+ memcpy(&prd, &(rn->p), sizeof(struct prefix_rd));
+ if (prefix_rd2str(&prd, rd, BUFSIZ) == NULL)
+ sprintf(rd,
+ "Unknown Type: %u",
+ decode_rd_type(prd.val));
+ bgp_show_table(vty, bgp, safi, rn->info, type,
+ output_arg, use_json,
+ rd, next == NULL,
+ &output_cum, &total_cum);
+ }
+ }
+ if (use_json)
+ vty_out(vty, " } }");
+ return CMD_SUCCESS;
+}
static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
enum bgp_show_type type, void *output_arg, u_char use_json)
{
@@ -8411,18 +8465,18 @@ static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
return CMD_WARNING;
}
+ table = bgp->rib[afi][safi];
/* use MPLS and ENCAP specific shows until they are merged */
if (safi == SAFI_MPLS_VPN) {
- return bgp_show_mpls_vpn(vty, afi, NULL, type, output_arg, 0,
- use_json);
+ return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
+ output_arg, use_json);
}
/* labeled-unicast routes live in the unicast table */
else if (safi == SAFI_LABELED_UNICAST)
safi = SAFI_UNICAST;
- table = bgp->rib[afi][safi];
-
- return bgp_show_table(vty, bgp, table, type, output_arg, use_json);
+ return bgp_show_table(vty, bgp, safi, table, type, output_arg, use_json,
+ NULL, 1, NULL, NULL);
}
static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
@@ -9092,12 +9146,7 @@ DEFUN (show_ip_bgp_json,
return bgp_show(vty, bgp, afi, safi,
bgp_show_type_community_all, NULL, uj);
}
-
- if (safi == SAFI_MPLS_VPN)
- return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
- NULL, 0, uj);
- else
- return bgp_show(vty, bgp, afi, safi, sh_type, NULL, uj);
+ return bgp_show(vty, bgp, afi, safi, sh_type, NULL, uj);
}
DEFUN (show_ip_bgp_route,
@@ -11415,12 +11464,6 @@ void bgp_route_init(void)
install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_network_cmd);
- install_element(BGP_IPV6L_NODE, &bgp_table_map_cmd);
- install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
- install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_route_map_cmd);
- install_element(BGP_IPV6L_NODE, &no_bgp_table_map_cmd);
- install_element(BGP_IPV6L_NODE, &no_ipv6_bgp_network_cmd);
-
install_element(BGP_NODE, &bgp_distance_cmd);
install_element(BGP_NODE, &no_bgp_distance_cmd);
install_element(BGP_NODE, &bgp_distance_source_cmd);
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index 6caa1c8939..6fbeed8963 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -442,4 +442,8 @@ extern void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
struct prefix *p, struct bgp_info *binfo,
afi_t afi, safi_t safi,
json_object *json_paths);
+extern int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
+ struct bgp_table *table, struct prefix_rd *prd,
+ enum bgp_show_type type, void *output_arg,
+ u_char use_json);
#endif /* _QUAGGA_BGP_ROUTE_H */
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 4ddb499821..355d1037b8 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -9868,17 +9868,13 @@ static int bgp_show_neighbor_vty(struct vty *vty, const char *name,
/* "show [ip] bgp neighbors" commands. */
DEFUN (show_ip_bgp_neighbors,
show_ip_bgp_neighbors_cmd,
- "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6|vpnv4 <all|rd ASN:NN_OR_IP-ADDRESS:NN>>] neighbors [<A.B.C.D|X:X::X:X|WORD>] [json]",
+ "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6>] neighbors [<A.B.C.D|X:X::X:X|WORD>] [json]",
SHOW_STR
IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
"Address Family\n"
"Address Family\n"
- "Address Family\n"
- "Display information about all VPNv4 NLRIs\n"
- "Display information for a route distinguisher\n"
- "VPN Route Distinguisher\n"
"Detailed information on TCP and BGP neighbor connections\n"
"Neighbor to display information about\n"
"Neighbor to display information about\n"
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index bc69b67de9..f979457244 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -224,6 +224,10 @@ static int bgp_interface_delete(int command, struct zclient *zclient,
struct interface *ifp;
struct bgp *bgp;
+ bgp = bgp_lookup_by_vrf_id(vrf_id);
+ if (!bgp)
+ return 0;
+
s = zclient->ibuf;
ifp = zebra_interface_state_read(s, vrf_id);
if (!ifp) /* This may happen if we've just unregistered for a VRF. */
@@ -232,10 +236,6 @@ static int bgp_interface_delete(int command, struct zclient *zclient,
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("Rx Intf del VRF %u IF %s", vrf_id, ifp->name);
- bgp = bgp_lookup_by_vrf_id(vrf_id);
- if (!bgp)
- return 0;
-
bgp_update_interface_nbrs(bgp, ifp, NULL);
ifp->ifindex = IFINDEX_DELETED;
@@ -252,6 +252,10 @@ static int bgp_interface_up(int command, struct zclient *zclient,
struct listnode *node, *nnode;
struct bgp *bgp;
+ bgp = bgp_lookup_by_vrf_id(vrf_id);
+ if (!bgp)
+ return 0;
+
s = zclient->ibuf;
ifp = zebra_interface_state_read(s, vrf_id);
@@ -261,10 +265,6 @@ static int bgp_interface_up(int command, struct zclient *zclient,
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("Rx Intf up VRF %u IF %s", vrf_id, ifp->name);
- bgp = bgp_lookup_by_vrf_id(vrf_id);
- if (!bgp)
- return 0;
-
for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c))
bgp_connected_add(bgp, c);
@@ -284,6 +284,10 @@ static int bgp_interface_down(int command, struct zclient *zclient,
struct listnode *node, *nnode;
struct bgp *bgp;
+ bgp = bgp_lookup_by_vrf_id(vrf_id);
+ if (!bgp)
+ return 0;
+
s = zclient->ibuf;
ifp = zebra_interface_state_read(s, vrf_id);
if (!ifp)
@@ -292,10 +296,6 @@ static int bgp_interface_down(int command, struct zclient *zclient,
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("Rx Intf down VRF %u IF %s", vrf_id, ifp->name);
- bgp = bgp_lookup_by_vrf_id(vrf_id);
- if (!bgp)
- return 0;
-
for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c))
bgp_connected_delete(bgp, c);
@@ -338,6 +338,11 @@ static int bgp_interface_address_add(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
struct connected *ifc;
+ struct bgp *bgp;
+
+ bgp = bgp_lookup_by_vrf_id(vrf_id);
+ if (!bgp)
+ return 0;
ifc = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
@@ -352,13 +357,8 @@ static int bgp_interface_address_add(int command, struct zclient *zclient,
}
if (if_is_operative(ifc->ifp)) {
- struct bgp *bgp;
-
- bgp = bgp_lookup_by_vrf_id(vrf_id);
- if (!bgp)
- return 0;
-
bgp_connected_add(bgp, ifc);
+
/* If we have learnt of any neighbors on this interface,
* check to kick off any BGP interface-based neighbors,
* but only if this is a link-local address.
@@ -377,6 +377,10 @@ static int bgp_interface_address_delete(int command, struct zclient *zclient,
struct connected *ifc;
struct bgp *bgp;
+ bgp = bgp_lookup_by_vrf_id(vrf_id);
+ if (!bgp)
+ return 0;
+
ifc = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
if (ifc == NULL)
@@ -390,9 +394,7 @@ static int bgp_interface_address_delete(int command, struct zclient *zclient,
}
if (if_is_operative(ifc->ifp)) {
- bgp = bgp_lookup_by_vrf_id(vrf_id);
- if (bgp)
- bgp_connected_delete(bgp, ifc);
+ bgp_connected_delete(bgp, ifc);
}
connected_free(ifc);
@@ -1290,10 +1292,8 @@ static void bgp_redist_del(struct bgp *bgp, afi_t afi, u_char type,
if (red) {
listnode_delete(bgp->redist[afi][type], red);
XFREE(MTYPE_BGP_REDIST, red);
- if (!bgp->redist[afi][type]->count) {
- list_free(bgp->redist[afi][type]);
- bgp->redist[afi][type] = NULL;
- }
+ if (!bgp->redist[afi][type]->count)
+ list_delete_and_null(&bgp->redist[afi][type]);
}
}
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 54155290d6..308698e1c5 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -2436,14 +2436,14 @@ int peer_group_delete(struct peer_group *group)
peer_delete(other);
}
}
- list_delete(group->peer);
+ list_delete_and_null(&group->peer);
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
for (ALL_LIST_ELEMENTS(group->listen_range[afi], node, nnode,
prefix)) {
prefix_free(prefix);
}
- list_delete(group->listen_range[afi]);
+ list_delete_and_null(&group->listen_range[afi]);
}
XFREE(MTYPE_PEER_GROUP_HOST, group->name);
@@ -3193,8 +3193,8 @@ void bgp_free(struct bgp *bgp)
QOBJ_UNREG(bgp);
- list_delete(bgp->group);
- list_delete(bgp->peer);
+ list_delete_and_null(&bgp->group);
+ list_delete_and_null(&bgp->peer);
if (bgp->peerhash) {
hash_free(bgp->peerhash);
@@ -7454,8 +7454,7 @@ void bgp_terminate(void)
/* reverse bgp_master_init */
bgp_close();
if (bm->listen_sockets)
- list_free(bm->listen_sockets);
- bm->listen_sockets = NULL;
+ list_delete_and_null(&bm->listen_sockets);
for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp))
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c
index 3dffb59d11..5ae27a2878 100644
--- a/bgpd/rfapi/bgp_rfapi_cfg.c
+++ b/bgpd/rfapi/bgp_rfapi_cfg.c
@@ -2327,8 +2327,7 @@ static void bgp_rfapi_delete_nve_group(struct vty *vty, /* NULL = no output */
listnode_delete(rfg->nves, rfd);
listnode_add(orphaned_nves, rfd);
}
- list_delete(rfg->nves);
- rfg->nves = NULL;
+ list_delete_and_null(&rfg->nves);
}
/* delete it */
@@ -2405,7 +2404,7 @@ static void bgp_rfapi_delete_nve_group(struct vty *vty, /* NULL = no output */
if (vty)
vty_out(vty, "\n");
}
- list_delete(orphaned_nves);
+ list_delete_and_null(&orphaned_nves);
}
}
@@ -3420,7 +3419,7 @@ static void bgp_rfapi_delete_l2_group(struct vty *vty, /* NULL = no output */
if (rfg->rt_export_list)
ecommunity_free(&rfg->rt_export_list);
if (rfg->labels)
- list_delete(rfg->labels);
+ list_delete_and_null(&rfg->labels);
if (rfg->rfp_cfg)
XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, rfg->rfp_cfg);
listnode_delete(bgp->rfapi_cfg->l2_groups, rfg);
@@ -3825,10 +3824,10 @@ void bgp_rfapi_cfg_destroy(struct bgp *bgp, struct rfapi_cfg *h)
bgp_rfapi_delete_named_nve_group(NULL, bgp, NULL, RFAPI_GROUP_CFG_MAX);
bgp_rfapi_delete_named_l2_group(NULL, bgp, NULL);
if (h->l2_groups != NULL)
- list_delete(h->l2_groups);
- list_delete(h->nve_groups_sequential);
- list_delete(h->rfg_export_direct_bgp_l);
- list_delete(h->rfg_export_zebra_l);
+ list_delete_and_null(&h->l2_groups);
+ list_delete_and_null(&h->nve_groups_sequential);
+ list_delete_and_null(&h->rfg_export_direct_bgp_l);
+ list_delete_and_null(&h->rfg_export_zebra_l);
if (h->default_rt_export_list)
ecommunity_free(&h->default_rt_export_list);
if (h->default_rt_import_list)
diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c
index 477716cafb..6e31b63451 100644
--- a/bgpd/rfapi/rfapi.c
+++ b/bgpd/rfapi/rfapi.c
@@ -490,7 +490,8 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
* Delete local_nexthops list
*/
if (bi->extra && bi->extra->vnc.export.local_nexthops) {
- list_delete(bi->extra->vnc.export.local_nexthops);
+ list_delete_and_null(
+ &bi->extra->vnc.export.local_nexthops);
}
bgp_aggregate_decrement(bgp, p, bi, afi, safi);
diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c
index d963a759ac..083a549307 100644
--- a/bgpd/rfapi/rfapi_import.c
+++ b/bgpd/rfapi/rfapi_import.c
@@ -3861,6 +3861,20 @@ void rfapiBgpInfoFilteredImportVPN(
VNC_ITRCCK;
}
+static void rfapiBgpInfoFilteredImportBadSafi(
+ struct rfapi_import_table *import_table, int action, struct peer *peer,
+ void *rfd, /* set for looped back routes */
+ struct prefix *p,
+ struct prefix *aux_prefix, /* AFI_L2VPN: optional IP */
+ afi_t afi, struct prefix_rd *prd,
+ struct attr *attr, /* part of bgp_info */
+ u_char type, /* part of bgp_info */
+ u_char sub_type, /* part of bgp_info */
+ uint32_t *label) /* part of bgp_info */
+{
+ vnc_zlog_debug_verbose("%s: Error, bad safi", __func__);
+}
+
static rfapi_bi_filtered_import_f *
rfapiBgpInfoFilteredImportFunction(safi_t safi)
{
@@ -3874,7 +3888,7 @@ rfapiBgpInfoFilteredImportFunction(safi_t safi)
default:
/* not expected */
zlog_err("%s: bad safi %d", __func__, safi);
- return NULL;
+ return rfapiBgpInfoFilteredImportBadSafi;
}
}
diff --git a/bgpd/rfapi/rfapi_monitor.c b/bgpd/rfapi/rfapi_monitor.c
index 6a7595443a..47a72d75fd 100644
--- a/bgpd/rfapi/rfapi_monitor.c
+++ b/bgpd/rfapi/rfapi_monitor.c
@@ -1378,6 +1378,8 @@ struct route_node *rfapiMonitorEthAdd(struct bgp *bgp,
#if DEBUG_L2_EXTRA
vnc_zlog_debug_verbose("%s: inserted rfd=%p mon_eth=%p, rc=%d",
__func__, rfd, val, rc);
+#else
+ (void)rc;
#endif
/*
diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c
index 748c0c476b..92cd1888ee 100644
--- a/bgpd/rfapi/rfapi_rib.c
+++ b/bgpd/rfapi/rfapi_rib.c
@@ -510,13 +510,12 @@ void rfapiRibClear(struct rfapi_descriptor *rfd)
*/
if (pn->info) {
if (pn->info != (void *)1) {
- list_delete(
- (struct list
- *)(pn->info));
+ list_delete_and_null(
+ (struct list **)(&pn->info));
}
pn->info = NULL;
- route_unlock_node(
- pn); /* linklist or 1 deleted */
+ /* linklist or 1 deleted */
+ route_unlock_node(pn);
}
}
}
@@ -1435,7 +1434,7 @@ callback:
}
delete_list->del = (void (*)(void *))rfapi_info_free;
- list_delete(delete_list);
+ list_delete_and_null(&delete_list);
}
RFAPI_RIB_CHECK_COUNTS(0, 0);
@@ -1450,7 +1449,7 @@ callback:
route_unlock_node(pn);
}
if (lPendCost) {
- list_delete(lPendCost);
+ list_delete_and_null(&lPendCost);
pn->info = NULL;
route_unlock_node(pn);
}
@@ -1634,7 +1633,7 @@ void rfapiRibUpdatePendingNode(
*/
if (pn->info) {
if (pn->info != (void *)1) {
- list_delete((struct list *)(pn->info));
+ list_delete_and_null((struct list **)(&pn->info));
}
pn->info = NULL;
route_unlock_node(pn); /* linklist or 1 deleted */
diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c
index c6958237a3..7bfc8882e2 100644
--- a/bgpd/rfapi/rfapi_vty.c
+++ b/bgpd/rfapi/rfapi_vty.c
@@ -3274,7 +3274,7 @@ static int rfapiDeleteLocalPrefixesByRFD(struct rfapi_local_reg_delete_arg *cda,
}
list_delete_all_node(adb_delete_list);
}
- list_delete(adb_delete_list);
+ list_delete_and_null(&adb_delete_list);
}
diff --git a/bgpd/rfapi/vnc_export_bgp.c b/bgpd/rfapi/vnc_export_bgp.c
index b699cec9e7..75347a7eea 100644
--- a/bgpd/rfapi/vnc_export_bgp.c
+++ b/bgpd/rfapi/vnc_export_bgp.c
@@ -1544,7 +1544,7 @@ void vnc_direct_bgp_vpn_disable(struct bgp *bgp, afi_t afi)
if (nve_list) {
vnc_direct_bgp_unexport_table(
afi, it->imported_vpn[afi], nve_list);
- list_free(nve_list);
+ list_delete_and_null(&nve_list);
}
}
}
diff --git a/bgpd/rfapi/vnc_import_bgp.c b/bgpd/rfapi/vnc_import_bgp.c
index 117d4fbfd4..4122ae5a9f 100644
--- a/bgpd/rfapi/vnc_import_bgp.c
+++ b/bgpd/rfapi/vnc_import_bgp.c
@@ -2426,7 +2426,7 @@ void vnc_import_bgp_exterior_add_route_interior(
skiplist_delete(it->monitor_exterior_orphans,
bi_exterior, NULL);
}
- list_delete(list_adopted);
+ list_delete_and_null(&list_adopted);
}
}
diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c
index 3fc6ddfe35..b8058cf1e5 100644
--- a/bgpd/rfapi/vnc_zebra.c
+++ b/bgpd/rfapi/vnc_zebra.c
@@ -584,7 +584,7 @@ static void vnc_zebra_add_del_prefix(struct bgp *bgp,
nve_list_to_nh_array(rn->p.family, nves, &nexthop_count,
&nh_ary, &nhp_ary);
- list_delete(nves);
+ list_delete_and_null(&nves);
if (nexthop_count)
vnc_zebra_route_msg(&rn->p, nexthop_count, nhp_ary,
@@ -753,7 +753,7 @@ static void vnc_zebra_add_del_group_afi(struct bgp *bgp,
vnc_zlog_debug_verbose("%s: family: %d, nve count: %d",
__func__, family, nexthop_count);
- list_delete(nves);
+ list_delete_and_null(&nves);
if (nexthop_count) {
/*
diff --git a/debian/control b/debian/control
index d2b2e7cea6..84b04c347d 100644
--- a/debian/control
+++ b/debian/control
@@ -10,7 +10,7 @@ XS-Testsuite: autopkgtest
Package: frr
Architecture: any
-Depends: ${shlibs:Depends}, logrotate (>= 3.2-11), iproute, ${misc:Depends}, libc-ares2
+Depends: ${shlibs:Depends}, logrotate (>= 3.2-11), iproute2 | iproute, ${misc:Depends}, libc-ares2
Pre-Depends: adduser
Conflicts: zebra, zebra-pj, quagga
Replaces: zebra, zebra-pj
diff --git a/debian/frr.logrotate b/debian/frr.logrotate
index 9a1fa2149b..2b4acd89c7 100644
--- a/debian/frr.logrotate
+++ b/debian/frr.logrotate
@@ -22,6 +22,6 @@
pids="$pids $(cat /var/run/frr/$i.pid)"
fi
done
- [ -n "$pids" ] && kill -USR1 $pids
+ [ -n "$pids" ] && kill -USR1 $pids || true
endscript
}
diff --git a/doc/Building_FRR_on_Ubuntu1604.md b/doc/Building_FRR_on_Ubuntu1604.md
index b33fb60253..bdd0a96249 100644
--- a/doc/Building_FRR_on_Ubuntu1604.md
+++ b/doc/Building_FRR_on_Ubuntu1604.md
@@ -14,7 +14,7 @@ Add packages:
apt-get install git autoconf automake libtool make gawk libreadline-dev \
texinfo dejagnu pkg-config libpam0g-dev libjson-c-dev bison flex \
- python-pytest libc-ares-dev python3-dev libsystemd-dev
+ python-pytest libc-ares-dev python3-dev libsystemd-dev python-ipaddr
Get FRR, compile it and install it (from Git)
---------------------------------------------
@@ -113,7 +113,7 @@ Add the following lines to `/etc/modules-load.d/modules.conf`:
**Reboot** or use `sysctl -p` to apply the same config to the running system
-### Install the systemd service
+### Install the systemd service (if rebooted from last step, change directory back to frr directory)
sudo install -m 644 tools/frr.service /etc/systemd/system/frr.service
sudo install -m 644 tools/etc/default/frr /etc/default/frr
diff --git a/eigrpd/eigrp_dump.c b/eigrpd/eigrp_dump.c
index 091b271129..20656ec4eb 100644
--- a/eigrpd/eigrp_dump.c
+++ b/eigrpd/eigrp_dump.c
@@ -210,14 +210,14 @@ void show_ip_eigrp_interface_sub(struct vty *vty, struct eigrp *eigrp,
struct eigrp_interface *ei)
{
vty_out(vty, "%-11s ", eigrp_if_name_string(ei));
- vty_out(vty, "%-11u", IF_DEF_PARAMS(ei->ifp)->bandwidth);
- vty_out(vty, "%-11u", IF_DEF_PARAMS(ei->ifp)->delay);
+ vty_out(vty, "%-11u", ei->params.bandwidth);
+ vty_out(vty, "%-11u", ei->params.delay);
vty_out(vty, "%-7u", ei->nbrs->count);
vty_out(vty, "%u %c %-10u", 0, '/',
eigrp_neighbor_packet_queue_sum(ei));
vty_out(vty, "%-7u %-14u %-12u %-8u", 0, 0, 0, 0);
- vty_out(vty, "%-8u %-8u \n", IF_DEF_PARAMS(ei->ifp)->v_hello,
- IF_DEF_PARAMS(ei->ifp)->v_wait);
+ vty_out(vty, "%-8u %-8u \n", ei->params.v_hello,
+ ei->params.v_wait);
}
void show_ip_eigrp_interface_detail(struct vty *vty, struct eigrp *eigrp,
@@ -301,7 +301,7 @@ void show_ip_eigrp_prefix_entry(struct vty *vty, struct eigrp_prefix_entry *tn)
tn->serno);
if (successors)
- list_delete(successors);
+ list_delete_and_null(&successors);
}
void show_ip_eigrp_nexthop_entry(struct vty *vty, struct eigrp *eigrp,
diff --git a/eigrpd/eigrp_filter.c b/eigrpd/eigrp_filter.c
index 7b9e0de525..b74127aa42 100644
--- a/eigrpd/eigrp_filter.c
+++ b/eigrpd/eigrp_filter.c
@@ -187,6 +187,7 @@ void eigrp_distribute_update(struct distribute *dist)
break;
}
}
+ assert(ei != NULL);
/* Access-list for interface in */
if (dist->list[DISTRIBUTE_V4_IN]) {
diff --git a/eigrpd/eigrp_fsm.c b/eigrpd/eigrp_fsm.c
index 4514e5b9a8..29357c2b24 100644
--- a/eigrpd/eigrp_fsm.c
+++ b/eigrpd/eigrp_fsm.c
@@ -366,7 +366,7 @@ int eigrp_fsm_event_nq_fcn(struct eigrp_fsm_action_message *msg)
// neighbors left
}
- list_delete(successors);
+ list_delete_and_null(&successors);
return 1;
}
@@ -393,7 +393,7 @@ int eigrp_fsm_event_q_fcn(struct eigrp_fsm_action_message *msg)
// neighbors left
}
- list_delete(successors);
+ list_delete_and_null(&successors);
return 1;
}
@@ -445,7 +445,7 @@ int eigrp_fsm_event_lr(struct eigrp_fsm_action_message *msg)
ne = listnode_head(successors);
eigrp_send_reply(ne->adv_router,
prefix);
- list_delete(successors);
+ list_delete_and_null(&successors);
}
prefix->state = EIGRP_FSM_STATE_PASSIVE;
@@ -475,7 +475,7 @@ int eigrp_fsm_event_dinc(struct eigrp_fsm_action_message *msg)
msg);
- list_delete(successors);
+ list_delete_and_null(&successors);
return 1;
}
@@ -500,7 +500,7 @@ int eigrp_fsm_event_lr_fcs(struct eigrp_fsm_action_message *msg)
eigrp_send_reply(ne->adv_router,
prefix);
- list_delete(successors);
+ list_delete_and_null(&successors);
}
prefix->req_action |= EIGRP_FSM_NEED_UPDATE;
listnode_add(eigrp->topology_changes_internalIPV4, prefix);
@@ -536,7 +536,7 @@ int eigrp_fsm_event_lr_fcn(struct eigrp_fsm_action_message *msg)
// neighbors left
}
- list_delete(successors);
+ list_delete_and_null(&successors);
return 1;
}
@@ -552,6 +552,6 @@ int eigrp_fsm_event_qact(struct eigrp_fsm_action_message *msg)
msg->prefix->state = EIGRP_FSM_STATE_ACTIVE_2;
msg->prefix->distance = ne->distance;
- list_delete(successors);
+ list_delete_and_null(&successors);
return 1;
}
diff --git a/eigrpd/eigrp_hello.c b/eigrpd/eigrp_hello.c
index 49647c6b85..1cb265cf12 100644
--- a/eigrpd/eigrp_hello.c
+++ b/eigrpd/eigrp_hello.c
@@ -89,7 +89,7 @@ int eigrp_hello_timer(struct thread *thread)
if (IS_DEBUG_EIGRP(0, TIMERS))
zlog_debug("Start Hello Timer (%s) Expire [%u]", IF_NAME(ei),
- EIGRP_IF_PARAM(ei, v_hello));
+ ei->params.v_hello);
/* Sending hello packet. */
eigrp_hello_send(ei, EIGRP_HELLO_NORMAL, NULL);
@@ -97,7 +97,7 @@ int eigrp_hello_timer(struct thread *thread)
/* Hello timer set. */
ei->t_hello = NULL;
thread_add_timer(master, eigrp_hello_timer, ei,
- EIGRP_IF_PARAM(ei, v_hello), &ei->t_hello);
+ ei->params.v_hello, &ei->t_hello);
return 0;
}
@@ -600,7 +600,7 @@ static u_int16_t eigrp_hello_parameter_encode(struct eigrp_interface *ei,
}
// and set hold time value..
- stream_putw(s, IF_DEF_PARAMS(ei->ifp)->v_wait);
+ stream_putw(s, ei->params.v_wait);
return length;
}
@@ -637,12 +637,12 @@ static struct eigrp_packet *eigrp_hello_encode(struct eigrp_interface *ei,
eigrp_packet_header_init(EIGRP_OPC_HELLO, ei->eigrp, ep->s, 0, 0, ack);
// encode Authentication TLV
- if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5)
- && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) {
+ if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
+ && (ei->params.auth_keychain != NULL)) {
length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei);
- } else if ((IF_DEF_PARAMS(ei->ifp)->auth_type
+ } else if ((ei->params.auth_type
== EIGRP_AUTH_TYPE_SHA256)
- && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) {
+ && (ei->params.auth_keychain != NULL)) {
length += eigrp_add_authTLV_SHA256_to_stream(ep->s, ei);
}
@@ -676,13 +676,13 @@ static struct eigrp_packet *eigrp_hello_encode(struct eigrp_interface *ei,
// set soruce address for the hello packet
ep->dst.s_addr = addr;
- if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5)
- && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) {
+ if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
+ && (ei->params.auth_keychain != NULL)) {
eigrp_make_md5_digest(ei, ep->s,
EIGRP_AUTH_BASIC_HELLO_FLAG);
- } else if ((IF_DEF_PARAMS(ei->ifp)->auth_type
+ } else if ((ei->params.auth_type
== EIGRP_AUTH_TYPE_SHA256)
- && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) {
+ && (ei->params.auth_keychain != NULL)) {
eigrp_make_sha256_digest(ei, ep->s,
EIGRP_AUTH_BASIC_HELLO_FLAG);
}
diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c
index f2512eadad..ec29d86fd2 100644
--- a/eigrpd/eigrp_interface.c
+++ b/eigrpd/eigrp_interface.c
@@ -55,41 +55,22 @@
#include "eigrpd/eigrp_memory.h"
#include "eigrpd/eigrp_fsm.h"
-static void eigrp_delete_from_if(struct interface *, struct eigrp_interface *);
-
-static void eigrp_add_to_if(struct interface *ifp, struct eigrp_interface *ei)
-{
- struct route_node *rn;
- struct prefix p;
-
- p = *ei->address;
- p.prefixlen = IPV4_MAX_PREFIXLEN;
-
- rn = route_node_get(IF_OIFS(ifp), &p);
- /* rn->info should either be NULL or equal to this ei
- * as route_node_get may return an existing node
- */
- assert(!rn->info || rn->info == ei);
- rn->info = ei;
-}
-
struct eigrp_interface *eigrp_if_new(struct eigrp *eigrp, struct interface *ifp,
struct prefix *p)
{
- struct eigrp_interface *ei;
+ struct eigrp_interface *ei = ifp->info;
int i;
- if ((ei = eigrp_if_table_lookup(ifp, p)) == NULL) {
- ei = XCALLOC(MTYPE_EIGRP_IF, sizeof(struct eigrp_interface));
- memset(ei, 0, sizeof(struct eigrp_interface));
- } else
+ if (ei)
return ei;
+ ei = XCALLOC(MTYPE_EIGRP_IF, sizeof(struct eigrp_interface));
+
/* Set zebra interface pointer. */
ei->ifp = ifp;
ei->address = p;
- eigrp_add_to_if(ifp, ei);
+ ifp->info = ei;
listnode_add(eigrp->eiflist, ei);
ei->type = EIGRP_IFTYPE_BROADCAST;
@@ -106,39 +87,32 @@ struct eigrp_interface *eigrp_if_new(struct eigrp *eigrp, struct interface *ifp,
ei->routemap[i] = NULL;
}
- return ei;
-}
-
-/* lookup ei for specified prefix/ifp */
-struct eigrp_interface *eigrp_if_table_lookup(struct interface *ifp,
- struct prefix *prefix)
-{
- struct prefix p;
- struct route_node *rn;
- struct eigrp_interface *rninfo = NULL;
-
- p = *prefix;
- p.prefixlen = IPV4_MAX_PREFIXLEN;
+ ei->eigrp = eigrp;
- /* route_node_get implicitly locks */
- if ((rn = route_node_lookup(IF_OIFS(ifp), &p))) {
- rninfo = (struct eigrp_interface *)rn->info;
- route_unlock_node(rn);
- }
+ ei->params.v_hello = EIGRP_HELLO_INTERVAL_DEFAULT;
+ ei->params.v_wait = EIGRP_HOLD_INTERVAL_DEFAULT;
+ ei->params.bandwidth = EIGRP_BANDWIDTH_DEFAULT;
+ ei->params.delay = EIGRP_DELAY_DEFAULT;
+ ei->params.reliability = EIGRP_RELIABILITY_DEFAULT;
+ ei->params.load = EIGRP_LOAD_DEFAULT;
+ ei->params.auth_type = EIGRP_AUTH_TYPE_NONE;
+ ei->params.auth_keychain = NULL;
- return rninfo;
+ return ei;
}
int eigrp_if_delete_hook(struct interface *ifp)
{
- struct route_node *rn;
+ struct eigrp_interface *ei = ifp->info;
+ struct eigrp *eigrp;
- route_table_finish(IF_OIFS(ifp));
+ if (!ei)
+ return 0;
+
+ list_delete_and_null(&ei->nbrs);
- for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn))
- if (rn->info)
- eigrp_del_if_params(rn->info);
- route_table_finish(IF_OIFS_PARAMS(ifp));
+ eigrp = ei->eigrp;
+ listnode_delete(eigrp->eiflist, ei);
XFREE(MTYPE_EIGRP_IF_INFO, ifp->info);
ifp->info = NULL;
@@ -151,95 +125,16 @@ struct list *eigrp_iflist;
void eigrp_if_init()
{
/* Initialize Zebra interface data structure. */
- hook_register_prio(if_add, 0, eigrp_if_new_hook);
+ //hook_register_prio(if_add, 0, eigrp_if_new);
hook_register_prio(if_del, 0, eigrp_if_delete_hook);
}
-int eigrp_if_new_hook(struct interface *ifp)
-{
- int rc = 0;
-
- ifp->info = XCALLOC(MTYPE_EIGRP_IF_INFO, sizeof(struct eigrp_if_info));
-
- IF_OIFS(ifp) = route_table_init();
- IF_OIFS_PARAMS(ifp) = route_table_init();
-
- IF_DEF_PARAMS(ifp) = eigrp_new_if_params();
-
- SET_IF_PARAM(IF_DEF_PARAMS(ifp), v_hello);
- IF_DEF_PARAMS(ifp)->v_hello = (u_int32_t)EIGRP_HELLO_INTERVAL_DEFAULT;
-
- SET_IF_PARAM(IF_DEF_PARAMS(ifp), v_wait);
- IF_DEF_PARAMS(ifp)->v_wait = (u_int16_t)EIGRP_HOLD_INTERVAL_DEFAULT;
-
- SET_IF_PARAM(IF_DEF_PARAMS(ifp), bandwidth);
- IF_DEF_PARAMS(ifp)->bandwidth = (u_int32_t)EIGRP_BANDWIDTH_DEFAULT;
-
- SET_IF_PARAM(IF_DEF_PARAMS(ifp), delay);
- IF_DEF_PARAMS(ifp)->delay = (u_int32_t)EIGRP_DELAY_DEFAULT;
-
- SET_IF_PARAM(IF_DEF_PARAMS(ifp), reliability);
- IF_DEF_PARAMS(ifp)->reliability = (u_char)EIGRP_RELIABILITY_DEFAULT;
-
- SET_IF_PARAM(IF_DEF_PARAMS(ifp), load);
- IF_DEF_PARAMS(ifp)->load = (u_char)EIGRP_LOAD_DEFAULT;
- SET_IF_PARAM(IF_DEF_PARAMS(ifp), auth_type);
- IF_DEF_PARAMS(ifp)->auth_type = EIGRP_AUTH_TYPE_NONE;
-
- SET_IF_PARAM(IF_DEF_PARAMS(ifp), auth_keychain);
- IF_DEF_PARAMS(ifp)->auth_keychain = NULL;
-
- return rc;
-}
-
-struct eigrp_if_params *eigrp_new_if_params(void)
-{
- struct eigrp_if_params *eip;
-
- eip = XCALLOC(MTYPE_EIGRP_IF_PARAMS, sizeof(struct eigrp_if_params));
- if (!eip)
- return NULL;
-
- UNSET_IF_PARAM(eip, passive_interface);
- UNSET_IF_PARAM(eip, v_hello);
- UNSET_IF_PARAM(eip, v_wait);
- UNSET_IF_PARAM(eip, bandwidth);
- UNSET_IF_PARAM(eip, delay);
- UNSET_IF_PARAM(eip, reliability);
- UNSET_IF_PARAM(eip, load);
- UNSET_IF_PARAM(eip, auth_keychain);
- UNSET_IF_PARAM(eip, auth_type);
-
- return eip;
-}
void eigrp_del_if_params(struct eigrp_if_params *eip)
{
if (eip->auth_keychain)
free(eip->auth_keychain);
-
- XFREE(MTYPE_EIGRP_IF_PARAMS, eip);
-}
-
-struct eigrp_if_params *eigrp_lookup_if_params(struct interface *ifp,
- struct in_addr addr)
-{
- struct prefix p;
- struct route_node *rn;
-
- p.family = AF_INET;
- p.prefixlen = IPV4_MAX_PREFIXLEN;
- p.u.prefix4 = addr;
-
- rn = route_node_lookup(IF_OIFS_PARAMS(ifp), &p);
-
- if (rn) {
- route_unlock_node(rn);
- return rn->info;
- }
-
- return NULL;
}
int eigrp_if_up(struct eigrp_interface *ei)
@@ -266,10 +161,10 @@ int eigrp_if_up(struct eigrp_interface *ei)
/*Prepare metrics*/
metric.bandwidth =
- eigrp_bandwidth_to_scaled(EIGRP_IF_PARAM(ei, bandwidth));
- metric.delay = eigrp_delay_to_scaled(EIGRP_IF_PARAM(ei, delay));
- metric.load = EIGRP_IF_PARAM(ei, load);
- metric.reliability = EIGRP_IF_PARAM(ei, reliability);
+ eigrp_bandwidth_to_scaled(ei->params.bandwidth);
+ metric.delay = eigrp_delay_to_scaled(ei->params.delay);
+ metric.load = ei->params.load;
+ metric.reliability = ei->params.reliability;
metric.mtu[0] = 0xDC;
metric.mtu[1] = 0x05;
metric.mtu[2] = 0x00;
@@ -387,33 +282,43 @@ void eigrp_if_stream_unset(struct eigrp_interface *ei)
}
}
+bool eigrp_if_is_passive(struct eigrp_interface *ei)
+{
+ if (ei->params.passive_interface == EIGRP_IF_ACTIVE)
+ return false;
+
+ if (ei->eigrp->passive_interface_default == EIGRP_IF_ACTIVE)
+ return false;
+
+ return true;
+}
+
void eigrp_if_set_multicast(struct eigrp_interface *ei)
{
- if ((EIGRP_IF_PASSIVE_STATUS(ei) == EIGRP_IF_ACTIVE)) {
+ if (!eigrp_if_is_passive(ei)) {
/* The interface should belong to the EIGRP-all-routers group.
*/
- if (!EI_MEMBER_CHECK(ei, MEMBER_ALLROUTERS)
+ if (!ei->member_allrouters
&& (eigrp_if_add_allspfrouters(ei->eigrp, ei->address,
ei->ifp->ifindex)
>= 0))
/* Set the flag only if the system call to join
* succeeded. */
- EI_MEMBER_JOINED(ei, MEMBER_ALLROUTERS);
+ ei->member_allrouters = true;
} else {
/* The interface should NOT belong to the EIGRP-all-routers
* group. */
- if (EI_MEMBER_CHECK(ei, MEMBER_ALLROUTERS)) {
+ if (ei->member_allrouters) {
/* Only actually drop if this is the last reference */
- if (EI_MEMBER_COUNT(ei, MEMBER_ALLROUTERS) == 1)
- eigrp_if_drop_allspfrouters(ei->eigrp,
- ei->address,
- ei->ifp->ifindex);
+ eigrp_if_drop_allspfrouters(ei->eigrp,
+ ei->address,
+ ei->ifp->ifindex);
/* Unset the flag regardless of whether the system call
to leave
the group succeeded, since it's much safer to assume
that
we are not a member. */
- EI_MEMBER_LEFT(ei, MEMBER_ALLROUTERS);
+ ei->member_allrouters = false;
}
}
}
@@ -428,7 +333,8 @@ u_char eigrp_default_iftype(struct interface *ifp)
return EIGRP_IFTYPE_BROADCAST;
}
-void eigrp_if_free(struct eigrp_interface *ei, int source)
+void eigrp_if_free(struct eigrp_interface *ei,
+ int source)
{
struct prefix dest_addr;
struct eigrp_prefix_entry *pe;
@@ -448,48 +354,21 @@ void eigrp_if_free(struct eigrp_interface *ei, int source)
eigrp_if_down(ei);
- list_delete(ei->nbrs);
- eigrp_delete_from_if(ei->ifp, ei);
+ list_delete_and_null(&ei->nbrs);
listnode_delete(ei->eigrp->eiflist, ei);
-
- thread_cancel_event(master, ei);
-
- memset(ei, 0, sizeof(*ei));
- XFREE(MTYPE_EIGRP_IF, ei);
-}
-
-static void eigrp_delete_from_if(struct interface *ifp,
- struct eigrp_interface *ei)
-{
- struct route_node *rn;
- struct prefix p;
-
- p = *ei->address;
- p.prefixlen = IPV4_MAX_PREFIXLEN;
-
- rn = route_node_lookup(IF_OIFS(ei->ifp), &p);
- assert(rn);
- assert(rn->info);
- rn->info = NULL;
- route_unlock_node(rn);
- route_unlock_node(rn);
}
/* Simulate down/up on the interface. This is needed, for example, when
the MTU changes. */
void eigrp_if_reset(struct interface *ifp)
{
- struct route_node *rn;
+ struct eigrp_interface *ei = ifp->info;
- for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
- struct eigrp_interface *ei;
+ if (!ei)
+ return;
- if ((ei = rn->info) == NULL)
- continue;
-
- eigrp_if_down(ei);
- eigrp_if_up(ei);
- }
+ eigrp_if_down(ei);
+ eigrp_if_up(ei);
}
struct eigrp_interface *eigrp_if_lookup_by_local_addr(struct eigrp *eigrp,
@@ -538,41 +417,6 @@ struct eigrp_interface *eigrp_if_lookup_by_name(struct eigrp *eigrp,
return NULL;
}
-/* determine receiving interface by ifp and source address */
-struct eigrp_interface *eigrp_if_lookup_recv_if(struct eigrp *eigrp,
- struct in_addr src,
- struct interface *ifp)
-{
- struct route_node *rn;
- struct prefix addr;
- struct eigrp_interface *ei, *match;
-
- addr.family = AF_INET;
- addr.u.prefix4 = src;
- addr.prefixlen = IPV4_MAX_BITLEN;
-
- match = NULL;
-
- for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
- ei = rn->info;
-
- if (!ei) /* oi can be NULL for PtP aliases */
- continue;
-
- if (if_is_loopback(ei->ifp))
- continue;
-
- if (prefix_match(CONNECTED_PREFIX(ei->connected),
- &addr)) {
- if ((match == NULL) || (match->address->prefixlen
- < ei->address->prefixlen))
- match = ei;
- }
- }
-
- return match;
-}
-
u_int32_t eigrp_bandwidth_to_scaled(u_int32_t bandwidth)
{
uint64_t temp_bandwidth = (256ull * 10000000) / bandwidth;
diff --git a/eigrpd/eigrp_interface.h b/eigrpd/eigrp_interface.h
index df5c7d395e..0999c938f6 100644
--- a/eigrpd/eigrp_interface.h
+++ b/eigrpd/eigrp_interface.h
@@ -37,14 +37,10 @@ extern void eigrp_if_init(void);
extern int eigrp_if_new_hook(struct interface *);
extern int eigrp_if_delete_hook(struct interface *);
+extern bool eigrp_if_is_passive(struct eigrp_interface *ei);
extern void eigrp_del_if_params(struct eigrp_if_params *);
-extern struct eigrp_if_params *eigrp_new_if_params(void);
extern struct eigrp_interface *eigrp_if_new(struct eigrp *, struct interface *,
struct prefix *);
-extern struct eigrp_interface *eigrp_if_table_lookup(struct interface *,
- struct prefix *);
-extern struct eigrp_if_params *eigrp_lookup_if_params(struct interface *,
- struct in_addr);
extern int eigrp_if_up(struct eigrp_interface *);
extern void eigrp_if_stream_set(struct eigrp_interface *);
extern void eigrp_if_set_multicast(struct eigrp_interface *);
@@ -58,8 +54,6 @@ extern struct eigrp_interface *eigrp_if_lookup_by_local_addr(struct eigrp *,
struct in_addr);
extern struct eigrp_interface *eigrp_if_lookup_by_name(struct eigrp *,
const char *);
-struct eigrp_interface *eigrp_if_lookup_recv_if(struct eigrp *, struct in_addr,
- struct interface *);
/* Simulate down/up on the interface. */
extern void eigrp_if_reset(struct interface *);
diff --git a/eigrpd/eigrp_macros.h b/eigrpd/eigrp_macros.h
index fdb84673df..14a8892bac 100644
--- a/eigrpd/eigrp_macros.h
+++ b/eigrpd/eigrp_macros.h
@@ -28,54 +28,14 @@
#ifndef _ZEBRA_EIGRP_MACROS_H_
#define _ZEBRA_EIGRP_MACROS_H_
-#define DECLARE_IF_PARAM(T, P) T P; u_char P##__config:1
-#define IF_EIGRP_IF_INFO(I) ((struct eigrp_if_info *)((I)->info))
-#define IF_OIFS(I) (IF_EIGRP_IF_INFO (I)->eifs)
-#define IF_OIFS_PARAMS(I) (IF_EIGRP_IF_INFO (I)->params)
-#define SET_IF_PARAM(S, P) ((S)->P##__config) = 1
-#define IF_DEF_PARAMS(I) (IF_EIGRP_IF_INFO (I)->def_params)
-
-#define UNSET_IF_PARAM(S, P) ((S)->P##__config) = 0
-
-#define EIGRP_IF_PARAM_CONFIGURED(S, P) ((S) && (S)->P##__config)
-#define EIGRP_IF_PARAM(O, P) \
- (EIGRP_IF_PARAM_CONFIGURED((O)->params, P) \
- ? (O)->params->P \
- : IF_DEF_PARAMS((O)->ifp)->P)
-
-#define EIGRP_IF_PASSIVE_STATUS(O) \
- (EIGRP_IF_PARAM_CONFIGURED((O)->params, passive_interface) \
- ? (O)->params->passive_interface \
- : (EIGRP_IF_PARAM_CONFIGURED(IF_DEF_PARAMS((O)->ifp), \
- passive_interface) \
- ? IF_DEF_PARAMS((O)->ifp)->passive_interface \
- : (O)->eigrp->passive_interface_default))
-
-//------------------------------------------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------
#define EIGRP_IF_STRING_MAXLEN 40
#define IF_NAME(I) eigrp_if_name_string ((I))
-//------------------------------------------------------------------------------------------------------------------------------------
-
-/*Macros for EIGRP interface multicast membership*/
-#define EI_MEMBER_FLAG(M) (1 << (M))
-#define EI_MEMBER_COUNT(O,M) (IF_EIGRP_IF_INFO(ei->ifp)->membership_counts[(M)])
-#define EI_MEMBER_CHECK(O, M) \
- (CHECK_FLAG((O)->multicast_memberships, EI_MEMBER_FLAG(M)))
-#define EI_MEMBER_JOINED(O, M) \
- do { \
- SET_FLAG((O)->multicast_memberships, EI_MEMBER_FLAG(M)); \
- IF_EIGRP_IF_INFO((O)->ifp)->membership_counts[(M)]++; \
- } while (0)
-#define EI_MEMBER_LEFT(O, M) \
- do { \
- UNSET_FLAG((O)->multicast_memberships, EI_MEMBER_FLAG(M)); \
- IF_EIGRP_IF_INFO((O)->ifp)->membership_counts[(M)]--; \
- } while (0)
+//--------------------------------------------------------------------------
-//-----------------------------------------------------------------------------------------------------------------------------------
/* Topology Macros */
diff --git a/eigrpd/eigrp_network.c b/eigrpd/eigrp_network.c
index c5f4080317..50e6b7b3be 100644
--- a/eigrpd/eigrp_network.c
+++ b/eigrpd/eigrp_network.c
@@ -271,6 +271,7 @@ static int eigrp_network_match_iface(const struct connected *co,
static void eigrp_network_run_interface(struct eigrp *eigrp, struct prefix *p,
struct interface *ifp)
{
+ struct eigrp_interface *ei;
struct listnode *cnode;
struct connected *co;
@@ -282,24 +283,15 @@ static void eigrp_network_run_interface(struct eigrp *eigrp, struct prefix *p,
continue;
if (p->family == co->address->family
- && !eigrp_if_table_lookup(ifp, co->address)
+ && !ifp->info
&& eigrp_network_match_iface(co, p)) {
- struct eigrp_interface *ei;
ei = eigrp_if_new(eigrp, ifp, co->address);
ei->connected = co;
- ei->params = eigrp_lookup_if_params(
- ifp, ei->address->u.prefix4);
-
/* Relate eigrp interface to eigrp instance. */
ei->eigrp = eigrp;
- /* update network type as interface flag */
- /* If network type is specified previously,
- skip network type setting. */
- ei->type = IF_DEF_PARAMS(ifp)->type;
-
/* if router_id is not configured, dont bring up
* interfaces.
* eigrp_router_id_update() will call eigrp_if_update
@@ -415,16 +407,17 @@ u_int32_t eigrp_calculate_metrics(struct eigrp *eigrp,
u_int32_t eigrp_calculate_total_metrics(struct eigrp *eigrp,
struct eigrp_nexthop_entry *entry)
{
+ struct eigrp_interface *ei = entry->ei;
+
entry->total_metric = entry->reported_metric;
uint64_t temp_delay = (uint64_t)entry->total_metric.delay
- + (uint64_t)eigrp_delay_to_scaled(
- EIGRP_IF_PARAM(entry->ei, delay));
+ + (uint64_t)eigrp_delay_to_scaled(ei->params.delay);
entry->total_metric.delay = temp_delay > EIGRP_MAX_METRIC
? EIGRP_MAX_METRIC
: (u_int32_t)temp_delay;
u_int32_t bw =
- eigrp_bandwidth_to_scaled(EIGRP_IF_PARAM(entry->ei, bandwidth));
+ eigrp_bandwidth_to_scaled(ei->params.bandwidth);
entry->total_metric.bandwidth = entry->total_metric.bandwidth > bw
? bw
: entry->total_metric.bandwidth;
diff --git a/eigrpd/eigrp_packet.c b/eigrpd/eigrp_packet.c
index d2bff74a54..83ff194729 100644
--- a/eigrpd/eigrp_packet.c
+++ b/eigrpd/eigrp_packet.c
@@ -108,7 +108,7 @@ int eigrp_make_md5_digest(struct eigrp_interface *ei, struct stream *s,
stream_get(auth_TLV, s, EIGRP_AUTH_MD5_TLV_SIZE);
stream_set_getp(s, backup_get);
- keychain = keychain_lookup(IF_DEF_PARAMS(ei->ifp)->auth_keychain);
+ keychain = keychain_lookup(ei->params.auth_keychain);
if (keychain)
key = key_lookup_for_send(keychain);
else {
@@ -169,7 +169,7 @@ int eigrp_check_md5_digest(struct stream *s,
struct TLV_MD5_Authentication_Type *auth_TLV;
struct eigrp_header *eigrph;
- if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(authTLV->key_sequence)) {
+ if (ntohl(nbr->crypt_seqnum) > ntohl(authTLV->key_sequence)) {
zlog_warn(
"interface %s: eigrp_check_md5 bad sequence %d (expect %d)",
IF_NAME(nbr->ei), ntohl(authTLV->key_sequence),
@@ -189,7 +189,7 @@ int eigrp_check_md5_digest(struct stream *s,
ibuf = s->data;
backup_end = s->endp;
- keychain = keychain_lookup(IF_DEF_PARAMS(nbr->ei->ifp)->auth_keychain);
+ keychain = keychain_lookup(nbr->ei->params.auth_keychain);
if (keychain)
key = key_lookup_for_send(keychain);
@@ -265,7 +265,7 @@ int eigrp_make_sha256_digest(struct eigrp_interface *ei, struct stream *s,
stream_get(auth_TLV, s, EIGRP_AUTH_SHA256_TLV_SIZE);
stream_set_getp(s, backup_get);
- keychain = keychain_lookup(IF_DEF_PARAMS(ei->ifp)->auth_keychain);
+ keychain = keychain_lookup(ei->params.auth_keychain);
if (keychain)
key = key_lookup_for_send(keychain);
@@ -317,7 +317,6 @@ int eigrp_write(struct thread *thread)
struct ip iph;
struct msghdr msg;
struct iovec iov[2];
- u_int16_t opcode = 0;
u_int32_t seqno, ack;
int ret;
@@ -363,7 +362,6 @@ int eigrp_write(struct thread *thread)
* this outgoing packet.
*/
eigrph = (struct eigrp_header *)STREAM_DATA(ep->s);
- opcode = eigrph->opcode;
seqno = ntohl(eigrph->sequence);
ack = ntohl(eigrph->ack);
if (ep->nbr && (ack != ep->nbr->recv_sequence_number)) {
@@ -427,9 +425,8 @@ int eigrp_write(struct thread *thread)
if (IS_DEBUG_EIGRP_TRANSMIT(0, SEND)) {
eigrph = (struct eigrp_header *)STREAM_DATA(ep->s);
- opcode = eigrph->opcode;
zlog_debug("Sending [%s][%d/%d] to [%s] via [%s] ret [%d].",
- lookup_msg(eigrp_packet_type_str, opcode, NULL),
+ lookup_msg(eigrp_packet_type_str, eigrph->opcode, NULL),
seqno, ack,
inet_ntoa(ep->dst), IF_NAME(ei), ret);
}
@@ -522,7 +519,7 @@ int eigrp_read(struct thread *thread)
}
/* associate packet with eigrp interface */
- ei = eigrp_if_lookup_recv_if(eigrp, iph->ip_src, ifp);
+ ei = ifp->info;
/* eigrp_verify_header() relies on a valid "ei" and thus can be called
only
@@ -557,21 +554,8 @@ int eigrp_read(struct thread *thread)
// stream_get_getp(ibuf)))
// return -1;
- /* Now it is safe to access all fields of EIGRP packet header. */
- /* associate packet with eigrp interface */
- ei = eigrp_if_lookup_recv_if(eigrp, iph->ip_src, ifp);
-
- /* eigrp_verify_header() relies on a valid "ei" and thus can be called
- only
- after the checks below are passed. These checks in turn access the
- fields of unverified "eigrph" structure for their own purposes and
- must remain very accurate in doing this.
- */
- if (!ei)
- return 0;
-
/* If incoming interface is passive one, ignore it. */
- if (ei && EIGRP_IF_PASSIVE_STATUS(ei) == EIGRP_IF_PASSIVE) {
+ if (ei && eigrp_if_is_passive(ei)) {
char buf[3][INET_ADDRSTRLEN];
if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV))
@@ -586,11 +570,6 @@ int eigrp_read(struct thread *thread)
buf[2], sizeof(buf[2])));
if (iph->ip_dst.s_addr == htonl(EIGRP_MULTICAST_ADDRESS)) {
- /* Try to fix multicast membership.
- * Some OS:es may have problems in this area,
- * make sure it is removed.
- */
- EI_MEMBER_JOINED(ei, MEMBER_ALLROUTERS);
eigrp_if_set_multicast(ei);
}
return 0;
@@ -1240,12 +1219,12 @@ u_int16_t eigrp_add_authTLV_MD5_to_stream(struct stream *s,
authTLV->key_sequence = 0;
memset(authTLV->Nullpad, 0, sizeof(authTLV->Nullpad));
- keychain = keychain_lookup(IF_DEF_PARAMS(ei->ifp)->auth_keychain);
+ keychain = keychain_lookup(ei->params.auth_keychain);
if (keychain)
key = key_lookup_for_send(keychain);
else {
- free(IF_DEF_PARAMS(ei->ifp)->auth_keychain);
- IF_DEF_PARAMS(ei->ifp)->auth_keychain = NULL;
+ free(ei->params.auth_keychain);
+ ei->params.auth_keychain = NULL;
eigrp_authTLV_MD5_free(authTLV);
return 0;
}
@@ -1280,12 +1259,12 @@ u_int16_t eigrp_add_authTLV_SHA256_to_stream(struct stream *s,
authTLV->key_sequence = 0;
memset(authTLV->Nullpad, 0, sizeof(authTLV->Nullpad));
- keychain = keychain_lookup(IF_DEF_PARAMS(ei->ifp)->auth_keychain);
+ keychain = keychain_lookup(ei->params.auth_keychain);
if (keychain)
key = key_lookup_for_send(keychain);
else {
- free(IF_DEF_PARAMS(ei->ifp)->auth_keychain);
- IF_DEF_PARAMS(ei->ifp)->auth_keychain = NULL;
+ free(ei->params.auth_keychain);
+ ei->params.auth_keychain = NULL;
eigrp_authTLV_SHA256_free(authTLV);
return 0;
}
diff --git a/eigrpd/eigrp_query.c b/eigrpd/eigrp_query.c
index 03c3705ffd..88a592e6c9 100644
--- a/eigrpd/eigrp_query.c
+++ b/eigrpd/eigrp_query.c
@@ -175,8 +175,8 @@ void eigrp_send_query(struct eigrp_interface *ei)
ei->eigrp->sequence_number, 0);
// encode Authentication TLV, if needed
- if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5)
- && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) {
+ if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
+ && (ei->params.auth_keychain != NULL)) {
length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei);
}
@@ -199,8 +199,8 @@ void eigrp_send_query(struct eigrp_interface *ei)
return;
}
- if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5)
- && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) {
+ if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
+ && ei->params.auth_keychain != NULL) {
eigrp_make_md5_digest(ei, ep->s, EIGRP_AUTH_UPDATE_FLAG);
}
diff --git a/eigrpd/eigrp_reply.c b/eigrpd/eigrp_reply.c
index 20d8b1b47c..8dbd1a5b35 100644
--- a/eigrpd/eigrp_reply.c
+++ b/eigrpd/eigrp_reply.c
@@ -1,5 +1,5 @@
/*
- * EIGRP Sending and Receiving EIGRP Reply Packets.
+ * Eigrp Sending and Receiving EIGRP Reply Packets.
* Copyright (C) 2013-2016
* Authors:
* Donnie Savage
@@ -94,16 +94,16 @@ void eigrp_send_reply(struct eigrp_neighbor *nbr, struct eigrp_prefix_entry *pe)
eigrp->sequence_number, 0);
// encode Authentication TLV, if needed
- if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5)
- && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) {
+ if (ei->params.auth_type == EIGRP_AUTH_TYPE_MD5
+ && (ei->params.auth_keychain != NULL)) {
length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei);
}
length += eigrp_add_internalTLV_to_stream(ep->s, pe2);
- if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5)
- && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) {
+ if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
+ && (ei->params.auth_keychain != NULL)) {
eigrp_make_md5_digest(ei, ep->s, EIGRP_AUTH_UPDATE_FLAG);
}
diff --git a/eigrpd/eigrp_siaquery.c b/eigrpd/eigrp_siaquery.c
index b242bcaae9..70df29c1f1 100644
--- a/eigrpd/eigrp_siaquery.c
+++ b/eigrpd/eigrp_siaquery.c
@@ -126,15 +126,15 @@ void eigrp_send_siaquery(struct eigrp_neighbor *nbr,
nbr->ei->eigrp->sequence_number, 0);
// encode Authentication TLV, if needed
- if ((IF_DEF_PARAMS(nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5)
- && (IF_DEF_PARAMS(nbr->ei->ifp)->auth_keychain != NULL)) {
+ if ((nbr->ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
+ && (nbr->ei->params.auth_keychain != NULL)) {
length += eigrp_add_authTLV_MD5_to_stream(ep->s, nbr->ei);
}
length += eigrp_add_internalTLV_to_stream(ep->s, pe);
- if ((IF_DEF_PARAMS(nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5)
- && (IF_DEF_PARAMS(nbr->ei->ifp)->auth_keychain != NULL)) {
+ if ((nbr->ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
+ && (nbr->ei->params.auth_keychain != NULL)) {
eigrp_make_md5_digest(nbr->ei, ep->s, EIGRP_AUTH_UPDATE_FLAG);
}
diff --git a/eigrpd/eigrp_siareply.c b/eigrpd/eigrp_siareply.c
index 4998a2d54b..b71e80cfcb 100644
--- a/eigrpd/eigrp_siareply.c
+++ b/eigrpd/eigrp_siareply.c
@@ -125,15 +125,15 @@ void eigrp_send_siareply(struct eigrp_neighbor *nbr,
nbr->ei->eigrp->sequence_number, 0);
// encode Authentication TLV, if needed
- if ((IF_DEF_PARAMS(nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5)
- && (IF_DEF_PARAMS(nbr->ei->ifp)->auth_keychain != NULL)) {
+ if (nbr->ei->params.auth_type == EIGRP_AUTH_TYPE_MD5
+ && nbr->ei->params.auth_keychain != NULL) {
length += eigrp_add_authTLV_MD5_to_stream(ep->s, nbr->ei);
}
length += eigrp_add_internalTLV_to_stream(ep->s, pe);
- if ((IF_DEF_PARAMS(nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5)
- && (IF_DEF_PARAMS(nbr->ei->ifp)->auth_keychain != NULL)) {
+ if ((nbr->ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
+ && (nbr->ei->params.auth_keychain != NULL)) {
eigrp_make_md5_digest(nbr->ei, ep->s, EIGRP_AUTH_UPDATE_FLAG);
}
diff --git a/eigrpd/eigrp_structs.h b/eigrpd/eigrp_structs.h
index 5bc63a7c47..4441f5d004 100644
--- a/eigrpd/eigrp_structs.h
+++ b/eigrpd/eigrp_structs.h
@@ -135,10 +135,32 @@ struct eigrp {
QOBJ_FIELDS
};
DECLARE_QOBJ_TYPE(eigrp)
-//------------------------------------------------------------------------------------------------------------------------------------------
+
+struct eigrp_if_params {
+ u_char passive_interface;
+ u_int32_t v_hello;
+ u_int16_t v_wait;
+ u_char type; /* type of interface */
+ u_int32_t bandwidth;
+ u_int32_t delay;
+ u_char reliability;
+ u_char load;
+
+ char *auth_keychain; /* Associated keychain with interface*/
+ int auth_type; /* EIGRP authentication type */
+};
+
+enum { MEMBER_ALLROUTERS = 0,
+ MEMBER_MAX,
+};
/*EIGRP interface structure*/
struct eigrp_interface {
+ struct eigrp_if_params params;
+
+ /*multicast group refcnts */
+ bool member_allrouters;
+
/* This interface's parent eigrp instance. */
struct eigrp *eigrp;
@@ -150,8 +172,6 @@ struct eigrp_interface {
/* To which multicast groups do we currently belong? */
- /* Configured varables. */
- struct eigrp_if_params *params;
u_char multicast_memberships;
@@ -196,39 +216,6 @@ struct eigrp_interface {
struct route_map *routemap[EIGRP_FILTER_MAX];
};
-struct eigrp_if_params {
- DECLARE_IF_PARAM(u_char, passive_interface); /* EIGRP Interface is
- passive: no sending or
- receiving (no need to
- join multicast groups)
- */
- DECLARE_IF_PARAM(u_int32_t, v_hello); /* Hello Interval */
- DECLARE_IF_PARAM(u_int16_t, v_wait); /* Router Hold Time Interval */
- DECLARE_IF_PARAM(u_char, type); /* type of interface */
- DECLARE_IF_PARAM(u_int32_t, bandwidth);
- DECLARE_IF_PARAM(u_int32_t, delay);
- DECLARE_IF_PARAM(u_char, reliability);
- DECLARE_IF_PARAM(u_char, load);
-
- DECLARE_IF_PARAM(char *,
- auth_keychain); /* Associated keychain with interface*/
- DECLARE_IF_PARAM(int, auth_type); /* EIGRP authentication type */
-};
-
-enum { MEMBER_ALLROUTERS = 0,
- MEMBER_MAX,
-};
-
-struct eigrp_if_info {
- struct eigrp_if_params *def_params;
- struct route_table *params;
- struct route_table *eifs;
- unsigned int
- membership_counts[MEMBER_MAX]; /* multicast group refcnts */
-};
-
-//------------------------------------------------------------------------------------------------------------------------------------------
-
/* Determines if it is first or last packet
* when packet consists of multiple packet
* chunks because of many route TLV
diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c
index f1bc83af63..94775622d9 100644
--- a/eigrpd/eigrp_topology.c
+++ b/eigrpd/eigrp_topology.c
@@ -101,8 +101,7 @@ static int eigrp_prefix_entry_cmp(struct eigrp_prefix_entry *node1,
static void eigrp_prefix_entry_del(struct eigrp_prefix_entry *node)
{
- list_delete_all_node(node->entries);
- list_free(node->entries);
+ list_delete_and_null(&node->entries);
}
/*
@@ -158,7 +157,7 @@ struct eigrp_nexthop_entry *eigrp_nexthop_entry_new()
*/
void eigrp_topology_free(struct list *list)
{
- list_free(list);
+ list_delete_and_null(&list);
}
/*
@@ -199,7 +198,7 @@ void eigrp_nexthop_entry_add(struct eigrp_prefix_entry *node,
eigrp_zebra_route_add(node->destination, l);
}
- list_delete(l);
+ list_delete_and_null(&l);
}
/*
@@ -217,9 +216,8 @@ void eigrp_prefix_entry_delete(struct list *topology,
listnode_delete(eigrp->topology_changes_internalIPV4, node);
if (listnode_lookup(topology, node) != NULL) {
- list_delete_all_node(node->entries);
- list_free(node->entries);
- list_free(node->rij);
+ list_delete_and_null(&node->entries);
+ list_delete_and_null(&node->rij);
listnode_delete(topology, node);
eigrp_zebra_route_delete(node->destination);
XFREE(MTYPE_EIGRP_PREFIX_ENTRY, node);
@@ -296,7 +294,7 @@ struct list *eigrp_topology_get_successor(struct eigrp_prefix_entry *table_node)
* If we have no successors return NULL
*/
if (!successors->count) {
- list_delete(successors);
+ list_delete_and_null(&successors);
successors = NULL;
}
@@ -475,7 +473,7 @@ void eigrp_update_routing_table(struct eigrp_prefix_entry *prefix)
for (ALL_LIST_ELEMENTS_RO(successors, node, entry))
entry->flags |= EIGRP_NEXTHOP_ENTRY_INTABLE_FLAG;
- list_delete(successors);
+ list_delete_and_null(&successors);
} else {
eigrp_zebra_route_delete(prefix->destination);
for (ALL_LIST_ELEMENTS_RO(prefix->entries, node, entry))
diff --git a/eigrpd/eigrp_update.c b/eigrpd/eigrp_update.c
index baa1ac5533..4a86b48944 100644
--- a/eigrpd/eigrp_update.c
+++ b/eigrpd/eigrp_update.c
@@ -411,7 +411,7 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph,
eigrp_update_send_all(eigrp, ei);
if (nbr_prefixes)
- list_delete(nbr_prefixes);
+ list_delete_and_null(&nbr_prefixes);
}
/*send EIGRP Update packet*/
@@ -434,8 +434,8 @@ void eigrp_update_send_init(struct eigrp_neighbor *nbr)
nbr->recv_sequence_number);
// encode Authentication TLV, if needed
- if ((IF_DEF_PARAMS(nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5)
- && (IF_DEF_PARAMS(nbr->ei->ifp)->auth_keychain != NULL)) {
+ if ((nbr->ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
+ && (nbr->ei->params.auth_keychain != NULL)) {
length += eigrp_add_authTLV_MD5_to_stream(ep->s, nbr->ei);
eigrp_make_md5_digest(nbr->ei, ep->s,
EIGRP_AUTH_UPDATE_INIT_FLAG);
@@ -467,8 +467,8 @@ static void eigrp_update_place_on_nbr_queue(struct eigrp_neighbor *nbr,
u_int32_t seq_no,
int length)
{
- if((IF_DEF_PARAMS (nbr->ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) &&
- (IF_DEF_PARAMS (nbr->ei->ifp)->auth_keychain != NULL)) {
+ if((nbr->ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) &&
+ (nbr->ei->params.auth_keychain != NULL)) {
eigrp_make_md5_digest(nbr->ei,ep->s, EIGRP_AUTH_UPDATE_FLAG);
}
@@ -544,8 +544,8 @@ void eigrp_update_send_EOT(struct eigrp_neighbor *nbr)
seq_no, nbr->recv_sequence_number);
// encode Authentication TLV, if needed
- if((IF_DEF_PARAMS (ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) &&
- (IF_DEF_PARAMS (ei->ifp)->auth_keychain != NULL)) {
+ if((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) &&
+ (ei->params.auth_keychain != NULL)) {
length += eigrp_add_authTLV_MD5_to_stream(ep->s,ei);
}
@@ -564,8 +564,8 @@ void eigrp_update_send_EOT(struct eigrp_neighbor *nbr)
ep->s, EIGRP_EOT_FLAG,
seq_no, nbr->recv_sequence_number);
- if((IF_DEF_PARAMS (ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5) &&
- (IF_DEF_PARAMS (ei->ifp)->auth_keychain != NULL))
+ if((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) &&
+ (ei->params.auth_keychain != NULL))
{
length += eigrp_add_authTLV_MD5_to_stream(ep->s,ei);
}
@@ -610,8 +610,8 @@ void eigrp_update_send(struct eigrp_interface *ei)
ep->s, 0, seq_no, 0);
// encode Authentication TLV, if needed
- if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5)
- && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) {
+ if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
+ && (ei->params.auth_keychain != NULL)) {
length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei);
}
@@ -628,8 +628,8 @@ void eigrp_update_send(struct eigrp_interface *ei)
continue;
if ((length + 0x001D) > (u_int16_t)ei->ifp->mtu) {
- if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5)
- && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) {
+ if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
+ && (ei->params.auth_keychain != NULL)) {
eigrp_make_md5_digest(ei, ep->s, EIGRP_AUTH_UPDATE_FLAG);
}
@@ -646,8 +646,8 @@ void eigrp_update_send(struct eigrp_interface *ei)
ep = eigrp_packet_new(ei->ifp->mtu, NULL);
eigrp_packet_header_init(EIGRP_OPC_UPDATE, eigrp,
ep->s, 0, seq_no, 0);
- if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5)
- && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) {
+ if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
+ && (ei->params.auth_keychain != NULL)) {
length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei);
}
has_tlv = 0;
@@ -672,8 +672,8 @@ void eigrp_update_send(struct eigrp_interface *ei)
return;
}
- if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5)
- && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) {
+ if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
+ && (ei->params.auth_keychain != NULL)) {
eigrp_make_md5_digest(ei, ep->s, EIGRP_AUTH_UPDATE_FLAG);
}
@@ -790,8 +790,8 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr)
nbr->recv_sequence_number);
// encode Authentication TLV, if needed
- if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5)
- && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) {
+ if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
+ && (ei->params.auth_keychain != NULL)) {
length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei);
}
@@ -856,8 +856,8 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr)
}
/* compute Auth digest */
- if ((IF_DEF_PARAMS(ei->ifp)->auth_type == EIGRP_AUTH_TYPE_MD5)
- && (IF_DEF_PARAMS(ei->ifp)->auth_keychain != NULL)) {
+ if ((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5)
+ && (ei->params.auth_keychain != NULL)) {
eigrp_make_md5_digest(ei, ep->s, EIGRP_AUTH_UPDATE_FLAG);
}
diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c
index 01407a746f..59ec571684 100644
--- a/eigrpd/eigrp_vty.c
+++ b/eigrpd/eigrp_vty.c
@@ -95,36 +95,32 @@ static int config_write_interfaces(struct vty *vty, struct eigrp *eigrp)
for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) {
vty_frame(vty, "interface %s\n", ei->ifp->name);
- if ((IF_DEF_PARAMS(ei->ifp)->auth_type)
- == EIGRP_AUTH_TYPE_MD5) {
+ if (ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) {
vty_out(vty, " ip authentication mode eigrp %d md5\n",
eigrp->AS);
}
- if ((IF_DEF_PARAMS(ei->ifp)->auth_type)
- == EIGRP_AUTH_TYPE_SHA256) {
+ if (ei->params.auth_type == EIGRP_AUTH_TYPE_SHA256) {
vty_out(vty,
" ip authentication mode eigrp %d hmac-sha-256\n",
eigrp->AS);
}
- if (IF_DEF_PARAMS(ei->ifp)->auth_keychain) {
+ if (ei->params.auth_keychain) {
vty_out(vty,
" ip authentication key-chain eigrp %d %s\n",
eigrp->AS,
- IF_DEF_PARAMS(ei->ifp)->auth_keychain);
+ ei->params.auth_keychain);
}
- if ((IF_DEF_PARAMS(ei->ifp)->v_hello)
- != EIGRP_HELLO_INTERVAL_DEFAULT) {
+ if (ei->params.v_hello != EIGRP_HELLO_INTERVAL_DEFAULT) {
vty_out(vty, " ip hello-interval eigrp %d\n",
- IF_DEF_PARAMS(ei->ifp)->v_hello);
+ ei->params.v_hello);
}
- if ((IF_DEF_PARAMS(ei->ifp)->v_wait)
- != EIGRP_HOLD_INTERVAL_DEFAULT) {
+ if (ei->params.v_wait != EIGRP_HOLD_INTERVAL_DEFAULT) {
vty_out(vty, " ip hold-time eigrp %d\n",
- IF_DEF_PARAMS(ei->ifp)->v_wait);
+ ei->params.v_wait);
}
/*Separate this EIGRP interface configuration from the others*/
@@ -138,24 +134,29 @@ static int eigrp_write_interface(struct vty *vty)
{
struct listnode *node;
struct interface *ifp;
+ struct eigrp_interface *ei;
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ ei = ifp->info;
+ if (!ei)
+ continue;
+
vty_frame(vty, "interface %s\n", ifp->name);
if (ifp->desc)
vty_out(vty, " description %s\n", ifp->desc);
- if (IF_DEF_PARAMS(ifp)->bandwidth != EIGRP_BANDWIDTH_DEFAULT)
+ if (ei->params.bandwidth != EIGRP_BANDWIDTH_DEFAULT)
vty_out(vty, " bandwidth %u\n",
- IF_DEF_PARAMS(ifp)->bandwidth);
- if (IF_DEF_PARAMS(ifp)->delay != EIGRP_DELAY_DEFAULT)
- vty_out(vty, " delay %u\n", IF_DEF_PARAMS(ifp)->delay);
- if (IF_DEF_PARAMS(ifp)->v_hello != EIGRP_HELLO_INTERVAL_DEFAULT)
+ ei->params.bandwidth);
+ if (ei->params.delay != EIGRP_DELAY_DEFAULT)
+ vty_out(vty, " delay %u\n", ei->params.delay);
+ if (ei->params.v_hello != EIGRP_HELLO_INTERVAL_DEFAULT)
vty_out(vty, " ip hello-interval eigrp %u\n",
- IF_DEF_PARAMS(ifp)->v_hello);
- if (IF_DEF_PARAMS(ifp)->v_wait != EIGRP_HOLD_INTERVAL_DEFAULT)
+ ei->params.v_hello);
+ if (ei->params.v_wait != EIGRP_HOLD_INTERVAL_DEFAULT)
vty_out(vty, " ip hold-time eigrp %u\n",
- IF_DEF_PARAMS(ifp)->v_wait);
+ ei->params.v_wait);
vty_endframe(vty, "!\n");
}
@@ -291,8 +292,10 @@ DEFUN (eigrp_passive_interface,
char *ifname = argv[1]->arg;
for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) {
- if (strcmp(ifname, ei->ifp->name) == 0)
- SET_IF_PARAM(IF_DEF_PARAMS(ei->ifp), passive_interface);
+ if (strcmp(ifname, ei->ifp->name) == 0) {
+ ei->params.passive_interface = EIGRP_IF_PASSIVE;
+ return CMD_SUCCESS;
+ }
}
return CMD_SUCCESS;
}
@@ -310,9 +313,10 @@ DEFUN (no_eigrp_passive_interface,
char *ifname = argv[2]->arg;
for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) {
- if (strcmp(ifname, ei->ifp->name) == 0)
- UNSET_IF_PARAM(IF_DEF_PARAMS(ei->ifp),
- passive_interface);
+ if (strcmp(ifname, ei->ifp->name) == 0) {
+ ei->params.passive_interface = EIGRP_IF_ACTIVE;
+ return CMD_SUCCESS;
+ }
}
return CMD_SUCCESS;
@@ -599,6 +603,7 @@ DEFUN (eigrp_if_delay,
"Throughput delay (tens of microseconds)\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct eigrp_interface *ei = ifp->info;
struct eigrp *eigrp;
u_int32_t delay;
@@ -609,9 +614,13 @@ DEFUN (eigrp_if_delay,
return CMD_SUCCESS;
}
+ if (!ei) {
+ vty_out(vty, " EIGRP not configured on this interface\n");
+ return CMD_SUCCESS;
+ }
delay = atoi(argv[1]->arg);
- IF_DEF_PARAMS(ifp)->delay = delay;
+ ei->params.delay = delay;
eigrp_if_reset(ifp);
return CMD_SUCCESS;
@@ -625,6 +634,7 @@ DEFUN (no_eigrp_if_delay,
"Throughput delay (tens of microseconds)\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct eigrp_interface *ei = ifp->info;
struct eigrp *eigrp;
eigrp = eigrp_lookup();
@@ -633,8 +643,12 @@ DEFUN (no_eigrp_if_delay,
return CMD_SUCCESS;
}
+ if (!ei) {
+ vty_out(vty, " EIGRP not configured on this interface\n");
+ return CMD_SUCCESS;
+ }
- IF_DEF_PARAMS(ifp)->delay = EIGRP_DELAY_DEFAULT;
+ ei->params.delay = EIGRP_DELAY_DEFAULT;
eigrp_if_reset(ifp);
return CMD_SUCCESS;
@@ -648,6 +662,7 @@ DEFUN (eigrp_if_bandwidth,
"Bandwidth in kilobits\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct eigrp_interface *ei = ifp->info;
u_int32_t bandwidth;
struct eigrp *eigrp;
@@ -657,9 +672,14 @@ DEFUN (eigrp_if_bandwidth,
return CMD_SUCCESS;
}
+ if (!ei) {
+ vty_out(vty, " EIGRP not configured on this interface\n");
+ return CMD_SUCCESS;
+ }
+
bandwidth = atoi(argv[1]->arg);
- IF_DEF_PARAMS(ifp)->bandwidth = bandwidth;
+ ei->params.bandwidth = bandwidth;
eigrp_if_reset(ifp);
return CMD_SUCCESS;
@@ -674,6 +694,7 @@ DEFUN (no_eigrp_if_bandwidth,
"Bandwidth in kilobits\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct eigrp_interface *ei = ifp->info;
struct eigrp *eigrp;
eigrp = eigrp_lookup();
@@ -682,7 +703,12 @@ DEFUN (no_eigrp_if_bandwidth,
return CMD_SUCCESS;
}
- IF_DEF_PARAMS(ifp)->bandwidth = EIGRP_BANDWIDTH_DEFAULT;
+ if (!ei) {
+ vty_out(vty, " EIGRP not configured on this interface\n");
+ return CMD_SUCCESS;
+ }
+
+ ei->params.bandwidth = EIGRP_BANDWIDTH_DEFAULT;
eigrp_if_reset(ifp);
return CMD_SUCCESS;
@@ -697,6 +723,7 @@ DEFUN (eigrp_if_ip_hellointerval,
"Seconds between hello transmissions\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct eigrp_interface *ei = ifp->info;
u_int32_t hello;
struct eigrp *eigrp;
@@ -706,9 +733,14 @@ DEFUN (eigrp_if_ip_hellointerval,
return CMD_SUCCESS;
}
+ if (!ei) {
+ vty_out(vty, " EIGRP not configured on this interface\n");
+ return CMD_SUCCESS;
+ }
+
hello = atoi(argv[3]->arg);
- IF_DEF_PARAMS(ifp)->v_hello = hello;
+ ei->params.v_hello = hello;
return CMD_SUCCESS;
}
@@ -723,9 +755,8 @@ DEFUN (no_eigrp_if_ip_hellointerval,
"Seconds between hello transmissions\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct eigrp_interface *ei = ifp->info;
struct eigrp *eigrp;
- struct eigrp_interface *ei;
- struct listnode *node, *nnode;
eigrp = eigrp_lookup();
if (eigrp == NULL) {
@@ -733,17 +764,17 @@ DEFUN (no_eigrp_if_ip_hellointerval,
return CMD_SUCCESS;
}
- IF_DEF_PARAMS(ifp)->v_hello = EIGRP_HELLO_INTERVAL_DEFAULT;
-
- for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, ei)) {
- if (ei->ifp == ifp) {
- THREAD_TIMER_OFF(ei->t_hello);
- thread_add_timer(master, eigrp_hello_timer, ei, 1,
- &ei->t_hello);
- break;
- }
+ if (!ei) {
+ vty_out(vty, " EIGRP not configured on this interface\n");
+ return CMD_SUCCESS;
}
+ ei->params.v_hello = EIGRP_HELLO_INTERVAL_DEFAULT;
+
+ THREAD_TIMER_OFF(ei->t_hello);
+ thread_add_timer(master, eigrp_hello_timer, ei, 1,
+ &ei->t_hello);
+
return CMD_SUCCESS;
}
@@ -756,6 +787,7 @@ DEFUN (eigrp_if_ip_holdinterval,
"Seconds before neighbor is considered down\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct eigrp_interface *ei = ifp->info;
u_int32_t hold;
struct eigrp *eigrp;
@@ -765,9 +797,14 @@ DEFUN (eigrp_if_ip_holdinterval,
return CMD_SUCCESS;
}
+ if (!ei) {
+ vty_out(vty, " EIGRP not configured on this interface\n");
+ return CMD_SUCCESS;
+ }
+
hold = atoi(argv[3]->arg);
- IF_DEF_PARAMS(ifp)->v_wait = hold;
+ ei->params.v_wait = hold;
return CMD_SUCCESS;
}
@@ -835,6 +872,7 @@ DEFUN (no_eigrp_if_ip_holdinterval,
"Seconds before neighbor is considered down\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct eigrp_interface *ei = ifp->info;
struct eigrp *eigrp;
eigrp = eigrp_lookup();
@@ -843,22 +881,27 @@ DEFUN (no_eigrp_if_ip_holdinterval,
return CMD_SUCCESS;
}
- IF_DEF_PARAMS(ifp)->v_wait = EIGRP_HOLD_INTERVAL_DEFAULT;
+ if (!ei) {
+ vty_out(vty, " EIGRP not configured on this interface\n");
+ return CMD_SUCCESS;
+ }
+
+ ei->params.v_wait = EIGRP_HOLD_INTERVAL_DEFAULT;
return CMD_SUCCESS;
}
-static int str2auth_type(const char *str, struct interface *ifp)
+static int str2auth_type(const char *str, struct eigrp_interface *ei)
{
/* Sanity check. */
if (str == NULL)
return CMD_WARNING_CONFIG_FAILED;
if (strncmp(str, "md5", 3) == 0) {
- IF_DEF_PARAMS(ifp)->auth_type = EIGRP_AUTH_TYPE_MD5;
+ ei->params.auth_type = EIGRP_AUTH_TYPE_MD5;
return CMD_SUCCESS;
} else if (strncmp(str, "hmac-sha-256", 12) == 0) {
- IF_DEF_PARAMS(ifp)->auth_type = EIGRP_AUTH_TYPE_SHA256;
+ ei->params.auth_type = EIGRP_AUTH_TYPE_SHA256;
return CMD_SUCCESS;
}
@@ -877,6 +920,7 @@ DEFUN (eigrp_authentication_mode,
"HMAC SHA256 algorithm \n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct eigrp_interface *ei = ifp->info;
struct eigrp *eigrp;
eigrp = eigrp_lookup();
@@ -885,12 +929,17 @@ DEFUN (eigrp_authentication_mode,
return CMD_SUCCESS;
}
+ if (!ei) {
+ vty_out(vty, " EIGRP not configured on this interface\n");
+ return CMD_SUCCESS;
+ }
+
// if(strncmp(argv[2], "md5",3))
// IF_DEF_PARAMS (ifp)->auth_type = EIGRP_AUTH_TYPE_MD5;
// else if(strncmp(argv[2], "hmac-sha-256",12))
// IF_DEF_PARAMS (ifp)->auth_type = EIGRP_AUTH_TYPE_SHA256;
- return str2auth_type(argv[5]->arg, ifp);
+ return str2auth_type(argv[5]->arg, ei);
}
DEFUN (no_eigrp_authentication_mode,
@@ -906,6 +955,7 @@ DEFUN (no_eigrp_authentication_mode,
"HMAC SHA256 algorithm \n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct eigrp_interface *ei = ifp->info;
struct eigrp *eigrp;
eigrp = eigrp_lookup();
@@ -914,7 +964,12 @@ DEFUN (no_eigrp_authentication_mode,
return CMD_SUCCESS;
}
- IF_DEF_PARAMS(ifp)->auth_type = EIGRP_AUTH_TYPE_NONE;
+ if (!ei) {
+ vty_out(vty, " EIGRP not configured on this interface\n");
+ return CMD_SUCCESS;
+ }
+
+ ei->params.auth_type = EIGRP_AUTH_TYPE_NONE;
return CMD_SUCCESS;
}
@@ -930,6 +985,7 @@ DEFUN (eigrp_authentication_keychain,
"Name of key-chain\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct eigrp_interface *ei = ifp->info;
struct eigrp *eigrp;
struct keychain *keychain;
@@ -939,14 +995,19 @@ DEFUN (eigrp_authentication_keychain,
return CMD_SUCCESS;
}
+ if (!ei) {
+ vty_out(vty, " EIGRP not configured on this interface\n");
+ return CMD_SUCCESS;
+ }
+
keychain = keychain_lookup(argv[4]->arg);
if (keychain != NULL) {
- if (IF_DEF_PARAMS(ifp)->auth_keychain) {
- free(IF_DEF_PARAMS(ifp)->auth_keychain);
- IF_DEF_PARAMS(ifp)->auth_keychain =
+ if (ei->params.auth_keychain) {
+ free(ei->params.auth_keychain);
+ ei->params.auth_keychain =
strdup(keychain->name);
} else
- IF_DEF_PARAMS(ifp)->auth_keychain =
+ ei->params.auth_keychain =
strdup(keychain->name);
} else
vty_out(vty, "Key chain with specified name not found\n");
@@ -966,6 +1027,7 @@ DEFUN (no_eigrp_authentication_keychain,
"Name of key-chain\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct eigrp_interface *ei = ifp->info;
struct eigrp *eigrp;
eigrp = eigrp_lookup();
@@ -974,10 +1036,15 @@ DEFUN (no_eigrp_authentication_keychain,
return CMD_SUCCESS;
}
- if ((IF_DEF_PARAMS(ifp)->auth_keychain != NULL)
- && (strcmp(IF_DEF_PARAMS(ifp)->auth_keychain, argv[5]->arg) == 0)) {
- free(IF_DEF_PARAMS(ifp)->auth_keychain);
- IF_DEF_PARAMS(ifp)->auth_keychain = NULL;
+ if (!ei) {
+ vty_out(vty, " EIGRP not configured on this interface\n");
+ return CMD_SUCCESS;
+ }
+
+ if ((ei->params.auth_keychain != NULL)
+ && (strcmp(ei->params.auth_keychain, argv[5]->arg) == 0)) {
+ free(ei->params.auth_keychain);
+ ei->params.auth_keychain = NULL;
} else
vty_out(vty,
"Key chain with specified name not configured on interface\n");
diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c
index 95d97cf97f..66f03b776e 100644
--- a/eigrpd/eigrp_zebra.c
+++ b/eigrpd/eigrp_zebra.c
@@ -148,15 +148,16 @@ static int eigrp_interface_add(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
struct interface *ifp;
+ struct eigrp_interface *ei;
ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
- assert(ifp->info);
+ if (!ifp->info)
+ return 0;
- if (!EIGRP_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp), type)) {
- SET_IF_PARAM(IF_DEF_PARAMS(ifp), type);
- IF_DEF_PARAMS(ifp)->type = eigrp_default_iftype(ifp);
- }
+ ei = ifp->info;
+
+ ei->params.type = eigrp_default_iftype(ifp);
eigrp_if_update(ifp);
@@ -168,7 +169,6 @@ static int eigrp_interface_delete(int command, struct zclient *zclient,
{
struct interface *ifp;
struct stream *s;
- struct route_node *rn;
s = zclient->ibuf;
/* zebra_interface_state_read () updates interface structure in iflist
@@ -188,12 +188,10 @@ static int eigrp_interface_delete(int command, struct zclient *zclient,
ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
ifp->metric, ifp->mtu);
- for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn))
- if (rn->info)
- eigrp_if_free((struct eigrp_interface *)rn->info,
- INTERFACE_DOWN_BY_ZEBRA);
+ if (ifp->info)
+ eigrp_if_free(ifp->info,
+ INTERFACE_DOWN_BY_ZEBRA);
- ifp->ifindex = IFINDEX_INTERNAL;
return 0;
}
@@ -225,8 +223,6 @@ static int eigrp_interface_address_delete(int command, struct zclient *zclient,
struct connected *c;
struct interface *ifp;
struct eigrp_interface *ei;
- struct route_node *rn;
- struct prefix p;
c = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
@@ -241,17 +237,9 @@ static int eigrp_interface_address_delete(int command, struct zclient *zclient,
}
ifp = c->ifp;
- p = *c->address;
- p.prefixlen = IPV4_MAX_PREFIXLEN;
-
- rn = route_node_lookup(IF_OIFS(ifp), &p);
- if (!rn) {
- connected_free(c);
+ ei = ifp->info;
+ if (!ei)
return 0;
- }
-
- assert(rn->info);
- ei = rn->info;
/* Call interface hook functions to clean up */
eigrp_if_free(ei, INTERFACE_DOWN_BY_ZEBRA);
@@ -265,8 +253,6 @@ static int eigrp_interface_state_up(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
struct interface *ifp;
- struct eigrp_interface *ei;
- struct route_node *rn;
ifp = zebra_interface_if_lookup(zclient->ibuf);
@@ -314,12 +300,8 @@ static int eigrp_interface_state_up(int command, struct zclient *zclient,
zlog_debug("Zebra: Interface[%s] state change to up.",
ifp->name);
- for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
- if ((ei = rn->info) == NULL)
- continue;
-
- eigrp_if_up(ei);
- }
+ if (ifp->info)
+ eigrp_if_up(ifp->info);
return 0;
}
@@ -328,8 +310,6 @@ static int eigrp_interface_state_down(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
struct interface *ifp;
- struct eigrp_interface *ei;
- struct route_node *node;
ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
@@ -340,11 +320,8 @@ static int eigrp_interface_state_down(int command, struct zclient *zclient,
zlog_debug("Zebra: Interface[%s] state change to down.",
ifp->name);
- for (node = route_top(IF_OIFS(ifp)); node; node = route_next(node)) {
- if ((ei = node->info) == NULL)
- continue;
- eigrp_if_down(ei);
- }
+ if (ifp->info)
+ eigrp_if_down(ifp->info);
return 0;
}
diff --git a/eigrpd/eigrpd.c b/eigrpd/eigrpd.c
index ee60898f86..c70e198bdb 100644
--- a/eigrpd/eigrpd.c
+++ b/eigrpd/eigrpd.c
@@ -282,10 +282,10 @@ void eigrp_finish_final(struct eigrp *eigrp)
THREAD_OFF(eigrp->t_read);
close(eigrp->fd);
- list_delete(eigrp->eiflist);
- list_delete(eigrp->oi_write_q);
- list_delete(eigrp->topology_changes_externalIPV4);
- list_delete(eigrp->topology_changes_internalIPV4);
+ list_delete_and_null(&eigrp->eiflist);
+ list_delete_and_null(&eigrp->oi_write_q);
+ list_delete_and_null(&eigrp->topology_changes_externalIPV4);
+ list_delete_and_null(&eigrp->topology_changes_internalIPV4);
eigrp_topology_cleanup(eigrp->topology_table);
eigrp_topology_free(eigrp->topology_table);
diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c
index 0afa65d726..c8b9a66e29 100644
--- a/isisd/isis_adjacency.c
+++ b/isisd/isis_adjacency.c
@@ -214,13 +214,11 @@ void isis_adj_state_change(struct isis_adjacency *adj,
} else if (new_state == ISIS_ADJ_DOWN) {
listnode_delete(circuit->u.bc.adjdb[level - 1],
adj);
+
circuit->upadjcount[level - 1]--;
- if (circuit->upadjcount[level - 1] == 0) {
- /* Clean lsp_queue when no adj is up. */
- if (circuit->lsp_queue)
- list_delete_all_node(
- circuit->lsp_queue);
- }
+ if (circuit->upadjcount[level - 1] == 0)
+ isis_circuit_lsp_queue_clean(circuit);
+
isis_event_adjacency_state_change(adj,
new_state);
del = true;
@@ -270,12 +268,9 @@ void isis_adj_state_change(struct isis_adjacency *adj,
if (adj->circuit->u.p2p.neighbor == adj)
adj->circuit->u.p2p.neighbor = NULL;
circuit->upadjcount[level - 1]--;
- if (circuit->upadjcount[level - 1] == 0) {
- /* Clean lsp_queue when no adj is up. */
- if (circuit->lsp_queue)
- list_delete_all_node(
- circuit->lsp_queue);
- }
+ if (circuit->upadjcount[level - 1] == 0)
+ isis_circuit_lsp_queue_clean(circuit);
+
isis_event_adjacency_state_change(adj,
new_state);
del = true;
diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c
index 1a978ee042..4179de1c01 100644
--- a/isisd/isis_circuit.c
+++ b/isisd/isis_circuit.c
@@ -45,6 +45,7 @@
#include "isisd/isis_flags.h"
#include "isisd/isis_circuit.h"
#include "isisd/isis_lsp.h"
+#include "isisd/isis_lsp_hash.h"
#include "isisd/isis_pdu.h"
#include "isisd/isis_network.h"
#include "isisd/isis_misc.h"
@@ -452,19 +453,19 @@ void isis_circuit_if_del(struct isis_circuit *circuit, struct interface *ifp)
if (circuit->ip_addrs) {
assert(listcount(circuit->ip_addrs) == 0);
- list_delete(circuit->ip_addrs);
+ list_delete_and_null(&circuit->ip_addrs);
circuit->ip_addrs = NULL;
}
if (circuit->ipv6_link) {
assert(listcount(circuit->ipv6_link) == 0);
- list_delete(circuit->ipv6_link);
+ list_delete_and_null(&circuit->ipv6_link);
circuit->ipv6_link = NULL;
}
if (circuit->ipv6_non_link) {
assert(listcount(circuit->ipv6_non_link) == 0);
- list_delete(circuit->ipv6_non_link);
+ list_delete_and_null(&circuit->ipv6_non_link);
circuit->ipv6_non_link = NULL;
}
@@ -674,7 +675,8 @@ int isis_circuit_up(struct isis_circuit *circuit)
isis_circuit_prepare(circuit);
circuit->lsp_queue = list_new();
- circuit->lsp_queue_last_cleared = time(NULL);
+ circuit->lsp_hash = isis_lsp_hash_new();
+ monotime(&circuit->lsp_queue_last_cleared);
return ISIS_OK;
}
@@ -690,22 +692,22 @@ void isis_circuit_down(struct isis_circuit *circuit)
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
/* destroy neighbour lists */
if (circuit->u.bc.lan_neighs[0]) {
- list_delete(circuit->u.bc.lan_neighs[0]);
+ list_delete_and_null(&circuit->u.bc.lan_neighs[0]);
circuit->u.bc.lan_neighs[0] = NULL;
}
if (circuit->u.bc.lan_neighs[1]) {
- list_delete(circuit->u.bc.lan_neighs[1]);
+ list_delete_and_null(&circuit->u.bc.lan_neighs[1]);
circuit->u.bc.lan_neighs[1] = NULL;
}
/* destroy adjacency databases */
if (circuit->u.bc.adjdb[0]) {
circuit->u.bc.adjdb[0]->del = isis_delete_adj;
- list_delete(circuit->u.bc.adjdb[0]);
+ list_delete_and_null(&circuit->u.bc.adjdb[0]);
circuit->u.bc.adjdb[0] = NULL;
}
if (circuit->u.bc.adjdb[1]) {
circuit->u.bc.adjdb[1]->del = isis_delete_adj;
- list_delete(circuit->u.bc.adjdb[1]);
+ list_delete_and_null(&circuit->u.bc.adjdb[1]);
circuit->u.bc.adjdb[1] = NULL;
}
if (circuit->u.bc.is_dr[0]) {
@@ -739,12 +741,16 @@ void isis_circuit_down(struct isis_circuit *circuit)
THREAD_TIMER_OFF(circuit->t_send_csnp[1]);
THREAD_TIMER_OFF(circuit->t_send_psnp[0]);
THREAD_TIMER_OFF(circuit->t_send_psnp[1]);
+ THREAD_OFF(circuit->t_send_lsp);
THREAD_OFF(circuit->t_read);
if (circuit->lsp_queue) {
- circuit->lsp_queue->del = NULL;
- list_delete(circuit->lsp_queue);
- circuit->lsp_queue = NULL;
+ list_delete_and_null(&circuit->lsp_queue);
+ }
+
+ if (circuit->lsp_hash) {
+ isis_lsp_hash_free(circuit->lsp_hash);
+ circuit->lsp_hash = NULL;
}
/* send one gratuitous hello to spead up convergence */
@@ -1339,3 +1345,56 @@ void isis_circuit_init()
isis_vty_init();
}
+
+void isis_circuit_schedule_lsp_send(struct isis_circuit *circuit)
+{
+ if (circuit->t_send_lsp)
+ return;
+ circuit->t_send_lsp = thread_add_event(master, send_lsp, circuit, 0, NULL);
+}
+
+void isis_circuit_queue_lsp(struct isis_circuit *circuit, struct isis_lsp *lsp)
+{
+ if (isis_lsp_hash_lookup(circuit->lsp_hash, lsp))
+ return;
+
+ listnode_add(circuit->lsp_queue, lsp);
+ isis_lsp_hash_add(circuit->lsp_hash, lsp);
+ isis_circuit_schedule_lsp_send(circuit);
+}
+
+void isis_circuit_lsp_queue_clean(struct isis_circuit *circuit)
+{
+ if (!circuit->lsp_queue)
+ return;
+
+ list_delete_all_node(circuit->lsp_queue);
+ isis_lsp_hash_clean(circuit->lsp_hash);
+}
+
+void isis_circuit_cancel_queued_lsp(struct isis_circuit *circuit,
+ struct isis_lsp *lsp)
+{
+ if (!circuit->lsp_queue)
+ return;
+
+ listnode_delete(circuit->lsp_queue, lsp);
+ isis_lsp_hash_release(circuit->lsp_hash, lsp);
+}
+
+struct isis_lsp *isis_circuit_lsp_queue_pop(struct isis_circuit *circuit)
+{
+ if (!circuit->lsp_queue)
+ return NULL;
+
+ struct listnode *node = listhead(circuit->lsp_queue);
+ if (!node)
+ return NULL;
+
+ struct isis_lsp *rv = listgetdata(node);
+
+ list_delete_node(circuit->lsp_queue, node);
+ isis_lsp_hash_release(circuit->lsp_hash, rv);
+
+ return rv;
+}
diff --git a/isisd/isis_circuit.h b/isisd/isis_circuit.h
index 5906efd2b8..29694deb34 100644
--- a/isisd/isis_circuit.h
+++ b/isisd/isis_circuit.h
@@ -34,6 +34,8 @@
#define CIRCUIT_MAX 255
+struct isis_lsp;
+
struct password {
struct password *next;
int len;
@@ -79,8 +81,10 @@ struct isis_circuit {
struct thread *t_read;
struct thread *t_send_csnp[2];
struct thread *t_send_psnp[2];
+ struct thread *t_send_lsp;
struct list *lsp_queue; /* LSPs to be txed (both levels) */
- time_t lsp_queue_last_cleared; /* timestamp used to enforce transmit
+ struct isis_lsp_hash *lsp_hash; /* Hashtable synchronized with lsp_queue */
+ struct timeval lsp_queue_last_cleared; /* timestamp used to enforce transmit
* interval;
* for scalability, use one timestamp per
* circuit, instead of one per lsp per
@@ -195,4 +199,10 @@ ferr_r isis_circuit_passwd_hmac_md5_set(struct isis_circuit *circuit,
int isis_circuit_mt_enabled_set(struct isis_circuit *circuit, uint16_t mtid,
bool enabled);
+void isis_circuit_schedule_lsp_send(struct isis_circuit *circuit);
+void isis_circuit_queue_lsp(struct isis_circuit *circuit, struct isis_lsp *lsp);
+void isis_circuit_lsp_queue_clean(struct isis_circuit *circuit);
+void isis_circuit_cancel_queued_lsp(struct isis_circuit *circuit,
+ struct isis_lsp *lsp);
+struct isis_lsp *isis_circuit_lsp_queue_pop(struct isis_circuit *circuit);
#endif /* _ZEBRA_ISIS_CIRCUIT_H */
diff --git a/isisd/isis_constants.h b/isisd/isis_constants.h
index f3a5a24dde..b7b5d35c2e 100644
--- a/isisd/isis_constants.h
+++ b/isisd/isis_constants.h
@@ -73,7 +73,7 @@
#define MAX_MIN_LSP_GEN_INTERVAL 120 /* RFC 4444 says 65535 */
#define DEFAULT_MIN_LSP_GEN_INTERVAL 30
-#define MIN_LSP_TRANS_INTERVAL 5
+#define MIN_LSP_TRANS_INTERVAL 20000 /* Microseconds */
#define MIN_CSNP_INTERVAL 1
#define MAX_CSNP_INTERVAL 600
diff --git a/isisd/isis_dr.c b/isisd/isis_dr.c
index 2db8271915..84b0bb9739 100644
--- a/isisd/isis_dr.c
+++ b/isisd/isis_dr.c
@@ -135,7 +135,7 @@ int isis_dr_elect(struct isis_circuit *circuit, int level)
if (!adjdb) {
zlog_warn("isis_dr_elect() adjdb == NULL");
- list_delete(list);
+ list_delete_and_null(&list);
return ISIS_WARNING;
}
isis_adj_build_up_list(adjdb, list);
@@ -177,7 +177,7 @@ int isis_dr_elect(struct isis_circuit *circuit, int level)
*/
if (circuit->u.bc.is_dr[level - 1])
retval = isis_dr_resign(circuit, level);
- list_delete(list);
+ list_delete_and_null(&list);
return retval;
}
@@ -217,7 +217,7 @@ int isis_dr_elect(struct isis_circuit *circuit, int level)
if (circuit->u.bc.is_dr[level - 1])
retval = isis_dr_resign(circuit, level);
}
- list_delete(list);
+ list_delete_and_null(&list);
return retval;
}
diff --git a/isisd/isis_events.c b/isisd/isis_events.c
index 1cc90d031c..bc35439926 100644
--- a/isisd/isis_events.c
+++ b/isisd/isis_events.c
@@ -132,10 +132,8 @@ static void circuit_resign_level(struct isis_circuit *circuit, int level)
THREAD_TIMER_OFF(circuit->u.bc.t_refresh_pseudo_lsp[idx]);
circuit->lsp_regenerate_pending[idx] = 0;
circuit->u.bc.run_dr_elect[idx] = 0;
- if (circuit->u.bc.lan_neighs[idx] != NULL) {
- list_delete(circuit->u.bc.lan_neighs[idx]);
- circuit->u.bc.lan_neighs[idx] = NULL;
- }
+ if (circuit->u.bc.lan_neighs[idx] != NULL)
+ list_delete_and_null(&circuit->u.bc.lan_neighs[idx]);
}
return;
diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c
index 33c52804e4..07579446aa 100644
--- a/isisd/isis_lsp.c
+++ b/isisd/isis_lsp.c
@@ -111,32 +111,22 @@ static void lsp_clear_data(struct isis_lsp *lsp)
static void lsp_destroy(struct isis_lsp *lsp)
{
- struct listnode *cnode, *lnode, *lnnode;
- struct isis_lsp *lsp_in_list;
+ struct listnode *cnode;
struct isis_circuit *circuit;
if (!lsp)
return;
- if (lsp->area->circuit_list) {
- for (ALL_LIST_ELEMENTS_RO(lsp->area->circuit_list, cnode,
- circuit)) {
- if (circuit->lsp_queue == NULL)
- continue;
- for (ALL_LIST_ELEMENTS(circuit->lsp_queue, lnode,
- lnnode, lsp_in_list))
- if (lsp_in_list == lsp)
- list_delete_node(circuit->lsp_queue,
- lnode);
- }
- }
+ for (ALL_LIST_ELEMENTS_RO(lsp->area->circuit_list, cnode, circuit))
+ isis_circuit_cancel_queued_lsp(circuit, lsp);
+
ISIS_FLAGS_CLEAR_ALL(lsp->SSNflags);
ISIS_FLAGS_CLEAR_ALL(lsp->SRMflags);
lsp_clear_data(lsp);
if (LSP_FRAGMENT(lsp->hdr.lsp_id) == 0 && lsp->lspu.frags) {
- list_delete(lsp->lspu.frags);
+ list_delete_and_null(&lsp->lspu.frags);
lsp->lspu.frags = NULL;
}
@@ -1153,7 +1143,7 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
frag->tlvs = tlvs;
}
- list_delete(fragments);
+ list_delete_and_null(&fragments);
lsp_debug("ISIS (%s): LSP construction is complete. Serializing...",
area->area_tag);
return;
@@ -1531,7 +1521,7 @@ static void lsp_build_pseudo(struct isis_lsp *lsp, struct isis_circuit *circuit,
LSP_PSEUDO_ID(ne_id));
}
}
- list_delete(adj_list);
+ list_delete_and_null(&adj_list);
return;
}
@@ -1890,12 +1880,15 @@ int lsp_tick(struct thread *thread)
if (listcount(lsp_list) > 0) {
for (ALL_LIST_ELEMENTS_RO(area->circuit_list,
cnode, circuit)) {
- int diff =
- time(NULL)
- - circuit->lsp_queue_last_cleared;
- if (circuit->lsp_queue == NULL
- || diff < MIN_LSP_TRANS_INTERVAL)
+ if (!circuit->lsp_queue)
continue;
+
+ if (monotime_since(
+ &circuit->lsp_queue_last_cleared,
+ NULL) < MIN_LSP_TRANS_INTERVAL) {
+ continue;
+ }
+
for (ALL_LIST_ELEMENTS_RO(
lsp_list, lspnode, lsp)) {
if (circuit->upadjcount
@@ -1903,23 +1896,7 @@ int lsp_tick(struct thread *thread)
&& ISIS_CHECK_FLAG(
lsp->SRMflags,
circuit)) {
- /* Add the lsp only if
- * it is not already in
- * lsp
- * queue */
- if (!listnode_lookup(
- circuit->lsp_queue,
- lsp)) {
- listnode_add(
- circuit->lsp_queue,
- lsp);
- thread_add_event(
- master,
- send_lsp,
- circuit,
- 0,
- NULL);
- }
+ isis_circuit_queue_lsp(circuit, lsp);
}
}
}
@@ -1928,7 +1905,7 @@ int lsp_tick(struct thread *thread)
}
}
- list_delete(lsp_list);
+ list_delete_and_null(&lsp_list);
return ISIS_OK;
}
diff --git a/isisd/isis_lsp_hash.c b/isisd/isis_lsp_hash.c
new file mode 100644
index 0000000000..9196128828
--- /dev/null
+++ b/isisd/isis_lsp_hash.c
@@ -0,0 +1,89 @@
+/*
+ * IS-IS Rout(e)ing protocol - LSP Hash
+ *
+ * Copyright (C) 2017 Christian Franke
+ *
+ * This file is part of FreeRangeRouting (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
+ */
+#include <zebra.h>
+
+#include "hash.h"
+#include "jhash.h"
+
+#include "isisd/isis_memory.h"
+#include "isisd/isis_flags.h"
+#include "dict.h"
+#include "isisd/isis_circuit.h"
+#include "isisd/isis_lsp.h"
+#include "isisd/isis_lsp_hash.h"
+
+DEFINE_MTYPE_STATIC(ISISD, LSP_HASH, "ISIS LSP Hash")
+
+struct isis_lsp_hash {
+ struct hash *h;
+};
+
+static unsigned lsp_hash_key(void *lp)
+{
+ struct isis_lsp *lsp = lp;
+
+ return jhash(lsp->hdr.lsp_id, ISIS_SYS_ID_LEN + 2, 0x55aa5a5a);
+}
+
+static int lsp_hash_cmp(const void *a, const void *b)
+{
+ const struct isis_lsp *la = a, *lb = b;
+
+ return 0 == memcmp(la->hdr.lsp_id, lb->hdr.lsp_id, ISIS_SYS_ID_LEN + 2);
+}
+
+struct isis_lsp_hash *isis_lsp_hash_new(void)
+{
+ struct isis_lsp_hash *rv = XCALLOC(MTYPE_LSP_HASH, sizeof(*rv));
+
+ rv->h = hash_create(lsp_hash_key, lsp_hash_cmp, NULL);
+ return rv;
+}
+
+void isis_lsp_hash_clean(struct isis_lsp_hash *ih)
+{
+ hash_clean(ih->h, NULL);
+}
+
+void isis_lsp_hash_free(struct isis_lsp_hash *ih)
+{
+ isis_lsp_hash_clean(ih);
+ hash_free(ih->h);
+}
+
+struct isis_lsp *isis_lsp_hash_lookup(struct isis_lsp_hash *ih,
+ struct isis_lsp *lsp)
+{
+ return hash_lookup(ih->h, lsp);
+}
+
+void isis_lsp_hash_add(struct isis_lsp_hash *ih, struct isis_lsp *lsp)
+{
+ struct isis_lsp *inserted;
+ inserted = hash_get(ih->h, lsp, hash_alloc_intern);
+ assert(inserted == lsp);
+}
+
+void isis_lsp_hash_release(struct isis_lsp_hash *ih, struct isis_lsp *lsp)
+{
+ hash_release(ih->h, lsp);
+}
diff --git a/isisd/isis_lsp_hash.h b/isisd/isis_lsp_hash.h
new file mode 100644
index 0000000000..b50aa09dc1
--- /dev/null
+++ b/isisd/isis_lsp_hash.h
@@ -0,0 +1,34 @@
+/*
+ * IS-IS Rout(e)ing protocol - LSP Hash
+ *
+ * Copyright (C) 2017 Christian Franke
+ *
+ * This file is part of FreeRangeRouting (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 ISIS_LSP_HASH_H
+#define ISIS_LSP_HASH_H
+
+struct isis_lsp_hash;
+
+struct isis_lsp_hash *isis_lsp_hash_new(void);
+void isis_lsp_hash_clean(struct isis_lsp_hash *ih);
+void isis_lsp_hash_free(struct isis_lsp_hash *ih);
+struct isis_lsp *isis_lsp_hash_lookup(struct isis_lsp_hash *ih,
+ struct isis_lsp *lsp);
+void isis_lsp_hash_add(struct isis_lsp_hash *ih, struct isis_lsp *lsp);
+void isis_lsp_hash_release(struct isis_lsp_hash *ih, struct isis_lsp *lsp);
+#endif
diff --git a/isisd/isis_mt.c b/isisd/isis_mt.c
index 52646c2624..d13f2a13f3 100644
--- a/isisd/isis_mt.c
+++ b/isisd/isis_mt.c
@@ -151,8 +151,7 @@ void area_mt_init(struct isis_area *area)
void area_mt_finish(struct isis_area *area)
{
- list_delete(area->mt_settings);
- area->mt_settings = NULL;
+ list_delete_and_null(&area->mt_settings);
}
struct isis_area_mt_setting *area_get_mt_setting(struct isis_area *area,
@@ -275,8 +274,7 @@ void circuit_mt_init(struct isis_circuit *circuit)
void circuit_mt_finish(struct isis_circuit *circuit)
{
- list_delete(circuit->mt_settings);
- circuit->mt_settings = NULL;
+ list_delete_and_null(&circuit->mt_settings);
}
struct isis_circuit_mt_setting *
diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c
index a20051f8c3..9c68fe5966 100644
--- a/isisd/isis_pdu.c
+++ b/isisd/isis_pdu.c
@@ -1292,7 +1292,7 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp))
ISIS_SET_FLAG(lsp->SRMflags, circuit);
/* lets free it */
- list_delete(lsp_list);
+ list_delete_and_null(&lsp_list);
}
retval = ISIS_OK;
@@ -1546,8 +1546,11 @@ int send_hello(struct isis_circuit *circuit, int level)
isis_tlvs_add_auth(tlvs, &circuit->passwd);
- if (!listcount(circuit->area->area_addrs))
+ if (!listcount(circuit->area->area_addrs)) {
+ isis_free_tlvs(tlvs);
return ISIS_WARNING;
+ }
+
isis_tlvs_add_area_addresses(tlvs, circuit->area->area_addrs);
if (circuit->circ_type == CIRCUIT_T_BROADCAST)
@@ -2046,39 +2049,24 @@ int send_lsp(struct thread *thread)
{
struct isis_circuit *circuit;
struct isis_lsp *lsp;
- struct listnode *node;
int clear_srm = 1;
int retval = ISIS_OK;
circuit = THREAD_ARG(thread);
assert(circuit);
+ circuit->t_send_lsp = NULL;
- if (!circuit->lsp_queue)
- return ISIS_OK;
-
- node = listhead(circuit->lsp_queue);
-
- /*
- * Handle case where there are no LSPs on the queue. This can
- * happen, for instance, if an adjacency goes down before this
- * thread gets a chance to run.
- */
- if (!node)
+ lsp = isis_circuit_lsp_queue_pop(circuit);
+ if (!lsp)
return ISIS_OK;
-
- /*
- * Delete LSP from lsp_queue. If it's still in queue, it is assumed
- * as 'transmit pending', but send_lsp may never be called again.
- * Retry will happen because SRM flag will not be cleared.
- */
- lsp = listgetdata(node);
- list_delete_node(circuit->lsp_queue, node);
-
/* Set the last-cleared time if the queue is empty. */
/* TODO: Is is possible that new lsps keep being added to the queue
* that the queue is never empty? */
- if (list_isempty(circuit->lsp_queue))
- circuit->lsp_queue_last_cleared = time(NULL);
+ if (list_isempty(circuit->lsp_queue)) {
+ monotime(&circuit->lsp_queue_last_cleared);
+ } else {
+ isis_circuit_schedule_lsp_send(circuit);
+ }
if (circuit->state != C_STATE_UP || circuit->is_passive == 1)
goto out;
diff --git a/isisd/isis_route.c b/isisd/isis_route.c
index ff17572ef9..b9605018ed 100644
--- a/isisd/isis_route.c
+++ b/isisd/isis_route.c
@@ -289,13 +289,13 @@ static void isis_route_info_delete(struct isis_route_info *route_info)
if (route_info->nexthops) {
route_info->nexthops->del =
(void (*)(void *))isis_nexthop_delete;
- list_delete(route_info->nexthops);
+ list_delete_and_null(&route_info->nexthops);
}
if (route_info->nexthops6) {
route_info->nexthops6->del =
(void (*)(void *))isis_nexthop6_delete;
- list_delete(route_info->nexthops6);
+ list_delete_and_null(&route_info->nexthops6);
}
XFREE(MTYPE_ISIS_ROUTE_INFO, route_info);
diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c
index 34fcf8f8c6..3008fb6a1e 100644
--- a/isisd/isis_spf.c
+++ b/isisd/isis_spf.c
@@ -153,7 +153,7 @@ static int isis_vertex_queue_tent_cmp(void *a, void *b)
if (va->insert_counter > vb->insert_counter)
return 1;
- assert(!"Vertizes should be strictly ordered");
+ return 0;
}
static struct skiplist *isis_vertex_queue_skiplist(void)
@@ -205,10 +205,8 @@ static void isis_vertex_queue_free(struct isis_vertex_queue *queue)
if (queue->insert_counter) {
skiplist_free(queue->l.slist);
queue->l.slist = NULL;
- } else {
- list_delete(queue->l.list);
- queue->l.list = NULL;
- }
+ } else
+ list_delete_and_null(&queue->l.list);
}
static unsigned int isis_vertex_queue_count(struct isis_vertex_queue *queue)
@@ -437,10 +435,8 @@ static struct isis_vertex *isis_vertex_new(void *id, enum vertextype vtype)
static void isis_vertex_del(struct isis_vertex *vertex)
{
- list_delete(vertex->Adj_N);
- vertex->Adj_N = NULL;
- list_delete(vertex->parents);
- vertex->parents = NULL;
+ list_delete_and_null(&vertex->Adj_N);
+ list_delete_and_null(&vertex->parents);
memset(vertex, 0, sizeof(struct isis_vertex));
XFREE(MTYPE_ISIS_VERTEX, vertex);
@@ -1038,7 +1034,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree,
adjdb = circuit->u.bc.adjdb[spftree->level - 1];
isis_adj_build_up_list(adjdb, adj_list);
if (listcount(adj_list) == 0) {
- list_delete(adj_list);
+ list_delete_and_null(&adj_list);
if (isis->debugs & DEBUG_SPF_EVENTS)
zlog_debug(
"ISIS-Spf: no L%d adjacencies on circuit %s",
@@ -1102,7 +1098,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree,
"isis_spf_preload_tent unknow adj type");
}
}
- list_delete(adj_list);
+ list_delete_and_null(&adj_list);
/*
* Add the pseudonode
*/
diff --git a/isisd/isis_te.c b/isisd/isis_te.c
index 70afef1a86..5a4fe82c91 100644
--- a/isisd/isis_te.c
+++ b/isisd/isis_te.c
@@ -223,6 +223,9 @@ uint8_t add_te_subtlvs(uint8_t *buf, struct mpls_te_circuit *mtc)
tlvs += size;
}
+ /* Add before this line any other parsing of TLV */
+ (void)tlvs;
+
/* Update SubTLVs length */
mtc->length = subtlvs_len(mtc);
diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c
index 25a10e91e6..b7389947b7 100644
--- a/isisd/isis_tlvs.c
+++ b/isisd/isis_tlvs.c
@@ -2397,8 +2397,7 @@ struct list *isis_fragment_tlvs(struct isis_tlvs *tlvs, size_t size)
struct listnode *node;
for (ALL_LIST_ELEMENTS_RO(rv, node, fragment_tlvs))
isis_free_tlvs(fragment_tlvs);
- list_delete(rv);
- rv = NULL;
+ list_delete_and_null(&rv);
}
stream_free(dummy_stream);
diff --git a/isisd/isisd.c b/isisd/isisd.c
index bdc1d836db..5dd348089d 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -220,8 +220,7 @@ int isis_area_destroy(struct vty *vty, const char *area_tag)
circuit->ipv6_router = 0;
isis_csm_state_change(ISIS_DISABLE, circuit, area);
}
- list_delete(area->circuit_list);
- area->circuit_list = NULL;
+ list_delete_and_null(&area->circuit_list);
}
if (area->lspdb[0] != NULL) {
diff --git a/isisd/subdir.am b/isisd/subdir.am
index 6e49d4ec80..7b56715fa9 100644
--- a/isisd/subdir.am
+++ b/isisd/subdir.am
@@ -18,6 +18,7 @@ isisd_libisis_a_SOURCES = \
isisd/isis_events.c \
isisd/isis_flags.c \
isisd/isis_lsp.c \
+ isisd/isis_lsp_hash.c \
isisd/isis_memory.c \
isisd/isis_misc.c \
isisd/isis_mt.c \
@@ -46,6 +47,7 @@ noinst_HEADERS += \
isisd/isis_events.h \
isisd/isis_flags.h \
isisd/isis_lsp.h \
+ isisd/isis_lsp_hash.h \
isisd/isis_memory.h \
isisd/isis_misc.h \
isisd/isis_mt.h \
diff --git a/ldpd/address.c b/ldpd/address.c
index 18ab037760..9c1564a31f 100644
--- a/ldpd/address.c
+++ b/ldpd/address.c
@@ -88,6 +88,7 @@ send_address(struct nbr *nbr, int af, struct if_addr_head *addr_list,
err |= gen_msg_hdr(buf, msg_type, size);
size -= LDP_MSG_SIZE;
err |= gen_address_list_tlv(buf, af, addr_list, tlv_addr_count);
+ (void)size;
if (err) {
address_list_clr(addr_list);
ibuf_free(buf);
@@ -98,6 +99,7 @@ send_address(struct nbr *nbr, int af, struct if_addr_head *addr_list,
log_msg_address(1, msg_type, nbr, af, &if_addr->addr);
LIST_REMOVE(if_addr, entry);
+ assert(if_addr != LIST_FIRST(addr_list));
free(if_addr);
if (--tlv_addr_count == 0)
break;
@@ -168,7 +170,6 @@ send_mac_withdrawal(struct nbr *nbr, struct map *fec, uint8_t *mac)
err = gen_ldp_hdr(buf, size);
size -= LDP_HDR_SIZE;
err |= gen_msg_hdr(buf, MSG_TYPE_ADDRWITHDRAW, size);
- size -= LDP_MSG_SIZE;
err |= gen_address_list_tlv(buf, AF_INET, NULL, 0);
err |= gen_fec_tlv(buf, fec);
err |= gen_mac_list_tlv(buf, mac);
@@ -400,6 +401,7 @@ address_list_clr(struct if_addr_head *addr_list)
while ((if_addr = LIST_FIRST(addr_list)) != NULL) {
LIST_REMOVE(if_addr, entry);
+ assert(if_addr != LIST_FIRST(addr_list));
free(if_addr);
}
}
diff --git a/ldpd/adjacency.c b/ldpd/adjacency.c
index 5b0723a008..7e4f0fd78b 100644
--- a/ldpd/adjacency.c
+++ b/ldpd/adjacency.c
@@ -60,11 +60,11 @@ adj_compare(const struct adj *a, const struct adj *b)
switch (a->source.type) {
case HELLO_LINK:
- if (strcmp(a->source.link.ia->iface->name,
- b->source.link.ia->iface->name) < 0)
+ if (if_cmp_name_func((char *)a->source.link.ia->iface->name,
+ (char *)b->source.link.ia->iface->name) < 0)
return (-1);
- if (strcmp(a->source.link.ia->iface->name,
- b->source.link.ia->iface->name) > 0)
+ if (if_cmp_name_func((char *)a->source.link.ia->iface->name,
+ (char *)b->source.link.ia->iface->name) > 0)
return (1);
return (ldp_addrcmp(a->source.link.ia->af,
&a->source.link.src_addr, &b->source.link.src_addr));
diff --git a/ldpd/interface.c b/ldpd/interface.c
index ac48520f7b..bbcea9f553 100644
--- a/ldpd/interface.c
+++ b/ldpd/interface.c
@@ -45,7 +45,7 @@ RB_GENERATE(iface_head, iface, entry, iface_compare)
static __inline int
iface_compare(const struct iface *a, const struct iface *b)
{
- return (strcmp(a->name, b->name));
+ return (if_cmp_name_func((char *)a->name, (char *)b->name));
}
struct iface *
@@ -103,6 +103,7 @@ ldpe_if_exit(struct iface *iface)
while ((if_addr = LIST_FIRST(&iface->addr_list)) != NULL) {
LIST_REMOVE(if_addr, entry);
+ assert(if_addr != LIST_FIRST(&iface->addr_list));
free(if_addr);
}
}
diff --git a/ldpd/l2vpn.c b/ldpd/l2vpn.c
index 9bad503b9c..f9f577d564 100644
--- a/ldpd/l2vpn.c
+++ b/ldpd/l2vpn.c
@@ -114,7 +114,7 @@ l2vpn_exit(struct l2vpn *l2vpn)
static __inline int
l2vpn_if_compare(const struct l2vpn_if *a, const struct l2vpn_if *b)
{
- return (strcmp(a->ifname, b->ifname));
+ return (if_cmp_name_func((char *)a->ifname, (char *)b->ifname));
}
struct l2vpn_if *
@@ -177,7 +177,7 @@ l2vpn_if_update(struct l2vpn_if *lif)
static __inline int
l2vpn_pw_compare(const struct l2vpn_pw *a, const struct l2vpn_pw *b)
{
- return (strcmp(a->ifname, b->ifname));
+ return (if_cmp_name_func((char *)a->ifname, (char *)b->ifname));
}
struct l2vpn_pw *
diff --git a/ldpd/labelmapping.c b/ldpd/labelmapping.c
index f53bc8333d..5662038a58 100644
--- a/ldpd/labelmapping.c
+++ b/ldpd/labelmapping.c
@@ -130,6 +130,7 @@ send_labelmessage(struct nbr *nbr, uint16_t type, struct mapping_head *mh)
}
TAILQ_REMOVE(mh, me, entry);
+ assert(me != TAILQ_FIRST(mh));
free(me);
}
@@ -459,6 +460,7 @@ recv_labelmessage(struct nbr *nbr, char *buf, uint16_t len, uint16_t type)
next:
TAILQ_REMOVE(&mh, me, entry);
+ assert(me != TAILQ_FIRST(&mh));
free(me);
}
diff --git a/ldpd/lde.c b/ldpd/lde.c
index 3482f3d722..a7f933bbe5 100644
--- a/ldpd/lde.c
+++ b/ldpd/lde.c
@@ -185,11 +185,14 @@ lde_shutdown(void)
if (iev_ldpe) {
msgbuf_clear(&iev_ldpe->ibuf.w);
close(iev_ldpe->ibuf.fd);
+ iev_ldpe->ibuf.fd = -1;
}
msgbuf_clear(&iev_main->ibuf.w);
close(iev_main->ibuf.fd);
+ iev_main->ibuf.fd = -1;
msgbuf_clear(&iev_main_sync->ibuf.w);
close(iev_main_sync->ibuf.fd);
+ iev_main_sync->ibuf.fd = -1;
lde_gc_stop_timer();
lde_nbr_clear();
@@ -210,12 +213,16 @@ lde_shutdown(void)
int
lde_imsg_compose_parent(int type, pid_t pid, void *data, uint16_t datalen)
{
+ if (iev_main->ibuf.fd == -1)
+ return (0);
return (imsg_compose_event(iev_main, type, 0, pid, -1, data, datalen));
}
void
lde_imsg_compose_parent_sync(int type, pid_t pid, void *data, uint16_t datalen)
{
+ if (iev_main_sync->ibuf.fd == -1)
+ return;
imsg_compose_event(iev_main_sync, type, 0, pid, -1, data, datalen);
imsg_flush(&iev_main_sync->ibuf);
}
@@ -224,6 +231,8 @@ int
lde_imsg_compose_ldpe(int type, uint32_t peerid, pid_t pid, void *data,
uint16_t datalen)
{
+ if (iev_ldpe->ibuf.fd == -1)
+ return (0);
return (imsg_compose_event(iev_ldpe, type, peerid, pid,
-1, data, datalen));
}
@@ -429,7 +438,7 @@ lde_dispatch_parent(struct thread *thread)
struct imsg imsg;
struct kif *kif;
struct kroute *kr;
- int fd = THREAD_FD(thread);
+ int fd;
struct imsgev *iev = THREAD_ARG(thread);
struct imsgbuf *ibuf = &iev->ibuf;
ssize_t n;
diff --git a/ldpd/lde_lib.c b/ldpd/lde_lib.c
index c56b7e33d0..18c8c0a122 100644
--- a/ldpd/lde_lib.c
+++ b/ldpd/lde_lib.c
@@ -229,8 +229,10 @@ fec_free(void *arg)
struct fec_node *fn = arg;
struct fec_nh *fnh;
- while ((fnh = LIST_FIRST(&fn->nexthops)))
+ while ((fnh = LIST_FIRST(&fn->nexthops))) {
fec_nh_del(fnh);
+ assert(fnh != LIST_FIRST(&fn->nexthops));
+ }
if (!RB_EMPTY(lde_map_head, &fn->downstream))
log_warnx("%s: fec %s downstream list not empty", __func__,
log_fec(&fn->fec));
diff --git a/ldpd/ldp_vty.h b/ldpd/ldp_vty.h
index 3d2072f1e5..5e9df4aafe 100644
--- a/ldpd/ldp_vty.h
+++ b/ldpd/ldp_vty.h
@@ -38,8 +38,8 @@ int ldp_l2vpn_config_write(struct vty *);
int ldp_debug_config_write(struct vty *);
int ldp_vty_mpls_ldp (struct vty *, const char *);
int ldp_vty_address_family (struct vty *, const char *, const char *);
-int ldp_vty_disc_holdtime(struct vty *, const char *, const char *, long);
-int ldp_vty_disc_interval(struct vty *, const char *, const char *, long);
+int ldp_vty_disc_holdtime(struct vty *, const char *, enum hello_type, long);
+int ldp_vty_disc_interval(struct vty *, const char *, enum hello_type, long);
int ldp_vty_targeted_hello_accept(struct vty *, const char *, const char *);
int ldp_vty_nbr_session_holdtime(struct vty *, const char *, struct in_addr, long);
int ldp_vty_af_session_holdtime(struct vty *, const char *, long);
@@ -69,13 +69,16 @@ int ldp_vty_l2vpn_pw_pwid(struct vty *, const char *, long);
int ldp_vty_l2vpn_pw_pwstatus(struct vty *, const char *);
int ldp_vty_clear_nbr(struct vty *, const char *);
int ldp_vty_debug(struct vty *, const char *, const char *, const char *, const char *);
-int ldp_vty_show_binding(struct vty *, const char *, const char *, const char *);
+int ldp_vty_show_binding(struct vty *, const char *, const char *, int,
+ const char *, unsigned long, unsigned long, const char *, const char *);
int ldp_vty_show_discovery(struct vty *, const char *, const char *, const char *);
int ldp_vty_show_interface(struct vty *, const char *, const char *);
int ldp_vty_show_capabilities(struct vty *, const char *);
-int ldp_vty_show_neighbor(struct vty *, int, const char *, const char *);
-int ldp_vty_show_atom_binding(struct vty *, const char *);
-int ldp_vty_show_atom_vc(struct vty *, const char *);
+int ldp_vty_show_neighbor(struct vty *, const char *, int, const char *, const char *);
+int ldp_vty_show_atom_binding(struct vty *, const char *, unsigned long,
+ unsigned long, const char *);
+int ldp_vty_show_atom_vc(struct vty *, const char *, const char *,
+ const char *, const char *);
int ldp_vty_show_debugging(struct vty *);
void ldp_vty_init(void);
diff --git a/ldpd/ldp_vty_cmds.c b/ldpd/ldp_vty_cmds.c
index cd92958d4c..aa2e06dfb9 100644
--- a/ldpd/ldp_vty_cmds.c
+++ b/ldpd/ldp_vty_cmds.c
@@ -112,30 +112,52 @@ DEFUN_NOSH(ldp_exit_address_family,
return CMD_SUCCESS;
}
-DEFPY (ldp_discovery_holdtime,
- ldp_discovery_holdtime_cmd,
- "[no] discovery <hello|targeted-hello>$hello_type holdtime (1-65535)$holdtime",
+DEFPY (ldp_discovery_link_holdtime,
+ ldp_discovery_link_holdtime_cmd,
+ "[no] discovery hello holdtime (1-65535)$holdtime",
NO_STR
"Configure discovery parameters\n"
"LDP Link Hellos\n"
+ "Hello holdtime\n"
+ "Time (seconds) - 65535 implies infinite\n")
+{
+ return (ldp_vty_disc_holdtime(vty, no, HELLO_LINK, holdtime));
+}
+
+DEFPY (ldp_discovery_targeted_holdtime,
+ ldp_discovery_targeted_holdtime_cmd,
+ "[no] discovery targeted-hello holdtime (1-65535)$holdtime",
+ NO_STR
+ "Configure discovery parameters\n"
"LDP Targeted Hellos\n"
"Hello holdtime\n"
"Time (seconds) - 65535 implies infinite\n")
{
- return (ldp_vty_disc_holdtime(vty, no, hello_type, holdtime));
+ return (ldp_vty_disc_holdtime(vty, no, HELLO_TARGETED, holdtime));
}
-DEFPY (ldp_discovery_interval,
- ldp_discovery_interval_cmd,
- "[no] discovery <hello|targeted-hello>$hello_type interval (1-65535)$interval",
+DEFPY (ldp_discovery_link_interval,
+ ldp_discovery_link_interval_cmd,
+ "[no] discovery hello interval (1-65535)$interval",
NO_STR
"Configure discovery parameters\n"
"LDP Link Hellos\n"
+ "Hello interval\n"
+ "Time (seconds)\n")
+{
+ return (ldp_vty_disc_interval(vty, no, HELLO_LINK, interval));
+}
+
+DEFPY (ldp_discovery_targeted_interval,
+ ldp_discovery_targeted_interval_cmd,
+ "[no] discovery targeted-hello interval (1-65535)$interval",
+ NO_STR
+ "Configure discovery parameters\n"
"LDP Targeted Hellos\n"
"Hello interval\n"
"Time (seconds)\n")
{
- return (ldp_vty_disc_interval(vty, no, hello_type, interval));
+ return (ldp_vty_disc_interval(vty, no, HELLO_TARGETED, interval));
}
DEFPY (ldp_dual_stack_transport_connection_prefer_ipv4,
@@ -581,17 +603,38 @@ DEFPY (ldp_debug_mpls_ldp_messages_sent,
DEFPY (ldp_show_mpls_ldp_binding,
ldp_show_mpls_ldp_binding_cmd,
- "show mpls ldp [<ipv4|ipv6>]$af binding [detail]$detail [json]$json",
+ "show mpls ldp [<ipv4|ipv6>]$af binding\
+ [<A.B.C.D/M|X:X::X:X/M>$prefix [longer-prefixes$longer_prefixes]]\
+ [{\
+ neighbor A.B.C.D$nbr\
+ |local-label (0-1048575)$local_label\
+ |remote-label (0-1048575)$remote_label\
+ }]\
+ [detail]$detail [json]$json",
"Show running system information\n"
"MPLS information\n"
"Label Distribution Protocol\n"
"IPv4 Address Family\n"
"IPv6 Address Family\n"
"Label Information Base (LIB) information\n"
+ "Destination prefix (IPv4)\n"
+ "Destination prefix (IPv6)\n"
+ "Include longer matches\n"
+ "Display labels from LDP neighbor\n"
+ "Neighbor LSR-ID\n"
+ "Match locally assigned label values\n"
+ "Locally assigned label value\n"
+ "Match remotely assigned label values\n"
+ "Remotely assigned label value\n"
"Show detailed information\n"
JSON_STR)
{
- return (ldp_vty_show_binding(vty, af, detail, json));
+ if (!local_label_str)
+ local_label = NO_LABEL;
+ if (!remote_label_str)
+ remote_label = NO_LABEL;
+ return (ldp_vty_show_binding(vty, af, prefix_str, !!longer_prefixes,
+ nbr_str, local_label, remote_label, detail, json));
}
DEFPY (ldp_show_mpls_ldp_discovery,
@@ -637,52 +680,81 @@ DEFPY (ldp_show_mpls_ldp_capabilities,
DEFPY (ldp_show_mpls_ldp_neighbor,
ldp_show_mpls_ldp_neighbor_cmd,
- "show mpls ldp neighbor [detail]$detail [json]$json",
+ "show mpls ldp neighbor [A.B.C.D]$lsr_id [detail]$detail [json]$json",
"Show running system information\n"
"MPLS information\n"
"Label Distribution Protocol\n"
"Neighbor information\n"
+ "Neighbor LSR-ID\n"
"Show detailed information\n"
JSON_STR)
{
- return (ldp_vty_show_neighbor(vty, 0, detail, json));
+ return (ldp_vty_show_neighbor(vty, lsr_id_str, 0, detail, json));
}
DEFPY (ldp_show_mpls_ldp_neighbor_capabilities,
ldp_show_mpls_ldp_neighbor_capabilities_cmd,
- "show mpls ldp neighbor capabilities [json]$json",
+ "show mpls ldp neighbor [A.B.C.D]$lsr_id capabilities [json]$json",
"Show running system information\n"
"MPLS information\n"
"Label Distribution Protocol\n"
"Neighbor information\n"
+ "Neighbor LSR-ID\n"
"Display neighbor capability information\n"
JSON_STR)
{
- return (ldp_vty_show_neighbor(vty, 1, NULL, json));
+ return (ldp_vty_show_neighbor(vty, lsr_id_str, 1, NULL, json));
}
DEFPY (ldp_show_l2vpn_atom_binding,
ldp_show_l2vpn_atom_binding_cmd,
- "show l2vpn atom binding [json]$json",
+ "show l2vpn atom binding\
+ [{\
+ A.B.C.D$peer\
+ |local-label (16-1048575)$local_label\
+ |remote-label (16-1048575)$remote_label\
+ }]\
+ [json]$json",
"Show running system information\n"
"Show information about Layer2 VPN\n"
"Show Any Transport over MPLS information\n"
"Show AToM label binding information\n"
+ "Destination address of the VC\n"
+ "Match locally assigned label values\n"
+ "Locally assigned label value\n"
+ "Match remotely assigned label values\n"
+ "Remotely assigned label value\n"
JSON_STR)
{
- return (ldp_vty_show_atom_binding(vty, json));
+ if (!local_label_str)
+ local_label = NO_LABEL;
+ if (!remote_label_str)
+ remote_label = NO_LABEL;
+ return (ldp_vty_show_atom_binding(vty, peer_str, local_label,
+ remote_label, json));
}
DEFPY (ldp_show_l2vpn_atom_vc,
ldp_show_l2vpn_atom_vc_cmd,
- "show l2vpn atom vc [json]$json",
+ "show l2vpn atom vc\
+ [{\
+ A.B.C.D$peer\
+ |interface IFNAME$ifname\
+ |vc-id (1-4294967295)$vcid\
+ }]\
+ [json]$json",
"Show running system information\n"
"Show information about Layer2 VPN\n"
"Show Any Transport over MPLS information\n"
"Show AToM virtual circuit information\n"
+ "Destination address of the VC\n"
+ "Local interface of the pseudowire\n"
+ "Interface's name\n"
+ "VC ID\n"
+ "VC ID\n"
JSON_STR)
{
- return (ldp_vty_show_atom_vc(vty, json));
+ return (ldp_vty_show_atom_vc(vty, peer_str, ifname, vcid_str, json));
}
DEFUN_NOSH (ldp_show_debugging_mpls_ldp,
@@ -747,8 +819,10 @@ ldp_vty_init (void)
install_element(LDP_NODE, &ldp_address_family_cmd);
install_element(LDP_NODE, &no_ldp_address_family_cmd);
- install_element(LDP_NODE, &ldp_discovery_holdtime_cmd);
- install_element(LDP_NODE, &ldp_discovery_interval_cmd);
+ install_element(LDP_NODE, &ldp_discovery_link_holdtime_cmd);
+ install_element(LDP_NODE, &ldp_discovery_targeted_holdtime_cmd);
+ install_element(LDP_NODE, &ldp_discovery_link_interval_cmd);
+ install_element(LDP_NODE, &ldp_discovery_targeted_interval_cmd);
install_element(LDP_NODE, &ldp_dual_stack_transport_connection_prefer_ipv4_cmd);
install_element(LDP_NODE, &ldp_dual_stack_cisco_interop_cmd);
install_element(LDP_NODE, &ldp_neighbor_password_cmd);
@@ -756,8 +830,10 @@ ldp_vty_init (void)
install_element(LDP_NODE, &ldp_neighbor_ttl_security_cmd);
install_element(LDP_NODE, &ldp_router_id_cmd);
- install_element(LDP_IPV4_NODE, &ldp_discovery_holdtime_cmd);
- install_element(LDP_IPV4_NODE, &ldp_discovery_interval_cmd);
+ install_element(LDP_IPV4_NODE, &ldp_discovery_link_holdtime_cmd);
+ install_element(LDP_IPV4_NODE, &ldp_discovery_targeted_holdtime_cmd);
+ install_element(LDP_IPV4_NODE, &ldp_discovery_link_interval_cmd);
+ install_element(LDP_IPV4_NODE, &ldp_discovery_targeted_interval_cmd);
install_element(LDP_IPV4_NODE, &ldp_discovery_targeted_hello_accept_cmd);
install_element(LDP_IPV4_NODE, &ldp_discovery_transport_address_ipv4_cmd);
install_element(LDP_IPV4_NODE, &ldp_label_local_advertise_cmd);
@@ -771,8 +847,10 @@ ldp_vty_init (void)
install_element(LDP_IPV4_NODE, &ldp_neighbor_ipv4_targeted_cmd);
install_element(LDP_IPV4_NODE, &ldp_exit_address_family_cmd);
- install_element(LDP_IPV6_NODE, &ldp_discovery_holdtime_cmd);
- install_element(LDP_IPV6_NODE, &ldp_discovery_interval_cmd);
+ install_element(LDP_IPV6_NODE, &ldp_discovery_link_holdtime_cmd);
+ install_element(LDP_IPV6_NODE, &ldp_discovery_targeted_holdtime_cmd);
+ install_element(LDP_IPV6_NODE, &ldp_discovery_link_interval_cmd);
+ install_element(LDP_IPV6_NODE, &ldp_discovery_targeted_interval_cmd);
install_element(LDP_IPV6_NODE, &ldp_discovery_targeted_hello_accept_cmd);
install_element(LDP_IPV6_NODE, &ldp_discovery_transport_address_ipv6_cmd);
install_element(LDP_IPV6_NODE, &ldp_label_local_advertise_cmd);
@@ -785,11 +863,11 @@ ldp_vty_init (void)
install_element(LDP_IPV6_NODE, &ldp_neighbor_ipv6_targeted_cmd);
install_element(LDP_IPV6_NODE, &ldp_exit_address_family_cmd);
- install_element(LDP_IPV4_IFACE_NODE, &ldp_discovery_holdtime_cmd);
- install_element(LDP_IPV4_IFACE_NODE, &ldp_discovery_interval_cmd);
+ install_element(LDP_IPV4_IFACE_NODE, &ldp_discovery_link_holdtime_cmd);
+ install_element(LDP_IPV4_IFACE_NODE, &ldp_discovery_link_interval_cmd);
- install_element(LDP_IPV6_IFACE_NODE, &ldp_discovery_holdtime_cmd);
- install_element(LDP_IPV6_IFACE_NODE, &ldp_discovery_interval_cmd);
+ install_element(LDP_IPV6_IFACE_NODE, &ldp_discovery_link_holdtime_cmd);
+ install_element(LDP_IPV6_IFACE_NODE, &ldp_discovery_link_interval_cmd);
install_element(LDP_L2VPN_NODE, &ldp_bridge_cmd);
install_element(LDP_L2VPN_NODE, &ldp_mtu_cmd);
diff --git a/ldpd/ldp_vty_conf.c b/ldpd/ldp_vty_conf.c
index e938582d0d..76c602afbb 100644
--- a/ldpd/ldp_vty_conf.c
+++ b/ldpd/ldp_vty_conf.c
@@ -233,6 +233,7 @@ ldp_af_config_write(struct vty *vty, int af, struct ldpd_conf *conf,
ldp_af_iface_config_write(vty, af);
+ vty_out(vty, " !\n");
vty_out(vty, " exit-address-family\n");
}
@@ -459,20 +460,13 @@ ldp_vty_address_family(struct vty *vty, const char *negate, const char *af_str)
return (CMD_SUCCESS);
}
-int
-ldp_vty_disc_holdtime(struct vty *vty, const char *negate,
- const char *hello_type_str, long secs)
+int ldp_vty_disc_holdtime(struct vty *vty, const char *negate,
+ enum hello_type hello_type, long secs)
{
struct ldpd_af_conf *af_conf;
struct iface *iface;
struct iface_af *ia;
int af;
- enum hello_type hello_type;
-
- if (hello_type_str[0] == 'h')
- hello_type = HELLO_LINK;
- else
- hello_type = HELLO_TARGETED;
switch (vty->node) {
case LDP_NODE:
@@ -547,18 +541,12 @@ ldp_vty_disc_holdtime(struct vty *vty, const char *negate,
int
ldp_vty_disc_interval(struct vty *vty, const char *negate,
- const char *hello_type_str, long secs)
+ enum hello_type hello_type, long secs)
{
struct ldpd_af_conf *af_conf;
struct iface *iface;
struct iface_af *ia;
int af;
- enum hello_type hello_type;
-
- if (hello_type_str[0] == 'h')
- hello_type = HELLO_LINK;
- else
- hello_type = HELLO_TARGETED;
switch (vty->node) {
case LDP_NODE:
diff --git a/ldpd/ldp_vty_exec.c b/ldpd/ldp_vty_exec.c
index ad5e79c721..66c127abdc 100644
--- a/ldpd/ldp_vty_exec.c
+++ b/ldpd/ldp_vty_exec.c
@@ -44,9 +44,28 @@ struct show_params {
int family;
union ldpd_addr addr;
uint8_t prefixlen;
- int capabilities;
int detail;
int json;
+ union {
+ struct {
+ struct in_addr lsr_id;
+ int capabilities;
+ } neighbor;
+ struct {
+ struct prefix prefix;
+ int longer_prefixes;
+ struct in_addr neighbor;
+ uint32_t local_label;
+ uint32_t remote_label;
+ } lib;
+ struct {
+ struct in_addr peer;
+ uint32_t local_label;
+ uint32_t remote_label;
+ char ifname[IFNAMSIZ];
+ uint32_t vcid;
+ } l2vpn;
+ };
};
#define LDPBUFSIZ 65535
@@ -1005,6 +1024,12 @@ show_lib_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
switch (imsg->hdr.type) {
case IMSG_CTL_SHOW_LIB_BEGIN:
+ rt = imsg->data;
+
+ if (params->lib.remote_label != NO_LABEL &&
+ params->lib.remote_label != rt->remote_label)
+ return (0);
+ /* FALLTHROUGH */
case IMSG_CTL_SHOW_LIB_RCVD:
rt = imsg->data;
@@ -1012,9 +1037,6 @@ show_lib_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
!rt->no_downstream)
break;
- if (params->family != AF_UNSPEC && params->family != rt->af)
- break;
-
snprintf(dstnet, sizeof(dstnet), "%s/%d",
log_addr(rt->af, &rt->prefix), rt->prefixlen);
@@ -1039,7 +1061,7 @@ static int
show_lib_detail_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
{
struct ctl_rt *rt = NULL;
- char dstnet[BUFSIZ];
+ static char dstnet[BUFSIZ];
static int upstream, downstream;
size_t buflen;
static char sent_buffer[LDPBUFSIZ];
@@ -1047,38 +1069,25 @@ show_lib_detail_msg(struct vty *vty, struct imsg *imsg, struct show_params *para
switch (imsg->hdr.type) {
case IMSG_CTL_SHOW_LIB_BEGIN:
- case IMSG_CTL_SHOW_LIB_SENT:
- case IMSG_CTL_SHOW_LIB_RCVD:
- case IMSG_CTL_SHOW_LIB_END:
rt = imsg->data;
- if (params->family != AF_UNSPEC && params->family != rt->af)
- return (0);
- break;
- default:
- break;
- }
- switch (imsg->hdr.type) {
- case IMSG_CTL_SHOW_LIB_BEGIN:
upstream = 0;
downstream = 0;
sent_buffer[0] = '\0';
rcvd_buffer[0] = '\0';
-
snprintf(dstnet, sizeof(dstnet), "%s/%d",
log_addr(rt->af, &rt->prefix), rt->prefixlen);
-
- vty_out (vty, "%s\n", dstnet);
- vty_out (vty, "%-8sLocal binding: label: %s\n", "",
- log_label(rt->local_label));
break;
case IMSG_CTL_SHOW_LIB_SENT:
+ rt = imsg->data;
+
upstream = 1;
buflen = strlen(sent_buffer);
snprintf(sent_buffer + buflen, LDPBUFSIZ - buflen,
"%12s%s:0\n", "", inet_ntoa(rt->nexthop));
break;
case IMSG_CTL_SHOW_LIB_RCVD:
+ rt = imsg->data;
downstream = 1;
buflen = strlen(rcvd_buffer);
snprintf(rcvd_buffer + buflen, LDPBUFSIZ - buflen,
@@ -1087,6 +1096,14 @@ show_lib_detail_msg(struct vty *vty, struct imsg *imsg, struct show_params *para
rt->in_use ? " (in use)" : "");
break;
case IMSG_CTL_SHOW_LIB_END:
+ rt = imsg->data;
+
+ if (params->lib.remote_label != NO_LABEL &&
+ !downstream)
+ break;
+ vty_out(vty, "%s\n", dstnet);
+ vty_out(vty, "%-8sLocal binding: label: %s\n", "",
+ log_label(rt->local_label));
if (upstream) {
vty_out (vty, "%-8sAdvertised to:\n", "");
vty_out(vty, "%s", sent_buffer);
@@ -1170,19 +1187,8 @@ show_lib_detail_msg_json(struct imsg *imsg, struct show_params *params,
switch (imsg->hdr.type) {
case IMSG_CTL_SHOW_LIB_BEGIN:
- case IMSG_CTL_SHOW_LIB_SENT:
- case IMSG_CTL_SHOW_LIB_RCVD:
- case IMSG_CTL_SHOW_LIB_END:
rt = imsg->data;
- if (params->family != AF_UNSPEC && params->family != rt->af)
- return (0);
- break;
- default:
- break;
- }
- switch (imsg->hdr.type) {
- case IMSG_CTL_SHOW_LIB_BEGIN:
snprintf(dstnet, sizeof(dstnet), "%s/%d",
log_addr(rt->af, &rt->prefix), rt->prefixlen);
@@ -1201,12 +1207,16 @@ show_lib_detail_msg_json(struct imsg *imsg, struct show_params *params,
json_object_object_add(json, dstnet, json_lib_entry);
break;
case IMSG_CTL_SHOW_LIB_SENT:
+ rt = imsg->data;
+
json_adv_label = json_object_new_object();
json_object_string_add(json_adv_label, "neighborId",
inet_ntoa(rt->nexthop));
json_object_array_add(json_adv_labels, json_adv_label);
break;
case IMSG_CTL_SHOW_LIB_RCVD:
+ rt = imsg->data;
+
json_remote_label = json_object_new_object();
json_object_string_add(json_remote_label, "neighborId",
inet_ntoa(rt->nexthop));
@@ -1410,89 +1420,273 @@ ldp_vty_connect(struct imsgbuf *ibuf)
}
static int
-ldp_vty_dispatch_msg(struct vty *vty, struct imsg *imsg, enum show_command cmd,
+ldp_vty_dispatch_iface(struct vty *vty, struct imsg *imsg,
struct show_params *params, json_object *json)
{
int ret;
- switch (cmd) {
- case SHOW_IFACE:
+ if (params->json)
+ ret = show_interface_msg_json(imsg, params, json);
+ else
+ ret = show_interface_msg(vty, imsg, params);
+
+ return (ret);
+}
+
+static int
+ldp_vty_dispatch_disc(struct vty *vty, struct imsg *imsg,
+ struct show_params *params, json_object *json)
+{
+ int ret;
+
+ if (params->detail) {
if (params->json)
- ret = show_interface_msg_json(imsg, params, json);
+ ret = show_discovery_detail_msg_json(imsg, params,
+ json);
else
- ret = show_interface_msg(vty, imsg, params);
- break;
- case SHOW_DISC:
- if (params->detail) {
- if (params->json)
- ret = show_discovery_detail_msg_json(imsg,
- params, json);
- else
- ret = show_discovery_detail_msg(vty, imsg,
- params);
- } else {
- if (params->json)
- ret = show_discovery_msg_json(imsg, params,
- json);
- else
- ret = show_discovery_msg(vty, imsg, params);
+ ret = show_discovery_detail_msg(vty, imsg, params);
+ } else {
+ if (params->json)
+ ret = show_discovery_msg_json(imsg, params, json);
+ else
+ ret = show_discovery_msg(vty, imsg, params);
+ }
+
+ return (ret);
+}
+
+static int
+ldp_vty_dispatch_nbr(struct vty *vty, struct imsg *imsg,
+ struct show_params *params, json_object *json)
+{
+ static bool filtered = false;
+ struct ctl_nbr *nbr;
+ int ret;
+
+ switch (imsg->hdr.type) {
+ case IMSG_CTL_SHOW_NBR:
+ filtered = false;
+ nbr = imsg->data;
+
+ if (params->neighbor.lsr_id.s_addr != INADDR_ANY &&
+ params->neighbor.lsr_id.s_addr != nbr->id.s_addr) {
+ filtered = true;
+ return (0);
}
break;
- case SHOW_NBR:
- if (params->capabilities) {
- if (params->json)
- ret = show_nbr_capabilities_msg_json(imsg,
- params, json);
- else
- ret = show_nbr_capabilities_msg(vty, imsg,
- params);
- } else if (params->detail) {
- if (params->json)
- ret = show_nbr_detail_msg_json(imsg, params,
- json);
- else
- ret = show_nbr_detail_msg(vty, imsg, params);
- } else {
- if (params->json)
- ret = show_nbr_msg_json(imsg, params, json);
- else
- ret = show_nbr_msg(vty, imsg, params);
- }
+ case IMSG_CTL_SHOW_NBR_DISC:
+ case IMSG_CTL_SHOW_NBR_END:
+ if (filtered)
+ return (0);
break;
- case SHOW_LIB:
- if (params->detail) {
- if (params->json)
- ret = show_lib_detail_msg_json(imsg, params,
- json);
- else
- ret = show_lib_detail_msg(vty, imsg, params);
- } else {
- if (params->json)
- ret = show_lib_msg_json(imsg, params, json);
- else
- ret = show_lib_msg(vty, imsg, params);
- }
+ default:
break;
- case SHOW_L2VPN_PW:
+ }
+
+ if (params->neighbor.capabilities) {
+ if (params->json)
+ ret = show_nbr_capabilities_msg_json(imsg, params,
+ json);
+ else
+ ret = show_nbr_capabilities_msg(vty, imsg, params);
+ } else if (params->detail) {
+ if (params->json)
+ ret = show_nbr_detail_msg_json(imsg, params, json);
+ else
+ ret = show_nbr_detail_msg(vty, imsg, params);
+ } else {
if (params->json)
- ret = show_l2vpn_pw_msg_json(imsg, params, json);
+ ret = show_nbr_msg_json(imsg, params, json);
else
- ret = show_l2vpn_pw_msg(vty, imsg, params);
+ ret = show_nbr_msg(vty, imsg, params);
+ }
+
+ return (ret);
+}
+
+static int
+ldp_vty_dispatch_lib(struct vty *vty, struct imsg *imsg,
+ struct show_params *params, json_object *json)
+{
+ static bool filtered = false;
+ struct ctl_rt *rt = NULL;
+ struct prefix prefix;
+ int ret;
+
+ switch (imsg->hdr.type) {
+ case IMSG_CTL_SHOW_LIB_BEGIN:
+ filtered = false;
break;
- case SHOW_L2VPN_BINDING:
+ case IMSG_CTL_SHOW_LIB_SENT:
+ case IMSG_CTL_SHOW_LIB_RCVD:
+ case IMSG_CTL_SHOW_LIB_END:
+ if (filtered)
+ return (0);
+ break;
+ default:
+ break;
+ }
+
+ switch (imsg->hdr.type) {
+ case IMSG_CTL_SHOW_LIB_BEGIN:
+ case IMSG_CTL_SHOW_LIB_SENT:
+ case IMSG_CTL_SHOW_LIB_RCVD:
+ case IMSG_CTL_SHOW_LIB_END:
+ rt = imsg->data;
+
+ if (params->family != AF_UNSPEC && params->family != rt->af) {
+ filtered = true;
+ return (0);
+ }
+
+ prefix.family = rt->af;
+ prefix.prefixlen = rt->prefixlen;
+ memcpy(&prefix.u.val, &rt->prefix, sizeof(prefix.u.val));
+ if (params->lib.prefix.family != AF_UNSPEC) {
+ if (!params->lib.longer_prefixes &&
+ !prefix_same(&params->lib.prefix, &prefix)) {
+ filtered = true;
+ return (0);
+ } else if (params->lib.longer_prefixes &&
+ !prefix_match(&params->lib.prefix, &prefix)) {
+ filtered = true;
+ return (0);
+ }
+ }
+
+ if (params->lib.local_label != NO_LABEL &&
+ params->lib.local_label != rt->local_label) {
+ filtered = true;
+ return (0);
+ }
+ break;
+ default:
+ break;
+ }
+
+ switch (imsg->hdr.type) {
+ case IMSG_CTL_SHOW_LIB_SENT:
+ case IMSG_CTL_SHOW_LIB_RCVD:
+ if (params->lib.neighbor.s_addr != INADDR_ANY &&
+ params->lib.neighbor.s_addr != rt->nexthop.s_addr)
+ return (0);
+ break;
+ default:
+ break;
+ }
+
+ switch (imsg->hdr.type) {
+ case IMSG_CTL_SHOW_LIB_RCVD:
+ if (params->lib.remote_label != NO_LABEL &&
+ params->lib.remote_label != rt->remote_label)
+ return (0);
+ break;
+ default:
+ break;
+ }
+
+ if (params->detail) {
if (params->json)
- ret = show_l2vpn_binding_msg_json(imsg, params, json);
+ ret = show_lib_detail_msg_json(imsg, params, json);
else
- ret = show_l2vpn_binding_msg(vty, imsg, params);
+ ret = show_lib_detail_msg(vty, imsg, params);
+ } else {
+ if (params->json)
+ ret = show_lib_msg_json(imsg, params, json);
+ else
+ ret = show_lib_msg(vty, imsg, params);
+ }
+
+ return (ret);
+}
+
+static int
+ldp_vty_dispatch_l2vpn_pw(struct vty *vty, struct imsg *imsg,
+ struct show_params *params, json_object *json)
+{
+ struct ctl_pw *pw;
+ int ret;
+
+ switch (imsg->hdr.type) {
+ case IMSG_CTL_SHOW_L2VPN_PW:
+ pw = imsg->data;
+ if (params->l2vpn.peer.s_addr != INADDR_ANY &&
+ params->l2vpn.peer.s_addr != pw->lsr_id.s_addr)
+ return (0);
+ if (params->l2vpn.ifname[0] != '\0' &&
+ strcmp(params->l2vpn.ifname, pw->ifname))
+ return (0);
+ if (params->l2vpn.vcid && params->l2vpn.vcid != pw->pwid)
+ return (0);
break;
default:
- return (0);
+ break;
}
+ if (params->json)
+ ret = show_l2vpn_pw_msg_json(imsg, params, json);
+ else
+ ret = show_l2vpn_pw_msg(vty, imsg, params);
+
+ return (ret);
+}
+
+static int
+ldp_vty_dispatch_l2vpn_binding(struct vty *vty, struct imsg *imsg,
+ struct show_params *params, json_object *json)
+{
+ struct ctl_pw *pw;
+ int ret;
+
+ switch (imsg->hdr.type) {
+ case IMSG_CTL_SHOW_L2VPN_BINDING:
+ pw = imsg->data;
+ if (params->l2vpn.peer.s_addr != INADDR_ANY &&
+ params->l2vpn.peer.s_addr != pw->lsr_id.s_addr)
+ return (0);
+ if (params->l2vpn.local_label != NO_LABEL &&
+ params->l2vpn.local_label != pw->local_label)
+ return (0);
+ if (params->l2vpn.remote_label != NO_LABEL &&
+ params->l2vpn.remote_label != pw->remote_label)
+ return (0);
+ break;
+ default:
+ break;
+ }
+
+ if (params->json)
+ ret = show_l2vpn_binding_msg_json(imsg, params, json);
+ else
+ ret = show_l2vpn_binding_msg(vty, imsg, params);
+
return (ret);
}
static int
+ldp_vty_dispatch_msg(struct vty *vty, struct imsg *imsg, enum show_command cmd,
+ struct show_params *params, json_object *json)
+{
+ switch (cmd) {
+ case SHOW_IFACE:
+ return (ldp_vty_dispatch_iface(vty, imsg, params, json));
+ case SHOW_DISC:
+ return (ldp_vty_dispatch_disc(vty, imsg, params, json));
+ case SHOW_NBR:
+ return (ldp_vty_dispatch_nbr(vty, imsg, params, json));
+ case SHOW_LIB:
+ return (ldp_vty_dispatch_lib(vty, imsg, params, json));
+ case SHOW_L2VPN_PW:
+ return (ldp_vty_dispatch_l2vpn_pw(vty, imsg, params, json));
+ case SHOW_L2VPN_BINDING:
+ return (ldp_vty_dispatch_l2vpn_binding(vty, imsg, params,
+ json));
+ default:
+ return (0);
+ }
+}
+
+static int
ldp_vty_dispatch(struct vty *vty, struct imsgbuf *ibuf, enum show_command cmd,
struct show_params *params)
{
@@ -1565,7 +1759,9 @@ ldp_vty_get_af(const char *str, int *af)
}
int
-ldp_vty_show_binding(struct vty *vty, const char *af_str, const char *detail, const char *json)
+ldp_vty_show_binding(struct vty *vty, const char *af_str, const char *prefix,
+ int longer_prefixes, const char *neighbor, unsigned long local_label,
+ unsigned long remote_label, const char *detail, const char *json)
{
struct imsgbuf ibuf;
struct show_params params;
@@ -1581,6 +1777,18 @@ ldp_vty_show_binding(struct vty *vty, const char *af_str, const char *detail, co
params.family = af;
params.detail = (detail) ? 1 : 0;
params.json = (json) ? 1 : 0;
+ if (prefix) {
+ (void)str2prefix(prefix, &params.lib.prefix);
+ params.lib.longer_prefixes = longer_prefixes;
+ }
+ if (neighbor &&
+ (inet_pton(AF_INET, neighbor, &params.lib.neighbor) != 1 ||
+ bad_addr_v4(params.lib.neighbor))) {
+ vty_out (vty, "%% Malformed address\n");
+ return (CMD_SUCCESS);
+ }
+ params.lib.local_label = local_label;
+ params.lib.remote_label = remote_label;
if (!params.detail && !params.json)
vty_out (vty, "%-4s %-20s %-15s %-11s %-13s %6s\n", "AF",
@@ -1703,7 +1911,8 @@ ldp_vty_show_capabilities(struct vty *vty, const char *json)
}
int
-ldp_vty_show_neighbor(struct vty *vty, int capabilities, const char *detail, const char *json)
+ldp_vty_show_neighbor(struct vty *vty, const char *lsr_id, int capabilities,
+ const char *detail, const char *json)
{
struct imsgbuf ibuf;
struct show_params params;
@@ -1712,11 +1921,17 @@ ldp_vty_show_neighbor(struct vty *vty, int capabilities, const char *detail, con
return (CMD_WARNING);
memset(&params, 0, sizeof(params));
- params.capabilities = capabilities;
params.detail = (detail) ? 1 : 0;
params.json = (json) ? 1 : 0;
+ params.neighbor.capabilities = capabilities;
+ if (lsr_id &&
+ (inet_pton(AF_INET, lsr_id, &params.neighbor.lsr_id) != 1 ||
+ bad_addr_v4(params.neighbor.lsr_id))) {
+ vty_out (vty, "%% Malformed address\n");
+ return (CMD_SUCCESS);
+ }
- if (params.capabilities)
+ if (params.neighbor.capabilities)
params.detail = 1;
if (!params.detail && !params.json)
@@ -1728,7 +1943,8 @@ ldp_vty_show_neighbor(struct vty *vty, int capabilities, const char *detail, con
}
int
-ldp_vty_show_atom_binding(struct vty *vty, const char *json)
+ldp_vty_show_atom_binding(struct vty *vty, const char *peer,
+ unsigned long local_label, unsigned long remote_label, const char *json)
{
struct imsgbuf ibuf;
struct show_params params;
@@ -1738,13 +1954,22 @@ ldp_vty_show_atom_binding(struct vty *vty, const char *json)
memset(&params, 0, sizeof(params));
params.json = (json) ? 1 : 0;
+ if (peer &&
+ (inet_pton(AF_INET, peer, &params.l2vpn.peer) != 1 ||
+ bad_addr_v4(params.l2vpn.peer))) {
+ vty_out (vty, "%% Malformed address\n");
+ return (CMD_SUCCESS);
+ }
+ params.l2vpn.local_label = local_label;
+ params.l2vpn.remote_label = remote_label;
imsg_compose(&ibuf, IMSG_CTL_SHOW_L2VPN_BINDING, 0, 0, -1, NULL, 0);
return (ldp_vty_dispatch(vty, &ibuf, SHOW_L2VPN_BINDING, &params));
}
int
-ldp_vty_show_atom_vc(struct vty *vty, const char *json)
+ldp_vty_show_atom_vc(struct vty *vty, const char *peer, const char *ifname,
+ const char *vcid, const char *json)
{
struct imsgbuf ibuf;
struct show_params params;
@@ -1754,6 +1979,17 @@ ldp_vty_show_atom_vc(struct vty *vty, const char *json)
memset(&params, 0, sizeof(params));
params.json = (json) ? 1 : 0;
+ if (peer &&
+ (inet_pton(AF_INET, peer, &params.l2vpn.peer) != 1 ||
+ bad_addr_v4(params.l2vpn.peer))) {
+ vty_out (vty, "%% Malformed address\n");
+ return (CMD_SUCCESS);
+ }
+ if (ifname)
+ strlcpy(params.l2vpn.ifname, ifname,
+ sizeof(params.l2vpn.ifname));
+ if (vcid)
+ params.l2vpn.vcid = atoi(vcid);
if (!params.json) {
/* header */
diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c
index d31c575920..12aeb1fff3 100644
--- a/ldpd/ldpd.c
+++ b/ldpd/ldpd.c
@@ -206,7 +206,7 @@ main(int argc, char *argv[])
frr_preinit(&ldpd_di, argc, argv);
frr_opt_add("LEn:", longopts,
" --ctl_socket Override ctl socket path\n"
- "-n, --instance Instance id\n");
+ " -n, --instance Instance id\n");
while (1) {
int opt;
@@ -260,7 +260,6 @@ main(int argc, char *argv[])
sizeof(init.zclient_serv_path));
argc -= optind;
- argv += optind;
if (argc > 0 || (lflag && eflag))
frr_help_exit(1);
@@ -435,7 +434,7 @@ static pid_t
start_child(enum ldpd_process p, char *argv0, int fd_async, int fd_sync)
{
char *argv[3];
- int argc = 0;
+ int argc = 0, nullfd;
pid_t pid;
switch (pid = fork()) {
@@ -449,6 +448,17 @@ start_child(enum ldpd_process p, char *argv0, int fd_async, int fd_sync)
return (pid);
}
+ nullfd = open("/dev/null", O_RDONLY | O_NOCTTY);
+ if (nullfd == -1) {
+ zlog_err("%s: failed to open /dev/null: %s", __func__,
+ safe_strerror(errno));
+ } else {
+ dup2(nullfd, 0);
+ dup2(nullfd, 1);
+ dup2(nullfd, 2);
+ close(nullfd);
+ }
+
if (dup2(fd_async, LDPD_FD_ASYNC) == -1)
fatal("cannot setup imsg async fd");
if (dup2(fd_sync, LDPD_FD_SYNC) == -1)
diff --git a/ldpd/ldpe.c b/ldpd/ldpe.c
index 1c0a8bdc84..9d00bcd2b6 100644
--- a/ldpd/ldpe.c
+++ b/ldpd/ldpe.c
@@ -190,15 +190,16 @@ ldpe_shutdown(void)
/* close pipes */
if (iev_lde) {
- msgbuf_write(&iev_lde->ibuf.w);
msgbuf_clear(&iev_lde->ibuf.w);
close(iev_lde->ibuf.fd);
+ iev_lde->ibuf.fd = -1;
}
- msgbuf_write(&iev_main->ibuf.w);
msgbuf_clear(&iev_main->ibuf.w);
close(iev_main->ibuf.fd);
+ iev_main->ibuf.fd = -1;
msgbuf_clear(&iev_main_sync->ibuf.w);
close(iev_main_sync->ibuf.fd);
+ iev_main_sync->ibuf.fd = -1;
control_cleanup(ctl_sock_path);
config_clear(leconf);
@@ -215,6 +216,7 @@ ldpe_shutdown(void)
/* remove addresses from global list */
while ((if_addr = LIST_FIRST(&global.addr_list)) != NULL) {
LIST_REMOVE(if_addr, entry);
+ assert(if_addr != LIST_FIRST(&global.addr_list));
free(if_addr);
}
while ((adj = RB_ROOT(global_adj_head, &global.adj_tree)) != NULL)
@@ -235,12 +237,16 @@ ldpe_shutdown(void)
int
ldpe_imsg_compose_parent(int type, pid_t pid, void *data, uint16_t datalen)
{
+ if (iev_main->ibuf.fd == -1)
+ return (0);
return (imsg_compose_event(iev_main, type, 0, pid, -1, data, datalen));
}
void
ldpe_imsg_compose_parent_sync(int type, pid_t pid, void *data, uint16_t datalen)
{
+ if (iev_main_sync->ibuf.fd == -1)
+ return;
imsg_compose_event(iev_main_sync, type, 0, pid, -1, data, datalen);
imsg_flush(&iev_main_sync->ibuf);
}
@@ -249,6 +255,8 @@ int
ldpe_imsg_compose_lde(int type, uint32_t peerid, pid_t pid, void *data,
uint16_t datalen)
{
+ if (iev_lde->ibuf.fd == -1)
+ return (0);
return (imsg_compose_event(iev_lde, type, peerid, pid, -1,
data, datalen));
}
@@ -265,7 +273,7 @@ ldpe_dispatch_main(struct thread *thread)
struct l2vpn_if *lif, *nlif;
struct l2vpn_pw *pw, *npw;
struct imsg imsg;
- int fd = THREAD_FD(thread);
+ int fd;
struct imsgev *iev = THREAD_ARG(thread);
struct imsgbuf *ibuf = &iev->ibuf;
struct iface *iface = NULL;
@@ -964,6 +972,7 @@ mapping_list_clr(struct mapping_head *mh)
while ((me = TAILQ_FIRST(mh)) != NULL) {
TAILQ_REMOVE(mh, me, entry);
+ assert(me != TAILQ_FIRST(mh));
free(me);
}
}
diff --git a/ldpd/packet.c b/ldpd/packet.c
index be7f2ba649..4a4b258b91 100644
--- a/ldpd/packet.c
+++ b/ldpd/packet.c
@@ -494,7 +494,7 @@ session_read(struct thread *thread)
msg_len = ntohs(msg->length);
if (msg_len < LDP_MSG_LEN ||
(msg_len + LDP_MSG_DEAD_LEN) > pdu_len) {
- session_shutdown(nbr, S_BAD_TLV_LEN, msg->id,
+ session_shutdown(nbr, S_BAD_MSG_LEN, msg->id,
msg->type);
free(buf);
return (0);
diff --git a/lib/bfd.c b/lib/bfd.c
index e8df42a1bd..d51b9f1e63 100644
--- a/lib/bfd.c
+++ b/lib/bfd.c
@@ -367,7 +367,7 @@ void bfd_show_param(struct vty *vty, struct bfd_info *bfd_info, int bfd_tag,
json_bfd);
} else {
vty_out(vty,
- " %s%sDetect Mul: %d, Min Rx interval: %d,"
+ " %s%sDetect Multiplier: %d, Min Rx interval: %d,"
" Min Tx interval: %d\n",
(extra_space) ? " " : "", (bfd_tag) ? "BFD: " : " ",
bfd_info->detect_mult, bfd_info->required_min_rx,
diff --git a/lib/command.c b/lib/command.c
index d1b0867372..97eba96c3a 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -686,7 +686,7 @@ static vector cmd_complete_command_real(vector vline, struct vty *vty,
}
vector comps = completions_to_vec(completions);
- list_delete(completions);
+ list_delete_and_null(&completions);
// set status code appropriately
switch (vector_active(comps)) {
@@ -1006,7 +1006,7 @@ static int cmd_execute_command_real(vector vline, enum filter_type filter,
// if matcher error, return corresponding CMD_ERR
if (MATCHER_ERROR(status)) {
if (argv_list)
- list_delete(argv_list);
+ list_delete_and_null(&argv_list);
switch (status) {
case MATCHER_INCOMPLETE:
return CMD_ERR_INCOMPLETE;
@@ -1035,7 +1035,7 @@ static int cmd_execute_command_real(vector vline, enum filter_type filter,
ret = matched_element->func(matched_element, vty, argc, argv);
// delete list and cmd_token's in it
- list_delete(argv_list);
+ list_delete_and_null(&argv_list);
XFREE(MTYPE_TMP, argv);
return ret;
@@ -2730,6 +2730,6 @@ void cmd_terminate()
if (host.config)
XFREE(MTYPE_HOST, host.config);
- list_delete(varhandlers);
+ list_delete_and_null(&varhandlers);
qobj_finish();
}
diff --git a/lib/command.h b/lib/command.h
index 8cccb62de3..e2d31decd4 100644
--- a/lib/command.h
+++ b/lib/command.h
@@ -380,6 +380,13 @@ extern void uninstall_element(enum node_type, struct cmd_element *);
string with a space between each element (allocated using
XMALLOC(MTYPE_TMP)). Returns NULL if shift >= argc. */
extern char *argv_concat(struct cmd_token **argv, int argc, int shift);
+
+/*
+ * It is preferred that you set the index initial value
+ * to a 0. This way in the future if you modify the
+ * cli then there is no need to modify the initial
+ * value of the index
+ */
extern int argv_find(struct cmd_token **argv, int argc, const char *text,
int *index);
diff --git a/lib/command_match.c b/lib/command_match.c
index 6384abe5ce..c60373f910 100644
--- a/lib/command_match.c
+++ b/lib/command_match.c
@@ -333,7 +333,7 @@ static enum matcher_rv command_match_r(struct graph_node *start, vector vline,
status = MATCHER_INCOMPLETE;
// cleanup
- list_delete(next);
+ list_delete_and_null(&next);
return status;
}
@@ -366,7 +366,7 @@ enum matcher_rv command_complete(struct graph *graph, vector vline,
unsigned int idx;
for (idx = 0; idx < vector_active(vline) && next->count > 0; idx++) {
- list_delete(current);
+ list_delete_and_null(&current);
current = next;
next = list_new();
next->del = stack_del;
@@ -457,8 +457,8 @@ enum matcher_rv command_complete(struct graph *graph, vector vline,
}
}
- list_delete(current);
- list_delete(next);
+ list_delete_and_null(&current);
+ list_delete_and_null(&next);
return mrv;
}
@@ -648,7 +648,7 @@ static void del_arglist(struct list *list)
list_delete_node(list, tail);
// delete the rest of the list as usual
- list_delete(list);
+ list_delete_and_null(&list);
}
/*---------- token level matching functions ----------*/
diff --git a/lib/csv.c b/lib/csv.c
index 0ad5c74be3..27d0fe4029 100644
--- a/lib/csv.c
+++ b/lib/csv.c
@@ -284,6 +284,11 @@ csv_record_t *csv_encode_record(csv_t *csv, csv_record_t *rec, int count, ...)
va_start(list, count);
str = csv_field_iter(rec, &fld);
+ if (!fld) {
+ va_end(list);
+ return NULL;
+ }
+
for (tempc = 0; tempc < count; tempc++) {
col = va_arg(list, char *);
for (i = 0; i < fld->field_len; i++) {
@@ -652,18 +657,15 @@ int main()
{
char buf[10000];
csv_t csv;
- int p;
- int i, j;
+ int i;
csv_record_t *rec;
- csv_field_t *fld;
- char *str;
char hdr1[32], hdr2[32];
- log_verbose("Mem: %ld\n", get_memory_usage(getpid()));
+ log_verbose("Mem: %d\n", get_memory_usage(getpid()));
csv_init(&csv, buf, 256);
sprintf(hdr1, "%4u", 0);
sprintf(hdr2, "%4u", 1);
- log_verbose("(%d/%d/%d/%d)\n", strlen(hdr1), strlen(hdr2), atoi(hdr1),
+ log_verbose("(%zu/%zu/%d/%d)\n", strlen(hdr1), strlen(hdr2), atoi(hdr1),
atoi(hdr2));
rec = csv_encode(&csv, 2, hdr1, hdr2);
csv_encode(&csv, 4, "name", "age", "sex", "hei");
@@ -676,19 +678,19 @@ int main()
log_verbose("%s\n", buf);
sprintf(hdr1, "%4u", csv.csv_len);
sprintf(hdr2, "%4u", 1);
- log_verbose("(%d/%d/%d/%d)\n", strlen(hdr1), strlen(hdr2), atoi(hdr1),
+ log_verbose("(%zu/%zu/%d/%d)\n", strlen(hdr1), strlen(hdr2), atoi(hdr1),
atoi(hdr2));
rec = csv_encode_record(&csv, rec, 2, hdr1, hdr2);
log_verbose("(%d/%d)\n%s\n", rec->rec_len, csv.csv_len, buf);
- log_verbose("Mem: %ld\n", get_memory_usage(getpid()));
+ log_verbose("Mem: %d\n", get_memory_usage(getpid()));
csv_clean(&csv);
- log_verbose("Mem: %ld\n", get_memory_usage(getpid()));
+ log_verbose("Mem: %d\n", get_memory_usage(getpid()));
csv_init(&csv, buf, 256);
csv_decode(&csv, NULL);
- log_verbose("AFTER DECODE\n");
+ log_verbose("%s", "AFTER DECODE\n");
csv_dump(&csv);
csv_clean(&csv);
- log_verbose("Mem: %ld\n", get_memory_usage(getpid()));
+ log_verbose("Mem: %d\n", get_memory_usage(getpid()));
}
#endif
diff --git a/lib/ferr.c b/lib/ferr.c
index 2a039d2089..69aeb3db40 100644
--- a/lib/ferr.c
+++ b/lib/ferr.c
@@ -74,6 +74,7 @@ static ferr_r ferr_set_va(const char *file, int line, const char *func,
/* we're screwed */
zlog_err("out of memory while allocating error info");
raise(SIGSEGV);
+ abort(); /* raise() can return, but raise(SIGSEGV) shall not */
}
pthread_setspecific(errkey, error);
diff --git a/lib/grammar_sandbox.c b/lib/grammar_sandbox.c
index 3c6396f347..66b042ad97 100644
--- a/lib/grammar_sandbox.c
+++ b/lib/grammar_sandbox.c
@@ -141,7 +141,7 @@ DEFUN (grammar_test_complete,
vty_out(vty, "%% No match\n");
// free resources
- list_delete(completions);
+ list_delete_and_null(&completions);
cmd_free_strvec(command);
XFREE(MTYPE_TMP, cmdstr);
@@ -185,7 +185,7 @@ DEFUN (grammar_test_match,
vty_out(vty, "func: %p\n", element->func);
- list_delete(argvv);
+ list_delete_and_null(&argvv);
} else {
assert(MATCHER_ERROR(result));
switch (result) {
@@ -426,7 +426,7 @@ DEFUN (grammar_findambig,
}
prev = cur;
}
- list_delete(commands);
+ list_delete_and_null(&commands);
vty_out(vty, "\n");
} while (scan && scannode < LINK_PARAMS_NODE);
diff --git a/lib/hash.c b/lib/hash.c
index 243521bef7..d2846d7379 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -318,8 +318,7 @@ void hash_free(struct hash *hash)
if (_hashes) {
listnode_delete(_hashes, hash);
if (_hashes->count == 0) {
- list_delete(_hashes);
- _hashes = NULL;
+ list_delete_and_null(&_hashes);
}
}
}
diff --git a/lib/if.c b/lib/if.c
index 7d27229656..34de2c8d8b 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -191,8 +191,8 @@ void if_delete(struct interface *ifp)
if_delete_retain(ifp);
- list_free(ifp->connected);
- list_free(ifp->nbr_connected);
+ list_delete_and_null(&ifp->connected);
+ list_delete_and_null(&ifp->nbr_connected);
if_link_params_free(ifp);
@@ -1095,8 +1095,7 @@ void if_terminate(struct list **intf_list)
if_delete(ifp);
}
- list_delete(*intf_list);
- *intf_list = NULL;
+ list_delete_and_null(intf_list);
}
const char *if_link_type_str(enum zebra_link_type llt)
diff --git a/lib/keychain.c b/lib/keychain.c
index f0108e0805..23a2d72b17 100644
--- a/lib/keychain.c
+++ b/lib/keychain.c
@@ -119,7 +119,7 @@ static void keychain_delete(struct keychain *keychain)
if (keychain->name)
XFREE(MTYPE_KEYCHAIN, keychain->name);
- list_delete(keychain->key);
+ list_delete_and_null(&keychain->key);
listnode_delete(keychain_list, keychain);
keychain_free(keychain);
}
diff --git a/lib/libfrr.c b/lib/libfrr.c
index d5078f98aa..6cb8711edf 100644
--- a/lib/libfrr.c
+++ b/lib/libfrr.c
@@ -534,7 +534,7 @@ struct thread_master *frr_init(void)
snprintf(p_pathspace, sizeof(p_pathspace), "/%s",
di->pathspace);
- snprintf(config_default, sizeof(config_default), "%s%s/%s%s.conf",
+ snprintf(config_default, sizeof(config_default), "%s%s%s%s.conf",
frr_sysconfdir, p_pathspace, di->name, p_instance);
snprintf(pidfile_default, sizeof(pidfile_default), "%s%s/%s%s.pid",
frr_vtydir, p_pathspace, di->name, p_instance);
@@ -768,6 +768,8 @@ void frr_vty_serv(void)
static void frr_terminal_close(int isexit)
{
+ int nullfd;
+
if (daemon_ctl_sock != -1) {
close(daemon_ctl_sock);
daemon_ctl_sock = -1;
@@ -783,11 +785,16 @@ static void frr_terminal_close(int isexit)
fflush(stdout);
}
- int nullfd = open("/dev/null", O_RDONLY | O_NOCTTY);
- dup2(nullfd, 0);
- dup2(nullfd, 1);
- dup2(nullfd, 2);
- close(nullfd);
+ nullfd = open("/dev/null", O_RDONLY | O_NOCTTY);
+ if (nullfd == -1) {
+ zlog_err("%s: failed to open /dev/null: %s", __func__,
+ safe_strerror(errno));
+ } else {
+ dup2(nullfd, 0);
+ dup2(nullfd, 1);
+ dup2(nullfd, 2);
+ close(nullfd);
+ }
}
static struct thread *daemon_ctl_thread = NULL;
@@ -849,10 +856,15 @@ void frr_run(struct thread_master *master)
}
} else if (di->daemon_mode) {
int nullfd = open("/dev/null", O_RDONLY | O_NOCTTY);
- dup2(nullfd, 0);
- dup2(nullfd, 1);
- dup2(nullfd, 2);
- close(nullfd);
+ if (nullfd == -1) {
+ zlog_err("%s: failed to open /dev/null: %s", __func__,
+ safe_strerror(errno));
+ } else {
+ dup2(nullfd, 0);
+ dup2(nullfd, 1);
+ dup2(nullfd, 2);
+ close(nullfd);
+ }
if (daemon_ctl_sock != -1)
close(daemon_ctl_sock);
diff --git a/lib/linklist.c b/lib/linklist.c
index c1b056d739..2306dd6d00 100644
--- a/lib/linklist.c
+++ b/lib/linklist.c
@@ -33,7 +33,7 @@ struct list *list_new(void)
}
/* Free list. */
-void list_free(struct list *l)
+static void list_free_internal(struct list *l)
{
XFREE(MTYPE_LINK_LIST, l);
}
@@ -239,7 +239,7 @@ void list_delete_all_node(struct list *list)
assert(list);
for (node = list->head; node; node = next) {
next = node->next;
- if (list->del)
+ if (*list->del)
(*list->del)(node->data);
listnode_free(node);
}
@@ -248,11 +248,17 @@ void list_delete_all_node(struct list *list)
}
/* Delete all listnode then free list itself. */
-void list_delete(struct list *list)
+void list_delete_and_null(struct list **list)
{
- assert(list);
- list_delete_all_node(list);
- list_free(list);
+ assert(*list);
+ list_delete_all_node(*list);
+ list_free_internal(*list);
+ *list = NULL;
+}
+
+void list_delete_original(struct list *list)
+{
+ list_delete_and_null(&list);
}
/* Lookup the node which has given data. */
diff --git a/lib/linklist.h b/lib/linklist.h
index 9bd6e38499..8a43fbe64b 100644
--- a/lib/linklist.h
+++ b/lib/linklist.h
@@ -56,12 +56,12 @@ struct list {
#define listtail(X) ((X) ? ((X)->tail) : NULL)
#define listcount(X) ((X)->count)
#define list_isempty(X) ((X)->head == NULL && (X)->tail == NULL)
-#define listgetdata(X) (assert((X)->data != NULL), (X)->data)
+/* return X->data only if X and X->data are not NULL */
+#define listgetdata(X) (assert(X), assert((X)->data != NULL), (X)->data)
/* Prototypes. */
extern struct list *
list_new(void); /* encouraged: set list.del callback on new lists */
-extern void list_free(struct list *);
extern void listnode_add(struct list *, void *);
extern void listnode_add_sort(struct list *, void *);
@@ -74,7 +74,26 @@ extern void listnode_delete(struct list *, void *);
extern struct listnode *listnode_lookup(struct list *, void *);
extern void *listnode_head(struct list *);
-extern void list_delete(struct list *);
+/*
+ * The usage of list_delete is being transitioned to pass in
+ * the double pointer to remove use after free's.
+ * list_free usage is deprecated, it leads to memory leaks
+ * of the linklist nodes. Please use list_delete_and_null
+ *
+ * In Oct of 2018, rename list_delete_and_null to list_delete
+ * and remove list_delete_original and the list_delete #define
+ * Additionally remove list_free entirely
+ */
+#if CONFDATE > 20181001
+CPP_NOTICE("list_delete without double pointer is deprecated, please fixup")
+#endif
+extern void list_delete_and_null(struct list **);
+extern void list_delete_original(struct list *);
+#define list_delete(X) list_delete_original((X)) \
+ CPP_WARN("Please transition to using list_delete_and_null")
+#define list_free(X) list_delete_original((X)) \
+ CPP_WARN("Please transition tousing list_delete_and_null")
+
extern void list_delete_all_node(struct list *);
/* For ospfd and ospf6d. */
diff --git a/lib/nexthop.c b/lib/nexthop.c
index ea6a310a4a..f6b2c9788d 100644
--- a/lib/nexthop.c
+++ b/lib/nexthop.c
@@ -128,7 +128,7 @@ int nexthop_labels_match(struct nexthop *nh1, struct nexthop *nh2)
nhl1 = nh1->nh_label;
nhl2 = nh2->nh_label;
- if ((nhl1 && !nhl2) || (!nhl1 && nhl2))
+ if (!nhl1 || !nhl2)
return 0;
if (nhl1->num_labels != nhl2->num_labels)
diff --git a/lib/ptm_lib.c b/lib/ptm_lib.c
index f50d1e2989..e881d49225 100644
--- a/lib/ptm_lib.c
+++ b/lib/ptm_lib.c
@@ -330,7 +330,7 @@ int ptm_lib_process_msg(ptm_lib_handle_t *hdl, int fd, char *inbuf, int inlen,
char client_name[32];
int cmd_id, type, ver, msglen;
csv_t *csv;
- ptm_lib_msg_ctxt_t *p_ctxt;
+ ptm_lib_msg_ctxt_t *p_ctxt = NULL;
len = _ptm_lib_read_ptm_socket(fd, inbuf, PTMLIB_MSG_HDR_LEN);
if (len <= 0)
diff --git a/lib/sha256.c b/lib/sha256.c
index a1b77901ee..37ced5b402 100644
--- a/lib/sha256.c
+++ b/lib/sha256.c
@@ -192,7 +192,8 @@ static void SHA256_Transform(uint32_t *state, const unsigned char block[64])
/* Clean the stack. */
memset(W, 0, 256);
memset(S, 0, 32);
- t0 = t1 = 0;
+ memset(&t0, 0, sizeof(t0));
+ memset(&t1, 0, sizeof(t0));
}
static unsigned char PAD[64] = {
diff --git a/lib/thread.c b/lib/thread.c
index a69bd2f0d5..2d37857b8a 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -554,8 +554,7 @@ void thread_master_free(struct thread_master *m)
{
listnode_delete(masters, m);
if (masters->count == 0) {
- list_free(masters);
- masters = NULL;
+ list_delete_and_null(&masters);
}
}
pthread_mutex_unlock(&masters_mtx);
@@ -570,7 +569,7 @@ void thread_master_free(struct thread_master *m)
pthread_cond_destroy(&m->cancel_cond);
close(m->io_pipe[0]);
close(m->io_pipe[1]);
- list_delete(m->cancel_req);
+ list_delete_and_null(&m->cancel_req);
m->cancel_req = NULL;
hash_clean(m->cpu_record, cpu_record_hash_free);
diff --git a/lib/wheel.c b/lib/wheel.c
index 9f1f189b72..b1a3e89fc7 100644
--- a/lib/wheel.c
+++ b/lib/wheel.c
@@ -99,7 +99,7 @@ void wheel_delete(struct timer_wheel *wheel)
int i;
for (i = 0; i < wheel->slots; i++) {
- list_delete(wheel->wheel_slot_lists[i]);
+ list_delete_and_null(&wheel->wheel_slot_lists[i]);
}
THREAD_OFF(wheel->timer);
diff --git a/lib/zclient.c b/lib/zclient.c
index e30f166dde..43d46a1801 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -123,8 +123,7 @@ void redist_del_instance(struct redist_proto *red, u_short instance)
XFREE(MTYPE_REDIST_INST, id);
if (!red->instances->count) {
red->enabled = 0;
- list_free(red->instances);
- red->instances = NULL;
+ list_delete_and_null(&red->instances);
}
}
@@ -1619,7 +1618,7 @@ static int zclient_read_sync_response(struct zclient *zclient,
u_int16_t expected_cmd)
{
struct stream *s;
- u_int16_t size;
+ u_int16_t size = -1;
u_char marker;
u_char version;
vrf_id_t vrf_id;
diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c
index 36528d063c..d270b9547e 100644
--- a/ospf6d/ospf6_abr.c
+++ b/ospf6d/ospf6_abr.c
@@ -1110,19 +1110,21 @@ void install_element_ospf6_debug_abr(void)
}
struct ospf6_lsa_handler inter_prefix_handler = {
- OSPF6_LSTYPE_INTER_PREFIX,
- "Inter-Prefix",
- "IAP",
- ospf6_inter_area_prefix_lsa_show,
- ospf6_inter_area_prefix_lsa_get_prefix_str,
+ .lh_type = OSPF6_LSTYPE_INTER_PREFIX,
+ .lh_name = "Inter-Prefix",
+ .lh_short_name = "IAP",
+ .lh_show = ospf6_inter_area_prefix_lsa_show,
+ .lh_get_prefix_str = ospf6_inter_area_prefix_lsa_get_prefix_str,
+ .lh_debug = 0
};
struct ospf6_lsa_handler inter_router_handler = {
- OSPF6_LSTYPE_INTER_ROUTER,
- "Inter-Router",
- "IAR",
- ospf6_inter_area_router_lsa_show,
- ospf6_inter_area_router_lsa_get_prefix_str,
+ .lh_type = OSPF6_LSTYPE_INTER_ROUTER,
+ .lh_name = "Inter-Router",
+ .lh_short_name = "IAR",
+ .lh_show = ospf6_inter_area_router_lsa_show,
+ .lh_get_prefix_str = ospf6_inter_area_router_lsa_get_prefix_str,
+ .lh_debug = 0
};
void ospf6_abr_init(void)
diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c
index b5584dc86d..b126786246 100644
--- a/ospf6d/ospf6_area.c
+++ b/ospf6d/ospf6_area.c
@@ -272,7 +272,7 @@ void ospf6_area_delete(struct ospf6_area *oa)
for (ALL_LIST_ELEMENTS_RO(oa->if_list, n, oi))
oi->area = NULL;
- list_delete(oa->if_list);
+ list_delete_and_null(&oa->if_list);
ospf6_lsdb_delete(oa->lsdb);
ospf6_lsdb_delete(oa->lsdb_self);
diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c
index de20fbc3ab..c65578c11e 100644
--- a/ospf6d/ospf6_asbr.c
+++ b/ospf6d/ospf6_asbr.c
@@ -438,6 +438,9 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
if (!ospf6_zebra_is_redistribute(type))
return;
+ memset(&troute, 0, sizeof(troute));
+ memset(&tinfo, 0, sizeof(tinfo));
+
if (IS_OSPF6_DEBUG_ASBR) {
prefix2str(prefix, pbuf, sizeof(pbuf));
zlog_debug("Redistribute %s (%s)", pbuf, ZROUTE_NAME(type));
@@ -457,8 +460,6 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
/* apply route-map */
if (ospf6->rmap[type].map) {
- memset(&troute, 0, sizeof(troute));
- memset(&tinfo, 0, sizeof(tinfo));
troute.route_option = &tinfo;
tinfo.ifindex = ifindex;
tinfo.tag = tag;
@@ -1234,8 +1235,13 @@ DEFUN (show_ipv6_ospf6_redistribute,
}
struct ospf6_lsa_handler as_external_handler = {
- OSPF6_LSTYPE_AS_EXTERNAL, "AS-External", "ASE",
- ospf6_as_external_lsa_show, ospf6_as_external_lsa_get_prefix_str};
+ .lh_type = OSPF6_LSTYPE_AS_EXTERNAL,
+ .lh_name = "AS-External",
+ .lh_short_name = "ASE",
+ .lh_show = ospf6_as_external_lsa_show,
+ .lh_get_prefix_str = ospf6_as_external_lsa_get_prefix_str,
+ .lh_debug = 0
+};
void ospf6_asbr_init(void)
{
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c
index 8e01cb4379..7286b3242d 100644
--- a/ospf6d/ospf6_interface.c
+++ b/ospf6d/ospf6_interface.c
@@ -242,7 +242,7 @@ void ospf6_interface_delete(struct ospf6_interface *oi)
for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
ospf6_neighbor_delete(on);
- list_delete(oi->neighbor_list);
+ list_delete_and_null(&oi->neighbor_list);
THREAD_OFF(oi->thread_send_hello);
THREAD_OFF(oi->thread_send_lsupdate);
diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c
index e4644bb09f..a2caeccb86 100644
--- a/ospf6d/ospf6_intra.c
+++ b/ospf6d/ospf6_intra.c
@@ -1630,21 +1630,41 @@ void ospf6_intra_brouter_calculation(struct ospf6_area *oa)
oa->name);
}
-struct ospf6_lsa_handler router_handler = {OSPF6_LSTYPE_ROUTER, "Router", "Rtr",
- ospf6_router_lsa_show,
- ospf6_router_lsa_get_nbr_id};
-
-struct ospf6_lsa_handler network_handler = {OSPF6_LSTYPE_NETWORK, "Network",
- "Net", ospf6_network_lsa_show,
- ospf6_network_lsa_get_ar_id};
-
-struct ospf6_lsa_handler link_handler = {OSPF6_LSTYPE_LINK, "Link", "Lnk",
- ospf6_link_lsa_show,
- ospf6_link_lsa_get_prefix_str};
+struct ospf6_lsa_handler router_handler = {
+ .lh_type = OSPF6_LSTYPE_ROUTER,
+ .lh_name = "Router",
+ .lh_short_name = "Rtr",
+ .lh_show = ospf6_router_lsa_show,
+ .lh_get_prefix_str = ospf6_router_lsa_get_nbr_id,
+ .lh_debug = 0
+};
+
+struct ospf6_lsa_handler network_handler = {
+ .lh_type = OSPF6_LSTYPE_NETWORK,
+ .lh_name = "Network",
+ .lh_short_name = "Net",
+ .lh_show = ospf6_network_lsa_show,
+ .lh_get_prefix_str = ospf6_network_lsa_get_ar_id,
+ .lh_debug = 0
+};
+
+struct ospf6_lsa_handler link_handler = {
+ .lh_type = OSPF6_LSTYPE_LINK,
+ .lh_name = "Link",
+ .lh_short_name = "Lnk",
+ .lh_show = ospf6_link_lsa_show,
+ .lh_get_prefix_str = ospf6_link_lsa_get_prefix_str,
+ .lh_debug = 0
+};
struct ospf6_lsa_handler intra_prefix_handler = {
- OSPF6_LSTYPE_INTRA_PREFIX, "Intra-Prefix", "INP",
- ospf6_intra_prefix_lsa_show, ospf6_intra_prefix_lsa_get_prefix_str};
+ .lh_type = OSPF6_LSTYPE_INTRA_PREFIX,
+ .lh_name = "Intra-Prefix",
+ .lh_short_name = "INP",
+ .lh_show = ospf6_intra_prefix_lsa_show,
+ .lh_get_prefix_str = ospf6_intra_prefix_lsa_get_prefix_str,
+ .lh_debug = 0
+};
void ospf6_intra_init(void)
{
diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c
index a0dad9344a..82f75b153e 100644
--- a/ospf6d/ospf6_lsa.c
+++ b/ospf6d/ospf6_lsa.c
@@ -68,19 +68,25 @@ static int ospf6_unknown_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
return 0;
}
-struct ospf6_lsa_handler unknown_handler = {
- OSPF6_LSTYPE_UNKNOWN, "Unknown", "Unk", ospf6_unknown_lsa_show, NULL};
+static struct ospf6_lsa_handler unknown_handler = {
+ .lh_type = OSPF6_LSTYPE_UNKNOWN,
+ .lh_name = "Unknown",
+ .lh_short_name = "Unk",
+ .lh_show = ospf6_unknown_lsa_show,
+ .lh_get_prefix_str = NULL,
+ .lh_debug = 0 /* No default debug */
+};
-void ospf6_install_lsa_handler(struct ospf6_lsa_handler *handler)
+void ospf6_install_lsa_handler(const struct ospf6_lsa_handler *handler)
{
/* type in handler is host byte order */
- int index = handler->type & OSPF6_LSTYPE_FCODE_MASK;
- vector_set_index(ospf6_lsa_handler_vector, index, handler);
+ int index = handler->lh_type & OSPF6_LSTYPE_FCODE_MASK;
+ vector_set_index(ospf6_lsa_handler_vector, index, (void *)handler);
}
-struct ospf6_lsa_handler *ospf6_get_lsa_handler(u_int16_t type)
+const struct ospf6_lsa_handler *ospf6_get_lsa_handler(u_int16_t type)
{
- struct ospf6_lsa_handler *handler = NULL;
+ const struct ospf6_lsa_handler *handler = NULL;
unsigned int index = ntohs(type) & OSPF6_LSTYPE_FCODE_MASK;
if (index >= vector_active(ospf6_lsa_handler_vector))
@@ -97,11 +103,11 @@ struct ospf6_lsa_handler *ospf6_get_lsa_handler(u_int16_t type)
const char *ospf6_lstype_name(u_int16_t type)
{
static char buf[8];
- struct ospf6_lsa_handler *handler;
+ const struct ospf6_lsa_handler *handler;
handler = ospf6_get_lsa_handler(type);
if (handler && handler != &unknown_handler)
- return handler->name;
+ return handler->lh_name;
snprintf(buf, sizeof(buf), "0x%04hx", ntohs(type));
return buf;
@@ -110,11 +116,11 @@ const char *ospf6_lstype_name(u_int16_t type)
const char *ospf6_lstype_short_name(u_int16_t type)
{
static char buf[8];
- struct ospf6_lsa_handler *handler;
+ const struct ospf6_lsa_handler *handler;
handler = ospf6_get_lsa_handler(type);
if (handler && handler != &unknown_handler)
- return handler->short_name;
+ return handler->lh_short_name;
snprintf(buf, sizeof(buf), "0x%04hx", ntohs(type));
return buf;
@@ -122,7 +128,7 @@ const char *ospf6_lstype_short_name(u_int16_t type)
u_char ospf6_lstype_debug(u_int16_t type)
{
- struct ospf6_lsa_handler *handler;
+ const struct ospf6_lsa_handler *handler;
handler = ospf6_get_lsa_handler(type);
return handler->debug;
}
@@ -369,7 +375,7 @@ void ospf6_lsa_show_summary(struct vty *vty, struct ospf6_lsa *lsa)
{
char adv_router[16], id[16];
int type;
- struct ospf6_lsa_handler *handler;
+ const struct ospf6_lsa_handler *handler;
char buf[64], tmpbuf[80];
int cnt = 0;
@@ -389,14 +395,14 @@ void ospf6_lsa_show_summary(struct vty *vty, struct ospf6_lsa *lsa)
ospf6_lstype_short_name(lsa->header->type), id,
adv_router, ospf6_lsa_age_current(lsa),
(u_long)ntohl(lsa->header->seqnum),
- handler->get_prefix_str(lsa, buf, sizeof(buf), 0));
+ handler->lh_get_prefix_str(lsa, buf, sizeof(buf), 0));
} else if (type != OSPF6_LSTYPE_UNKNOWN) {
sprintf(tmpbuf, "%-4s %-15s%-15s%4hu %8lx",
ospf6_lstype_short_name(lsa->header->type), id,
adv_router, ospf6_lsa_age_current(lsa),
(u_long)ntohl(lsa->header->seqnum));
- while (handler->get_prefix_str(lsa, buf, sizeof(buf), cnt)
+ while (handler->lh_get_prefix_str(lsa, buf, sizeof(buf), cnt)
!= NULL) {
vty_out(vty, "%s %30s\n", tmpbuf, buf);
cnt++;
@@ -465,7 +471,7 @@ void ospf6_lsa_show_internal(struct vty *vty, struct ospf6_lsa *lsa)
void ospf6_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
{
char adv_router[64], id[64];
- struct ospf6_lsa_handler *handler;
+ const struct ospf6_lsa_handler *handler;
struct timeval now, res;
char duration[64];
@@ -490,9 +496,13 @@ void ospf6_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
vty_out(vty, "Duration: %s\n", duration);
handler = ospf6_get_lsa_handler(lsa->header->type);
- if (handler->show == NULL)
- handler = &unknown_handler;
- (*handler->show)(vty, lsa);
+
+ if (handler->lh_show != NULL)
+ handler->lh_show(vty, lsa);
+ else {
+ assert(unknown_handler.lh_show != NULL);
+ unknown_handler.lh_show(vty, lsa);
+ }
vty_out(vty, "\n");
}
@@ -739,22 +749,22 @@ void ospf6_lsa_terminate(void)
vector_free(ospf6_lsa_handler_vector);
}
-static char *ospf6_lsa_handler_name(struct ospf6_lsa_handler *h)
+static char *ospf6_lsa_handler_name(const struct ospf6_lsa_handler *h)
{
static char buf[64];
unsigned int i;
- unsigned int size = strlen(h->name);
+ unsigned int size = strlen(h->lh_name);
- if (!strcmp(h->name, "unknown") && h->type != OSPF6_LSTYPE_UNKNOWN) {
- snprintf(buf, sizeof(buf), "%#04hx", h->type);
+ if (!strcmp(h->lh_name, "unknown") && h->lh_type != OSPF6_LSTYPE_UNKNOWN) {
+ snprintf(buf, sizeof(buf), "%#04hx", h->lh_type);
return buf;
}
for (i = 0; i < MIN(size, sizeof(buf)); i++) {
- if (!islower((unsigned char)h->name[i]))
- buf[i] = tolower((unsigned char)h->name[i]);
+ if (!islower((unsigned char)h->lh_name[i]))
+ buf[i] = tolower((unsigned char)h->lh_name[i]);
else
- buf[i] = h->name[i];
+ buf[i] = h->lh_name[i];
}
buf[size] = '\0';
return buf;
@@ -791,7 +801,7 @@ DEFUN (debug_ospf6_lsa_type,
strlen(argv[idx_lsa]->arg))
== 0)
break;
- if (!strcasecmp(argv[idx_lsa]->arg, handler->name))
+ if (!strcasecmp(argv[idx_lsa]->arg, handler->lh_name))
break;
handler = NULL;
}
@@ -844,7 +854,7 @@ DEFUN (no_debug_ospf6_lsa_type,
strlen(argv[idx_lsa]->arg))
== 0)
break;
- if (!strcasecmp(argv[idx_lsa]->arg, handler->name))
+ if (!strcasecmp(argv[idx_lsa]->arg, handler->lh_name))
break;
}
@@ -875,7 +885,7 @@ void install_element_ospf6_debug_lsa(void)
int config_write_ospf6_debug_lsa(struct vty *vty)
{
u_int i;
- struct ospf6_lsa_handler *handler;
+ const struct ospf6_lsa_handler *handler;
for (i = 0; i < vector_active(ospf6_lsa_handler_vector); i++) {
handler = vector_slot(ospf6_lsa_handler_vector, i);
diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h
index ef63429fdf..3536d33d19 100644
--- a/ospf6d/ospf6_lsa.h
+++ b/ospf6d/ospf6_lsa.h
@@ -137,18 +137,25 @@ struct ospf6_lsa {
#define OSPF6_LSA_SEQWRAPPED 0x20
struct ospf6_lsa_handler {
- u_int16_t type; /* host byte order */
- const char *name;
- const char *short_name;
- int (*show)(struct vty *, struct ospf6_lsa *);
- char *(*get_prefix_str)(struct ospf6_lsa *, char *buf, int buflen,
- int pos);
+ const struct {
+ u_int16_t type; /* host byte order */
+ const char *name;
+ const char *short_name;
+ int (*show)(struct vty *, struct ospf6_lsa *);
+ char *(*get_prefix_str)(struct ospf6_lsa *, char *buf, int buflen,
+ int pos);
+ } s;
+#define lh_type s.type
+#define lh_name s.name
+#define lh_short_name s.short_name
+#define lh_show s.show
+#define lh_get_prefix_str s.get_prefix_str
u_char debug;
+#define lh_debug debug
};
-extern struct ospf6_lsa_handler unknown_handler;
-#define OSPF6_LSA_IS_KNOWN(type) \
- (ospf6_get_lsa_handler(type) != &unknown_handler ? 1 : 0)
+#define OSPF6_LSA_IS_KNOWN(t) \
+ (ospf6_get_lsa_handler(t)->lh_type != OSPF6_LSTYPE_UNKNOWN ? 1 : 0)
extern vector ospf6_lsa_handler_vector;
@@ -237,8 +244,8 @@ extern int ospf6_lsa_checksum_valid(struct ospf6_lsa_header *);
extern int ospf6_lsa_prohibited_duration(u_int16_t type, u_int32_t id,
u_int32_t adv_router, void *scope);
-extern void ospf6_install_lsa_handler(struct ospf6_lsa_handler *handler);
-extern struct ospf6_lsa_handler *ospf6_get_lsa_handler(u_int16_t type);
+extern void ospf6_install_lsa_handler(const struct ospf6_lsa_handler *handler);
+extern const struct ospf6_lsa_handler *ospf6_get_lsa_handler(u_int16_t type);
extern void ospf6_lsa_init(void);
extern void ospf6_lsa_terminate(void);
diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c
index e58eab2b15..5b78dda688 100644
--- a/ospf6d/ospf6_route.c
+++ b/ospf6d/ospf6_route.c
@@ -353,7 +353,7 @@ void ospf6_route_delete(struct ospf6_route *route)
{
if (route) {
if (route->nh_list)
- list_delete(route->nh_list);
+ list_delete_and_null(&route->nh_list);
XFREE(MTYPE_OSPF6_ROUTE, route);
}
}
@@ -1469,13 +1469,13 @@ DEFUN (debug_ospf6_route,
int idx_type = 3;
unsigned char level = 0;
- if (!strncmp(argv[idx_type]->arg, "table", 5))
+ if (!strcmp(argv[idx_type]->text, "table"))
level = OSPF6_DEBUG_ROUTE_TABLE;
- else if (!strncmp(argv[idx_type]->arg, "intra", 5))
+ else if (!strcmp(argv[idx_type]->text, "intra-area"))
level = OSPF6_DEBUG_ROUTE_INTRA;
- else if (!strncmp(argv[idx_type]->arg, "inter", 5))
+ else if (!strcmp(argv[idx_type]->text, "inter-area"))
level = OSPF6_DEBUG_ROUTE_INTER;
- else if (!strncmp(argv[idx_type]->arg, "memor", 5))
+ else if (!strcmp(argv[idx_type]->text, "memory"))
level = OSPF6_DEBUG_ROUTE_MEMORY;
OSPF6_DEBUG_ROUTE_ON(level);
return CMD_SUCCESS;
@@ -1496,13 +1496,13 @@ DEFUN (no_debug_ospf6_route,
int idx_type = 4;
unsigned char level = 0;
- if (!strncmp(argv[idx_type]->arg, "table", 5))
+ if (!strcmp(argv[idx_type]->text, "table"))
level = OSPF6_DEBUG_ROUTE_TABLE;
- else if (!strncmp(argv[idx_type]->arg, "intra", 5))
+ else if (!strcmp(argv[idx_type]->text, "intra-area"))
level = OSPF6_DEBUG_ROUTE_INTRA;
- else if (!strncmp(argv[idx_type]->arg, "inter", 5))
+ else if (!strcmp(argv[idx_type]->text, "inter-area"))
level = OSPF6_DEBUG_ROUTE_INTER;
- else if (!strncmp(argv[idx_type]->arg, "memor", 5))
+ else if (!strcmp(argv[idx_type]->text, "memory"))
level = OSPF6_DEBUG_ROUTE_MEMORY;
OSPF6_DEBUG_ROUTE_OFF(level);
return CMD_SUCCESS;
@@ -1516,6 +1516,9 @@ int config_write_ospf6_debug_route(struct vty *vty)
vty_out(vty, "debug ospf6 route intra-area\n");
if (IS_OSPF6_DEBUG_ROUTE(INTER))
vty_out(vty, "debug ospf6 route inter-area\n");
+ if (IS_OSPF6_DEBUG_ROUTE(MEMORY))
+ vty_out(vty, "debug ospf6 route memory\n");
+
return 0;
}
diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c
index ccfa25aaa8..2381318b27 100644
--- a/ospf6d/ospf6_spf.c
+++ b/ospf6d/ospf6_spf.c
@@ -152,8 +152,8 @@ static struct ospf6_vertex *ospf6_vertex_create(struct ospf6_lsa *lsa)
static void ospf6_vertex_delete(struct ospf6_vertex *v)
{
- list_delete(v->nh_list);
- list_delete(v->child_list);
+ list_delete_and_null(&v->nh_list);
+ list_delete_and_null(&v->child_list);
XFREE(MTYPE_OSPF6_VERTEX, v);
}
diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c
index 9794e92b06..b0281b9e0a 100644
--- a/ospf6d/ospf6_top.c
+++ b/ospf6d/ospf6_top.c
@@ -172,7 +172,7 @@ void ospf6_delete(struct ospf6 *o)
ospf6_area_delete(oa);
- list_delete(o->area_list);
+ list_delete_and_null(&o->area_list);
ospf6_lsdb_delete(o->lsdb);
ospf6_lsdb_delete(o->lsdb_self);
diff --git a/ospfd/.gitignore b/ospfd/.gitignore
index 752c875a62..018a363a93 100644
--- a/ospfd/.gitignore
+++ b/ospfd/.gitignore
@@ -15,3 +15,4 @@ TAGS
*~
*.loT
*.a
+*.clippy.c
diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c
index 968461b4d0..f7aa94ad18 100644
--- a/ospfd/ospf_abr.c
+++ b/ospfd/ospf_abr.c
@@ -91,7 +91,7 @@ static void ospf_area_range_delete(struct ospf_area *area,
struct ospf_area_range *range = rn->info;
if (range->specifics != 0)
- ospf_delete_discard_route(area->ospf->new_table,
+ ospf_delete_discard_route(area->ospf, area->ospf->new_table,
(struct prefix_ipv4 *)&rn->p);
ospf_area_range_free(range);
@@ -1684,12 +1684,12 @@ static void ospf_abr_manage_discard_routes(struct ospf *ospf)
if (CHECK_FLAG(range->flags,
OSPF_AREA_RANGE_ADVERTISE)) {
if (range->specifics)
- ospf_add_discard_route(
+ ospf_add_discard_route(ospf,
ospf->new_table, area,
(struct prefix_ipv4
*)&rn->p);
else
- ospf_delete_discard_route(
+ ospf_delete_discard_route(ospf,
ospf->new_table,
(struct prefix_ipv4
*)&rn->p);
diff --git a/ospfd/ospf_apiserver.c b/ospfd/ospf_apiserver.c
index a5f5971ac0..8c1ad5ff0c 100644
--- a/ospfd/ospf_apiserver.c
+++ b/ospfd/ospf_apiserver.c
@@ -80,9 +80,10 @@ struct ospf_interface *ospf_apiserver_if_lookup_by_addr(struct in_addr address)
{
struct listnode *node, *nnode;
struct ospf_interface *oi;
- struct ospf *ospf;
+ struct ospf *ospf = NULL;
- if (!(ospf = ospf_lookup()))
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (!ospf)
return NULL;
for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi))
@@ -97,9 +98,10 @@ struct ospf_interface *ospf_apiserver_if_lookup_by_ifp(struct interface *ifp)
{
struct listnode *node, *nnode;
struct ospf_interface *oi;
- struct ospf *ospf;
+ struct ospf *ospf = NULL;
- if (!(ospf = ospf_lookup()))
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (!ospf)
return NULL;
for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi))
@@ -178,7 +180,7 @@ void ospf_apiserver_term(void)
/* Free client list itself */
if (apiserver_list)
- list_delete(apiserver_list);
+ list_delete_and_null(&apiserver_list);
/* Free wildcard list */
/* XXX */
@@ -999,7 +1001,7 @@ void ospf_apiserver_notify_ready_type9(struct ospf_apiserver *apiserv)
struct ospf_interface *oi;
struct registered_opaque_type *r;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) {
/* Check if this interface is indeed ready for type 9 */
@@ -1047,7 +1049,7 @@ void ospf_apiserver_notify_ready_type10(struct ospf_apiserver *apiserv)
struct ospf *ospf;
struct ospf_area *area;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) {
struct registered_opaque_type *r;
@@ -1094,7 +1096,7 @@ void ospf_apiserver_notify_ready_type11(struct ospf_apiserver *apiserv)
struct ospf *ospf;
struct registered_opaque_type *r;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
/* Can type 11 be originated? */
if (!ospf_apiserver_is_ready_type11(ospf))
@@ -1271,7 +1273,7 @@ int ospf_apiserver_handle_sync_lsdb(struct ospf_apiserver *apiserv,
struct ospf *ospf;
struct ospf_area *area;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
/* Get request sequence number */
seqnum = msg_get_seq(msg);
@@ -1374,7 +1376,11 @@ struct ospf_lsa *ospf_apiserver_opaque_lsa_new(struct ospf_area *area,
struct ospf *ospf;
- ospf = ospf_lookup();
+ if (oi && oi->ospf)
+ ospf = oi->ospf;
+ else
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+
assert(ospf);
/* Create a stream for internal opaque LSA */
@@ -1429,6 +1435,7 @@ struct ospf_lsa *ospf_apiserver_opaque_lsa_new(struct ospf_area *area,
new->area = area;
new->oi = oi;
+ new->vrf_id = ospf->vrf_id;
SET_FLAG(new->flags, OSPF_LSA_SELF);
memcpy(new->data, newlsa, length);
@@ -1497,7 +1504,7 @@ int ospf_apiserver_handle_originate_request(struct ospf_apiserver *apiserv,
int ready = 0;
int rc = 0;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
/* Extract opaque LSA data from message */
omsg = (struct msg_originate_request *)STREAM_DATA(msg->s);
@@ -1640,7 +1647,7 @@ void ospf_apiserver_flood_opaque_lsa(struct ospf_lsa *lsa)
case OSPF_OPAQUE_AS_LSA: {
struct ospf *ospf;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
assert(ospf);
/* Increment counters? XXX */
@@ -1656,7 +1663,7 @@ int ospf_apiserver_originate1(struct ospf_lsa *lsa)
{
struct ospf *ospf;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
assert(ospf);
/* Install this LSA into LSDB. */
@@ -1726,7 +1733,7 @@ struct ospf_lsa *ospf_apiserver_lsa_refresher(struct ospf_lsa *lsa)
struct ospf_lsa *new = NULL;
struct ospf *ospf;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
assert(ospf);
apiserv = lookup_apiserver_by_lsa(lsa);
@@ -1810,7 +1817,7 @@ int ospf_apiserver_handle_delete_request(struct ospf_apiserver *apiserv,
int rc = 0;
struct ospf *ospf;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
assert(ospf);
/* Extract opaque LSA from message */
@@ -1862,7 +1869,7 @@ int ospf_apiserver_handle_delete_request(struct ospf_apiserver *apiserv,
* the LSDB until it is finally handled by the maxage remover thread.
* Therefore, the lookup function below may return non-NULL result.
*/
- old = ospf_lsa_lookup(area, dmsg->lsa_type, id, ospf->router_id);
+ old = ospf_lsa_lookup(ospf, area, dmsg->lsa_type, id, ospf->router_id);
if (!old) {
zlog_warn(
"ospf_apiserver_lsa_delete: LSA[Type%d:%s] not in LSDB",
@@ -1923,7 +1930,7 @@ void ospf_apiserver_flush_opaque_lsa(struct ospf_apiserver *apiserv,
struct ospf *ospf;
struct ospf_area *area;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
assert(ospf);
/* Set parameter struct. */
@@ -2315,7 +2322,7 @@ void ospf_apiserver_clients_notify_nsm_change(struct ospf_neighbor *nbr)
{
struct msg *msg;
struct in_addr ifaddr = {.s_addr = 0L};
- struct in_addr nbraddr = {.s_addr = 0L};
+ struct in_addr nbraddr;
assert(nbr);
diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c
index e3b66d597b..89c462693b 100644
--- a/ospfd/ospf_asbr.c
+++ b/ospfd/ospf_asbr.c
@@ -58,7 +58,8 @@ void ospf_external_route_remove(struct ospf *ospf, struct prefix_ipv4 *p)
/* Remove route from zebra. */
if (or->type == OSPF_DESTINATION_NETWORK)
- ospf_zebra_delete((struct prefix_ipv4 *)&rn->p,
+ ospf_zebra_delete(ospf,
+ (struct prefix_ipv4 *)&rn->p,
or);
ospf_route_free(or);
diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c
index bf2b809ddc..2f1b27f0f1 100644
--- a/ospfd/ospf_ase.c
+++ b/ospfd/ospf_ase.c
@@ -77,7 +77,7 @@ struct ospf_route *ospf_find_asbr_route(struct ospf *ospf,
/* If none is found -- look through all. */
if (listcount(chosen) == 0) {
- list_free(chosen);
+ list_delete_and_null(&chosen);
chosen = rn->info;
}
@@ -98,7 +98,7 @@ struct ospf_route *ospf_find_asbr_route(struct ospf *ospf,
}
if (chosen != rn->info)
- list_delete(chosen);
+ list_delete_and_null(&chosen);
return best;
}
@@ -598,7 +598,8 @@ static int ospf_ase_route_match_same(struct route_table *rt,
return 1;
}
-static int ospf_ase_compare_tables(struct route_table *new_external_route,
+static int ospf_ase_compare_tables(struct ospf *ospf,
+ struct route_table *new_external_route,
struct route_table *old_external_route)
{
struct route_node *rn, *new_rn;
@@ -609,7 +610,8 @@ static int ospf_ase_compare_tables(struct route_table *new_external_route,
if ((or = rn->info)) {
if (!(new_rn = route_node_lookup(new_external_route,
&rn->p)))
- ospf_zebra_delete((struct prefix_ipv4 *)&rn->p,
+ ospf_zebra_delete(ospf,
+ (struct prefix_ipv4 *)&rn->p,
or);
else
route_unlock_node(new_rn);
@@ -621,7 +623,8 @@ static int ospf_ase_compare_tables(struct route_table *new_external_route,
if ((or = rn->info) != NULL)
if (!ospf_ase_route_match_same(old_external_route,
&rn->p, or))
- ospf_zebra_add((struct prefix_ipv4 *)&rn->p,
+ ospf_zebra_add(ospf,
+ (struct prefix_ipv4 *)&rn->p,
or);
return 0;
@@ -666,7 +669,7 @@ static int ospf_ase_calculate_timer(struct thread *t)
/* Compare old and new external routing table and install the
difference info zebra/kernel */
- ospf_ase_compare_tables(ospf->new_external_route,
+ ospf_ase_compare_tables(ospf, ospf->new_external_route,
ospf->old_external_route);
/* Delete old external routing table */
@@ -758,7 +761,7 @@ void ospf_ase_external_lsas_finish(struct route_table *rt)
if ((lst = rn->info) != NULL) {
for (ALL_LIST_ELEMENTS(lst, node, nnode, lsa))
ospf_lsa_unlock(&lsa); /* external_lsas lst */
- list_delete(lst);
+ list_delete_and_null(&lst);
}
route_table_finish(rt);
@@ -814,7 +817,7 @@ void ospf_ase_incremental_update(struct ospf *ospf, struct ospf_lsa *lsa)
}
/* install changes to zebra */
- ospf_ase_compare_tables(ospf->new_external_route, tmp_old);
+ ospf_ase_compare_tables(ospf, ospf->new_external_route, tmp_old);
/* update ospf->old_external_route table */
if (rn && rn->info)
diff --git a/ospfd/ospf_bfd.c b/ospfd/ospf_bfd.c
index 6d07b44364..9254e7d240 100644
--- a/ospfd/ospf_bfd.c
+++ b/ospfd/ospf_bfd.c
@@ -75,12 +75,13 @@ static void ospf_bfd_reg_dereg_nbr(struct ospf_neighbor *nbr, int command)
bfd_info = (struct bfd_info *)params->bfd_info;
if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
- zlog_debug("%s nbr (%s) with BFD",
+ zlog_debug("%s nbr (%s) with BFD. OSPF vrf %s",
bfd_get_command_dbg_str(command),
- inet_ntoa(nbr->src));
+ inet_ntoa(nbr->src),
+ ospf_vrf_id_to_name(oi->ospf->vrf_id));
bfd_peer_sendmsg(zclient, bfd_info, AF_INET, &nbr->src, NULL, ifp->name,
- 0, 0, command, 0, VRF_DEFAULT);
+ 0, 0, command, 0, oi->ospf->vrf_id);
}
/*
@@ -158,7 +159,7 @@ static int ospf_bfd_nbr_replay(int command, struct zclient *zclient,
/* Send the client registration */
bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER);
- /* Replay the neighbor, if BFD is enabled in BGP */
+ /* Replay the neighbor, if BFD is enabled in OSPF */
for (ALL_LIST_ELEMENTS(om->ospf, node, onode, ospf)) {
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, inode, oi)) {
if ((nbrs = oi->nbrs) == NULL)
diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c
index 619bd4e5f5..5933f5abfe 100644
--- a/ospfd/ospf_dump.c
+++ b/ospfd/ospf_dump.c
@@ -169,6 +169,7 @@ const char *ospf_timeval_dump(struct timeval *t, char *buf, size_t size)
if (us >= 1000) {
ms = us / 1000;
us %= 1000;
+ (void)us; /* unused */
}
if (ms >= 1000) {
@@ -1604,9 +1605,10 @@ DEFUN_NOSH (show_debugging_ospf,
DEBUG_STR
OSPF_STR)
{
- struct ospf *ospf;
+ struct ospf *ospf = NULL;
- if ((ospf = ospf_lookup()) == NULL)
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL)
return CMD_SUCCESS;
return show_debugging_ospf_common(vty, ospf);
@@ -1651,7 +1653,8 @@ static int config_write_debug(struct vty *vty)
char str[16];
memset(str, 0, 16);
- if ((ospf = ospf_lookup()) == NULL)
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL)
return CMD_SUCCESS;
if (ospf->instance)
diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c
index c775f2ea2e..aac2f3ee92 100644
--- a/ospfd/ospf_flood.c
+++ b/ospfd/ospf_flood.c
@@ -77,7 +77,8 @@ static void ospf_flood_delayed_lsa_ack(struct ospf_neighbor *inbr,
}
/* Check LSA is related to external info. */
-struct external_info *ospf_external_info_check(struct ospf_lsa *lsa)
+struct external_info *ospf_external_info_check(struct ospf *ospf,
+ struct ospf_lsa *lsa)
{
struct as_external_lsa *al;
struct prefix_ipv4 p;
@@ -96,11 +97,11 @@ struct external_info *ospf_external_info_check(struct ospf_lsa *lsa)
redist_on =
is_prefix_default(&p)
? vrf_bitmap_check(zclient->default_information,
- VRF_DEFAULT)
+ ospf->vrf_id)
: (zclient->mi_redist[AFI_IP][type].enabled
|| vrf_bitmap_check(
zclient->redist[AFI_IP][type],
- VRF_DEFAULT));
+ ospf->vrf_id));
// Pending: check for MI above.
if (redist_on) {
struct list *ext_list;
@@ -205,7 +206,7 @@ static void ospf_process_self_originated_lsa(struct ospf *ospf,
ospf_translated_nssa_refresh(ospf, NULL, new);
return;
}
- ei = ospf_external_info_check(new);
+ ei = ospf_external_info_check(ospf, new);
if (ei)
ospf_external_lsa_refresh(ospf, new, ei,
LSA_REFRESH_FORCE);
diff --git a/ospfd/ospf_flood.h b/ospfd/ospf_flood.h
index b74894567d..6f7ecfccf0 100644
--- a/ospfd/ospf_flood.h
+++ b/ospfd/ospf_flood.h
@@ -61,7 +61,8 @@ extern void ospf_flood_lsa_as(struct ospf_lsa *);
extern void ospf_lsa_flush_area(struct ospf_lsa *, struct ospf_area *);
extern void ospf_lsa_flush_as(struct ospf *, struct ospf_lsa *);
extern void ospf_lsa_flush(struct ospf *, struct ospf_lsa *);
-extern struct external_info *ospf_external_info_check(struct ospf_lsa *);
+extern struct external_info *ospf_external_info_check(struct ospf *,
+ struct ospf_lsa *);
extern void ospf_lsdb_init(struct ospf_lsdb *);
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index 422e1a2a6b..67ce6f1713 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -243,6 +243,11 @@ struct ospf_interface *ospf_if_new(struct ospf *ospf, struct interface *ifp,
oi->ospf = ospf;
QOBJ_REG(oi, ospf_interface);
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: ospf interface %s vrf %s id %u created",
+ __PRETTY_FUNCTION__, ifp->name,
+ ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id);
+
return oi;
}
@@ -308,10 +313,16 @@ void ospf_if_free(struct ospf_interface *oi)
route_table_finish(oi->ls_upd_queue);
/* Free any lists that should be freed */
- list_free(oi->nbr_nbma);
+ list_delete_and_null(&oi->nbr_nbma);
+
+ list_delete_and_null(&oi->ls_ack);
+ list_delete_and_null(&oi->ls_ack_direct.ls_ack);
- list_free(oi->ls_ack);
- list_free(oi->ls_ack_direct.ls_ack);
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: ospf interface %s vrf %s id %u deleted",
+ __PRETTY_FUNCTION__, oi->ifp->name,
+ ospf_vrf_id_to_name(oi->ifp->vrf_id),
+ oi->ifp->vrf_id);
ospf_delete_from_if(oi->ifp, oi);
@@ -335,7 +346,11 @@ struct ospf_interface *ospf_if_exists(struct ospf_interface *oic)
struct ospf *ospf;
struct ospf_interface *oi;
- if ((ospf = ospf_lookup()) == NULL)
+ if (!oic)
+ return NULL;
+
+ ospf = oic->ospf;
+ if (ospf == NULL)
return NULL;
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi))
@@ -494,7 +509,7 @@ static struct ospf_if_params *ospf_new_if_params(void)
void ospf_del_if_params(struct ospf_if_params *oip)
{
- list_delete(oip->auth_crypt);
+ list_delete_and_null(&oip->auth_crypt);
bfd_info_free(&(oip->bfd_info));
XFREE(MTYPE_OSPF_IF_PARAMS, oip);
}
@@ -800,10 +815,11 @@ struct ospf_interface *ospf_vl_new(struct ospf *ospf,
}
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("ospf_vl_new(): creating pseudo zebra interface");
+ zlog_debug("ospf_vl_new(): creating pseudo zebra interface vrf id %u",
+ ospf->vrf_id);
snprintf(ifname, sizeof(ifname), "VLINK%d", vlink_count);
- vi = if_create(ifname, strnlen(ifname, sizeof(ifname)), VRF_DEFAULT);
+ vi = if_create(ifname, strnlen(ifname, sizeof(ifname)), ospf->vrf_id);
/*
* if_create sets ZEBRA_INTERFACE_LINKDETECTION
* virtual links don't need this.
@@ -1164,7 +1180,6 @@ u_char ospf_default_iftype(struct interface *ifp)
void ospf_if_init()
{
/* Initialize Zebra interface data structure. */
- om->iflist = vrf_iflist(VRF_DEFAULT);
hook_register_prio(if_add, 0, ospf_if_new_hook);
hook_register_prio(if_del, 0, ospf_if_delete_hook);
}
diff --git a/ospfd/ospf_ism.c b/ospfd/ospf_ism.c
index f223a870da..25ab9cbe0f 100644
--- a/ospfd/ospf_ism.c
+++ b/ospfd/ospf_ism.c
@@ -104,7 +104,7 @@ static struct ospf_neighbor *ospf_elect_dr(struct ospf_interface *oi,
else
DR(oi).s_addr = 0;
- list_delete(dr_list);
+ list_delete_and_null(&dr_list);
return dr;
}
@@ -144,8 +144,8 @@ static struct ospf_neighbor *ospf_elect_bdr(struct ospf_interface *oi,
else
BDR(oi).s_addr = 0;
- list_delete(bdr_list);
- list_delete(no_dr_list);
+ list_delete_and_null(&bdr_list);
+ list_delete_and_null(&no_dr_list);
return bdr;
}
@@ -232,7 +232,7 @@ static int ospf_dr_election(struct ospf_interface *oi)
zlog_debug("DR-Election[2nd]: DR %s", inet_ntoa(DR(oi)));
}
- list_delete(el_list);
+ list_delete_and_null(&el_list);
/* if DR or BDR changes, cause AdjOK? neighbor event. */
if (!IPV4_ADDR_SAME(&old_dr, &DR(oi))
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index 68adf2e10b..74d5178f55 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -161,6 +161,7 @@ struct ospf_lsa *ospf_lsa_new()
monotime(&new->tv_recv);
new->tv_orig = new->tv_recv;
new->refresh_list = -1;
+ new->vrf_id = VRF_DEFAULT;
return new;
}
@@ -786,6 +787,7 @@ static struct ospf_lsa *ospf_router_lsa_new(struct ospf_area *area)
new->area = area;
SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
+ new->vrf_id = area->ospf->vrf_id;
/* Copy LSA data to store, discard stream. */
new->data = ospf_lsa_data_new(length);
@@ -1001,6 +1003,7 @@ static struct ospf_lsa *ospf_network_lsa_new(struct ospf_interface *oi)
new->area = oi->area;
SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
+ new->vrf_id = oi->ospf->vrf_id;
/* Copy LSA to store. */
new->data = ospf_lsa_data_new(length);
@@ -1180,6 +1183,7 @@ static struct ospf_lsa *ospf_summary_lsa_new(struct ospf_area *area,
new = ospf_lsa_new();
new->area = area;
SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
+ new->vrf_id = area->ospf->vrf_id;
/* Copy LSA to store. */
new->data = ospf_lsa_data_new(length);
@@ -1321,6 +1325,7 @@ static struct ospf_lsa *ospf_summary_asbr_lsa_new(struct ospf_area *area,
new = ospf_lsa_new();
new->area = area;
SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
+ new->vrf_id = area->ospf->vrf_id;
/* Copy LSA to store. */
new->data = ospf_lsa_data_new(length);
@@ -1627,6 +1632,7 @@ static struct ospf_lsa *ospf_external_lsa_new(struct ospf *ospf,
new->area = NULL;
SET_FLAG(new->flags,
OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED);
+ new->vrf_id = ospf->vrf_id;
/* Copy LSA data to store, discard stream. */
new->data = ospf_lsa_data_new(length);
@@ -1696,7 +1702,7 @@ static void ospf_install_flood_nssa(struct ospf *ospf, struct ospf_lsa *lsa,
not adversited into OSPF as an internal OSPF route and
the
type-7 LSA's P-bit is set a forwarding address should be
- selected from one of the router's active OSPF inteface
+ selected from one of the router's active OSPF interface
addresses
which belong to the NSSA. If no such addresses exist,
then
@@ -2121,14 +2127,15 @@ int ospf_default_originate_timer(struct thread *thread)
void ospf_nssa_lsa_flush(struct ospf *ospf, struct prefix_ipv4 *p)
{
struct listnode *node, *nnode;
- struct ospf_lsa *lsa;
+ struct ospf_lsa *lsa = NULL;
struct ospf_area *area;
for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) {
if (area->external_routing == OSPF_AREA_NSSA) {
- if (!(lsa = ospf_lsa_lookup(area, OSPF_AS_NSSA_LSA,
- p->prefix,
- ospf->router_id))) {
+ lsa = ospf_lsa_lookup(ospf, area,
+ OSPF_AS_NSSA_LSA, p->prefix,
+ ospf->router_id);
+ if (!lsa) {
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
zlog_debug(
"LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
@@ -2844,11 +2851,12 @@ static int ospf_maxage_lsa_remover(struct thread *thread)
void ospf_lsa_maxage_delete(struct ospf *ospf, struct ospf_lsa *lsa)
{
struct route_node *rn;
- struct prefix_ptr lsa_prefix;
+ struct prefix lsa_prefix;
+ memset(&lsa_prefix, 0, sizeof(struct prefix));
lsa_prefix.family = 0;
- lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT;
- lsa_prefix.prefix = (uintptr_t)lsa;
+ lsa_prefix.prefixlen = sizeof(lsa_prefix.u.ptr) * CHAR_BIT;
+ lsa_prefix.u.ptr = (uintptr_t)lsa;
if ((rn = route_node_lookup(ospf->maxage_lsa,
(struct prefix *)&lsa_prefix))) {
@@ -2860,6 +2868,10 @@ void ospf_lsa_maxage_delete(struct ospf *ospf, struct ospf_lsa *lsa)
rn); /* unlock node because lsa is deleted */
}
route_unlock_node(rn); /* route_node_lookup */
+ } else {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: lsa %s is not found in maxage db.",
+ __PRETTY_FUNCTION__, dump_lsa_key(lsa));
}
}
@@ -2870,7 +2882,7 @@ void ospf_lsa_maxage_delete(struct ospf *ospf, struct ospf_lsa *lsa)
*/
void ospf_lsa_maxage(struct ospf *ospf, struct ospf_lsa *lsa)
{
- struct prefix_ptr lsa_prefix;
+ struct prefix lsa_prefix;
struct route_node *rn;
/* When we saw a MaxAge LSA flooded to us, we put it on the list
@@ -2884,9 +2896,10 @@ void ospf_lsa_maxage(struct ospf *ospf, struct ospf_lsa *lsa)
return;
}
+ memset(&lsa_prefix, 0, sizeof(struct prefix));
lsa_prefix.family = 0;
- lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT;
- lsa_prefix.prefix = (uintptr_t)lsa;
+ lsa_prefix.prefixlen = sizeof(lsa_prefix.u.ptr) * CHAR_BIT;
+ lsa_prefix.u.ptr = (uintptr_t)lsa;
if ((rn = route_node_get(ospf->maxage_lsa,
(struct prefix *)&lsa_prefix))
@@ -2903,7 +2916,8 @@ void ospf_lsa_maxage(struct ospf *ospf, struct ospf_lsa *lsa)
SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
}
} else {
- zlog_err("Unable to allocate memory for maxage lsa\n");
+ zlog_err("Unable to allocate memory for maxage lsa %s\n",
+ dump_lsa_key(lsa));
assert(0);
}
@@ -3039,11 +3053,12 @@ struct ospf_lsa *ospf_lsa_lookup_by_prefix(struct ospf_lsdb *lsdb, u_char type,
return lsa;
}
-struct ospf_lsa *ospf_lsa_lookup(struct ospf_area *area, u_int32_t type,
- struct in_addr id, struct in_addr adv_router)
+struct ospf_lsa *ospf_lsa_lookup(struct ospf *ospf, struct ospf_area *area,
+ u_int32_t type, struct in_addr id,
+ struct in_addr adv_router)
{
- struct ospf *ospf = ospf_lookup();
- assert(ospf);
+ if (!ospf)
+ return NULL;
switch (type) {
case OSPF_ROUTER_LSA:
@@ -3113,7 +3128,8 @@ struct ospf_lsa *ospf_lsa_lookup_by_header(struct ospf_area *area,
* they two were forming a unique LSA-ID.
*/
- match = ospf_lsa_lookup(area, lsah->type, lsah->id, lsah->adv_router);
+ match = ospf_lsa_lookup(area->ospf, area, lsah->type, lsah->id,
+ lsah->adv_router);
if (match == NULL)
if (IS_DEBUG_OSPF(lsa, LSA) == OSPF_DEBUG_LSA)
@@ -3529,7 +3545,7 @@ struct ospf_lsa *ospf_lsa_refresh(struct ospf *ospf, struct ospf_lsa *lsa)
*/
if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT))
break;
- ei = ospf_external_info_check(lsa);
+ ei = ospf_external_info_check(ospf, lsa);
if (ei)
new = ospf_external_lsa_refresh(ospf, lsa, ei,
LSA_REFRESH_FORCE);
@@ -3606,7 +3622,7 @@ void ospf_refresher_unregister_lsa(struct ospf *ospf, struct ospf_lsa *lsa)
ospf->lsa_refresh_queue.qs[lsa->refresh_list];
listnode_delete(refresh_list, lsa);
if (!listcount(refresh_list)) {
- list_free(refresh_list);
+ list_delete_and_null(&refresh_list);
ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
}
ospf_lsa_unlock(&lsa); /* lsa_refresh_queue */
@@ -3675,7 +3691,7 @@ int ospf_lsa_refresh_walker(struct thread *t)
lsa->refresh_list = -1;
listnode_add(lsa_to_refresh, lsa);
}
- list_free(refresh_list);
+ list_delete_and_null(&refresh_list);
}
}
@@ -3691,7 +3707,7 @@ int ospf_lsa_refresh_walker(struct thread *t)
&lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/
}
- list_delete(lsa_to_refresh);
+ list_delete_and_null(&lsa_to_refresh);
if (IS_DEBUG_OSPF(lsa, LSA_REFRESH))
zlog_debug("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h
index ab8e62b6e4..94a34d4a90 100644
--- a/ospfd/ospf_lsa.h
+++ b/ospfd/ospf_lsa.h
@@ -111,6 +111,9 @@ struct ospf_lsa {
/* For Type-9 Opaque-LSAs */
struct ospf_interface *oi;
+
+ /* VRF Id */
+ vrf_id_t vrf_id;
};
/* OSPF LSA Link Type. */
@@ -267,8 +270,9 @@ extern struct ospf_lsa *ospf_external_lsa_originate(struct ospf *,
struct external_info *);
extern int ospf_external_lsa_originate_timer(struct thread *);
extern int ospf_default_originate_timer(struct thread *);
-extern struct ospf_lsa *ospf_lsa_lookup(struct ospf_area *, u_int32_t,
- struct in_addr, struct in_addr);
+extern struct ospf_lsa *ospf_lsa_lookup(struct ospf *ospf, struct ospf_area *,
+ u_int32_t, struct in_addr,
+ struct in_addr);
extern struct ospf_lsa *ospf_lsa_lookup_by_id(struct ospf_area *, u_int32_t,
struct in_addr);
extern struct ospf_lsa *ospf_lsa_lookup_by_header(struct ospf_area *,
diff --git a/ospfd/ospf_main.c b/ospfd/ospf_main.c
index f284a04cbe..7bd644f43d 100644
--- a/ospfd/ospf_main.c
+++ b/ospfd/ospf_main.c
@@ -187,7 +187,7 @@ int main(int argc, char **argv)
/* Library inits. */
debug_init();
- vrf_init(NULL, NULL, NULL, NULL);
+ ospf_vrf_init();
access_list_init();
prefix_list_init();
diff --git a/ospfd/ospf_network.c b/ospfd/ospf_network.c
index c72c69856c..699f2341d5 100644
--- a/ospfd/ospf_network.c
+++ b/ospfd/ospf_network.c
@@ -153,7 +153,10 @@ int ospf_if_ipmulticast(struct ospf *top, struct prefix *p, ifindex_t ifindex)
if (ret < 0)
zlog_warn("can't setsockopt IP_MULTICAST_TTL(1) for fd %d: %s",
top->fd, safe_strerror(errno));
-
+#ifndef GNU_LINUX
+ /* For GNU LINUX ospf_write uses IP_PKTINFO, in_pktinfo to send
+ * packet out of ifindex. Below would be used Non Linux system.
+ */
ret = setsockopt_ipv4_multicast_if(top->fd, p->u.prefix4, ifindex);
if (ret < 0)
zlog_warn(
@@ -161,23 +164,53 @@ int ospf_if_ipmulticast(struct ospf *top, struct prefix *p, ifindex_t ifindex)
"ifindex %u): %s",
top->fd, inet_ntoa(p->u.prefix4), ifindex,
safe_strerror(errno));
+#endif
return ret;
}
-int ospf_sock_init(void)
+int ospf_bind_vrfdevice(struct ospf *ospf, int ospf_sock)
+{
+ int ret = 0;
+
+#ifdef SO_BINDTODEVICE
+
+ if (ospf && ospf->vrf_id != VRF_DEFAULT &&
+ ospf->vrf_id != VRF_UNKNOWN) {
+ ret = setsockopt(ospf_sock, SOL_SOCKET, SO_BINDTODEVICE,
+ ospf->name,
+ strlen(ospf->name));
+ if (ret < 0) {
+ int save_errno = errno;
+
+ zlog_warn("%s: Could not setsockopt SO_BINDTODEVICE %s",
+ __PRETTY_FUNCTION__,
+ safe_strerror(save_errno));
+ } else {
+ zlog_debug("%s: Bind socket %d to vrf %s id %u device",
+ __PRETTY_FUNCTION__, ospf_sock,
+ ospf->name, ospf->vrf_id);
+ }
+ }
+#endif
+ return ret;
+}
+
+int ospf_sock_init(struct ospf *ospf)
{
int ospf_sock;
int ret, hincl = 1;
int bufsize = (8 * 1024 * 1024);
- if (ospfd_privs.change(ZPRIVS_RAISE))
+ if (ospfd_privs.change(ZPRIVS_RAISE)) {
zlog_err("ospf_sock_init: could not raise privs, %s",
safe_strerror(errno));
+ }
ospf_sock = socket(AF_INET, SOCK_RAW, IPPROTO_OSPFIGP);
if (ospf_sock < 0) {
int save_errno = errno;
+
if (ospfd_privs.change(ZPRIVS_LOWER))
zlog_err("ospf_sock_init: could not lower privs, %s",
safe_strerror(errno));
@@ -186,17 +219,23 @@ int ospf_sock_init(void)
exit(1);
}
+ ret = ospf_bind_vrfdevice(ospf, ospf_sock);
+ if (ret < 0) {
+ close(ospf_sock);
+ goto out;
+ }
+
#ifdef IP_HDRINCL
/* we will include IP header with packet */
ret = setsockopt(ospf_sock, IPPROTO_IP, IP_HDRINCL, &hincl,
sizeof(hincl));
if (ret < 0) {
int save_errno = errno;
- if (ospfd_privs.change(ZPRIVS_LOWER))
- zlog_err("ospf_sock_init: could not lower privs, %s",
- safe_strerror(errno));
+
zlog_warn("Can't set IP_HDRINCL option for fd %d: %s",
ospf_sock, safe_strerror(save_errno));
+ close(ospf_sock);
+ goto out;
}
#elif defined(IPTOS_PREC_INTERNETCONTROL)
#warning "IP_HDRINCL not available on this system"
@@ -204,13 +243,11 @@ int ospf_sock_init(void)
ret = setsockopt_ipv4_tos(ospf_sock, IPTOS_PREC_INTERNETCONTROL);
if (ret < 0) {
int save_errno = errno;
- if (ospfd_privs.change(ZPRIVS_LOWER))
- zlog_err("ospf_sock_init: could not lower privs, %s",
- safe_strerror(errno));
+
zlog_warn("can't set sockopt IP_TOS %d to socket %d: %s", tos,
ospf_sock, safe_strerror(save_errno));
close(ospf_sock); /* Prevent sd leak. */
- return ret;
+ goto out;
}
#else /* !IPTOS_PREC_INTERNETCONTROL */
#warning "IP_HDRINCL not available, nor is IPTOS_PREC_INTERNETCONTROL"
@@ -222,13 +259,14 @@ int ospf_sock_init(void)
if (ret < 0)
zlog_warn("Can't set pktinfo option for fd %d", ospf_sock);
+ setsockopt_so_sendbuf(ospf_sock, bufsize);
+ setsockopt_so_recvbuf(ospf_sock, bufsize);
+
+ ospf->fd = ospf_sock;
+out:
if (ospfd_privs.change(ZPRIVS_LOWER)) {
zlog_err("ospf_sock_init: could not lower privs, %s",
safe_strerror(errno));
}
-
- setsockopt_so_sendbuf(ospf_sock, bufsize);
- setsockopt_so_recvbuf(ospf_sock, bufsize);
-
- return ospf_sock;
+ return ret;
}
diff --git a/ospfd/ospf_network.h b/ospfd/ospf_network.h
index ed5e00315c..41a7abda70 100644
--- a/ospfd/ospf_network.h
+++ b/ospfd/ospf_network.h
@@ -29,6 +29,7 @@ extern int ospf_if_drop_allspfrouters(struct ospf *, struct prefix *,
extern int ospf_if_add_alldrouters(struct ospf *, struct prefix *, ifindex_t);
extern int ospf_if_drop_alldrouters(struct ospf *, struct prefix *, ifindex_t);
extern int ospf_if_ipmulticast(struct ospf *, struct prefix *, ifindex_t);
-extern int ospf_sock_init(void);
+extern int ospf_sock_init(struct ospf *ospf);
+extern int ospf_bind_vrfdevice(struct ospf *, int);
#endif /* _ZEBRA_OSPF_NETWORK_H */
diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c
index db523bd2a4..5a1f28b036 100644
--- a/ospfd/ospf_opaque.c
+++ b/ospfd/ospf_opaque.c
@@ -113,7 +113,7 @@ void ospf_opaque_term(void)
int ospf_opaque_type9_lsa_init(struct ospf_interface *oi)
{
if (oi->opaque_lsa_self != NULL)
- list_delete(oi->opaque_lsa_self);
+ list_delete_and_null(&oi->opaque_lsa_self);
oi->opaque_lsa_self = list_new();
oi->opaque_lsa_self->del = free_opaque_info_per_type;
@@ -125,7 +125,7 @@ void ospf_opaque_type9_lsa_term(struct ospf_interface *oi)
{
OSPF_TIMER_OFF(oi->t_opaque_lsa_self);
if (oi->opaque_lsa_self != NULL)
- list_delete(oi->opaque_lsa_self);
+ list_delete_and_null(&oi->opaque_lsa_self);
oi->opaque_lsa_self = NULL;
return;
}
@@ -133,7 +133,7 @@ void ospf_opaque_type9_lsa_term(struct ospf_interface *oi)
int ospf_opaque_type10_lsa_init(struct ospf_area *area)
{
if (area->opaque_lsa_self != NULL)
- list_delete(area->opaque_lsa_self);
+ list_delete_and_null(&area->opaque_lsa_self);
area->opaque_lsa_self = list_new();
area->opaque_lsa_self->del = free_opaque_info_per_type;
@@ -154,15 +154,14 @@ void ospf_opaque_type10_lsa_term(struct ospf_area *area)
OSPF_TIMER_OFF(area->t_opaque_lsa_self);
if (area->opaque_lsa_self != NULL)
- list_delete(area->opaque_lsa_self);
- area->opaque_lsa_self = NULL;
+ list_delete_and_null(&area->opaque_lsa_self);
return;
}
int ospf_opaque_type11_lsa_init(struct ospf *top)
{
if (top->opaque_lsa_self != NULL)
- list_delete(top->opaque_lsa_self);
+ list_delete_and_null(&top->opaque_lsa_self);
top->opaque_lsa_self = list_new();
top->opaque_lsa_self->del = free_opaque_info_per_type;
@@ -183,8 +182,7 @@ void ospf_opaque_type11_lsa_term(struct ospf *top)
OSPF_TIMER_OFF(top->t_opaque_lsa_self);
if (top->opaque_lsa_self != NULL)
- list_delete(top->opaque_lsa_self);
- top->opaque_lsa_self = NULL;
+ list_delete_and_null(&top->opaque_lsa_self);
return;
}
@@ -287,16 +285,16 @@ static void ospf_opaque_funclist_term(void)
struct list *funclist;
funclist = ospf_opaque_wildcard_funclist;
- list_delete(funclist);
+ list_delete_and_null(&funclist);
funclist = ospf_opaque_type9_funclist;
- list_delete(funclist);
+ list_delete_and_null(&funclist);
funclist = ospf_opaque_type10_funclist;
- list_delete(funclist);
+ list_delete_and_null(&funclist);
funclist = ospf_opaque_type11_funclist;
- list_delete(funclist);
+ list_delete_and_null(&funclist);
return;
}
@@ -544,7 +542,7 @@ register_opaque_info_per_type(struct ospf_opaque_functab *functab,
listnode_add(new->area->opaque_lsa_self, oipt);
break;
case OSPF_OPAQUE_AS_LSA:
- top = ospf_lookup();
+ top = ospf_lookup_by_vrf_id(new->vrf_id);
if (new->area != NULL && (top = new->area->ospf) == NULL) {
free_opaque_info_per_type((void *)oipt);
oipt = NULL;
@@ -616,7 +614,7 @@ static void free_opaque_info_per_type(void *val)
}
OSPF_TIMER_OFF(oipt->t_opaque_lsa_self);
- list_delete(oipt->id_list);
+ list_delete_and_null(&oipt->id_list);
XFREE(MTYPE_OPAQUE_INFO_PER_TYPE, oipt);
return;
}
@@ -648,7 +646,7 @@ lookup_opaque_info_by_type(struct ospf_lsa *lsa)
"Type-10 Opaque-LSA: Reference to AREA is missing?");
break;
case OSPF_OPAQUE_AS_LSA:
- top = ospf_lookup();
+ top = ospf_lookup_by_vrf_id(lsa->vrf_id);
if ((area = lsa->area) != NULL && (top = area->ospf) == NULL) {
zlog_warn(
"Type-11 Opaque-LSA: Reference to OSPF is missing?");
@@ -1571,7 +1569,7 @@ struct ospf_lsa *ospf_opaque_lsa_install(struct ospf_lsa *lsa, int rt_recalc)
}
break;
case OSPF_OPAQUE_AS_LSA:
- top = ospf_lookup();
+ top = ospf_lookup_by_vrf_id(lsa->vrf_id);
if (lsa->area != NULL && (top = lsa->area->ospf) == NULL) {
/* Above conditions must have passed. */
zlog_warn("ospf_opaque_lsa_install: Sonmething wrong?");
@@ -1597,7 +1595,7 @@ struct ospf_lsa *ospf_opaque_lsa_refresh(struct ospf_lsa *lsa)
struct ospf_opaque_functab *functab;
struct ospf_lsa *new = NULL;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(lsa->vrf_id);
if ((functab = ospf_opaque_functab_lookup(lsa)) == NULL
|| functab->lsa_refresher == NULL) {
@@ -1638,7 +1636,7 @@ static int ospf_opaque_lsa_refresh_timer(struct thread *t);
void ospf_opaque_lsa_reoriginate_schedule(void *lsa_type_dependent,
u_char lsa_type, u_char opaque_type)
{
- struct ospf *top;
+ struct ospf *top = NULL;
struct ospf_area dummy, *area = NULL;
struct ospf_interface *oi = NULL;
@@ -1739,6 +1737,7 @@ void ospf_opaque_lsa_reoriginate_schedule(void *lsa_type_dependent,
/* Generate a dummy lsa to be passed for a lookup function. */
lsa = pseudo_lsa(oi, area, lsa_type, opaque_type);
+ lsa->vrf_id = top->vrf_id;
if ((oipt = lookup_opaque_info_by_type(lsa)) == NULL) {
struct ospf_opaque_functab *functab;
@@ -1804,6 +1803,7 @@ static struct ospf_lsa *pseudo_lsa(struct ospf_interface *oi,
lsa.oi = oi;
lsa.area = area;
lsa.data = &lsah;
+ lsa.vrf_id = VRF_DEFAULT;
lsah.type = lsa_type;
tmp = SET_OPAQUE_LSID(opaque_type, 0); /* Opaque-ID is unused here. */
@@ -2000,7 +2000,7 @@ void ospf_opaque_lsa_refresh_schedule(struct ospf_lsa *lsa0)
ospf_ls_retransmit_delete_nbr_area(lsa->area, lsa);
break;
case OSPF_OPAQUE_AS_LSA:
- top = ospf_lookup();
+ top = ospf_lookup_by_vrf_id(lsa0->vrf_id);
if ((lsa0->area != NULL) && (lsa0->area->ospf != NULL))
top = lsa0->area->ospf;
ospf_ls_retransmit_delete_nbr_as(top, lsa);
@@ -2054,7 +2054,7 @@ void ospf_opaque_lsa_flush_schedule(struct ospf_lsa *lsa0)
struct ospf_lsa *lsa;
struct ospf *top;
- top = ospf_lookup();
+ top = ospf_lookup_by_vrf_id(lsa0->vrf_id);
if ((oipt = lookup_opaque_info_by_type(lsa0)) == NULL
|| (oipi = lookup_opaque_info_by_id(oipt, lsa0)) == NULL) {
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index 36f9a6757a..47f5ee76d2 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -519,7 +519,7 @@ int ospf_ls_upd_timer(struct thread *thread)
if (listcount(update) > 0)
ospf_ls_upd_send(nbr, update, OSPF_SEND_PACKET_DIRECT);
- list_delete(update);
+ list_delete_and_null(&update);
}
/* Set LS Update retransmission timer. */
@@ -649,6 +649,12 @@ static int ospf_write(struct thread *thread)
#define OSPF_WRITE_IPHL_SHIFT 2
int pkt_count = 0;
+#ifdef GNU_LINUX
+ unsigned char cmsgbuf[64] = {};
+ struct cmsghdr *cm = (struct cmsghdr *)cmsgbuf;
+ struct in_pktinfo *pi;
+#endif
+
ospf->t_write = NULL;
node = listhead(ospf->oi_write_q);
@@ -753,14 +759,28 @@ static int ospf_write(struct thread *thread)
msg.msg_namelen = sizeof(sa_dst);
msg.msg_iov = iov;
msg.msg_iovlen = 2;
+
iov[0].iov_base = (char *)&iph;
iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
iov[1].iov_base = STREAM_PNT(op->s);
iov[1].iov_len = op->length;
-/* Sadly we can not rely on kernels to fragment packets because of either
- * IP_HDRINCL and/or multicast destination being set.
- */
+#ifdef GNU_LINUX
+ msg.msg_control = (caddr_t)cm;
+ cm->cmsg_level = SOL_IP;
+ cm->cmsg_type = IP_PKTINFO;
+ cm->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
+ pi = (struct in_pktinfo *)CMSG_DATA(cm);
+ pi->ipi_ifindex = oi->ifp->ifindex;
+
+ msg.msg_controllen = cm->cmsg_len;
+#endif
+
+ /* Sadly we can not rely on kernels to fragment packets
+ * because of either IP_HDRINCL and/or multicast
+ * destination being set.
+ */
+
#ifdef WANT_OSPF_WRITE_FRAGMENT
if (op->length > maxdatasize)
ospf_write_frags(ospf->fd, op, &iph, &msg, maxdatasize,
@@ -907,9 +927,10 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh,
}
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("Packet %s [Hello:RECV]: Options %s",
+ zlog_debug("Packet %s [Hello:RECV]: Options %s vrf %s",
inet_ntoa(ospfh->router_id),
- ospf_options_dump(hello->options));
+ ospf_options_dump(hello->options),
+ ospf_vrf_id_to_name(oi->ospf->vrf_id));
/* Compare options. */
#define REJECT_IF_TBIT_ON 1 /* XXX */
@@ -1551,15 +1572,16 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh,
/* Verify LSA type. */
if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA) {
OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_BadLSReq);
- list_delete(ls_upd);
+ list_delete_and_null(&ls_upd);
return;
}
/* Search proper LSA in LSDB. */
- find = ospf_lsa_lookup(oi->area, ls_type, ls_id, adv_router);
+ find = ospf_lsa_lookup(oi->ospf, oi->area, ls_type, ls_id,
+ adv_router);
if (find == NULL) {
OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_BadLSReq);
- list_delete(ls_upd);
+ list_delete_and_null(&ls_upd);
return;
}
@@ -1593,9 +1615,9 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh,
ospf_ls_upd_send(nbr, ls_upd,
OSPF_SEND_PACKET_INDIRECT);
- list_delete(ls_upd);
+ list_delete_and_null(&ls_upd);
} else
- list_free(ls_upd);
+ list_delete_and_null(&ls_upd);
}
/* Get the list of LSAs from Link State Update packet.
@@ -1696,6 +1718,7 @@ static struct list *ospf_ls_upd_list_lsa(struct ospf_neighbor *nbr,
/* Create OSPF LSA instance. */
lsa = ospf_lsa_new();
+ lsa->vrf_id = oi->ospf->vrf_id;
/* We may wish to put some error checking if type NSSA comes in
and area not in NSSA mode */
switch (lsah->type) {
@@ -1735,7 +1758,7 @@ static void ospf_upd_list_clean(struct list *lsas)
for (ALL_LIST_ELEMENTS(lsas, node, nnode, lsa))
ospf_lsa_discard(lsa);
- list_delete(lsas);
+ list_delete_and_null(&lsas);
}
/* OSPF Link State Update message read -- RFC2328 Section 13. */
@@ -1784,6 +1807,8 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph,
*/
lsas = ospf_ls_upd_list_lsa(nbr, s, oi, size);
+ if (lsas == NULL)
+ return;
#define DISCARD_LSA(L, N) \
{ \
if (IS_DEBUG_OSPF_EVENT) \
@@ -2134,7 +2159,7 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph,
#undef DISCARD_LSA
assert(listcount(lsas) == 0);
- list_delete(lsas);
+ list_delete_and_null(&lsas);
}
/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
@@ -2173,6 +2198,7 @@ static void ospf_ls_ack(struct ip *iph, struct ospf_header *ospfh,
lsa = ospf_lsa_new();
lsa->data = (struct lsa_header *)STREAM_PNT(s);
+ lsa->vrf_id = oi->ospf->vrf_id;
/* lsah = (struct lsa_header *) STREAM_PNT (s); */
size -= OSPF_LSA_HEADER_SIZE;
@@ -2197,7 +2223,8 @@ static void ospf_ls_ack(struct ip *iph, struct ospf_header *ospfh,
return;
}
-static struct stream *ospf_recv_packet(int fd, struct interface **ifp,
+static struct stream *ospf_recv_packet(struct ospf *ospf, int fd,
+ struct interface **ifp,
struct stream *ibuf)
{
int ret;
@@ -2265,7 +2292,7 @@ static struct stream *ospf_recv_packet(int fd, struct interface **ifp,
ifindex = getsockopt_ifindex(AF_INET, &msgh);
- *ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
+ *ifp = if_lookup_by_index(ifindex, ospf->vrf_id);
if (ret != ip_len) {
zlog_warn(
@@ -2833,7 +2860,7 @@ int ospf_read(struct thread *thread)
struct ip *iph;
struct ospf_header *ospfh;
u_int16_t length;
- struct interface *ifp;
+ struct interface *ifp = NULL;
struct connected *c;
/* first of all get interface pointer. */
@@ -2844,7 +2871,8 @@ int ospf_read(struct thread *thread)
thread_add_read(master, ospf_read, ospf, ospf->fd, &ospf->t_read);
stream_reset(ospf->ibuf);
- if (!(ibuf = ospf_recv_packet(ospf->fd, &ifp, ospf->ibuf)))
+ ibuf = ospf_recv_packet(ospf, ospf->fd, &ifp, ospf->ibuf);
+ if (ibuf == NULL)
return -1;
/* This raw packet is known to be at least as big as its IP header. */
@@ -2861,7 +2889,7 @@ int ospf_read(struct thread *thread)
ifindex
retrieval but do not. */
c = if_lookup_address((void *)&iph->ip_src, AF_INET,
- VRF_DEFAULT);
+ ospf->vrf_id);
if (c)
ifp = c->ifp;
if (ifp == NULL)
@@ -3487,6 +3515,13 @@ static void ospf_hello_send_sub(struct ospf_interface *oi, in_addr_t addr)
op->dst.s_addr = addr;
+ if (IS_DEBUG_OSPF_EVENT) {
+ if (oi->ospf->vrf_id)
+ zlog_debug("%s: Hello Tx interface %s ospf vrf %s id %u",
+ __PRETTY_FUNCTION__, oi->ifp->name,
+ ospf_vrf_id_to_name(oi->ospf->vrf_id),
+ oi->ospf->vrf_id);
+ }
/* Add packet to the top of the interface output queue, so that they
* can't get delayed by things like long queues of LS Update packets
*/
@@ -3739,7 +3774,7 @@ void ospf_ls_upd_send_lsa(struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
listnode_add(update, lsa);
ospf_ls_upd_send(nbr, update, flag);
- list_delete(update);
+ list_delete_and_null(&update);
}
/* Determine size for packet. Must be at least big enough to accomodate next
@@ -3883,8 +3918,7 @@ static int ospf_ls_upd_send_queue_event(struct thread *thread)
/* list might not be empty. */
if (listcount(update) == 0) {
- list_delete(rn->info);
- rn->info = NULL;
+ list_delete_and_null((struct list **)&rn->info);
route_unlock_node(rn);
} else
again = 1;
@@ -4065,21 +4099,19 @@ void ospf_ls_ack_send_delayed(struct ospf_interface *oi)
* punt-to-CPU set on them. This may overload the CPU control path that
* can be avoided if the MAC was known apriori.
*/
-#define OSPF_PING_NBR_STR_MAX (8 + 40 + 20)
+#define OSPF_PING_NBR_STR_MAX (BUFSIZ)
void ospf_proactively_arp(struct ospf_neighbor *nbr)
{
char ping_nbr[OSPF_PING_NBR_STR_MAX];
- char *str_ptr;
int ret;
if (!nbr || !nbr->oi || !nbr->oi->ifp)
return;
- str_ptr = strcpy(ping_nbr, "ping -c 1 -I ");
- str_ptr = strcat(str_ptr, nbr->oi->ifp->name);
- str_ptr = strcat(str_ptr, " ");
- str_ptr = strcat(str_ptr, inet_ntoa(nbr->address.u.prefix4));
- str_ptr = strcat(str_ptr, " > /dev/null 2>&1 &");
+ snprintf(ping_nbr, sizeof(ping_nbr),
+ "ping -c 1 -I %s %s > /dev/null 2>&1 &",
+ nbr->oi->ifp->name, inet_ntoa(nbr->address.u.prefix4));
+
ret = system(ping_nbr);
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("Executed %s %s", ping_nbr,
diff --git a/ospfd/ospf_ri.c b/ospfd/ospf_ri.c
index 13013bf8ca..69f6883186 100644
--- a/ospfd/ospf_ri.c
+++ b/ospfd/ospf_ri.c
@@ -188,11 +188,9 @@ static int ospf_router_info_unregister()
void ospf_router_info_term(void)
{
- list_delete(OspfRI.pce_info.pce_domain);
- list_delete(OspfRI.pce_info.pce_neighbor);
+ list_delete_and_null(&OspfRI.pce_info.pce_domain);
+ list_delete_and_null(&OspfRI.pce_info.pce_neighbor);
- OspfRI.pce_info.pce_domain = NULL;
- OspfRI.pce_info.pce_neighbor = NULL;
OspfRI.enabled = false;
ospf_router_info_unregister();
@@ -427,7 +425,7 @@ static void initialize_params(struct ospf_router_info *ori)
/* If Area address is not null and exist, retrieve corresponding
* structure */
- top = ospf_lookup();
+ top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
zlog_info("RI-> Initialize Router Info for %s scope within area %s",
OspfRI.scope == OSPF_OPAQUE_AREA_LSA ? "Area" : "AS",
inet_ntoa(OspfRI.area_id));
@@ -586,7 +584,7 @@ static struct ospf_lsa *ospf_router_info_lsa_new()
"LSA[Type%d:%s]: Create an Opaque-LSA/ROUTER INFORMATION instance",
lsa_type, inet_ntoa(lsa_id));
- top = ospf_lookup();
+ top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
/* Set opaque-LSA header fields. */
lsa_header_set(s, options, lsa_type, lsa_id, top->router_id);
@@ -615,6 +613,11 @@ static struct ospf_lsa *ospf_router_info_lsa_new()
new->area = OspfRI.area; /* Area must be null if the Opaque type is AS
scope, fulfill otherwise */
+ if (new->area && new->area->ospf)
+ new->vrf_id = new->area->ospf->vrf_id;
+ else
+ new->vrf_id = VRF_DEFAULT;
+
SET_FLAG(new->flags, OSPF_LSA_SELF);
memcpy(new->data, lsah, length);
stream_free(s);
@@ -628,6 +631,7 @@ static int ospf_router_info_lsa_originate1(void *arg)
struct ospf *top;
struct ospf_area *area;
int rc = -1;
+ vrf_id_t vrf_id = VRF_DEFAULT;
/* First check if the area is known if flooding scope is Area */
if (OspfRI.scope == OSPF_OPAQUE_AREA_LSA) {
@@ -638,6 +642,8 @@ static int ospf_router_info_lsa_originate1(void *arg)
return rc;
}
OspfRI.area = area;
+ if (area->ospf)
+ vrf_id = area->ospf->vrf_id;
}
/* Create new Opaque-LSA/ROUTER INFORMATION instance. */
@@ -646,9 +652,16 @@ static int ospf_router_info_lsa_originate1(void *arg)
"ospf_router_info_lsa_originate1: ospf_router_info_lsa_new() ?");
return rc;
}
+ new->vrf_id = vrf_id;
/* Get ospf info */
- top = ospf_lookup();
+ top = ospf_lookup_by_vrf_id(vrf_id);
+ if (top == NULL) {
+ zlog_debug("%s: ospf instance not found for vrf id %u",
+ __PRETTY_FUNCTION__, vrf_id);
+ ospf_lsa_unlock(&new);
+ return rc;
+ }
/* Install this LSA into LSDB. */
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
@@ -751,10 +764,11 @@ static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa)
return NULL;
}
new->data->ls_seqnum = lsa_seqnum_increment(lsa);
+ new->vrf_id = lsa->vrf_id;
/* Install this LSA into LSDB. */
/* Given "lsa" will be freed in the next function. */
- top = ospf_lookup();
+ top = ospf_lookup_by_vrf_id(lsa->vrf_id);
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
zlog_warn("ospf_router_info_lsa_refresh: ospf_lsa_install() ?");
ospf_lsa_unlock(&new);
@@ -800,7 +814,7 @@ static void ospf_router_info_lsa_schedule(enum lsa_opcode opcode)
if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED) && (opcode == REORIGINATE_THIS_LSA))
opcode = REFRESH_THIS_LSA;
- top = ospf_lookup();
+ top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if ((OspfRI.scope == OSPF_OPAQUE_AREA_LSA) && (OspfRI.area == NULL)) {
zlog_warn(
"ospf_router_info_lsa_schedule(): Router Info is Area scope flooding but area is not set");
diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c
index 89ea331b52..cc7c6d2666 100644
--- a/ospfd/ospf_route.c
+++ b/ospfd/ospf_route.c
@@ -54,7 +54,7 @@ struct ospf_route *ospf_route_new()
void ospf_route_free(struct ospf_route * or)
{
if (or->paths)
- list_delete(or->paths);
+ list_delete_and_null(&or->paths);
XFREE(MTYPE_OSPF_ROUTE, or);
}
@@ -83,7 +83,7 @@ void ospf_path_free(struct ospf_path *op)
XFREE(MTYPE_OSPF_PATH, op);
}
-void ospf_route_delete(struct route_table *rt)
+void ospf_route_delete(struct ospf *ospf, struct route_table *rt)
{
struct route_node *rn;
struct ospf_route * or ;
@@ -91,10 +91,11 @@ void ospf_route_delete(struct route_table *rt)
for (rn = route_top(rt); rn; rn = route_next(rn))
if ((or = rn->info) != NULL) {
if (or->type == OSPF_DESTINATION_NETWORK)
- ospf_zebra_delete((struct prefix_ipv4 *)&rn->p,
+ ospf_zebra_delete(ospf,
+ (struct prefix_ipv4 *)&rn->p,
or);
else if (or->type == OSPF_DESTINATION_DISCARD)
- ospf_zebra_delete_discard(
+ ospf_zebra_delete_discard(ospf,
(struct prefix_ipv4 *)&rn->p);
}
}
@@ -191,7 +192,8 @@ int ospf_route_match_same(struct route_table *rt, struct prefix_ipv4 *prefix,
/* delete routes generated from AS-External routes if there is a inter/intra
* area route
*/
-static void ospf_route_delete_same_ext(struct route_table *external_routes,
+static void ospf_route_delete_same_ext(struct ospf *ospf,
+ struct route_table *external_routes,
struct route_table *routes)
{
struct route_node *rn, *ext_rn;
@@ -206,7 +208,8 @@ static void ospf_route_delete_same_ext(struct route_table *external_routes,
if ((ext_rn = route_node_lookup(external_routes,
(struct prefix *)p))) {
if (ext_rn->info) {
- ospf_zebra_delete(p, ext_rn->info);
+ ospf_zebra_delete(ospf, p,
+ ext_rn->info);
ospf_route_free(ext_rn->info);
ext_rn->info = NULL;
}
@@ -217,7 +220,7 @@ static void ospf_route_delete_same_ext(struct route_table *external_routes,
}
/* rt: Old, cmprt: New */
-static void ospf_route_delete_uniq(struct route_table *rt,
+static void ospf_route_delete_uniq(struct ospf *ospf, struct route_table *rt,
struct route_table *cmprt)
{
struct route_node *rn;
@@ -232,7 +235,7 @@ static void ospf_route_delete_uniq(struct route_table *rt,
cmprt,
(struct prefix_ipv4 *)&rn
->p))
- ospf_zebra_delete(
+ ospf_zebra_delete(ospf,
(struct prefix_ipv4
*)&rn->p,
or);
@@ -241,7 +244,7 @@ static void ospf_route_delete_uniq(struct route_table *rt,
cmprt,
(struct prefix_ipv4 *)&rn
->p))
- ospf_zebra_delete_discard(
+ ospf_zebra_delete_discard(ospf,
(struct prefix_ipv4
*)&rn->p);
}
@@ -263,9 +266,9 @@ void ospf_route_install(struct ospf *ospf, struct route_table *rt)
/* Delete old routes. */
if (ospf->old_table)
- ospf_route_delete_uniq(ospf->old_table, rt);
+ ospf_route_delete_uniq(ospf, ospf->old_table, rt);
if (ospf->old_external_route)
- ospf_route_delete_same_ext(ospf->old_external_route, rt);
+ ospf_route_delete_same_ext(ospf, ospf->old_external_route, rt);
/* Install new routes. */
for (rn = route_top(rt); rn; rn = route_next(rn))
@@ -274,14 +277,14 @@ void ospf_route_install(struct ospf *ospf, struct route_table *rt)
if (!ospf_route_match_same(
ospf->old_table,
(struct prefix_ipv4 *)&rn->p, or))
- ospf_zebra_add(
+ ospf_zebra_add(ospf,
(struct prefix_ipv4 *)&rn->p,
or);
} else if (or->type == OSPF_DESTINATION_DISCARD)
if (!ospf_route_match_same(
ospf->old_table,
(struct prefix_ipv4 *)&rn->p, or))
- ospf_zebra_add_discard(
+ ospf_zebra_add_discard(ospf,
(struct prefix_ipv4 *)&rn->p);
}
}
@@ -899,14 +902,15 @@ void ospf_prune_unreachable_routers(struct route_table *rtrs)
zlog_debug("Pruning router node %s",
inet_ntoa(rn->p.u.prefix4));
- list_delete(paths);
+ list_delete_and_null(&paths);
rn->info = NULL;
route_unlock_node(rn);
}
}
}
-int ospf_add_discard_route(struct route_table *rt, struct ospf_area *area,
+int ospf_add_discard_route(struct ospf *ospf, struct route_table *rt,
+ struct ospf_area *area,
struct prefix_ipv4 *p)
{
struct route_node *rn;
@@ -961,12 +965,13 @@ int ospf_add_discard_route(struct route_table *rt, struct ospf_area *area,
new_or->path_type = OSPF_PATH_INTER_AREA;
rn->info = new_or;
- ospf_zebra_add_discard(p);
+ ospf_zebra_add_discard(ospf, p);
return 1;
}
-void ospf_delete_discard_route(struct route_table *rt, struct prefix_ipv4 *p)
+void ospf_delete_discard_route(struct ospf *ospf, struct route_table *rt,
+ struct prefix_ipv4 *p)
{
struct route_node *rn;
struct ospf_route * or ;
@@ -1012,7 +1017,7 @@ void ospf_delete_discard_route(struct route_table *rt, struct prefix_ipv4 *p)
route_unlock_node(rn);
/* remove the discard entry from the rib */
- ospf_zebra_delete_discard(p);
+ ospf_zebra_delete_discard(ospf, p);
return;
}
diff --git a/ospfd/ospf_route.h b/ospfd/ospf_route.h
index 1999379844..76df54fb3f 100644
--- a/ospfd/ospf_route.h
+++ b/ospfd/ospf_route.h
@@ -115,7 +115,7 @@ extern void ospf_path_free(struct ospf_path *);
extern struct ospf_path *ospf_path_lookup(struct list *, struct ospf_path *);
extern struct ospf_route *ospf_route_new(void);
extern void ospf_route_free(struct ospf_route *);
-extern void ospf_route_delete(struct route_table *);
+extern void ospf_route_delete(struct ospf *, struct route_table *);
extern void ospf_route_table_free(struct route_table *);
extern void ospf_route_install(struct ospf *, struct route_table *);
@@ -145,9 +145,9 @@ extern void ospf_route_add(struct route_table *, struct prefix_ipv4 *,
extern void ospf_route_subst_nexthops(struct ospf_route *, struct list *);
extern void ospf_prune_unreachable_networks(struct route_table *);
extern void ospf_prune_unreachable_routers(struct route_table *);
-extern int ospf_add_discard_route(struct route_table *, struct ospf_area *,
- struct prefix_ipv4 *);
-extern void ospf_delete_discard_route(struct route_table *,
+extern int ospf_add_discard_route(struct ospf *, struct route_table *,
+ struct ospf_area *, struct prefix_ipv4 *);
+extern void ospf_delete_discard_route(struct ospf *, struct route_table *,
struct prefix_ipv4 *);
extern int ospf_route_match_same(struct route_table *, struct prefix_ipv4 *,
struct ospf_route *);
diff --git a/ospfd/ospf_routemap.c b/ospfd/ospf_routemap.c
index f47e2b6f1e..b7a47602d0 100644
--- a/ospfd/ospf_routemap.c
+++ b/ospfd/ospf_routemap.c
@@ -45,38 +45,40 @@ static void ospf_route_map_update(const char *name)
{
struct ospf *ospf;
int type;
+ struct listnode *n1 = NULL;
/* If OSPF instatnce does not exist, return right now. */
- ospf = ospf_lookup();
- if (ospf == NULL)
+ if (listcount(om->ospf) == 0)
return;
- /* Update route-map */
- for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
- struct list *red_list;
- struct listnode *node;
- struct ospf_redist *red;
-
- red_list = ospf->redist[type];
- if (!red_list)
- continue;
-
- for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
- if (ROUTEMAP_NAME(red)
- && strcmp(ROUTEMAP_NAME(red), name) == 0) {
- /* Keep old route-map. */
- struct route_map *old = ROUTEMAP(red);
-
- /* Update route-map. */
- ROUTEMAP(red) = route_map_lookup_by_name(
- ROUTEMAP_NAME(red));
-
- /* No update for this distribute type. */
- if (old == NULL && ROUTEMAP(red) == NULL)
- continue;
-
- ospf_distribute_list_update(ospf, type,
- red->instance);
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
+ /* Update route-map */
+ for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
+ struct list *red_list;
+ struct listnode *node;
+ struct ospf_redist *red;
+
+ red_list = ospf->redist[type];
+ if (!red_list)
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
+ if (ROUTEMAP_NAME(red)
+ && strcmp(ROUTEMAP_NAME(red), name) == 0) {
+ /* Keep old route-map. */
+ struct route_map *old = ROUTEMAP(red);
+
+ /* Update route-map. */
+ ROUTEMAP(red) = route_map_lookup_by_name(
+ ROUTEMAP_NAME(red));
+
+ /* No update for this distribute type. */
+ if (old == NULL && ROUTEMAP(red) == NULL)
+ continue;
+
+ ospf_distribute_list_update(ospf, type,
+ red->instance);
+ }
}
}
}
@@ -86,26 +88,24 @@ static void ospf_route_map_event(route_map_event_t event, const char *name)
{
struct ospf *ospf;
int type;
-
- /* If OSPF instatnce does not exist, return right now. */
- ospf = ospf_lookup();
- if (ospf == NULL)
- return;
-
- for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
- struct list *red_list;
- struct listnode *node;
- struct ospf_redist *red;
-
- red_list = ospf->redist[type];
- if (!red_list)
- continue;
-
- for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
- if (ROUTEMAP_NAME(red) && ROUTEMAP(red)
- && !strcmp(ROUTEMAP_NAME(red), name)) {
- ospf_distribute_list_update(ospf, type,
- red->instance);
+ struct listnode *n1 = NULL;
+
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
+ for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
+ struct list *red_list;
+ struct listnode *node;
+ struct ospf_redist *red;
+
+ red_list = ospf->redist[type];
+ if (!red_list)
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
+ if (ROUTEMAP_NAME(red) && ROUTEMAP(red)
+ && !strcmp(ROUTEMAP_NAME(red), name)) {
+ ospf_distribute_list_update(ospf, type,
+ red->instance);
+ }
}
}
}
@@ -285,7 +285,7 @@ static route_map_result_t route_match_interface(void *rule,
if (type == RMAP_OSPF) {
ei = object;
- ifp = if_lookup_by_name((char *)rule, VRF_DEFAULT);
+ ifp = if_lookup_by_name_all_vrf((char *)rule);
if (ifp == NULL || ifp->ifindex != ei->ifindex)
return RMAP_NOMATCH;
diff --git a/ospfd/ospf_snmp.c b/ospfd/ospf_snmp.c
index 6a352380b8..36ae091f99 100644
--- a/ospfd/ospf_snmp.c
+++ b/ospfd/ospf_snmp.c
@@ -532,7 +532,7 @@ static u_char *ospfGeneralGroup(struct variable *v, oid *name, size_t *length,
{
struct ospf *ospf;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
/* Check whether the instance identifier is valid */
if (smux_header_generic(v, name, length, exact, var_len, write_method)
@@ -661,7 +661,7 @@ static struct ospf_area *ospfAreaLookup(struct variable *v, oid name[],
struct ospf_area *area;
int len;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
@@ -765,7 +765,7 @@ static struct ospf_area *ospf_stub_area_lookup_next(struct in_addr *area_id,
struct listnode *node;
struct ospf *ospf;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
@@ -792,7 +792,7 @@ static struct ospf_area *ospfStubAreaLookup(struct variable *v, oid name[],
struct ospf_area *area;
int len;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
@@ -934,7 +934,7 @@ static struct ospf_lsa *ospfLsdbLookup(struct variable *v, oid *name,
oid *offset;
int offsetlen;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
#define OSPF_LSDB_ENTRY_OFFSET (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
@@ -1084,7 +1084,7 @@ static u_char *ospfLsdbEntry(struct variable *v, oid *name, size_t *length,
memset(&router_id, 0, sizeof(struct in_addr));
/* Check OSPF instance. */
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
@@ -1145,7 +1145,7 @@ static struct ospf_area_range *ospfAreaRangeLookup(struct variable *v,
p.family = AF_INET;
p.prefixlen = IPV4_MAX_BITLEN;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (exact) {
/* Area ID + Range Network. */
@@ -1239,7 +1239,7 @@ static u_char *ospfAreaRangeEntry(struct variable *v, oid *name, size_t *length,
return NULL;
/* Check OSPF instance. */
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
@@ -1290,7 +1290,7 @@ static struct ospf_nbr_nbma *ospfHostLookup(struct variable *v, oid *name,
struct ospf_nbr_nbma *nbr_nbma;
struct ospf *ospf;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
@@ -1347,7 +1347,7 @@ static u_char *ospfHostEntry(struct variable *v, oid *name, size_t *length,
return NULL;
/* Check OSPF instance. */
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
@@ -1504,7 +1504,7 @@ static struct ospf_interface *ospf_snmp_if_lookup(struct in_addr *ifaddr,
struct listnode *node;
struct ospf_snmp_if *osif;
struct ospf_interface *oi = NULL;
- struct ospf *ospf = ospf_lookup();
+ struct ospf *ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
for (ALL_LIST_ELEMENTS_RO(ospf_snmp_iflist, node, osif)) {
if (ifaddr->s_addr) {
@@ -1527,7 +1527,7 @@ static struct ospf_interface *ospf_snmp_if_lookup_next(struct in_addr *ifaddr,
{
struct ospf_snmp_if *osif;
struct listnode *nn;
- struct ospf *ospf = ospf_lookup();
+ struct ospf *ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
struct ospf_interface *oi = NULL;
if (ospf == NULL)
@@ -1675,7 +1675,7 @@ static u_char *ospfIfEntry(struct variable *v, oid *name, size_t *length,
memset(&ifaddr, 0, sizeof(struct in_addr));
/* Check OSPF instance. */
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
@@ -1845,7 +1845,7 @@ static u_char *ospfIfMetricEntry(struct variable *v, oid *name, size_t *length,
memset(&ifaddr, 0, sizeof(struct in_addr));
/* Check OSPF instance. */
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
@@ -2125,7 +2125,7 @@ static struct ospf_neighbor *ospf_snmp_nbr_lookup_next(struct in_addr *nbr_addr,
struct ospf_neighbor *min = NULL;
struct ospf *ospf = ospf;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, nn, oi)) {
for (rn = route_top(oi->nbrs); rn; rn = route_next(rn))
@@ -2165,7 +2165,7 @@ static struct ospf_neighbor *ospfNbrLookup(struct variable *v, oid *name,
struct ospf_neighbor *nbr;
struct ospf *ospf;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (!ospf)
return NULL;
@@ -2325,7 +2325,7 @@ static u_char *ospfVirtNbrEntry(struct variable *v, oid *name, size_t *length,
memset(&neighbor, 0, sizeof(struct in_addr));
/* Check OSPF instance. */
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
@@ -2379,7 +2379,7 @@ static struct ospf_lsa *ospfExtLsdbLookup(struct variable *v, oid *name,
struct ospf_lsa *lsa;
struct ospf *ospf;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (exact) {
if (*length != v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
return NULL;
@@ -2476,7 +2476,7 @@ static u_char *ospfExtLsdbEntry(struct variable *v, oid *name, size_t *length,
memset(&router_id, 0, sizeof(struct in_addr));
/* Check OSPF instance. */
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c
index 891088ecc2..65437dba9e 100644
--- a/ospfd/ospf_spf.c
+++ b/ospfd/ospf_spf.c
@@ -210,12 +210,10 @@ static void ospf_vertex_free(void *data)
// assert (listcount (v->parents) == 0);
if (v->children)
- list_delete(v->children);
- v->children = NULL;
+ list_delete_and_null(&v->children);
if (v->parents)
- list_delete(v->parents);
- v->parents = NULL;
+ list_delete_and_null(&v->parents);
v->lsa = NULL;
@@ -781,7 +779,8 @@ static unsigned int ospf_nexthop_calculation(struct ospf_area *area,
* of candidates with any vertices not already on the list. If a lower-cost
* path is found to a vertex already on the candidate list, store the new cost.
*/
-static void ospf_spf_next(struct vertex *v, struct ospf_area *area,
+static void ospf_spf_next(struct vertex *v, struct ospf *ospf,
+ struct ospf_area *area,
struct pqueue *candidate)
{
struct ospf_lsa *w_lsa = NULL;
@@ -841,7 +840,8 @@ static void ospf_spf_next(struct vertex *v, struct ospf_area *area,
inet_ntoa(l->link_id));
}
- w_lsa = ospf_lsa_lookup(area, OSPF_ROUTER_LSA,
+ w_lsa = ospf_lsa_lookup(ospf, area,
+ OSPF_ROUTER_LSA,
l->link_id, l->link_id);
if (w_lsa) {
if (IS_DEBUG_OSPF_EVENT)
@@ -1087,7 +1087,7 @@ void ospf_rtrs_free(struct route_table *rtrs)
for (ALL_LIST_ELEMENTS(or_list, node, nnode, or))
ospf_route_free(or);
- list_delete(or_list);
+ list_delete_and_null(&or_list);
/* Unlock the node. */
rn->info = NULL;
@@ -1159,7 +1159,7 @@ ospf_rtrs_print (struct route_table *rtrs)
#endif
/* Calculating the shortest-path tree for an area. */
-static void ospf_spf_calculate(struct ospf_area *area,
+static void ospf_spf_calculate(struct ospf *ospf, struct ospf_area *area,
struct route_table *new_table,
struct route_table *new_rtrs)
{
@@ -1209,7 +1209,7 @@ static void ospf_spf_calculate(struct ospf_area *area,
for (;;) {
/* RFC2328 16.1. (2). */
- ospf_spf_next(v, area, candidate);
+ ospf_spf_next(v, ospf, area, candidate);
/* RFC2328 16.1. (3). */
/* If at this step the candidate list is empty, the shortest-
@@ -1307,13 +1307,13 @@ static int ospf_spf_calculate_timer(struct thread *thread)
if (ospf->backbone && ospf->backbone == area)
continue;
- ospf_spf_calculate(area, new_table, new_rtrs);
+ ospf_spf_calculate(ospf, area, new_table, new_rtrs);
areas_processed++;
}
/* SPF for backbone, if required */
if (ospf->backbone) {
- ospf_spf_calculate(ospf->backbone, new_table, new_rtrs);
+ ospf_spf_calculate(ospf, ospf->backbone, new_table, new_rtrs);
areas_processed++;
}
@@ -1339,6 +1339,12 @@ static int ospf_spf_calculate_timer(struct thread *thread)
ospf_ase_calculate_timer_add(ospf);
+
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: ospf install new route, vrf %s id %u new_table count %lu",
+ __PRETTY_FUNCTION__,
+ ospf_vrf_id_to_name(ospf->vrf_id),
+ ospf->vrf_id, new_table->count);
/* Update routing table. */
monotime(&start_time);
ospf_route_install(ospf, new_table);
diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c
index 5517008909..392df5fb40 100644
--- a/ospfd/ospf_te.c
+++ b/ospfd/ospf_te.c
@@ -166,8 +166,7 @@ static int ospf_mpls_te_unregister()
void ospf_mpls_te_term(void)
{
- list_delete(OspfMplsTE.iflist);
- OspfMplsTE.iflist = NULL;
+ list_delete_and_null(&OspfMplsTE.iflist);
ospf_delete_opaque_functab(OSPF_OPAQUE_AREA_LSA,
OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA);
@@ -728,7 +727,7 @@ static void update_linkparams(struct mpls_te_link *lp)
else {
lp->flags = INTER_AS | FLOOD_AREA;
lp->area = ospf_area_lookup_by_area_id(
- ospf_lookup(),
+ ospf_lookup_by_vrf_id(VRF_DEFAULT),
OspfMplsTE.interas_areaid);
}
}
@@ -1127,7 +1126,8 @@ static void ospf_mpls_te_lsa_body_set(struct stream *s, struct mpls_te_link *lp)
}
/* Create new opaque-LSA. */
-static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf_area *area,
+static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf *ospf,
+ struct ospf_area *area,
struct mpls_te_link *lp)
{
struct stream *s;
@@ -1167,9 +1167,12 @@ static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf_area *area,
tmp = SET_OPAQUE_LSID(OPAQUE_TYPE_INTER_AS_LSA, lp->instance);
lsa_id.s_addr = htonl(tmp);
- struct ospf *top = ospf_lookup();
+ if (!ospf) {
+ stream_free(s);
+ return NULL;
+ }
- lsa_header_set(s, options, lsa_type, lsa_id, top->router_id);
+ lsa_header_set(s, options, lsa_type, lsa_id, ospf->router_id);
} else {
options |= LSA_OPTIONS_GET(area); /* Get area default option */
options |= LSA_OPTIONS_NSSA_GET(area);
@@ -1207,6 +1210,9 @@ static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf_area *area,
return new;
}
+ new->vrf_id = ospf->vrf_id;
+ if (area && area->ospf)
+ new->vrf_id = area->ospf->vrf_id;
new->area = area;
SET_FLAG(new->flags, OSPF_LSA_SELF);
memcpy(new->data, lsah, length);
@@ -1218,11 +1224,12 @@ static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf_area *area,
static int ospf_mpls_te_lsa_originate1(struct ospf_area *area,
struct mpls_te_link *lp)
{
- struct ospf_lsa *new;
+ struct ospf_lsa *new = NULL;
int rc = -1;
/* Create new Opaque-LSA/MPLS-TE instance. */
- if ((new = ospf_mpls_te_lsa_new(area, lp)) == NULL) {
+ new = ospf_mpls_te_lsa_new(area->ospf, area, lp);
+ if (new == NULL) {
zlog_warn(
"ospf_mpls_te_lsa_originate1: ospf_mpls_te_lsa_new() ?");
return rc;
@@ -1321,11 +1328,13 @@ static int ospf_mpls_te_lsa_originate2(struct ospf *top,
int rc = -1;
/* Create new Opaque-LSA/Inter-AS instance. */
- if ((new = ospf_mpls_te_lsa_new(NULL, lp)) == NULL) {
+ new = ospf_mpls_te_lsa_new(top, NULL, lp);
+ if (new == NULL) {
zlog_warn(
"ospf_mpls_te_lsa_originate2: ospf_router_info_lsa_new() ?");
return rc;
}
+ new->vrf_id = top->vrf_id;
/* Install this LSA into LSDB. */
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
@@ -1451,9 +1460,10 @@ static struct ospf_lsa *ospf_mpls_te_lsa_refresh(struct ospf_lsa *lsa)
ospf_opaque_lsa_flush_schedule(lsa);
return NULL;
}
-
+ top = ospf_lookup_by_vrf_id(lsa->vrf_id);
/* Create new Opaque-LSA/MPLS-TE instance. */
- if ((new = ospf_mpls_te_lsa_new(area, lp)) == NULL) {
+ new = ospf_mpls_te_lsa_new(top, area, lp);
+ if (new == NULL) {
zlog_warn("ospf_mpls_te_lsa_refresh: ospf_mpls_te_lsa_new() ?");
return NULL;
}
@@ -1465,8 +1475,6 @@ static struct ospf_lsa *ospf_mpls_te_lsa_refresh(struct ospf_lsa *lsa)
* ospf_lookup() to get ospf instance */
if (area)
top = area->ospf;
- else
- top = ospf_lookup();
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
zlog_warn("ospf_mpls_te_lsa_refresh: ospf_lsa_install() ?");
@@ -1500,7 +1508,7 @@ void ospf_mpls_te_lsa_schedule(struct mpls_te_link *lp, enum lsa_opcode opcode)
memset(&lsa, 0, sizeof(lsa));
memset(&lsah, 0, sizeof(lsah));
- top = ospf_lookup();
+ top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
/* Check if the pseudo link is ready to flood */
if (!(CHECK_FLAG(lp->flags, LPFLG_LSA_ACTIVE))
@@ -2517,29 +2525,64 @@ static void show_mpls_te_link_sub(struct vty *vty, struct interface *ifp)
DEFUN (show_ip_ospf_mpls_te_link,
show_ip_ospf_mpls_te_link_cmd,
- "show ip ospf mpls-te interface [INTERFACE]",
+ "show ip ospf [vrf <NAME|all>] mpls-te interface [INTERFACE]",
SHOW_STR
IP_STR
OSPF_STR
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
"MPLS-TE information\n"
"Interface information\n"
"Interface name\n")
{
int idx_interface = 5;
struct interface *ifp;
- struct listnode *node, *nnode;
-
+ struct listnode *node, *nnode, *n1;
+ char *vrf_name = NULL;
+ bool all_vrf;
+ int inst = 0;
+ int idx_vrf = 0;
+ struct ospf *ospf = NULL;
+
+ if (argv_find(argv, argc, "vrf", &idx_vrf)) {
+ vrf_name = argv[idx_vrf + 1]->arg;
+ all_vrf = strmatch(vrf_name, "all");
+ }
+
+ /* vrf input is provided could be all or specific vrf*/
+ if (vrf_name) {
+ if (all_vrf) {
+ 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);
+ }
+ return CMD_SUCCESS;
+ }
+ ospf = ospf_lookup_by_inst_name (inst, vrf_name);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ for (ALL_LIST_ELEMENTS(vrf_iflist(ospf->vrf_id), node,
+ nnode, ifp))
+ show_mpls_te_link_sub(vty, ifp);
+ return CMD_SUCCESS;
+ }
/* Show All Interfaces. */
if (argc == 5) {
- for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), node, nnode,
- ifp))
- show_mpls_te_link_sub(vty, 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 {
- if ((ifp = if_lookup_by_name(argv[idx_interface]->arg,
- VRF_DEFAULT))
- == NULL)
+ ifp = if_lookup_by_name_all_vrf(argv[idx_interface]->arg);
+ if (ifp == NULL)
vty_out(vty, "No such interface name\n");
else
show_mpls_te_link_sub(vty, ifp);
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index 4cbd4b4a99..7b7a53baa9 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -126,25 +126,82 @@ 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;
+}
+
+static void ospf_show_vrf_name(struct ospf *ospf, struct vty *vty,
+ json_object *json)
+{
+ if (ospf->name) {
+ if (json)
+ json_object_string_add(json, "vrfName", ospf->name);
+ else
+ vty_out(vty, "VRF Name: %s\n", ospf->name);
+ }
+
+}
+
+#ifndef VTYSH_EXTRACT_PL
+#include "ospf_vty_clippy.c"
+#endif
+
DEFUN_NOSH (router_ospf,
router_ospf_cmd,
- "router ospf [(1-65535)]",
+ "router ospf [{(1-65535)|vrf NAME}]",
"Enable a routing process\n"
"Start OSPF configuration\n"
- "Instance ID\n")
+ "Instance ID\n"
+ VRF_CMD_HELP_STR)
{
- struct ospf *ospf;
- u_short instance = 0;
+ struct ospf *ospf = NULL;
int ret = CMD_SUCCESS;
+ u_short instance = 0;
- ospf = ospf_lookup();
- 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. */
@@ -152,10 +209,12 @@ DEFUN_NOSH (router_ospf,
VTY_PUSH_CONTEXT_NULL(OSPF_NODE);
ret = CMD_NOT_MY_INSTANCE;
} else {
+ if (ospf->vrf_id != VRF_UNKNOWN)
+ ospf->oi_running = 1;
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("Config command 'router ospf %d' received",
- instance);
- ospf->oi_running = 1;
+ zlog_debug("Config command 'router ospf %d' received, vrf %s id %d oi_running %u",
+ instance, ospf->name ? ospf->name : "NIL",
+ ospf->vrf_id, ospf->oi_running);
VTY_PUSH_CONTEXT(OSPF_NODE, ospf);
ospf_router_id_update(ospf);
}
@@ -165,29 +224,30 @@ DEFUN_NOSH (router_ospf,
DEFUN (no_router_ospf,
no_router_ospf_cmd,
- "no router ospf [(1-65535)]",
+ "no router ospf [{(1-65535)|vrf NAME}]",
NO_STR
"Enable a routing process\n"
"Start OSPF configuration\n"
- "Instance ID\n")
+ "Instance ID\n"
+ VRF_CMD_HELP_STR)
{
struct ospf *ospf;
u_short instance = 0;
- if (argc > 3)
- instance = strtoul(argv[3]->arg, NULL, 10);
-
- ospf = ospf_lookup_instance(instance);
- if (ospf == NULL)
- return CMD_NOT_MY_INSTANCE;
-
+ 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"
@@ -195,17 +255,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;
@@ -256,7 +308,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
@@ -268,6 +320,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))
@@ -292,7 +351,7 @@ static void ospf_passive_interface_default(struct ospf *ospf, u_char newval)
ospf->passive_interface_default = newval;
- for (ALL_LIST_ELEMENTS_RO(om->iflist, ln, ifp)) {
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), ln, ifp)) {
if (ifp && OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp),
passive_interface))
UNSET_IF_PARAM(IF_DEF_PARAMS(ifp), passive_interface);
@@ -366,7 +425,12 @@ DEFUN (ospf_passive_interface,
return CMD_SUCCESS;
}
- ifp = if_get_by_name(argv[1]->arg, VRF_DEFAULT);
+ ifp = if_get_by_name(argv[1]->arg, ospf->vrf_id);
+ if (ifp == NULL) {
+ vty_out(vty, "interface %s not found.\n",
+ (char *)argv[1]->arg);
+ return CMD_WARNING;
+ }
params = IF_DEF_PARAMS(ifp);
@@ -433,7 +497,12 @@ DEFUN (no_ospf_passive_interface,
return CMD_SUCCESS;
}
- ifp = if_get_by_name(argv[2]->arg, VRF_DEFAULT);
+ ifp = if_get_by_name(argv[2]->arg, ospf->vrf_id);
+ if (ifp == NULL) {
+ vty_out(vty, "interface %s not found.\n",
+ (char *)argv[1]->arg);
+ return CMD_WARNING;
+ }
params = IF_DEF_PARAMS(ifp);
@@ -963,26 +1032,23 @@ static int ospf_vl_set(struct ospf *ospf, struct ospf_vl_config_data *vl_config)
#define VLINK_HELPSTR_AUTH_SIMPLE \
"Authentication password (key)\n" \
- "The OSPF password (key)"
+ "The OSPF password (key)\n"
#define VLINK_HELPSTR_AUTH_MD5 \
"Message digest authentication password (key)\n" \
- "dummy string \n" \
"Key ID\n" \
"Use MD5 algorithm\n" \
- "The OSPF password (key)"
+ "The OSPF password (key)\n"
DEFUN (ospf_area_vlink,
ospf_area_vlink_cmd,
- "area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D [authentication] [<message-digest|null>] [<message-digest-key (1-255) md5 KEY|authentication-key AUTH_KEY>]",
+ "area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D [authentication [<message-digest|null>]] [<message-digest-key (1-255) md5 KEY|authentication-key AUTH_KEY>]",
VLINK_HELPSTR_IPADDR
- "Enable authentication on this virtual link\n" \
- "Use null authentication\n" \
+ "Enable authentication on this virtual link\n"
"Use message-digest authentication\n"
- "Message digest authentication password (key)\n" \
- "Key ID\n" \
- "Use MD5 algorithm\n" \
- "The OSPF password (key)")
+ "Use null authentication\n"
+ VLINK_HELPSTR_AUTH_MD5
+ VLINK_HELPSTR_AUTH_SIMPLE)
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
int idx_ipv4_number = 1;
@@ -990,8 +1056,8 @@ DEFUN (ospf_area_vlink,
struct ospf_vl_config_data vl_config;
char auth_key[OSPF_AUTH_SIMPLE_SIZE + 1];
char md5_key[OSPF_AUTH_MD5_SIZE + 1];
- int i;
int ret;
+ int idx = 0;
ospf_vl_config_data_init(&vl_config, vty);
@@ -1015,80 +1081,36 @@ DEFUN (ospf_area_vlink,
return ospf_vl_set(ospf, &vl_config);
}
- /* Deal with other parameters */
- for (i = 5; i < argc; i++) {
-
- /* vty_out (vty, "argv[%d]->arg - %s\n", i, argv[i]->text); */
-
- switch (argv[i]->arg[0]) {
-
- case 'a':
- if (i > 5
- || strncmp(argv[i]->arg, "authentication-", 15)
- == 0) {
- /* authentication-key - this option can occur
- anywhere on
- command line. At start
- of command line
- must check for
- authentication option. */
- memset(auth_key, 0, OSPF_AUTH_SIMPLE_SIZE + 1);
- strncpy(auth_key, argv[i + 1]->text,
- OSPF_AUTH_SIMPLE_SIZE);
- vl_config.auth_key = auth_key;
- i++;
- } else if (strncmp(argv[i]->arg, "authentication", 14)
- == 0) {
- /* authentication - this option can only occur
- at start
- of command line */
- vl_config.auth_type = OSPF_AUTH_SIMPLE;
- if ((i + 1) < argc) {
- if (strncmp(argv[i + 1]->arg, "n", 1)
- == 0) {
- /* "authentication null" */
- vl_config.auth_type =
- OSPF_AUTH_NULL;
- i++;
- } else if (
- strncmp(argv[i + 1]->arg, "m",
- 1)
- == 0
- && !strmatch(
- argv[i + 1]->text,
- "message-digest-")) {
- /* "authentication
- * message-digest" */
- vl_config.auth_type =
- OSPF_AUTH_CRYPTOGRAPHIC;
- i++;
- }
- }
- }
- break;
+ if (argv_find(argv, argc, "authentication", &idx)) {
+ /* authentication - this option can only occur
+ at start of command line */
+ vl_config.auth_type = OSPF_AUTH_SIMPLE;
+ }
- case 'm':
- /* message-digest-key */
- i++;
- if (i < argc) {
- vl_config.crypto_key_id =
- strtol(argv[i]->arg, NULL, 10);
- if (vl_config.crypto_key_id < 0)
- return CMD_WARNING_CONFIG_FAILED;
- i++;
- if (i < argc) {
- memset(md5_key, 0,
- OSPF_AUTH_MD5_SIZE + 1);
- strncpy(md5_key, argv[i]->arg,
- OSPF_AUTH_MD5_SIZE);
- vl_config.md5_key = md5_key;
- }
- } else
- vl_config.md5_key = NULL;
- break;
- }
+ if (argv_find(argv, argc, "message-digest", &idx)) {
+ /* authentication message-digest */
+ vl_config.auth_type = OSPF_AUTH_CRYPTOGRAPHIC;
+ } else if (argv_find(argv, argc, "null", &idx)) {
+ /* "authentication null" */
+ vl_config.auth_type = OSPF_AUTH_NULL;
}
+ if (argv_find(argv, argc, "message-digest-key", &idx)) {
+ vl_config.md5_key = NULL;
+ vl_config.crypto_key_id = strtol(argv[idx + 1]->arg, NULL, 10);
+ if (vl_config.crypto_key_id < 0)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ memset(md5_key, 0, OSPF_AUTH_MD5_SIZE + 1);
+ strncpy(md5_key, argv[idx + 3]->arg, OSPF_AUTH_MD5_SIZE);
+ vl_config.md5_key = md5_key;
+ }
+
+ if (argv_find(argv, argc, "authentication-key", &idx)) {
+ memset(auth_key, 0, OSPF_AUTH_SIMPLE_SIZE + 1);
+ strncpy(auth_key, argv[idx + 1]->arg, OSPF_AUTH_SIMPLE_SIZE);
+ vl_config.auth_key = auth_key;
+ }
/* Action configuration */
@@ -1097,16 +1119,14 @@ DEFUN (ospf_area_vlink,
DEFUN (no_ospf_area_vlink,
no_ospf_area_vlink_cmd,
- "no area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D [authentication] [<message-digest|null>] [<message-digest-key (1-255) md5 KEY|authentication-key AUTH_KEY>]",
+ "no area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D [authentication [<message-digest|null>]] [<message-digest-key (1-255) md5 KEY|authentication-key AUTH_KEY>]",
NO_STR
VLINK_HELPSTR_IPADDR
"Enable authentication on this virtual link\n" \
+ "Use message-digest authentication\n" \
"Use null authentication\n" \
- "Use message-digest authentication\n"
- "Message digest authentication password (key)\n" \
- "Key ID\n" \
- "Use MD5 algorithm\n" \
- "The OSPF password (key)")
+ VLINK_HELPSTR_AUTH_MD5
+ VLINK_HELPSTR_AUTH_SIMPLE)
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
int idx_ipv4_number = 2;
@@ -1115,7 +1135,7 @@ DEFUN (no_ospf_area_vlink,
struct ospf_vl_config_data vl_config;
struct ospf_vl_data *vl_data = NULL;
char auth_key[OSPF_AUTH_SIMPLE_SIZE + 1];
- int i;
+ int idx = 0;
int ret, format;
ospf_vl_config_data_init(&vl_config, vty);
@@ -1151,50 +1171,26 @@ DEFUN (no_ospf_area_vlink,
}
/* If we are down here, we are reseting parameters */
-
/* Deal with other parameters */
- for (i = 6; i < argc; i++) {
- /* vty_out (vty, "argv[%d] - %s\n", i, argv[i]); */
-
- switch (argv[i]->arg[0]) {
-
- case 'a':
- if (i > 2
- || strncmp(argv[i]->text, "authentication-", 15)
- == 0) {
- /* authentication-key - this option can occur
- anywhere on
- command line. At start
- of command line
- must check for
- authentication option. */
- memset(auth_key, 0, OSPF_AUTH_SIMPLE_SIZE + 1);
- vl_config.auth_key = auth_key;
- } else if (strncmp(argv[i]->text, "authentication", 14)
- == 0) {
- /* authentication - this option can only occur
- at start
- of command line */
- vl_config.auth_type = OSPF_AUTH_NOTSET;
- }
- break;
- case 'm':
- /* message-digest-key */
- /* Delete one key */
- i++;
- if (i < argc) {
- vl_config.crypto_key_id =
- strtol(argv[i]->arg, NULL, 10);
- if (vl_config.crypto_key_id < 0)
- return CMD_WARNING_CONFIG_FAILED;
- vl_config.md5_key = NULL;
- } else
- return CMD_WARNING_CONFIG_FAILED;
- break;
- }
+ if (argv_find(argv, argc, "authentication", &idx)) {
+ /* authentication - this option can only occur
+ at start of command line */
+ vl_config.auth_type = OSPF_AUTH_NOTSET;
}
+ if (argv_find(argv, argc, "message-digest-key", &idx)) {
+ vl_config.md5_key = NULL;
+ vl_config.crypto_key_id = strtol(argv[idx + 1]->arg, NULL, 10);
+ if (vl_config.crypto_key_id < 0)
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ if (argv_find(argv, argc, "authentication-key", &idx)) {
+ /* Reset authentication-key to 0 */
+ memset(auth_key, 0, OSPF_AUTH_SIMPLE_SIZE + 1);
+ vl_config.auth_key = auth_key;
+ }
/* Action configuration */
@@ -2489,7 +2485,7 @@ DEFUN (ospf_auto_cost_reference_bandwidth,
return CMD_SUCCESS;
ospf->ref_bandwidth = refbw;
- for (ALL_LIST_ELEMENTS_RO(om->iflist, node, ifp))
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), node, ifp))
ospf_if_recalculate_output_cost(ifp);
return CMD_SUCCESS;
@@ -2515,7 +2511,7 @@ DEFUN (no_ospf_auto_cost_reference_bandwidth,
vty_out(vty,
" Please ensure reference bandwidth is consistent across all routers\n");
- for (ALL_LIST_ELEMENTS(om->iflist, node, nnode, ifp))
+ for (ALL_LIST_ELEMENTS(vrf_iflist(ospf->vrf_id), node, nnode, ifp))
ospf_if_recalculate_output_cost(ifp);
return CMD_SUCCESS;
@@ -2906,6 +2902,8 @@ static int show_ip_ospf_common(struct vty *vty, struct ospf *ospf,
}
}
+ ospf_show_vrf_name(ospf, vty, json);
+
/* Show Router ID. */
if (use_json) {
json_object_string_add(json, "routerId",
@@ -3175,19 +3173,52 @@ static int show_ip_ospf_common(struct vty *vty, struct ospf *ospf,
DEFUN (show_ip_ospf,
show_ip_ospf_cmd,
- "show ip ospf [json]",
+ "show ip ospf [vrf <NAME|all>] [json]",
SHOW_STR
IP_STR
"OSPF information\n"
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
JSON_STR)
{
struct ospf *ospf;
u_char uj = use_json(argc, argv);
+ struct listnode *node = NULL;
+ char *vrf_name = NULL;
+ bool all_vrf = FALSE;
+ int ret = CMD_SUCCESS;
+ int inst = 0;
+ int idx_vrf = 0;
- if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
+ if (listcount(om->ospf) == 0)
return CMD_SUCCESS;
- return (show_ip_ospf_common(vty, ospf, uj));
+ 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) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ ret = show_ip_ospf_common(vty, ospf, uj);
+ }
+ return ret;
+ }
+ ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+ if ((ospf == NULL) || !ospf->oi_running)
+ return CMD_SUCCESS;
+ } else {
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ /* Display default ospf (instance 0) info */
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ }
+
+ if (ospf)
+ show_ip_ospf_common(vty, ospf, uj);
+
+ return ret;
}
DEFUN (show_ip_ospf_instance,
@@ -3556,7 +3587,8 @@ static int show_ip_ospf_interface_common(struct vty *vty, struct ospf *ospf,
if (argc == iface_argv) {
/* Show All Interfaces.*/
- for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id),
+ node, ifp)) {
if (ospf_oi_count(ifp)) {
if (use_json)
json_interface_sub =
@@ -3575,7 +3607,7 @@ static int show_ip_ospf_interface_common(struct vty *vty, struct ospf *ospf,
} else {
/* Interface name is specified. */
if ((ifp = if_lookup_by_name(argv[iface_argv]->arg,
- VRF_DEFAULT))
+ ospf->vrf_id))
== NULL) {
if (use_json)
json_object_boolean_true_add(json,
@@ -3607,24 +3639,59 @@ 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 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)
{
struct ospf *ospf;
u_char uj = use_json(argc, argv);
+ struct listnode *node = NULL;
+ char *vrf_name = NULL;
+ bool all_vrf = FALSE;
+ int ret = CMD_SUCCESS;
+ int inst = 0;
+ int idx_vrf = 0;
- if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
- return CMD_SUCCESS;
+ OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
if (uj)
argc--;
- return show_ip_ospf_interface_common(vty, ospf, argc, argv, 4, uj);
+ /* vrf input is provided could be all or specific vrf*/
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ ret = show_ip_ospf_interface_common(vty,
+ ospf, argc,
+ argv, 6,
+ uj);
+ }
+ return ret;
+ }
+ ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ ret = show_ip_ospf_interface_common(vty, ospf,
+ argc, argv, 6, uj);
+
+ } else {
+ /* Display default ospf (instance 0) info */
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ ret = show_ip_ospf_interface_common(vty, ospf,
+ argc, argv, 4, uj);
+ }
+
+ return ret;
}
DEFUN (show_ip_ospf_instance_interface,
@@ -3795,8 +3862,6 @@ static int show_ip_ospf_neighbor_common(struct vty *vty, struct ospf *ospf,
if (use_json)
json = json_object_new_object();
- else
- show_ip_ospf_neighbour_header(vty);
if (ospf->instance) {
if (use_json)
@@ -3806,6 +3871,8 @@ static int show_ip_ospf_neighbor_common(struct vty *vty, struct ospf *ospf,
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
}
+ ospf_show_vrf_name(ospf, vty, json);
+
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi))
show_ip_ospf_neighbor_sub(vty, oi, json, use_json);
@@ -3821,20 +3888,54 @@ static int show_ip_ospf_neighbor_common(struct vty *vty, struct ospf *ospf,
DEFUN (show_ip_ospf_neighbor,
show_ip_ospf_neighbor_cmd,
- "show ip ospf neighbor [json]",
+ "show ip ospf [vrf <NAME|all>] neighbor [json]",
SHOW_STR
IP_STR
"OSPF information\n"
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
"Neighbor list\n"
JSON_STR)
{
struct ospf *ospf;
u_char uj = use_json(argc, argv);
+ struct listnode *node = NULL;
+ char *vrf_name = NULL;
+ bool all_vrf = FALSE;
+ int ret = CMD_SUCCESS;
+ int inst = 0;
+ int idx_vrf = 0;
- if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
- return CMD_SUCCESS;
+ OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
- return show_ip_ospf_neighbor_common(vty, ospf, uj);
+ if (!uj)
+ show_ip_ospf_neighbour_header(vty);
+
+ /* vrf input is provided could be all or specific vrf*/
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ ret = show_ip_ospf_neighbor_common(vty, ospf,
+ uj);
+ }
+ return ret;
+ }
+ ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ } else {
+ /* Display default ospf (instance 0) info */
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ }
+
+ if (ospf)
+ ret = show_ip_ospf_neighbor_common(vty, ospf, uj);
+
+ return ret;
}
@@ -3861,6 +3962,9 @@ DEFUN (show_ip_ospf_instance_neighbor,
if (!ospf->oi_running)
return CMD_SUCCESS;
+ if (!uj)
+ show_ip_ospf_neighbour_header(vty);
+
return show_ip_ospf_neighbor_common(vty, ospf, uj);
}
@@ -3875,8 +3979,7 @@ static int show_ip_ospf_neighbor_all_common(struct vty *vty, struct ospf *ospf,
if (use_json) {
json = json_object_new_object();
json_neighbor_sub = json_object_new_object();
- } else
- show_ip_ospf_neighbour_header(vty);
+ }
if (ospf->instance) {
if (use_json)
@@ -3886,6 +3989,22 @@ static int show_ip_ospf_neighbor_all_common(struct vty *vty, struct ospf *ospf,
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
}
+ if (ospf->name) {
+ if (use_json) {
+ json_object_int_add(json, "vrfId",
+ (ospf->vrf_id == VRF_UNKNOWN)
+ ? -1 : ospf->vrf_id);
+ json_object_string_add(json, "vrfName",
+ (ospf->vrf_id == VRF_DEFAULT)
+ ? "Default" : ospf->name);
+ } else {
+ vty_out(vty, "\nOSPF vrf: %s\n\n",
+ ospf->vrf_id == VRF_DEFAULT
+ ? "Default" : ospf->name);
+ }
+ }
+
+
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
struct listnode *nbr_node;
struct ospf_nbr_nbma *nbr_nbma;
@@ -3944,21 +4063,56 @@ static int show_ip_ospf_neighbor_all_common(struct vty *vty, struct ospf *ospf,
DEFUN (show_ip_ospf_neighbor_all,
show_ip_ospf_neighbor_all_cmd,
- "show ip ospf neighbor all [json]",
+ "show ip ospf [vrf <NAME|all>] neighbor all [json]",
SHOW_STR
IP_STR
"OSPF information\n"
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
"Neighbor list\n"
"include down status neighbor\n"
JSON_STR)
{
struct ospf *ospf;
u_char uj = use_json(argc, argv);
+ struct listnode *node = NULL;
+ char *vrf_name = NULL;
+ bool all_vrf = FALSE;
+ int ret = CMD_SUCCESS;
+ int inst = 0;
+ int idx_vrf = 0;
- if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
- return CMD_SUCCESS;
+ OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
- return show_ip_ospf_neighbor_all_common(vty, ospf, uj);
+ if (!uj)
+ show_ip_ospf_neighbour_header(vty);
+
+ /* vrf input is provided could be all or specific vrf*/
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ ret = show_ip_ospf_neighbor_all_common(vty,
+ ospf,
+ uj);
+ }
+ return ret;
+ }
+ ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ } else {
+ /* Display default ospf (instance 0) info */
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ }
+
+ if (ospf)
+ ret = show_ip_ospf_neighbor_all_common(vty, ospf, uj);
+
+ return ret;
}
DEFUN (show_ip_ospf_instance_neighbor_all,
@@ -3999,8 +4153,6 @@ static int show_ip_ospf_neighbor_int_common(struct vty *vty, struct ospf *ospf,
if (use_json)
json = json_object_new_object();
- else
- show_ip_ospf_neighbour_header(vty);
if (ospf->instance) {
if (use_json)
@@ -4010,7 +4162,10 @@ static int show_ip_ospf_neighbor_int_common(struct vty *vty, struct ospf *ospf,
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
}
- ifp = if_lookup_by_name(argv[arg_base]->arg, VRF_DEFAULT);
+ ospf_show_vrf_name(ospf, vty, json);
+
+ /*ifp = if_lookup_by_name(argv[arg_base]->arg, ospf->vrf_id);*/
+ ifp = if_lookup_by_name_all_vrf(argv[arg_base]->arg);
if (!ifp) {
if (use_json)
json_object_boolean_true_add(json, "noSuchIface");
@@ -4051,11 +4206,24 @@ DEFUN (show_ip_ospf_neighbor_int,
struct ospf *ospf;
int idx_ifname = 4;
u_char uj = use_json(argc, argv);
+ struct listnode *node = NULL;
+ int ret = CMD_SUCCESS;
+ struct interface *ifp = NULL;
- if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
- return CMD_SUCCESS;
+ if (!uj)
+ show_ip_ospf_neighbour_header(vty);
- return show_ip_ospf_neighbor_int_common(vty, ospf, idx_ifname, argv, uj);
+ ifp = if_lookup_by_name_all_vrf(argv[idx_ifname]->arg);
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ if (!ifp || ifp->vrf_id != ospf->vrf_id)
+ continue;
+ ret = show_ip_ospf_neighbor_int_common(vty, ospf,
+ idx_ifname, argv, uj);
+ }
+
+ return ret;
}
DEFUN (show_ip_ospf_instance_neighbor_int,
@@ -4075,6 +4243,9 @@ DEFUN (show_ip_ospf_instance_neighbor_int,
u_short instance = 0;
u_char uj = use_json(argc, argv);
+ if (!uj)
+ show_ip_ospf_neighbour_header(vty);
+
instance = strtoul(argv[idx_number]->arg, NULL, 10);
ospf = ospf_lookup_instance(instance);
if (ospf == NULL)
@@ -4083,6 +4254,9 @@ DEFUN (show_ip_ospf_instance_neighbor_int,
if (!ospf->oi_running)
return CMD_SUCCESS;
+ if (!uj)
+ show_ip_ospf_neighbour_header(vty);
+
return show_ip_ospf_neighbor_int_common(vty, ospf, idx_ifname, argv, uj);
}
@@ -4402,6 +4576,8 @@ static int show_ip_ospf_neighbor_id_common(struct vty *vty, struct ospf *ospf,
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
}
+ ospf_show_vrf_name(ospf, vty, json);
+
ret = inet_aton(argv[arg_base]->arg, &router_id);
if (!ret) {
if (!use_json)
@@ -4441,13 +4617,17 @@ DEFUN (show_ip_ospf_neighbor_id,
JSON_STR)
{
struct ospf *ospf;
- int idx_router_id = 4;
u_char uj = use_json(argc, argv);
+ struct listnode *node = NULL;
+ int ret = CMD_SUCCESS;
- if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
- return CMD_SUCCESS;
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ ret = show_ip_ospf_neighbor_id_common(vty, ospf, 0, argv, uj);
+ }
- return show_ip_ospf_neighbor_id_common(vty, ospf, idx_router_id, argv, uj);
+ return ret;
}
DEFUN (show_ip_ospf_instance_neighbor_id,
@@ -4497,6 +4677,8 @@ static int show_ip_ospf_neighbor_detail_common(struct vty *vty,
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
}
+ ospf_show_vrf_name(ospf, vty, json);
+
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
struct route_node *rn;
struct ospf_neighbor *nbr;
@@ -4526,21 +4708,53 @@ static int show_ip_ospf_neighbor_detail_common(struct vty *vty,
DEFUN (show_ip_ospf_neighbor_detail,
show_ip_ospf_neighbor_detail_cmd,
- "show ip ospf neighbor detail [json]",
+ "show ip ospf [vrf <NAME|all>] neighbor detail [json]",
SHOW_STR
IP_STR
"OSPF information\n"
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
"Neighbor list\n"
"detail of all neighbors\n"
JSON_STR)
{
struct ospf *ospf;
u_char uj = use_json(argc, argv);
+ struct listnode *node = NULL;
+ char *vrf_name = NULL;
+ bool all_vrf = FALSE;
+ int ret = CMD_SUCCESS;
+ int inst = 0;
+ int idx_vrf = 0;
- if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
- return CMD_SUCCESS;
+ OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
- return show_ip_ospf_neighbor_detail_common(vty, ospf, uj);
+ /* vrf input is provided could be all or specific vrf*/
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ ret = show_ip_ospf_neighbor_detail_common(vty,
+ ospf,
+ uj);
+ }
+ return ret;
+ }
+ ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ } else {
+ /* Display default ospf (instance 0) info */
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ }
+
+ if (ospf)
+ ret = show_ip_ospf_neighbor_detail_common(vty, ospf, uj);
+
+ return ret;
}
DEFUN (show_ip_ospf_instance_neighbor_detail,
@@ -4589,6 +4803,8 @@ static int show_ip_ospf_neighbor_detail_all_common(struct vty *vty,
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
}
+ ospf_show_vrf_name(ospf, vty, json);
+
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
struct route_node *rn;
struct ospf_neighbor *nbr;
@@ -4628,10 +4844,12 @@ static int show_ip_ospf_neighbor_detail_all_common(struct vty *vty,
DEFUN (show_ip_ospf_neighbor_detail_all,
show_ip_ospf_neighbor_detail_all_cmd,
- "show ip ospf neighbor detail all [json]",
+ "show ip ospf [vrf <NAME|all>] neighbor detail all [json]",
SHOW_STR
IP_STR
"OSPF information\n"
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
"Neighbor list\n"
"detail of all neighbors\n"
"include down status neighbor\n"
@@ -4639,11 +4857,41 @@ DEFUN (show_ip_ospf_neighbor_detail_all,
{
struct ospf *ospf;
u_char uj = use_json(argc, argv);
+ struct listnode *node = NULL;
+ char *vrf_name = NULL;
+ bool all_vrf = FALSE;
+ int ret = CMD_SUCCESS;
+ int inst = 0;
+ int idx_vrf = 0;
- if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
- return CMD_SUCCESS;
+ OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
- return show_ip_ospf_neighbor_detail_all_common(vty, ospf, uj);
+ /* vrf input is provided could be all or specific vrf*/
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ ret = show_ip_ospf_neighbor_detail_all_common(vty,
+ ospf,
+ uj);
+ }
+ return ret;
+ }
+ ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ } else {
+ /* Display default ospf (instance 0) info */
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ }
+
+ if (ospf)
+ ret = show_ip_ospf_neighbor_detail_all_common(vty, ospf, uj);
+
+ return ret;
}
DEFUN (show_ip_ospf_instance_neighbor_detail_all,
@@ -4697,7 +4945,7 @@ static int show_ip_ospf_neighbor_int_detail_common(struct vty *vty,
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
}
- ifp = if_lookup_by_name(argv[arg_base]->arg, VRF_DEFAULT);
+ ifp = if_lookup_by_name_all_vrf(argv[arg_base]->arg);
if (!ifp) {
if (!use_json)
vty_out(vty, "No such interface.\n");
@@ -4746,13 +4994,18 @@ DEFUN (show_ip_ospf_neighbor_int_detail,
JSON_STR)
{
struct ospf *ospf;
- int idx_ifname = 4;
u_char uj = use_json(argc, argv);
+ struct listnode *node = NULL;
+ int ret = CMD_SUCCESS;
- if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
- return CMD_SUCCESS;
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ ret = show_ip_ospf_neighbor_int_detail_common(vty, ospf, 0,
+ argv, uj);
+ }
- return show_ip_ospf_neighbor_int_detail_common(vty, ospf, idx_ifname, argv, uj);
+ return ret;
}
DEFUN (show_ip_ospf_instance_neighbor_int_detail,
@@ -5362,6 +5615,8 @@ static int show_ip_ospf_database_common(struct vty *vty, struct ospf *ospf,
if (ospf->instance)
vty_out(vty, "\nOSPF Instance: %d\n", ospf->instance);
+ ospf_show_vrf_name(ospf, vty, NULL);
+
vty_out(vty, "\n OSPF Router with ID (%s)\n\n",
inet_ntoa(ospf->router_id));
@@ -5429,29 +5684,62 @@ static int show_ip_ospf_database_common(struct vty *vty, struct ospf *ospf,
DEFUN (show_ip_ospf_database_max,
show_ip_ospf_database_max_cmd,
- "show ip ospf database <max-age|self-originate>",
+ "show ip ospf [vrf <NAME|all>] database <max-age|self-originate>",
SHOW_STR
IP_STR
"OSPF information\n"
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
"Database summary\n"
"LSAs in MaxAge list\n"
"Self-originated link states\n")
{
- struct ospf *ospf;
+ struct ospf *ospf = NULL;
+ struct listnode *node = NULL;
+ char *vrf_name = NULL;
+ bool all_vrf = FALSE;
+ int ret = CMD_SUCCESS;
+ int inst = 0;
+ int idx_vrf = 0;
- if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
- return CMD_SUCCESS;
+ 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)) {
+ if (!ospf->oi_running)
+ continue;
+ ret = show_ip_ospf_database_common(vty, ospf,
+ idx_vrf ? 2
+ : 0, argc,
+ argv);
+ }
+ } else {
+ ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ ret = (show_ip_ospf_database_common(vty, ospf, idx_vrf ?
+ 2 : 0, argc, argv));
+ }
+ } else {
+ /* Display default ospf (instance 0) info */
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ ret = show_ip_ospf_database_common(vty, ospf, 0, argc, argv);
+ }
- return (show_ip_ospf_database_common(vty, ospf, 0, argc, argv));
+ return ret;
}
DEFUN (show_ip_ospf_instance_database,
show_ip_ospf_instance_database_cmd,
- "show ip ospf [(1-65535)] 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"
"Instance ID\n"
+ VRF_CMD_HELP_STR
"Database summary\n"
OSPF_LSA_TYPES_DESC
"Link State ID (as an IP address)\n"
@@ -5461,22 +5749,53 @@ DEFUN (show_ip_ospf_instance_database,
{
struct ospf *ospf;
u_short instance = 0;
-
+ struct listnode *node = NULL;
+ char *vrf_name = NULL;
+ bool all_vrf = FALSE;
+ int ret = CMD_SUCCESS;
+ int inst = 0;
int idx = 0;
+
if (argv_find(argv, argc, "(1-65535)", &idx)) {
instance = strtoul(argv[idx]->arg, NULL, 10);
ospf = ospf_lookup_instance(instance);
if (ospf == NULL)
return CMD_NOT_MY_INSTANCE;
- } else {
- ospf = ospf_lookup();
+ if (!ospf->oi_running)
+ return CMD_SUCCESS;
+
+ return (show_ip_ospf_database_common(vty, ospf, idx ? 1 : 0,
+ argc, argv));
+ } else if (argv_find(argv, argc, "vrf", &idx)) {
+ vrf_name = argv[++idx]->arg;
+ all_vrf = strmatch(vrf_name, "all");
}
- if (!ospf || !ospf->oi_running)
- return CMD_SUCCESS;
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ ret = (show_ip_ospf_database_common(vty, ospf,
+ idx ? 2 : 0,
+ argc, argv));
+ }
+ } else {
+ ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+ if ((ospf == NULL) || !ospf->oi_running)
+ return CMD_SUCCESS;
+ ret = (show_ip_ospf_database_common(vty, ospf, idx ? 2 :
+ 0, argc, argv));
+ }
+ } else {
+ /* Display default ospf (instance 0) info */
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ ret = (show_ip_ospf_database_common(vty, ospf, 0, argc, argv));
+ }
- return (show_ip_ospf_database_common(vty, ospf, idx ? 1 : 0, argc,
- argv));
+ return ret;
}
DEFUN (show_ip_ospf_instance_database_max,
@@ -5519,6 +5838,8 @@ static int show_ip_ospf_database_type_adv_router_common(struct vty *vty,
if (ospf->instance)
vty_out(vty, "\nOSPF Instance: %d\n", ospf->instance);
+ ospf_show_vrf_name(ospf, vty, NULL);
+
vty_out(vty, "\n OSPF Router with ID (%s)\n\n",
inet_ntoa(ospf->router_id));
@@ -5560,34 +5881,69 @@ 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)] 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"
"Instance ID\n"
+ VRF_CMD_HELP_STR
"Database summary\n"
OSPF_LSA_TYPES_DESC
"Advertising Router link states\n"
"Advertising Router (as an IP address)\n"
"Self-originated link states\n")
{
- struct ospf *ospf;
+ struct ospf *ospf = NULL;
u_short instance = 0;
- int idx = 0;
+ struct listnode *node = NULL;
+ char *vrf_name = NULL;
+ bool all_vrf = FALSE;
+ int ret = CMD_SUCCESS;
+ int inst = 0;
+ int idx = 0, idx_vrf = 0;
if (argv_find(argv, argc, "(1-65535)", &idx)) {
instance = strtoul(argv[idx]->arg, NULL, 10);
ospf = ospf_lookup_instance(instance);
if (ospf == NULL)
return CMD_NOT_MY_INSTANCE;
- } else
- ospf = ospf_lookup();
+ if (!ospf->oi_running)
+ return CMD_SUCCESS;
+ return (show_ip_ospf_database_type_adv_router_common(vty, ospf,
+ idx ? 1 : 0,
+ argc,
+ argv));
+ }
- if (!ospf || !ospf->oi_running)
- return CMD_SUCCESS;
+ OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
- return (show_ip_ospf_database_type_adv_router_common(
- vty, ospf, idx ? 1 : 0, argc, argv));
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ ret = show_ip_ospf_database_type_adv_router_common(vty,
+ ospf, idx ? 1 : 0, argc, argv);
+ }
+ } else {
+ ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+ if ((ospf == NULL) || !ospf->oi_running)
+ return CMD_SUCCESS;
+ ret = show_ip_ospf_database_type_adv_router_common(vty,
+ ospf, idx ? 1 : 0, argc, argv);
+ }
+ } else {
+ /* Display default ospf (instance 0) info */
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ ret = show_ip_ospf_database_type_adv_router_common(vty, ospf,
+ idx ? 1 : 0,
+ argc, argv);
+ }
+ return ret;
+ /*return (show_ip_ospf_database_type_adv_router_common(
+ vty, ospf, idx ? 1 : 0, argc, argv));*/
}
DEFUN (ip_ospf_authentication_args,
@@ -5871,8 +6227,7 @@ DEFUN_HIDDEN (ospf_authentication_key,
ospf_authentication_key_cmd,
"ospf authentication-key AUTH_KEY [A.B.C.D]",
"OSPF interface commands\n"
- "Authentication password (key)\n"
- "The OSPF password (key)\n"
+ VLINK_HELPSTR_AUTH_SIMPLE
"Address of interface\n")
{
return ip_ospf_authentication_key(self, vty, argc, argv);
@@ -5884,8 +6239,8 @@ DEFUN (no_ip_ospf_authentication_key,
NO_STR
"IP Information\n"
"OSPF interface commands\n"
- "Authentication password (key)\n"
- "The OSPF password (key)")
+ VLINK_HELPSTR_AUTH_SIMPLE
+ "Address of interface\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx = 0;
@@ -5921,8 +6276,8 @@ DEFUN_HIDDEN (no_ospf_authentication_key,
"no ospf authentication-key [AUTH_KEY [A.B.C.D]]",
NO_STR
"OSPF interface commands\n"
- "Authentication password (key)\n"
- "The OSPF password (key)")
+ VLINK_HELPSTR_AUTH_SIMPLE
+ "Address of interface\n")
{
return no_ip_ospf_authentication_key(self, vty, argc, argv);
}
@@ -6068,19 +6423,19 @@ DEFUN (ip_ospf_cost,
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx = 0;
- u_int32_t cost;
+ u_int32_t cost = OSPF_OUTPUT_COST_DEFAULT;
struct in_addr addr;
struct ospf_if_params *params;
params = IF_DEF_PARAMS(ifp);
// get arguments
char *coststr = NULL, *ifaddr = NULL;
- coststr = argv_find(argv, argc, "(1-65535)", &idx) ? argv[idx]->arg
- : NULL;
- ifaddr = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL;
+ argv_find(argv, argc, "(1-65535)", &idx);
+ coststr = argv[idx]->arg;
cost = strtol(coststr, NULL, 10);
+ ifaddr = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL;
if (ifaddr) {
if (!inet_aton(ifaddr, &addr)) {
vty_out(vty,
@@ -6234,8 +6589,10 @@ static int ospf_vty_dead_interval_set(struct vty *vty, const char *interval_str,
/* Update timer values in neighbor structure. */
if (nbr_str) {
- struct ospf *ospf;
- if ((ospf = ospf_lookup())) {
+ struct ospf *ospf = NULL;
+
+ ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
+ if (ospf) {
oi = ospf_if_lookup_by_local_addr(ospf, ifp, addr);
if (oi)
ospf_nbr_timer_update(oi);
@@ -6346,9 +6703,10 @@ DEFUN (no_ip_ospf_dead_interval,
/* Update timer values in neighbor structure. */
if (argc == 1) {
- struct ospf *ospf;
+ struct ospf *ospf = NULL;
- if ((ospf = ospf_lookup())) {
+ ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
+ if (ospf) {
oi = ospf_if_lookup_by_local_addr(ospf, ifp, addr);
if (oi)
ospf_nbr_timer_update(oi);
@@ -6930,9 +7288,9 @@ DEFUN (ip_ospf_area,
int format, ret;
struct in_addr area_id;
struct in_addr addr;
- struct ospf_if_params *params;
+ struct ospf_if_params *params = NULL;
struct route_node *rn;
- struct ospf *ospf;
+ struct ospf *ospf = NULL;
u_short instance = 0;
char *areaid;
@@ -6942,13 +7300,17 @@ DEFUN (ip_ospf_area,
argv_find(argv, argc, "area", &idx);
areaid = argv[idx + 1]->arg;
- ospf = ospf_lookup_instance(instance);
+ if (ifp->vrf_id && !instance)
+ ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
+ else
+ ospf = ospf_lookup_instance(instance);
+
if (ospf == NULL) {
params = IF_DEF_PARAMS(ifp);
if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) {
UNSET_IF_PARAM(params, if_area);
- ospf_interface_area_unset(ifp);
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ ospf_interface_area_unset(ospf, ifp);
ospf->if_ospf_cli_count--;
}
return CMD_NOT_MY_INSTANCE;
@@ -6997,10 +7359,12 @@ DEFUN (ip_ospf_area,
}
/* enable ospf on this interface with area_id */
- SET_IF_PARAM(params, if_area);
- params->if_area = area_id;
- params->if_area_id_fmt = format;
- ospf_interface_area_set(ifp);
+ if (params) {
+ SET_IF_PARAM(params, if_area);
+ params->if_area = area_id;
+ params->if_area_id_fmt = format;
+ }
+ ospf_interface_area_set(ospf, ifp);
ospf->if_ospf_cli_count++;
return CMD_SUCCESS;
@@ -7028,7 +7392,11 @@ DEFUN (no_ip_ospf_area,
if (argv_find(argv, argc, "(1-65535)", &idx))
instance = strtol(argv[idx]->arg, NULL, 10);
- ospf = ospf_lookup_instance(instance);
+ if (ifp->vrf_id && !instance)
+ ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
+ else
+ ospf = ospf_lookup_instance(instance);
+
if (ospf == NULL)
return CMD_NOT_MY_INSTANCE;
@@ -7058,7 +7426,7 @@ DEFUN (no_ip_ospf_area,
ospf_if_update_params((ifp), (addr));
}
- ospf_interface_area_unset(ifp);
+ ospf_interface_area_unset(ospf, ifp);
ospf->if_ospf_cli_count--;
return CMD_SUCCESS;
}
@@ -7732,7 +8100,7 @@ DEFUN (ospf_max_metric_router_lsa_startup,
int idx_number = 3;
unsigned int seconds;
- if (argc != 1) {
+ if (argc < 4) {
vty_out(vty, "%% Must supply stub-router period");
return CMD_WARNING_CONFIG_FAILED;
}
@@ -7788,7 +8156,7 @@ DEFUN (ospf_max_metric_router_lsa_shutdown,
int idx_number = 3;
unsigned int seconds;
- if (argc != 1) {
+ if (argc < 4) {
vty_out(vty, "%% Must supply stub-router shutdown period");
return CMD_WARNING_CONFIG_FAILED;
}
@@ -7837,7 +8205,8 @@ static void config_write_stub_router(struct vty *vty, struct ospf *ospf)
return;
}
-static void show_ip_ospf_route_network(struct vty *vty, struct route_table *rt)
+static void show_ip_ospf_route_network(struct vty *vty, struct ospf *ospf,
+ struct route_table *rt)
{
struct route_node *rn;
struct ospf_route * or ;
@@ -7877,14 +8246,14 @@ static void show_ip_ospf_route_network(struct vty *vty, struct route_table *rt)
for (ALL_LIST_ELEMENTS(or->paths, pnode, pnnode,
path)) {
if (if_lookup_by_index(path->ifindex,
- VRF_DEFAULT)) {
+ ospf->vrf_id)) {
if (path->nexthop.s_addr == 0)
vty_out(vty,
"%24s directly attached to %s\n",
"",
ifindex2ifname(
path->ifindex,
- VRF_DEFAULT));
+ ospf->vrf_id));
else
vty_out(vty,
"%24s via %s, %s\n",
@@ -7893,14 +8262,15 @@ static void show_ip_ospf_route_network(struct vty *vty, struct route_table *rt)
path->nexthop),
ifindex2ifname(
path->ifindex,
- VRF_DEFAULT));
+ ospf->vrf_id));
}
}
}
vty_out(vty, "\n");
}
-static void show_ip_ospf_route_router(struct vty *vty, struct route_table *rtrs)
+static void show_ip_ospf_route_router(struct vty *vty, struct ospf *ospf,
+ struct route_table *rtrs)
{
struct route_node *rn;
struct ospf_route * or ;
@@ -7939,14 +8309,14 @@ static void show_ip_ospf_route_router(struct vty *vty, struct route_table *rtrs)
for (ALL_LIST_ELEMENTS_RO(or->paths, pnode,
path)) {
if (if_lookup_by_index(path->ifindex,
- VRF_DEFAULT)) {
+ ospf->vrf_id)) {
if (path->nexthop.s_addr == 0)
vty_out(vty,
"%24s directly attached to %s\n",
"",
ifindex2ifname(
path->ifindex,
- VRF_DEFAULT));
+ ospf->vrf_id));
else
vty_out(vty,
"%24s via %s, %s\n",
@@ -7955,7 +8325,7 @@ static void show_ip_ospf_route_router(struct vty *vty, struct route_table *rtrs)
path->nexthop),
ifindex2ifname(
path->ifindex,
- VRF_DEFAULT));
+ ospf->vrf_id));
}
}
}
@@ -7963,7 +8333,8 @@ static void show_ip_ospf_route_router(struct vty *vty, struct route_table *rtrs)
vty_out(vty, "\n");
}
-static void show_ip_ospf_route_external(struct vty *vty, struct route_table *rt)
+static void show_ip_ospf_route_external(struct vty *vty, struct ospf *ospf,
+ struct route_table *rt)
{
struct route_node *rn;
struct ospf_route *er;
@@ -7996,14 +8367,14 @@ static void show_ip_ospf_route_external(struct vty *vty, struct route_table *rt)
for (ALL_LIST_ELEMENTS(er->paths, pnode, pnnode,
path)) {
if (if_lookup_by_index(path->ifindex,
- VRF_DEFAULT)) {
+ ospf->vrf_id)) {
if (path->nexthop.s_addr == 0)
vty_out(vty,
"%24s directly attached to %s\n",
"",
ifindex2ifname(
path->ifindex,
- VRF_DEFAULT));
+ ospf->vrf_id));
else
vty_out(vty,
"%24s via %s, %s\n",
@@ -8012,7 +8383,7 @@ static void show_ip_ospf_route_external(struct vty *vty, struct route_table *rt)
path->nexthop),
ifindex2ifname(
path->ifindex,
- VRF_DEFAULT));
+ ospf->vrf_id));
}
}
}
@@ -8025,6 +8396,8 @@ static int show_ip_ospf_border_routers_common(struct vty *vty,
if (ospf->instance)
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
+ ospf_show_vrf_name(ospf, vty, NULL);
+
if (ospf->new_table == NULL) {
vty_out(vty, "No OSPF routing information exist\n");
return CMD_SUCCESS;
@@ -8034,7 +8407,7 @@ static int show_ip_ospf_border_routers_common(struct vty *vty,
show_ip_ospf_route_network (vty, ospf->new_table); */
/* Show Router routes. */
- show_ip_ospf_route_router(vty, ospf->new_rtrs);
+ show_ip_ospf_route_router(vty, ospf, ospf->new_rtrs);
vty_out(vty, "\n");
@@ -8043,18 +8416,49 @@ static int show_ip_ospf_border_routers_common(struct vty *vty,
DEFUN (show_ip_ospf_border_routers,
show_ip_ospf_border_routers_cmd,
- "show ip ospf border-routers",
+ "show ip ospf [vrf <NAME|all>] border-routers",
SHOW_STR
IP_STR
"OSPF information\n"
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
"Show all the ABR's and ASBR's\n")
{
- struct ospf *ospf;
+ struct ospf *ospf = NULL;
+ struct listnode *node = NULL;
+ char *vrf_name = NULL;
+ bool all_vrf = FALSE;
+ int ret = CMD_SUCCESS;
+ int inst = 0;
+ int idx_vrf = 0;
- if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
- return CMD_SUCCESS;
+ OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
- return show_ip_ospf_border_routers_common(vty, ospf);
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+
+ ret = show_ip_ospf_border_routers_common(vty,
+ ospf);
+ }
+ } else {
+ ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+
+ ret = show_ip_ospf_border_routers_common(vty, ospf);
+ }
+ } else {
+ /* Display default ospf (instance 0) info */
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ ret = show_ip_ospf_border_routers_common(vty, ospf);
+ }
+
+ return ret;
}
DEFUN (show_ip_ospf_instance_border_routers,
@@ -8086,19 +8490,21 @@ static int show_ip_ospf_route_common(struct vty *vty, struct ospf *ospf)
if (ospf->instance)
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
+ ospf_show_vrf_name(ospf, vty, NULL);
+
if (ospf->new_table == NULL) {
vty_out(vty, "No OSPF routing information exist\n");
return CMD_SUCCESS;
}
/* Show Network routes. */
- show_ip_ospf_route_network(vty, ospf->new_table);
+ show_ip_ospf_route_network(vty, ospf, ospf->new_table);
/* Show Router routes. */
- show_ip_ospf_route_router(vty, ospf->new_rtrs);
+ show_ip_ospf_route_router(vty, ospf, ospf->new_rtrs);
/* Show AS External routes. */
- show_ip_ospf_route_external(vty, ospf->old_external_route);
+ show_ip_ospf_route_external(vty, ospf, ospf->old_external_route);
vty_out(vty, "\n");
@@ -8107,18 +8513,48 @@ static int show_ip_ospf_route_common(struct vty *vty, struct ospf *ospf)
DEFUN (show_ip_ospf_route,
show_ip_ospf_route_cmd,
- "show ip ospf route",
- SHOW_STR
- IP_STR
- "OSPF information\n"
- "OSPF routing table\n")
-{
- struct ospf *ospf;
+ "show ip ospf [vrf <NAME|all>] route",
+ SHOW_STR
+ IP_STR
+ "OSPF information\n"
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
+ "OSPF routing table\n")
+{
+ struct ospf *ospf = NULL;
+ struct listnode *node = NULL;
+ char *vrf_name = NULL;
+ bool all_vrf = FALSE;
+ int ret = CMD_SUCCESS;
+ int inst = 0;
+ int idx_vrf = 0;
- if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
- return CMD_SUCCESS;
+ OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
- return show_ip_ospf_route_common(vty, ospf);
+ /* vrf input is provided could be all or specific vrf*/
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ ret = show_ip_ospf_route_common(vty, ospf);
+ }
+ return ret;
+ }
+ ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ } else {
+ /* Display default ospf (instance 0) info */
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ }
+
+ if (ospf)
+ ret = show_ip_ospf_route_common(vty, ospf);
+
+ return ret;
}
DEFUN (show_ip_ospf_instance_route,
@@ -8145,6 +8581,77 @@ DEFUN (show_ip_ospf_instance_route,
return show_ip_ospf_route_common(vty, ospf);
}
+
+DEFUN (show_ip_ospf_vrfs,
+ show_ip_ospf_vrfs_cmd,
+ "show ip ospf vrfs [json]",
+ SHOW_STR
+ IP_STR
+ "OSPF information\n"
+ "Show OSPF VRFs \n"
+ JSON_STR)
+{
+ u_char uj = use_json(argc, argv);
+ json_object *json = NULL;
+ json_object *json_vrfs = NULL;
+ struct ospf *ospf = NULL;
+ struct listnode *node = NULL;
+ int count = 0;
+ static char header[] = "Name Id RouterId ";
+
+ if (uj) {
+ json = json_object_new_object();
+ json_vrfs = json_object_new_object();
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ json_object *json_vrf = NULL;
+ const char *name = NULL;
+ int vrf_id_ui = 0;
+
+ count++;
+
+ if (!uj && count == 1)
+ vty_out(vty, "%s\n", header);
+ if (uj)
+ json_vrf = json_object_new_object();
+
+ if (ospf->vrf_id == 0)
+ name = VRF_DEFAULT_NAME;
+ else
+ name = ospf->name;
+
+ vrf_id_ui = (ospf->vrf_id == VRF_UNKNOWN) ? -1 : ospf->vrf_id;
+
+ if (uj) {
+ json_object_int_add(json_vrf, "vrfId", vrf_id_ui);
+ json_object_string_add(json_vrf, "routerId",
+ inet_ntoa(ospf->router_id));
+
+ json_object_object_add(json_vrfs, name, json_vrf);
+
+ } else {
+ vty_out(vty, "%-25s %-5d %-16s \n",
+ name, ospf->vrf_id, inet_ntoa(ospf->router_id));
+ }
+ }
+
+ if (uj) {
+ json_object_object_add(json, "vrfs", json_vrfs);
+ json_object_int_add(json, "totalVrfs", count);
+
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(json,
+ JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ } else {
+ if (count)
+ vty_out(vty, "\nTotal number of OSPF VRFs (including default): %d\n",
+ count);
+ }
+
+ return CMD_SUCCESS;
+}
+
const char *ospf_abr_type_str[] = {"unknown", "standard", "ibm", "cisco",
"shortcut"};
@@ -8156,26 +8663,32 @@ 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 = ospf_lookup();
+ int write = 0;
+
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), n1, ifp)) {
+ struct vrf *vrf = NULL;
- for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), n1, ifp)) {
if (memcmp(ifp->name, "VLINK", 5) == 0)
continue;
if (ifp->ifindex == IFINDEX_DELETED)
continue;
+ vrf = vrf_lookup_by_id(ifp->vrf_id);
+
vty_frame(vty, "!\n");
- vty_frame(vty, "interface %s\n", ifp->name);
+ if (ifp->vrf_id == VRF_DEFAULT || vrf == NULL)
+ vty_frame(vty, "interface %s\n", ifp->name);
+ else
+ vty_frame(vty, "interface %s vrf %s\n",
+ ifp->name, vrf->name);
if (ifp->desc)
vty_out(vty, " description %s\n", ifp->desc);
@@ -8190,11 +8703,11 @@ static int config_write_interface(struct vty *vty)
if (params->type != ospf_default_iftype(ifp)) {
vty_out(vty, " ip ospf network %s",
ospf_int_type_str
- [params->type]);
+ [params->type]);
if (params != IF_DEF_PARAMS(ifp))
vty_out(vty, " %s",
inet_ntoa(
- rn->p.u.prefix4));
+ rn->p.u.prefix4));
vty_out(vty, "\n");
}
}
@@ -8205,8 +8718,8 @@ static int config_write_interface(struct vty *vty)
const char *auth_str;
/* Translation tables are not that much help
- here due to syntax
- of the simple option */
+ * here due to syntax
+ * of the simple option */
switch (params->auth_type) {
case OSPF_AUTH_NULL:
@@ -8246,18 +8759,22 @@ static int config_write_interface(struct vty *vty)
}
/* Cryptographic Authentication Key print. */
- for (ALL_LIST_ELEMENTS_RO(params->auth_crypt, n2, ck)) {
- vty_out(vty,
- " ip ospf message-digest-key %d md5 %s",
- ck->key_id, ck->auth_key);
- if (params != IF_DEF_PARAMS(ifp))
- vty_out(vty, " %s",
- inet_ntoa(rn->p.u.prefix4));
- vty_out(vty, "\n");
+ if (params && params->auth_crypt) {
+ for (ALL_LIST_ELEMENTS_RO(params->auth_crypt,
+ n2, ck)) {
+ vty_out(vty,
+ " ip ospf message-digest-key %d md5 %s",
+ ck->key_id, ck->auth_key);
+ if (params != IF_DEF_PARAMS(ifp))
+ vty_out(vty, " %s",
+ inet_ntoa(rn->p.u.prefix4));
+ vty_out(vty, "\n");
+ }
}
/* Interface Output Cost print. */
- if (OSPF_IF_PARAM_CONFIGURED(params, output_cost_cmd)) {
+ if (OSPF_IF_PARAM_CONFIGURED(params,
+ output_cost_cmd)) {
vty_out(vty, " ip ospf cost %u",
params->output_cost_cmd);
if (params != IF_DEF_PARAMS(ifp))
@@ -8281,7 +8798,7 @@ static int config_write_interface(struct vty *vty)
/* Router Dead Interval print. */
if (OSPF_IF_PARAM_CONFIGURED(params, v_wait)
&& params->v_wait
- != OSPF_ROUTER_DEAD_INTERVAL_DEFAULT) {
+ != OSPF_ROUTER_DEAD_INTERVAL_DEFAULT) {
vty_out(vty, " ip ospf dead-interval ");
/* fast hello ? */
@@ -8302,7 +8819,7 @@ static int config_write_interface(struct vty *vty)
/* Router Priority print. */
if (OSPF_IF_PARAM_CONFIGURED(params, priority)
&& params->priority
- != OSPF_ROUTER_PRIORITY_DEFAULT) {
+ != OSPF_ROUTER_PRIORITY_DEFAULT) {
vty_out(vty, " ip ospf priority %u",
params->priority);
if (params != IF_DEF_PARAMS(ifp))
@@ -8315,7 +8832,7 @@ static int config_write_interface(struct vty *vty)
if (OSPF_IF_PARAM_CONFIGURED(params,
retransmit_interval)
&& params->retransmit_interval
- != OSPF_RETRANSMIT_INTERVAL_DEFAULT) {
+ != OSPF_RETRANSMIT_INTERVAL_DEFAULT) {
vty_out(vty, " ip ospf retransmit-interval %u",
params->retransmit_interval);
if (params != IF_DEF_PARAMS(ifp))
@@ -8327,7 +8844,7 @@ static int config_write_interface(struct vty *vty)
/* Transmit Delay print. */
if (OSPF_IF_PARAM_CONFIGURED(params, transmit_delay)
&& params->transmit_delay
- != OSPF_TRANSMIT_DELAY_DEFAULT) {
+ != OSPF_TRANSMIT_DELAY_DEFAULT) {
vty_out(vty, " ip ospf transmit-delay %u",
params->transmit_delay);
if (params != IF_DEF_PARAMS(ifp))
@@ -8348,7 +8865,9 @@ 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,
+
+ area_id2str(buf, sizeof(buf),
+ &params->if_area,
params->if_area_id_fmt);
vty_out(vty, " area %s", buf);
if (params != IF_DEF_PARAMS(ifp))
@@ -8392,6 +8911,19 @@ 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;
}
@@ -8732,154 +9264,174 @@ 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;
+ struct listnode *node = NULL;
int write = 0;
- ospf = ospf_lookup();
- if (ospf != NULL && ospf->oi_running) {
- /* `router ospf' print. */
- if (ospf->instance)
- vty_out(vty, "router ospf %d\n", ospf->instance);
- else
- vty_out(vty, "router ospf\n");
+ /* `router ospf' print. */
+ if (ospf->instance && ospf->name) {
+ vty_out(vty, "router ospf %d vrf %s\n",
+ ospf->instance, ospf->name);
+ } else if (ospf->instance) {
+ vty_out(vty, "router ospf %d\n",
+ ospf->instance);
+ } else if (ospf->name) {
+ vty_out(vty, "router ospf vrf %s\n",
+ ospf->name);
+ } else
+ vty_out(vty, "router ospf\n");
+ if (!ospf->networks) {
write++;
+ return write;
+ }
- if (!ospf->networks)
- return write;
-
- /* Router ID print. */
- if (ospf->router_id_static.s_addr != 0)
- vty_out(vty, " ospf router-id %s\n",
- inet_ntoa(ospf->router_id_static));
-
- /* ABR type print. */
- if (ospf->abr_type != OSPF_ABR_DEFAULT)
- vty_out(vty, " ospf abr-type %s\n",
- ospf_abr_type_str[ospf->abr_type]);
-
- /* log-adjacency-changes flag print. */
- if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES)) {
- if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL))
- vty_out(vty, " log-adjacency-changes detail\n");
- else if (!DFLT_OSPF_LOG_ADJACENCY_CHANGES)
- vty_out(vty, " log-adjacency-changes\n");
- } else if (DFLT_OSPF_LOG_ADJACENCY_CHANGES) {
- vty_out(vty, " no log-adjacency-changes\n");
- }
+ /* Router ID print. */
+ if (ospf->router_id_static.s_addr != 0)
+ vty_out(vty, " ospf router-id %s\n",
+ inet_ntoa(ospf->router_id_static));
- /* RFC1583 compatibility flag print -- Compatible with CISCO
- * 12.1. */
- if (CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE))
- vty_out(vty, " compatible rfc1583\n");
+ /* ABR type print. */
+ if (ospf->abr_type != OSPF_ABR_DEFAULT)
+ vty_out(vty, " ospf abr-type %s\n",
+ ospf_abr_type_str[ospf->abr_type]);
- /* auto-cost reference-bandwidth configuration. */
- if (ospf->ref_bandwidth != OSPF_DEFAULT_REF_BANDWIDTH) {
- vty_out(vty,
- "! Important: ensure reference bandwidth "
- "is consistent across all routers\n");
- vty_out(vty, " auto-cost reference-bandwidth %d\n",
- ospf->ref_bandwidth);
- }
+ /* log-adjacency-changes flag print. */
+ if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES)) {
+ if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL))
+ vty_out(vty, " log-adjacency-changes detail\n");
+ else if (!DFLT_OSPF_LOG_ADJACENCY_CHANGES)
+ vty_out(vty, " log-adjacency-changes\n");
+ } else if (DFLT_OSPF_LOG_ADJACENCY_CHANGES) {
+ vty_out(vty, " no log-adjacency-changes\n");
+ }
- /* SPF timers print. */
- if (ospf->spf_delay != OSPF_SPF_DELAY_DEFAULT
- || ospf->spf_holdtime != OSPF_SPF_HOLDTIME_DEFAULT
- || ospf->spf_max_holdtime != OSPF_SPF_MAX_HOLDTIME_DEFAULT)
- vty_out(vty, " timers throttle spf %d %d %d\n",
- ospf->spf_delay, ospf->spf_holdtime,
- ospf->spf_max_holdtime);
-
- /* LSA timers print. */
- if (ospf->min_ls_interval != OSPF_MIN_LS_INTERVAL)
- vty_out(vty, " timers throttle lsa all %d\n",
- ospf->min_ls_interval);
- if (ospf->min_ls_arrival != OSPF_MIN_LS_ARRIVAL)
- vty_out(vty, " timers lsa min-arrival %d\n",
- ospf->min_ls_arrival);
-
- /* Write multiplier print. */
- if (ospf->write_oi_count != OSPF_WRITE_INTERFACE_COUNT_DEFAULT)
- vty_out(vty, " ospf write-multiplier %d\n",
- ospf->write_oi_count);
-
- /* Max-metric router-lsa print */
- config_write_stub_router(vty, ospf);
-
- /* SPF refresh parameters print. */
- if (ospf->lsa_refresh_interval
- != OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
- vty_out(vty, " refresh timer %d\n",
- ospf->lsa_refresh_interval);
-
- /* Redistribute information print. */
- config_write_ospf_redistribute(vty, ospf);
-
- /* passive-interface print. */
- if (ospf->passive_interface_default == OSPF_IF_PASSIVE)
- vty_out(vty, " passive-interface default\n");
-
- for (ALL_LIST_ELEMENTS_RO(om->iflist, node, ifp))
- if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp),
- passive_interface)
- && IF_DEF_PARAMS(ifp)->passive_interface
- != ospf->passive_interface_default) {
- vty_out(vty, " %spassive-interface %s\n",
- IF_DEF_PARAMS(ifp)->passive_interface
- ? ""
- : "no ",
- ifp->name);
- }
- for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
- if (!OSPF_IF_PARAM_CONFIGURED(oi->params,
- passive_interface))
- continue;
- if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(oi->ifp),
- passive_interface)) {
- if (oi->params->passive_interface
- == IF_DEF_PARAMS(oi->ifp)
- ->passive_interface)
- continue;
- } else if (oi->params->passive_interface
- == ospf->passive_interface_default)
- continue;
+ /* RFC1583 compatibility flag print -- Compatible with CISCO
+ * 12.1. */
+ if (CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE))
+ vty_out(vty, " compatible rfc1583\n");
- vty_out(vty, " %spassive-interface %s %s\n",
- oi->params->passive_interface ? "" : "no ",
- oi->ifp->name,
- inet_ntoa(oi->address->u.prefix4));
- }
+ /* auto-cost reference-bandwidth configuration. */
+ if (ospf->ref_bandwidth != OSPF_DEFAULT_REF_BANDWIDTH) {
+ vty_out(vty,
+ "! Important: ensure reference bandwidth "
+ "is consistent across all routers\n");
+ vty_out(vty, " auto-cost reference-bandwidth %d\n",
+ ospf->ref_bandwidth);
+ }
- /* Network area print. */
- config_write_network_area(vty, ospf);
+ /* SPF timers print. */
+ if (ospf->spf_delay != OSPF_SPF_DELAY_DEFAULT
+ || ospf->spf_holdtime != OSPF_SPF_HOLDTIME_DEFAULT
+ || ospf->spf_max_holdtime != OSPF_SPF_MAX_HOLDTIME_DEFAULT)
+ vty_out(vty, " timers throttle spf %d %d %d\n",
+ ospf->spf_delay, ospf->spf_holdtime,
+ ospf->spf_max_holdtime);
- /* Area config print. */
- config_write_ospf_area(vty, ospf);
+ /* LSA timers print. */
+ if (ospf->min_ls_interval != OSPF_MIN_LS_INTERVAL)
+ vty_out(vty, " timers throttle lsa all %d\n",
+ ospf->min_ls_interval);
+ if (ospf->min_ls_arrival != OSPF_MIN_LS_ARRIVAL)
+ vty_out(vty, " timers lsa min-arrival %d\n",
+ ospf->min_ls_arrival);
- /* static neighbor print. */
- config_write_ospf_nbr_nbma(vty, ospf);
+ /* Write multiplier print. */
+ if (ospf->write_oi_count != OSPF_WRITE_INTERFACE_COUNT_DEFAULT)
+ vty_out(vty, " ospf write-multiplier %d\n",
+ ospf->write_oi_count);
- /* Virtual-Link print. */
- config_write_virtual_link(vty, ospf);
+ /* Max-metric router-lsa print */
+ config_write_stub_router(vty, ospf);
- /* Default metric configuration. */
- config_write_ospf_default_metric(vty, ospf);
+ /* SPF refresh parameters print. */
+ if (ospf->lsa_refresh_interval
+ != OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
+ vty_out(vty, " refresh timer %d\n",
+ ospf->lsa_refresh_interval);
- /* Distribute-list and default-information print. */
- config_write_ospf_distribute(vty, ospf);
+ /* Redistribute information print. */
+ config_write_ospf_redistribute(vty, ospf);
- /* Distance configuration. */
- config_write_ospf_distance(vty, ospf);
+ /* passive-interface print. */
+ if (ospf->passive_interface_default == OSPF_IF_PASSIVE)
+ vty_out(vty, " passive-interface default\n");
+
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), node, ifp))
+ if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp),
+ passive_interface)
+ && IF_DEF_PARAMS(ifp)->passive_interface
+ != ospf->passive_interface_default) {
+ vty_out(vty, " %spassive-interface %s\n",
+ IF_DEF_PARAMS(ifp)->passive_interface
+ ? ""
+ : "no ",
+ ifp->name);
+ }
+ for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
+ if (!OSPF_IF_PARAM_CONFIGURED(oi->params,
+ passive_interface))
+ continue;
+ if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(oi->ifp),
+ passive_interface)) {
+ if (oi->params->passive_interface
+ == IF_DEF_PARAMS(oi->ifp)
+ ->passive_interface)
+ continue;
+ } else if (oi->params->passive_interface
+ == ospf->passive_interface_default)
+ continue;
- ospf_opaque_config_write_router(vty, ospf);
+ vty_out(vty, " %spassive-interface %s %s\n",
+ oi->params->passive_interface ? "" : "no ",
+ oi->ifp->name,
+ inet_ntoa(oi->address->u.prefix4));
}
+ /* Network area print. */
+ config_write_network_area(vty, ospf);
+
+ /* Area config print. */
+ config_write_ospf_area(vty, ospf);
+
+ /* static neighbor print. */
+ config_write_ospf_nbr_nbma(vty, ospf);
+
+ /* Virtual-Link print. */
+ config_write_virtual_link(vty, ospf);
+
+ /* Default metric configuration. */
+ config_write_ospf_default_metric(vty, ospf);
+
+ /* Distribute-list and default-information print. */
+ config_write_ospf_distribute(vty, ospf);
+
+ /* Distance configuration. */
+ config_write_ospf_distance(vty, ospf);
+
+ 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;
}
@@ -8928,6 +9480,9 @@ void ospf_vty_show_init(void)
install_element(VIEW_NODE, &show_ip_ospf_instance_route_cmd);
install_element(VIEW_NODE, &show_ip_ospf_instance_border_routers_cmd);
+
+ /* "show ip ospf vrfs" commands. */
+ install_element(VIEW_NODE, &show_ip_ospf_vrfs_cmd);
}
@@ -9068,17 +9623,20 @@ DEFUN (clear_ip_ospf_interface,
{
int idx_ifname = 4;
struct interface *ifp;
- struct listnode *node;
+ struct listnode *node, *n1;
+ struct ospf *ospf = NULL;
if (argc == 4) /* Clear all the ospfv2 interfaces. */
{
- for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp))
- ospf_interface_clear(ifp);
- } else /* Interface name is specified. */
- {
- if ((ifp = if_lookup_by_name(argv[idx_ifname]->arg,
- VRF_DEFAULT))
- == NULL)
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id),
+ node, ifp))
+ ospf_interface_clear(ifp);
+ }
+ } else {
+ /* Interface name is specified. */
+ ifp = if_lookup_by_name_all_vrf(argv[idx_ifname]->arg);
+ if (ifp == NULL)
vty_out(vty, "No such interface name\n");
else
ospf_interface_clear(ifp);
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index 9bba2c9806..16f87735be 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -53,6 +53,7 @@
DEFINE_MTYPE_STATIC(OSPFD, OSPF_EXTERNAL, "OSPF External route table")
DEFINE_MTYPE_STATIC(OSPFD, OSPF_REDISTRIBUTE, "OSPF Redistriute")
+DEFINE_MTYPE_STATIC(OSPFD, OSPF_DIST_ARGS, "OSPF Distribute arguments")
DEFINE_HOOK(ospf_if_update, (struct interface * ifp), (ifp))
DEFINE_HOOK(ospf_if_delete, (struct interface * ifp), (ifp))
@@ -68,23 +69,33 @@ struct in_addr router_id_zebra;
static int ospf_router_id_update_zebra(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
- struct ospf *ospf;
+ struct ospf *ospf = NULL;
struct prefix router_id;
zebra_router_id_update_read(zclient->ibuf, &router_id);
if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) {
char buf[PREFIX2STR_BUFFER];
prefix2str(&router_id, buf, sizeof(buf));
- zlog_debug("Zebra rcvd: router id update %s", buf);
+ zlog_debug("Zebra rcvd: router id update %s vrf %s id %u",
+ buf, ospf_vrf_id_to_name(vrf_id), vrf_id);
}
router_id_zebra = router_id.u.prefix4;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(vrf_id);
if (ospf != NULL)
ospf_router_id_update(ospf);
-
+ else {
+ if (IS_DEBUG_OSPF_EVENT) {
+ char buf[PREFIX2STR_BUFFER];
+
+ prefix2str(&router_id, buf, sizeof(buf));
+ zlog_debug("%s: ospf instance not found for vrf %s id %u router_id %s",
+ __PRETTY_FUNCTION__,
+ ospf_vrf_id_to_name(vrf_id), vrf_id, buf);
+ }
+ }
return 0;
}
@@ -92,14 +103,18 @@ static int ospf_router_id_update_zebra(int command, struct zclient *zclient,
static int ospf_interface_add(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
- struct interface *ifp;
+ struct interface *ifp = NULL;
+ 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(
- "Zebra: interface add %s[%u] index %d flags %llx metric %d mtu %d",
- ifp->name, ifp->vrf_id, ifp->ifindex,
+ "Zebra: interface add %s vrf %s[%u] index %d flags %llx metric %d mtu %d",
+ ifp->name, ospf_vrf_id_to_name(ifp->vrf_id),
+ ifp->vrf_id, ifp->ifindex,
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
assert(ifp->info);
@@ -109,7 +124,11 @@ static int ospf_interface_add(int command, struct zclient *zclient,
IF_DEF_PARAMS(ifp)->type = ospf_default_iftype(ifp);
}
- ospf_if_update(NULL, ifp);
+ ospf = ospf_lookup_by_vrf_id(vrf_id);
+ if (!ospf)
+ return 0;
+
+ ospf_if_update(ospf, ifp);
hook_call(ospf_if_update, ifp);
@@ -136,8 +155,9 @@ static int ospf_interface_delete(int command, struct zclient *zclient,
if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
zlog_debug(
- "Zebra: interface delete %s[%u] index %d flags %llx metric %d mtu %d",
- ifp->name, ifp->vrf_id, ifp->ifindex,
+ "Zebra: interface delete %s vrf %s[%u] index %d flags %llx metric %d mtu %d",
+ ifp->name, ospf_vrf_id_to_name(ifp->vrf_id),
+ ifp->vrf_id, ifp->ifindex,
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
hook_call(ospf_if_delete, ifp);
@@ -160,7 +180,7 @@ static struct interface *zebra_interface_if_lookup(struct stream *s,
/* And look it up. */
return if_lookup_by_name_len(
- ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ), VRF_DEFAULT);
+ ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ), vrf_id);
}
static int ospf_interface_state_up(int command, struct zclient *zclient,
@@ -249,6 +269,8 @@ static int ospf_interface_address_add(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
struct connected *c;
+ struct ospf *ospf = NULL;
+
c = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
@@ -258,11 +280,16 @@ static int ospf_interface_address_add(int command, struct zclient *zclient,
if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) {
char buf[PREFIX2STR_BUFFER];
prefix2str(c->address, buf, sizeof(buf));
- zlog_debug("Zebra: interface %s address add %s", c->ifp->name,
- buf);
+ zlog_debug("Zebra: interface %s address add %s vrf %s id %u",
+ c->ifp->name, buf, ospf_vrf_id_to_name(vrf_id),
+ vrf_id);
}
- ospf_if_update(NULL, c->ifp);
+ ospf = ospf_lookup_by_vrf_id(vrf_id);
+ if (!ospf)
+ return 0;
+
+ ospf_if_update(ospf, c->ifp);
hook_call(ospf_if_update, c->ifp);
@@ -330,19 +357,41 @@ static int ospf_interface_link_params(int command, struct zclient *zclient,
return 0;
}
+/* VRF update for an interface. */
+static int ospf_interface_vrf_update(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+ struct interface *ifp = NULL;
+ vrf_id_t new_vrf_id;
+
+ ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id,
+ &new_vrf_id);
+ if (!ifp)
+ return 0;
+
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: Rx Interface %s VRF change vrf_id %u New vrf %s id %u",
+ __PRETTY_FUNCTION__, ifp->name, vrf_id,
+ ospf_vrf_id_to_name(new_vrf_id), new_vrf_id);
+
+ /*if_update(ifp, ifp->name, strlen(ifp->name), new_vrf_id);*/
+ if_update_to_new_vrf(ifp, new_vrf_id);
+
+ return 0;
+}
-void ospf_zebra_add(struct prefix_ipv4 *p, struct ospf_route * or)
+void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *p,
+ struct ospf_route *or)
{
struct zapi_route api;
struct zapi_nexthop *api_nh;
u_char distance;
struct ospf_path *path;
struct listnode *node;
- struct ospf *ospf = ospf_lookup();
int count = 0;
memset(&api, 0, sizeof(api));
- api.vrf_id = VRF_DEFAULT;
+ api.vrf_id = ospf->vrf_id;
api.type = ZEBRA_ROUTE_OSPF;
api.instance = ospf->instance;
api.safi = SAFI_UNICAST;
@@ -368,7 +417,7 @@ void ospf_zebra_add(struct prefix_ipv4 *p, struct ospf_route * or)
}
/* Distance value. */
- distance = ospf_distance_apply(p, or);
+ distance = ospf_distance_apply(ospf, p, or);
if (distance) {
SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
api.distance = distance;
@@ -413,13 +462,13 @@ void ospf_zebra_add(struct prefix_ipv4 *p, struct ospf_route * or)
zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
}
-void ospf_zebra_delete(struct prefix_ipv4 *p, struct ospf_route * or)
+void ospf_zebra_delete(struct ospf *ospf, struct prefix_ipv4 *p,
+ struct ospf_route *or)
{
struct zapi_route api;
- struct ospf *ospf = ospf_lookup();
memset(&api, 0, sizeof(api));
- api.vrf_id = VRF_DEFAULT;
+ api.vrf_id = ospf->vrf_id;
api.type = ZEBRA_ROUTE_OSPF;
api.instance = ospf->instance;
api.safi = SAFI_UNICAST;
@@ -435,13 +484,12 @@ void ospf_zebra_delete(struct prefix_ipv4 *p, struct ospf_route * or)
zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
}
-void ospf_zebra_add_discard(struct prefix_ipv4 *p)
+void ospf_zebra_add_discard(struct ospf *ospf, struct prefix_ipv4 *p)
{
struct zapi_route api;
- struct ospf *ospf = ospf_lookup();
memset(&api, 0, sizeof(api));
- api.vrf_id = VRF_DEFAULT;
+ api.vrf_id = ospf->vrf_id;
api.type = ZEBRA_ROUTE_OSPF;
api.instance = ospf->instance;
api.safi = SAFI_UNICAST;
@@ -455,13 +503,12 @@ void ospf_zebra_add_discard(struct prefix_ipv4 *p)
inet_ntoa(p->prefix), p->prefixlen);
}
-void ospf_zebra_delete_discard(struct prefix_ipv4 *p)
+void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *p)
{
struct zapi_route api;
- struct ospf *ospf = ospf_lookup();
memset(&api, 0, sizeof(api));
- api.vrf_id = VRF_DEFAULT;
+ api.vrf_id = ospf->vrf_id;
api.type = ZEBRA_ROUTE_OSPF;
api.instance = ospf->instance;
api.safi = SAFI_UNICAST;
@@ -527,8 +574,7 @@ void ospf_external_del(u_char type, u_short instance)
listnode_delete(om->external[type], ext);
if (!om->external[type]->count) {
- list_free(om->external[type]);
- om->external[type] = NULL;
+ list_delete_and_null(&om->external[type]);
}
XFREE(MTYPE_OSPF_EXTERNAL, ext);
}
@@ -586,8 +632,7 @@ void ospf_redist_del(struct ospf *ospf, u_char type, u_short instance)
if (red) {
listnode_delete(ospf->redist[type], red);
if (!ospf->redist[type]->count) {
- list_free(ospf->redist[type]);
- ospf->redist[type] = NULL;
+ list_delete_and_null(&ospf->redist[type]);
}
ospf_routemap_unset(red);
XFREE(MTYPE_OSPF_REDISTRIBUTE, red);
@@ -595,11 +640,11 @@ void ospf_redist_del(struct ospf *ospf, u_char type, u_short instance)
}
-int ospf_is_type_redistributed(int type, u_short instance)
+int ospf_is_type_redistributed(struct ospf *ospf, int type, u_short instance)
{
return (DEFAULT_ROUTE_TYPE(type)
? vrf_bitmap_check(zclient->default_information,
- VRF_DEFAULT)
+ ospf->vrf_id)
: ((instance
&& redist_check_instance(
&zclient->mi_redist[AFI_IP][type],
@@ -607,7 +652,7 @@ int ospf_is_type_redistributed(int type, u_short instance)
|| (!instance
&& vrf_bitmap_check(
zclient->redist[AFI_IP][type],
- VRF_DEFAULT))));
+ ospf->vrf_id))));
}
int ospf_redistribute_set(struct ospf *ospf, int type, u_short instance,
@@ -617,7 +662,7 @@ int ospf_redistribute_set(struct ospf *ospf, int type, u_short instance,
struct ospf_redist *red;
red = ospf_redist_lookup(ospf, type, instance);
- if (ospf_is_type_redistributed(type, instance)) {
+ if (ospf_is_type_redistributed(ospf, type, instance)) {
if (mtype != red->dmetric.type) {
red->dmetric.type = mtype;
force = LSA_REFRESH_FORCE;
@@ -645,11 +690,11 @@ int ospf_redistribute_set(struct ospf *ospf, int type, u_short instance,
ospf_external_add(type, instance);
zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type,
- instance, VRF_DEFAULT);
+ instance, ospf->vrf_id);
if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
- zlog_debug("Redistribute[%s][%d]: Start Type[%d], Metric[%d]",
- ospf_redist_string(type), instance,
+ zlog_debug("Redistribute[%s][%d] vrf id %u: Start Type[%d], Metric[%d]",
+ ospf_redist_string(type), instance, ospf->vrf_id,
metric_type(ospf, type, instance),
metric_value(ospf, type, instance));
@@ -663,15 +708,15 @@ int ospf_redistribute_unset(struct ospf *ospf, int type, u_short instance)
if (type == zclient->redist_default && instance == zclient->instance)
return CMD_SUCCESS;
- if (!ospf_is_type_redistributed(type, instance))
+ if (!ospf_is_type_redistributed(ospf, type, instance))
return CMD_SUCCESS;
zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, type,
- instance, VRF_DEFAULT);
+ instance, ospf->vrf_id);
if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
- zlog_debug("Redistribute[%s][%d]: Stop",
- ospf_redist_string(type), instance);
+ zlog_debug("Redistribute[%s][%d] vrf id %u: Stop",
+ ospf_redist_string(type), instance, ospf->vrf_id);
ospf_redist_del(ospf, type, instance);
@@ -698,7 +743,7 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype,
ospf_external_add(DEFAULT_ROUTE, 0);
- if (ospf_is_type_redistributed(DEFAULT_ROUTE, 0)) {
+ if (ospf_is_type_redistributed(ospf, DEFAULT_ROUTE, 0)) {
/* if ospf->default_originate changes value, is calling
ospf_external_lsa_refresh_default sufficient to implement
the change? */
@@ -714,7 +759,7 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype,
}
zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient,
- VRF_DEFAULT);
+ ospf->vrf_id);
if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
zlog_debug("Redistribute[DEFAULT]: Start Type[%d], Metric[%d]",
@@ -734,14 +779,14 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype,
int ospf_redistribute_default_unset(struct ospf *ospf)
{
- if (!ospf_is_type_redistributed(DEFAULT_ROUTE, 0))
+ if (!ospf_is_type_redistributed(ospf, DEFAULT_ROUTE, 0))
return CMD_SUCCESS;
ospf->default_originate = DEFAULT_ORIGINATE_NONE;
ospf_redist_del(ospf, DEFAULT_ROUTE, 0);
zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient,
- VRF_DEFAULT);
+ ospf->vrf_id);
if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
zlog_debug("Redistribute[DEFAULT]: Stop");
@@ -886,7 +931,7 @@ static int ospf_zebra_read_route(int command, struct zclient *zclient,
struct ospf *ospf;
int i;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(vrf_id);
if (ospf == NULL)
return 0;
@@ -1019,10 +1064,13 @@ static int ospf_distribute_list_update_timer(struct thread *thread)
struct external_info *ei;
struct route_table *rt;
struct ospf_lsa *lsa;
- int type, default_refresh = 0;
- struct ospf *ospf;
+ int type, default_refresh = 0, arg_type;
+ struct ospf *ospf = NULL;
+ void **arg = THREAD_ARG (thread);
+
+ ospf = (struct ospf *)arg[0];
+ arg_type = (int)(intptr_t)arg[1];
- ospf = ospf_lookup();
if (ospf == NULL)
return 0;
@@ -1030,6 +1078,12 @@ static int ospf_distribute_list_update_timer(struct thread *thread)
zlog_info("Zebra[Redistribute]: distribute-list update timer fired!");
+ if (IS_DEBUG_OSPF_EVENT) {
+ zlog_debug("%s: ospf distribute-list update arg_type %d vrf %s id %d",
+ __PRETTY_FUNCTION__, arg_type,
+ ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id);
+ }
+
/* foreach all external info. */
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
struct list *ext_list;
@@ -1062,29 +1116,39 @@ static int ospf_distribute_list_update_timer(struct thread *thread)
}
if (default_refresh)
ospf_external_lsa_refresh_default(ospf);
+
+ XFREE(MTYPE_OSPF_DIST_ARGS, arg);
return 0;
}
/* Update distribute-list and set timer to apply access-list. */
-void ospf_distribute_list_update(struct ospf *ospf, uintptr_t type,
+void ospf_distribute_list_update(struct ospf *ospf, int type,
u_short instance)
{
struct route_table *rt;
struct ospf_external *ext;
+ void **args = XCALLOC(MTYPE_OSPF_DIST_ARGS, sizeof(void *)*2);
+
+ args[0] = ospf;
+ args[1] = (void *)((ptrdiff_t) type);
/* External info does not exist. */
ext = ospf_external_lookup(type, instance);
- if (!ext || !(rt = EXTERNAL_INFO(ext)))
+ if (!ext || !(rt = EXTERNAL_INFO(ext))) {
+ XFREE(MTYPE_OSPF_DIST_ARGS, args);
return;
+ }
/* If exists previously invoked thread, then let it continue. */
- if (ospf->t_distribute_update)
+ if (ospf->t_distribute_update) {
+ XFREE(MTYPE_OSPF_DIST_ARGS, args);
return;
+ }
/* Set timer. */
ospf->t_distribute_update = NULL;
thread_add_timer_msec(master, ospf_distribute_list_update_timer,
- (void *)type, ospf->min_ls_interval,
+ (void **)args, ospf->min_ls_interval,
&ospf->t_distribute_update);
}
@@ -1095,134 +1159,148 @@ static void ospf_filter_update(struct access_list *access)
int type;
int abr_inv = 0;
struct ospf_area *area;
- struct listnode *node;
+ struct listnode *node, *n1;
/* If OSPF instance does not exist, return right now. */
- ospf = ospf_lookup();
- if (ospf == NULL)
+ if (listcount(om->ospf) == 0)
return;
- /* Update distribute-list, and apply filter. */
- for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
- struct list *red_list;
- struct listnode *node;
- struct ospf_redist *red;
-
- red_list = ospf->redist[type];
- if (red_list)
- for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
- if (ROUTEMAP(red)) {
- /* if route-map is not NULL it may be
- * using this access list */
- ospf_distribute_list_update(
- ospf, type, red->instance);
+ /* Iterate all ospf [VRF] instances */
+ 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;
+ struct listnode *node;
+ struct ospf_redist *red;
+
+ red_list = ospf->redist[type];
+ if (red_list)
+ for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
+ if (ROUTEMAP(red)) {
+ /* if route-map is not NULL it may be
+ * using this access list */
+ ospf_distribute_list_update(
+ ospf,
+ type, red->instance);
+ }
}
- }
-
- /* There is place for route-map for default-information
- * (ZEBRA_ROUTE_MAX),
- * but no distribute list. */
- if (type == ZEBRA_ROUTE_MAX)
- break;
-
- if (DISTRIBUTE_NAME(ospf, type)) {
- /* Keep old access-list for distribute-list. */
- struct access_list *old = DISTRIBUTE_LIST(ospf, type);
-
- /* Update access-list for distribute-list. */
- DISTRIBUTE_LIST(ospf, type) = access_list_lookup(
- AFI_IP, DISTRIBUTE_NAME(ospf, type));
-
- /* No update for this distribute type. */
- if (old == NULL && DISTRIBUTE_LIST(ospf, type) == NULL)
- continue;
- /* Schedule distribute-list update timer. */
- if (DISTRIBUTE_LIST(ospf, type) == NULL
- || strcmp(DISTRIBUTE_NAME(ospf, type), access->name)
- == 0)
- ospf_distribute_list_update(ospf, type, 0);
+ /* There is place for route-map for default-information
+ * (ZEBRA_ROUTE_MAX),
+ * but no distribute list. */
+ if (type == ZEBRA_ROUTE_MAX)
+ break;
+
+ if (DISTRIBUTE_NAME(ospf, type)) {
+ /* Keep old access-list for distribute-list. */
+ struct access_list *old = DISTRIBUTE_LIST(ospf,
+ type);
+
+ /* Update access-list for distribute-list. */
+ DISTRIBUTE_LIST(ospf, type) = access_list_lookup(
+ AFI_IP, DISTRIBUTE_NAME(ospf, type));
+
+ /* No update for this distribute type. */
+ if (old == NULL && DISTRIBUTE_LIST(ospf, type) == NULL)
+ continue;
+
+ /* Schedule distribute-list update timer. */
+ if (DISTRIBUTE_LIST(ospf, type) == NULL
+ || strcmp(DISTRIBUTE_NAME(ospf, type), access->name)
+ == 0)
+ ospf_distribute_list_update(ospf, type, 0);
+ }
}
- }
- /* Update Area access-list. */
- for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
- if (EXPORT_NAME(area)) {
- EXPORT_LIST(area) = NULL;
- abr_inv++;
- }
+ /* Update Area access-list. */
+ for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
+ if (EXPORT_NAME(area)) {
+ EXPORT_LIST(area) = NULL;
+ abr_inv++;
+ }
- if (IMPORT_NAME(area)) {
- IMPORT_LIST(area) = NULL;
- abr_inv++;
+ if (IMPORT_NAME(area)) {
+ IMPORT_LIST(area) = NULL;
+ abr_inv++;
+ }
}
- }
- /* Schedule ABR tasks -- this will be changed -- takada. */
- if (IS_OSPF_ABR(ospf) && abr_inv)
- ospf_schedule_abr_task(ospf);
+ /* Schedule ABR tasks -- this will be changed -- takada. */
+ if (IS_OSPF_ABR(ospf) && abr_inv)
+ ospf_schedule_abr_task(ospf);
+ }
}
/* If prefix-list is updated, do some updates. */
void ospf_prefix_list_update(struct prefix_list *plist)
{
- struct ospf *ospf;
+ struct ospf *ospf = NULL;
int type;
int abr_inv = 0;
struct ospf_area *area;
- struct listnode *node;
+ struct listnode *node, *n1;
/* If OSPF instatnce does not exist, return right now. */
- ospf = ospf_lookup();
- if (ospf == NULL)
+ if (listcount(om->ospf) == 0)
return;
- /* Update all route-maps which are used as redistribution filters.
- * They might use prefix-list.
- */
- for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
- struct list *red_list;
- struct listnode *node;
- struct ospf_redist *red;
-
- red_list = ospf->redist[type];
- if (red_list)
- for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
- if (ROUTEMAP(red)) {
- /* if route-map is not NULL it may be
- * using this prefix list */
- ospf_distribute_list_update(
- ospf, type, red->instance);
+ /* Iterate all ospf [VRF] instances */
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
+
+ /* Update all route-maps which are used
+ * as redistribution filters.
+ * They might use prefix-list.
+ */
+ for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
+ struct list *red_list;
+ struct listnode *node;
+ struct ospf_redist *red;
+
+ red_list = ospf->redist[type];
+ if (red_list) {
+ for (ALL_LIST_ELEMENTS_RO(red_list,
+ node, red)) {
+ if (ROUTEMAP(red)) {
+ /* if route-map is not NULL
+ * it may be using
+ * this prefix list */
+ ospf_distribute_list_update(
+ ospf, type,
+ red->instance);
+ }
}
}
- }
+ }
- /* Update area filter-lists. */
- for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
- /* Update filter-list in. */
- if (PREFIX_NAME_IN(area))
- if (strcmp(PREFIX_NAME_IN(area),
- prefix_list_name(plist))
- == 0) {
- PREFIX_LIST_IN(area) = prefix_list_lookup(
- AFI_IP, PREFIX_NAME_IN(area));
- abr_inv++;
- }
+ /* Update area filter-lists. */
+ for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
+ /* Update filter-list in. */
+ if (PREFIX_NAME_IN(area))
+ if (strcmp(PREFIX_NAME_IN(area),
+ prefix_list_name(plist)) == 0) {
+ PREFIX_LIST_IN(area) =
+ prefix_list_lookup(
+ AFI_IP,
+ PREFIX_NAME_IN(area));
+ abr_inv++;
+ }
- /* Update filter-list out. */
- if (PREFIX_NAME_OUT(area))
- if (strcmp(PREFIX_NAME_OUT(area),
- prefix_list_name(plist))
- == 0) {
- PREFIX_LIST_IN(area) = prefix_list_lookup(
- AFI_IP, PREFIX_NAME_OUT(area));
- abr_inv++;
- }
- }
+ /* Update filter-list out. */
+ if (PREFIX_NAME_OUT(area))
+ if (strcmp(PREFIX_NAME_OUT(area),
+ prefix_list_name(plist)) == 0) {
+ PREFIX_LIST_IN(area) =
+ prefix_list_lookup(
+ AFI_IP,
+ PREFIX_NAME_OUT(area));
+ abr_inv++;
+ }
+ }
- /* Schedule ABR task. */
- if (IS_OSPF_ABR(ospf) && abr_inv)
- ospf_schedule_abr_task(ospf);
+ /* Schedule ABR task. */
+ if (IS_OSPF_ABR(ospf) && abr_inv)
+ ospf_schedule_abr_task(ospf);
+ }
}
static struct ospf_distance *ospf_distance_new(void)
@@ -1326,11 +1404,10 @@ void ospf_distance_reset(struct ospf *ospf)
}
}
-u_char ospf_distance_apply(struct prefix_ipv4 *p, struct ospf_route * or)
+u_char ospf_distance_apply(struct ospf *ospf, struct prefix_ipv4 *p,
+ struct ospf_route *or)
{
- struct ospf *ospf;
- ospf = ospf_lookup();
if (ospf == NULL)
return 0;
@@ -1353,6 +1430,37 @@ u_char ospf_distance_apply(struct prefix_ipv4 *p, struct ospf_route * or)
return 0;
}
+void ospf_zebra_vrf_register(struct ospf *ospf)
+{
+ if (!zclient || zclient->sock < 0 || !ospf)
+ return;
+
+ if (ospf->vrf_id != VRF_DEFAULT && ospf->vrf_id != VRF_UNKNOWN) {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: Register VRF %s id %u",
+ __PRETTY_FUNCTION__,
+ ospf_vrf_id_to_name(ospf->vrf_id),
+ ospf->vrf_id);
+ zclient_send_reg_requests(zclient, ospf->vrf_id);
+ }
+}
+
+void ospf_zebra_vrf_deregister(struct ospf *ospf)
+{
+ if (!zclient || zclient->sock < 0 || !ospf)
+ return;
+
+ if (ospf->vrf_id != VRF_DEFAULT && ospf->vrf_id != VRF_UNKNOWN) {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: De-Register VRF %s id %u",
+ __PRETTY_FUNCTION__,
+ ospf_vrf_id_to_name(ospf->vrf_id),
+ ospf->vrf_id);
+ /* Deregister for router-id, interfaces,
+ * redistributed routes. */
+ zclient_send_dereg_requests(zclient, ospf->vrf_id);
+ }
+}
static void ospf_zebra_connected(struct zclient *zclient)
{
/* Send the client registration */
@@ -1375,6 +1483,7 @@ void ospf_zebra_init(struct thread_master *master, u_short instance)
zclient->interface_address_add = ospf_interface_address_add;
zclient->interface_address_delete = ospf_interface_address_delete;
zclient->interface_link_params = ospf_interface_link_params;
+ zclient->interface_vrf_update = ospf_interface_vrf_update;
zclient->redistribute_route_add = ospf_zebra_read_route;
zclient->redistribute_route_del = ospf_zebra_read_route;
diff --git a/ospfd/ospf_zebra.h b/ospfd/ospf_zebra.h
index 6fa9e33ddd..8340f49ede 100644
--- a/ospfd/ospf_zebra.h
+++ b/ospfd/ospf_zebra.h
@@ -41,21 +41,24 @@ struct ospf_distance {
};
/* Prototypes */
-extern void ospf_zebra_add(struct prefix_ipv4 *, struct ospf_route *);
-extern void ospf_zebra_delete(struct prefix_ipv4 *, struct ospf_route *);
+extern void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *,
+ struct ospf_route *);
+extern void ospf_zebra_delete(struct ospf *ospf, struct prefix_ipv4 *,
+ struct ospf_route *);
-extern void ospf_zebra_add_discard(struct prefix_ipv4 *);
-extern void ospf_zebra_delete_discard(struct prefix_ipv4 *);
+extern void ospf_zebra_add_discard(struct ospf *ospf, struct prefix_ipv4 *);
+extern void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *);
extern int ospf_redistribute_check(struct ospf *, struct external_info *,
int *);
extern int ospf_distribute_check_connected(struct ospf *,
struct external_info *);
-extern void ospf_distribute_list_update(struct ospf *, uintptr_t, u_short);
+extern void ospf_distribute_list_update(struct ospf *, int, u_short);
-extern int ospf_is_type_redistributed(int, u_short);
+extern int ospf_is_type_redistributed(struct ospf *, int, u_short);
extern void ospf_distance_reset(struct ospf *);
-extern u_char ospf_distance_apply(struct prefix_ipv4 *, struct ospf_route *);
+extern u_char ospf_distance_apply(struct ospf *ospf, struct prefix_ipv4 *,
+ struct ospf_route *);
extern struct ospf_external *ospf_external_lookup(u_char, u_short);
extern struct ospf_external *ospf_external_add(u_char, u_short);
extern void ospf_external_del(u_char, u_short);
@@ -77,6 +80,8 @@ extern int ospf_distance_set(struct vty *, struct ospf *, const char *,
extern int ospf_distance_unset(struct vty *, struct ospf *, const char *,
const char *, const char *);
extern void ospf_zebra_init(struct thread_master *, u_short);
+extern void ospf_zebra_vrf_register(struct ospf *ospf);
+extern void ospf_zebra_vrf_deregister(struct ospf *ospf);
DECLARE_HOOK(ospf_if_update, (struct interface * ifp), (ifp))
DECLARE_HOOK(ospf_if_delete, (struct interface * ifp), (ifp))
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index ed1d8901fb..88833e64de 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -67,6 +67,7 @@ struct ospf_master *om;
extern struct zclient *zclient;
extern struct in_addr router_id_zebra;
+extern struct zebra_privs_t ospfd_privs;
static void ospf_remove_vls_through_area(struct ospf *, struct ospf_area *);
@@ -118,6 +119,10 @@ void ospf_router_id_update(struct ospf *ospf)
else
router_id = router_id_zebra;
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("Router-ID[OLD:%s]: Update to %s",
+ inet_ntoa(ospf->router_id),
+ inet_ntoa(router_id_old));
if (!IPV4_ADDR_SAME(&router_id_old, &router_id)) {
@@ -204,7 +209,7 @@ void ospf_router_id_update(struct ospf *ospf)
ospf_router_lsa_update(ospf);
/* update ospf_interface's */
- for (ALL_LIST_ELEMENTS_RO(om->iflist, node, ifp))
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), node, ifp))
ospf_if_update(ospf, ifp);
}
}
@@ -220,9 +225,10 @@ static int ospf_area_id_cmp(struct ospf_area *a1, struct ospf_area *a2)
}
/* Allocate new ospf structure. */
-static struct ospf *ospf_new(u_short instance)
+static struct ospf *ospf_new(u_short instance, const char *name)
{
int i;
+ struct vrf *vrf = NULL;
struct ospf *new = XCALLOC(MTYPE_OSPF_TOP, sizeof(struct ospf));
@@ -230,6 +236,23 @@ static struct ospf *ospf_new(u_short instance)
new->router_id.s_addr = htonl(0);
new->router_id_static.s_addr = htonl(0);
+ if (name) {
+ new->vrf_id = VRF_UNKNOWN;
+ /* Freed in ospf_finish_final */
+ new->name = XSTRDUP(MTYPE_OSPF_TOP, name);
+ vrf = vrf_lookup_by_name(new->name);
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: Create new ospf instance with vrf_name %s vrf_id %d",
+ __PRETTY_FUNCTION__, name, new->vrf_id);
+ if (vrf)
+ ospf_vrf_link(new, vrf);
+ } else {
+ new->vrf_id = VRF_DEFAULT;
+ vrf = vrf_lookup_by_id(VRF_DEFAULT);
+ ospf_vrf_link(new, vrf);
+ }
+ ospf_zebra_vrf_register(new);
+
new->abr_type = OSPF_ABR_DEFAULT;
new->oiflist = list_new();
new->vlinks = list_new();
@@ -286,7 +309,7 @@ static struct ospf *ospf_new(u_short instance)
new->lsa_refresh_interval, &new->t_lsa_refresher);
new->lsa_refresher_started = monotime(NULL);
- if ((new->fd = ospf_sock_init()) < 0) {
+ if ((ospf_sock_init(new)) < 0) {
zlog_err(
"ospf_new: fatal error: ospf_sock_init was unable to open "
"a socket");
@@ -313,14 +336,6 @@ static struct ospf *ospf_new(u_short instance)
return new;
}
-struct ospf *ospf_lookup()
-{
- if (listcount(om->ospf) == 0)
- return NULL;
-
- return listgetdata((struct listnode *)listhead(om->ospf));
-}
-
struct ospf *ospf_lookup_instance(u_short instance)
{
struct ospf *ospf;
@@ -357,13 +372,33 @@ static void ospf_delete(struct ospf *ospf)
listnode_delete(om->ospf, ospf);
}
-struct ospf *ospf_get()
+struct ospf *ospf_lookup_by_inst_name(u_short instance, const char *name)
+{
+ struct ospf *ospf = NULL;
+ struct listnode *node, *nnode;
+
+ for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf)) {
+ if ((ospf->instance == instance) &&
+ ((ospf->name == NULL && name == NULL) ||
+ (ospf->name && name && strcmp(ospf->name, name) == 0)))
+ return ospf;
+ }
+ return NULL;
+}
+
+struct ospf *ospf_get(u_short instance, const char *name)
{
struct ospf *ospf;
- ospf = ospf_lookup();
+ /* vrf name provided call inst and name based api
+ * in case of no name pass default ospf instance */
+ if (name)
+ ospf = ospf_lookup_by_inst_name(instance, name);
+ else
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+
if (ospf == NULL) {
- ospf = ospf_new(0);
+ ospf = ospf_new(instance, name);
ospf_add(ospf);
if (ospf->router_id_static.s_addr == 0)
@@ -381,11 +416,20 @@ struct ospf *ospf_get_instance(u_short instance)
ospf = ospf_lookup_instance(instance);
if (ospf == NULL) {
- ospf = ospf_new(instance);
+ ospf = ospf_new(instance, NULL /* VRF_DEFAULT*/);
ospf_add(ospf);
- if (ospf->router_id_static.s_addr == 0)
+ if (ospf->router_id_static.s_addr == 0) {
+ if (vrf_lookup_by_id(ospf->vrf_id))
+ ospf_router_id_update(ospf);
+ else {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: ospf VRF (id %d) is not active yet, skip router id update"
+ , __PRETTY_FUNCTION__,
+ ospf->vrf_id);
+ }
ospf_router_id_update(ospf);
+ }
ospf_opaque_type11_lsa_init(ospf);
}
@@ -393,6 +437,34 @@ struct ospf *ospf_get_instance(u_short instance)
return ospf;
}
+struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id)
+{
+ struct vrf *vrf = NULL;
+
+ vrf = vrf_lookup_by_id(vrf_id);
+ if (!vrf)
+ return NULL;
+ return (vrf->info) ? (struct ospf *)vrf->info : NULL;
+
+}
+
+/* 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 && vrf_name == NULL)
+ || (ospf->name && vrf_name &&
+ strcmp(ospf->name, vrf_name) == 0))
+ return ospf;
+ return NULL;
+}
+
/* Handle the second half of deferred shutdown. This is called either
* from the deferred-shutdown timer thread, or directly through
* ospf_deferred_shutdown_check.
@@ -519,6 +591,7 @@ static void ospf_finish_final(struct ospf *ospf)
struct listnode *node, *nnode;
int i;
u_short instance = 0;
+ struct vrf *vrf = NULL;
QOBJ_UNREG(ospf);
@@ -547,10 +620,10 @@ static void ospf_finish_final(struct ospf *ospf)
for (ALL_LIST_ELEMENTS(ospf->vlinks, node, nnode, vl_data))
ospf_vl_delete(ospf, vl_data);
- list_delete(ospf->vlinks);
+ list_delete_and_null(&ospf->vlinks);
/* Remove any ospf interface config params */
- for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), node, ifp)) {
struct ospf_if_params *params;
params = IF_DEF_PARAMS(ifp);
@@ -561,6 +634,10 @@ static void ospf_finish_final(struct ospf *ospf)
/* Reset interface. */
for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi))
ospf_if_free(oi);
+ list_delete_and_null(&ospf->oiflist);
+
+ /* De-Register VRF */
+ ospf_zebra_vrf_deregister(ospf);
/* Clear static neighbors */
for (rn = route_top(ospf->nbr_nbma); rn; rn = route_next(rn))
@@ -639,7 +716,7 @@ static void ospf_finish_final(struct ospf *ospf)
if (ospf->old_table)
ospf_route_table_free(ospf->old_table);
if (ospf->new_table) {
- ospf_route_delete(ospf->new_table);
+ ospf_route_delete(ospf, ospf->new_table);
ospf_route_table_free(ospf->new_table);
}
if (ospf->old_rtrs)
@@ -647,20 +724,19 @@ static void ospf_finish_final(struct ospf *ospf)
if (ospf->new_rtrs)
ospf_rtrs_free(ospf->new_rtrs);
if (ospf->new_external_route) {
- ospf_route_delete(ospf->new_external_route);
+ ospf_route_delete(ospf, ospf->new_external_route);
ospf_route_table_free(ospf->new_external_route);
}
if (ospf->old_external_route) {
- ospf_route_delete(ospf->old_external_route);
+ ospf_route_delete(ospf, ospf->old_external_route);
ospf_route_table_free(ospf->old_external_route);
}
if (ospf->external_lsas) {
ospf_ase_external_lsas_finish(ospf->external_lsas);
}
- list_delete(ospf->areas);
- list_delete(ospf->oi_write_q);
- list_delete(ospf->oiflist);
+ list_delete_and_null(&ospf->areas);
+ list_delete_and_null(&ospf->oi_write_q);
for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++) {
struct list *ext_list;
@@ -694,6 +770,17 @@ static void ospf_finish_final(struct ospf *ospf)
ospf_delete(ospf);
+ if (ospf->name) {
+ vrf = vrf_lookup_by_name(ospf->name);
+ if (vrf)
+ ospf_vrf_unlink(ospf, vrf);
+ XFREE(MTYPE_OSPF_TOP, ospf->name);
+ } else {
+ vrf = vrf_lookup_by_id(VRF_DEFAULT);
+ if (vrf)
+ ospf_vrf_unlink(ospf, vrf);
+ }
+
XFREE(MTYPE_OSPF_TOP, ospf);
if (!CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN))
@@ -741,6 +828,8 @@ static void ospf_area_free(struct ospf_area *area)
struct route_node *rn;
struct ospf_lsa *lsa;
+ ospf_opaque_type10_lsa_term(area);
+
/* Free LSDBs. */
LSDB_LOOP(ROUTER_LSDB(area), rn, lsa)
ospf_discard_from_db(area->ospf, area->lsdb, lsa);
@@ -765,7 +854,7 @@ static void ospf_area_free(struct ospf_area *area)
ospf_lsa_unlock(&area->router_lsa_self);
route_table_finish(area->ranges);
- list_delete(area->oiflist);
+ list_delete_and_null(&area->oiflist);
if (EXPORT_NAME(area))
free(EXPORT_NAME(area));
@@ -883,7 +972,7 @@ static void update_redistributed(struct ospf *ospf, int add_to_ospf)
struct external_info *ei;
struct ospf_external *ext;
- if (ospf_is_type_redistributed(ZEBRA_ROUTE_CONNECT, 0))
+ if (ospf_is_type_redistributed(ospf, ZEBRA_ROUTE_CONNECT, 0))
if ((ext = ospf_external_lookup(ZEBRA_ROUTE_CONNECT, 0))
&& EXTERNAL_INFO(ext)) {
for (rn = route_top(EXTERNAL_INFO(ext)); rn;
@@ -1004,9 +1093,10 @@ int ospf_network_unset(struct ospf *ospf, struct prefix_ipv4 *p,
*
* Otherwise, doesn't do anything different to ospf_if_update for now
*/
-void ospf_interface_area_set(struct interface *ifp)
+void ospf_interface_area_set(struct ospf *ospf, struct interface *ifp)
{
- struct ospf *ospf = ospf_get();
+ if (!ospf)
+ return;
ospf_if_update(ospf, ifp);
/* if_update does a update_redistributed */
@@ -1014,19 +1104,17 @@ void ospf_interface_area_set(struct interface *ifp)
return;
}
-void ospf_interface_area_unset(struct interface *ifp)
+void ospf_interface_area_unset(struct ospf *ospf, struct interface *ifp)
{
struct route_node *rn_oi;
- struct ospf *ospf;
- ospf = ospf_lookup();
if (!ospf)
return; /* Ospf not ready yet */
/* Find interfaces that may need to be removed. */
for (rn_oi = route_top(IF_OIFS(ifp)); rn_oi;
rn_oi = route_next(rn_oi)) {
- struct ospf_interface *oi;
+ struct ospf_interface *oi = NULL;
if ((oi = rn_oi->info) == NULL)
continue;
@@ -1174,7 +1262,7 @@ static void ospf_network_run(struct prefix *p, struct ospf_area *area)
ospf_router_id_update(area->ospf);
/* Get target interface. */
- for (ALL_LIST_ELEMENTS_RO(om->iflist, node, ifp))
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(area->ospf->vrf_id), node, ifp))
ospf_network_run_interface(area->ospf, ifp, p, area);
}
@@ -1190,7 +1278,7 @@ void ospf_ls_upd_queue_empty(struct ospf_interface *oi)
if ((lst = (struct list *)rn->info)) {
for (ALL_LIST_ELEMENTS(lst, node, nnode, lsa))
ospf_lsa_unlock(&lsa); /* oi->ls_upd_queue */
- list_delete(lst);
+ list_delete_and_null(&lst);
rn->info = NULL;
}
@@ -1203,8 +1291,15 @@ 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();
+ return;
+
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: interface %s ifp->vrf_id %u ospf vrf %s vrf_id %u router_id %s",
+ __PRETTY_FUNCTION__, ifp->name, ifp->vrf_id,
+ ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id,
+ inet_ntoa(ospf->router_id));
/* OSPF must be ready. */
if (!ospf_is_ready(ospf))
@@ -1863,3 +1958,128 @@ void ospf_master_init(struct thread_master *master)
om->ospf = list_new();
om->master = master;
}
+
+/* Link OSPF instance to VRF. */
+void ospf_vrf_link(struct ospf *ospf, struct vrf *vrf)
+{
+ ospf->vrf_id = vrf->vrf_id;
+ if (vrf->info != (void *)ospf)
+ vrf->info = (void *)ospf;
+}
+
+/* Unlink OSPF instance from VRF. */
+void ospf_vrf_unlink(struct ospf *ospf, struct vrf *vrf)
+{
+ if (vrf->info == (void *)ospf)
+ vrf->info = NULL;
+ ospf->vrf_id = VRF_UNKNOWN;
+}
+
+/* This is hook function for vrf create called as part of vrf_init */
+static int ospf_vrf_new(struct vrf *vrf)
+{
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: VRF Created: %s(%d)", __PRETTY_FUNCTION__,
+ vrf->name, vrf->vrf_id);
+
+ return 0;
+}
+
+/* This is hook function for vrf delete call as part of vrf_init */
+static int ospf_vrf_delete(struct vrf *vrf)
+{
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: VRF Deletion: %s(%d)", __PRETTY_FUNCTION__,
+ vrf->name, vrf->vrf_id);
+
+ return 0;
+}
+
+/* Enable OSPF VRF instance */
+static int ospf_vrf_enable(struct vrf *vrf)
+{
+ struct ospf *ospf = NULL;
+ vrf_id_t old_vrf_id = VRF_DEFAULT;
+
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: VRF %s id %d enabled",
+ __PRETTY_FUNCTION__, vrf->name, vrf->vrf_id);
+
+ ospf = ospf_lookup_by_name(vrf->name);
+ if (ospf) {
+ old_vrf_id = ospf->vrf_id;
+ /* We have instance configured, link to VRF and make it "up". */
+ ospf_vrf_link(ospf, vrf);
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: ospf linked to vrf %s vrf_id %d (old id %d)",
+ __PRETTY_FUNCTION__, vrf->name, ospf->vrf_id,
+ old_vrf_id);
+
+ if (old_vrf_id != ospf->vrf_id) {
+ if (ospfd_privs.change(ZPRIVS_RAISE)) {
+ zlog_err("ospf_sock_init: could not raise privs, %s",
+ safe_strerror(errno));
+ }
+ if (ospf_bind_vrfdevice(ospf, ospf->fd) < 0)
+ return 0;
+ if (ospfd_privs.change(ZPRIVS_LOWER)) {
+ zlog_err("ospf_sock_init: could not lower privs, %s",
+ safe_strerror(errno));
+ }
+
+ ospf->oi_running = 1;
+ ospf_router_id_update(ospf);
+ }
+ }
+
+ return 0;
+}
+
+/* Disable OSPF VRF instance */
+static int ospf_vrf_disable(struct vrf *vrf)
+{
+ struct ospf *ospf = NULL;
+ vrf_id_t old_vrf_id = VRF_UNKNOWN;
+
+ if (vrf->vrf_id == VRF_DEFAULT)
+ return 0;
+
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: VRF %s id %d disabled.",
+ __PRETTY_FUNCTION__, vrf->name, vrf->vrf_id);
+
+ ospf = ospf_lookup_by_name(vrf->name);
+ if (ospf) {
+ old_vrf_id = ospf->vrf_id;
+
+ /* We have instance configured, unlink
+ * from VRF and make it "down".
+ */
+ ospf_vrf_unlink(ospf, vrf);
+ ospf->oi_running = 0;
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: ospf old_vrf_id %d unlinked",
+ __PRETTY_FUNCTION__, old_vrf_id);
+ }
+
+ /* Note: This is a callback, the VRF will be deleted by the caller. */
+ return 0;
+}
+
+void ospf_vrf_init(void)
+{
+ vrf_init(ospf_vrf_new, ospf_vrf_enable,
+ ospf_vrf_disable, ospf_vrf_delete);
+}
+
+void ospf_vrf_terminate(void)
+{
+ vrf_terminate();
+}
+
+const char *ospf_vrf_id_to_name(vrf_id_t vrf_id)
+{
+ struct vrf *vrf = vrf_lookup_by_id(vrf_id);
+
+ return vrf ? vrf->name : "NIL";
+}
diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h
index b49bbdc17d..01147c2004 100644
--- a/ospfd/ospfd.h
+++ b/ospfd/ospfd.h
@@ -28,6 +28,7 @@
#include "filter.h"
#include "log.h"
+#include "vrf.h"
#include "ospf_memory.h"
#include "ospf_dump_api.h"
@@ -92,8 +93,6 @@ struct ospf_master {
/* OSPF thread master. */
struct thread_master *master;
- /* Zebra interface list. */
- struct list *iflist;
/* Redistributed external information. */
struct list *external[ZEBRA_ROUTE_MAX + 1];
@@ -136,6 +135,9 @@ struct ospf {
struct in_addr router_id; /* Configured automatically. */
struct in_addr router_id_static; /* Configured manually. */
+ vrf_id_t vrf_id; /* VRF Id */
+ char *name; /* VRF name */
+
/* ABR/ASBR internal flags. */
u_char flags;
#define OSPF_FLAG_ABR 0x0001
@@ -503,10 +505,12 @@ extern int ospf_zlog;
/* Prototypes. */
extern const char *ospf_redist_string(u_int route_type);
-extern struct ospf *ospf_lookup(void);
extern struct ospf *ospf_lookup_instance(u_short);
-extern struct ospf *ospf_get(void);
+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_inst_name(u_short instance,
+ const char *name);
+extern struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id);
extern void ospf_finish(struct ospf *);
extern void ospf_router_id_update(struct ospf *ospf);
extern int ospf_network_set(struct ospf *, struct prefix_ipv4 *, struct in_addr,
@@ -559,11 +563,15 @@ extern struct ospf_area *ospf_area_lookup_by_area_id(struct ospf *,
extern void ospf_area_add_if(struct ospf_area *, struct ospf_interface *);
extern void ospf_area_del_if(struct ospf_area *, struct ospf_interface *);
-extern void ospf_interface_area_set(struct interface *);
-extern void ospf_interface_area_unset(struct interface *);
+extern void ospf_interface_area_set(struct ospf *, struct interface *);
+extern void ospf_interface_area_unset(struct ospf *, struct interface *);
extern void ospf_route_map_init(void);
extern void ospf_master_init(struct thread_master *master);
-
+extern void ospf_vrf_init(void);
+extern void ospf_vrf_terminate(void);
+extern void ospf_vrf_link(struct ospf *ospf, struct vrf *vrf);
+extern void ospf_vrf_unlink(struct ospf *ospf, struct vrf *vrf);
+const char *ospf_vrf_id_to_name(vrf_id_t vrf_id);
#endif /* _ZEBRA_OSPFD_H */
diff --git a/ospfd/subdir.am b/ospfd/subdir.am
index 12c2313e65..e063415fbd 100644
--- a/ospfd/subdir.am
+++ b/ospfd/subdir.am
@@ -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 \
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index 1ebe9c9aba..ed1d6a8195 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -1063,58 +1063,48 @@ static void pim_show_interfaces_single(struct pim_instance *pim,
// FHR
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode,
up)) {
- if (ifp == up->rpf.source_nexthop.interface) {
- if (up->flags
- & PIM_UPSTREAM_FLAG_MASK_FHR) {
- if (!json_fhr_sources) {
- json_fhr_sources =
- json_object_new_object();
- }
-
- pim_inet4_dump("<src?>",
- up->sg.src,
- src_str,
- sizeof(src_str));
- pim_inet4_dump("<grp?>",
- up->sg.grp,
- grp_str,
- sizeof(grp_str));
- pim_time_uptime(
- uptime, sizeof(uptime),
- now - up->state_transition);
-
- /* Does this group live in
- * json_fhr_sources? If not
- * create it. */
- json_object_object_get_ex(
- json_fhr_sources,
- grp_str, &json_group);
-
- if (!json_group) {
- json_group =
- json_object_new_object();
- json_object_object_add(
- json_fhr_sources,
- grp_str,
- json_group);
- }
-
- json_group_source =
- json_object_new_object();
- json_object_string_add(
- json_group_source,
- "source", src_str);
- json_object_string_add(
- json_group_source,
- "group", grp_str);
- json_object_string_add(
- json_group_source,
- "upTime", uptime);
- json_object_object_add(
- json_group, src_str,
- json_group_source);
- }
+ if (ifp != up->rpf.source_nexthop.interface)
+ continue;
+
+ if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_FHR))
+ continue;
+
+ if (!json_fhr_sources)
+ json_fhr_sources =
+ json_object_new_object();
+
+ pim_inet4_dump("<src?>", up->sg.src,
+ src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", up->sg.grp,
+ grp_str, sizeof(grp_str));
+ pim_time_uptime(uptime, sizeof(uptime),
+ now - up->state_transition);
+
+ /*
+ * Does this group live in json_fhr_sources?
+ * If not create it.
+ */
+ json_object_object_get_ex(json_fhr_sources,
+ grp_str,
+ &json_group);
+
+ if (!json_group) {
+ json_group = json_object_new_object();
+ json_object_object_add(
+ json_fhr_sources,
+ grp_str,
+ json_group);
}
+
+ json_group_source = json_object_new_object();
+ json_object_string_add(json_group_source,
+ "source", src_str);
+ json_object_string_add(json_group_source,
+ "group", grp_str);
+ json_object_string_add(json_group_source,
+ "upTime", uptime);
+ json_object_object_add(json_group, src_str,
+ json_group_source);
}
if (json_fhr_sources) {
@@ -1237,37 +1227,33 @@ static void pim_show_interfaces_single(struct pim_instance *pim,
print_header = 1;
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode,
up)) {
- if (strcmp(ifp->name, up->rpf.source_nexthop
- .interface->name)
- == 0) {
- if (up->flags
- & PIM_UPSTREAM_FLAG_MASK_FHR) {
-
- if (print_header) {
- vty_out(vty,
- "FHR - First Hop Router\n");
- vty_out(vty,
- "----------------------\n");
- print_header = 0;
- }
-
- pim_inet4_dump("<src?>",
- up->sg.src,
- src_str,
- sizeof(src_str));
- pim_inet4_dump("<grp?>",
- up->sg.grp,
- grp_str,
- sizeof(grp_str));
- pim_time_uptime(
- uptime, sizeof(uptime),
- now - up->state_transition);
- vty_out(vty,
- "%s : %s is a source, uptime is %s\n",
- grp_str, src_str,
- uptime);
- }
+
+ if (strcmp(ifp->name,
+ up->rpf.source_nexthop.
+ interface->name) != 0)
+ continue;
+
+ if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_FHR))
+ continue;
+
+ if (print_header) {
+ vty_out(vty,
+ "FHR - First Hop Router\n");
+ vty_out(vty,
+ "----------------------\n");
+ print_header = 0;
}
+
+ pim_inet4_dump("<src?>", up->sg.src,
+ src_str, sizeof(src_str));
+ pim_inet4_dump("<grp?>", up->sg.grp,
+ grp_str, sizeof(grp_str));
+ pim_time_uptime(uptime, sizeof(uptime),
+ now - up->state_transition);
+ vty_out(vty,
+ "%s : %s is a source, uptime is %s\n",
+ grp_str, src_str,
+ uptime);
}
if (!print_header) {
@@ -2400,6 +2386,30 @@ static void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
json_object_string_add(
json_row, "inboundInterface",
up->rpf.source_nexthop.interface->name);
+
+ /*
+ * The RPF address we use is slightly different
+ * based upon what we are looking up.
+ * If we have a S, list that unless
+ * we are the FHR, else we just put
+ * the RP as the rpfAddress
+ */
+ if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR ||
+ up->sg.src.s_addr == INADDR_ANY) {
+ char rpf[PREFIX_STRLEN];
+ struct pim_rpf *rpg;
+
+ rpg = RP(pim, up->sg.grp);
+ pim_inet4_dump("<rpf?>",
+ rpg->rpf_addr.u.prefix4,
+ rpf, sizeof(rpf));
+ json_object_string_add(json_row,
+ "rpfAddress", rpf);
+ } else {
+ json_object_string_add(json_row,
+ "rpfAddress", src_str);
+ }
+
json_object_string_add(json_row, "source", src_str);
json_object_string_add(json_row, "group", grp_str);
json_object_string_add(json_row, "state", state_str);
@@ -3160,12 +3170,12 @@ static void clear_interfaces(struct pim_instance *pim)
clear_pim_interfaces(pim);
}
-#define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
- pim_ifp = ifp->info; \
- if (!pim_ifp) { \
- vty_out(vty, \
+#define PIM_GET_PIM_INTERFACE(pim_ifp, ifp) \
+ pim_ifp = ifp->info; \
+ if (!pim_ifp) { \
+ vty_out(vty, \
"%% Enable PIM and/or IGMP on this interface first\n"); \
- return CMD_WARNING_CONFIG_FAILED; \
+ return CMD_WARNING_CONFIG_FAILED; \
}
DEFUN (clear_ip_interfaces,
@@ -4451,7 +4461,8 @@ DEFUN (show_ip_multicast_vrf_all,
return CMD_SUCCESS;
}
-static void show_mroute(struct pim_instance *pim, struct vty *vty, u_char uj)
+static void show_mroute(struct pim_instance *pim, struct vty *vty,
+ bool fill, u_char uj)
{
struct listnode *node;
struct channel_oil *c_oil;
@@ -4704,11 +4715,9 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty, u_char uj)
continue;
ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
- pim_time_uptime(
- oif_uptime, sizeof(oif_uptime),
- now
- - s_route->c_oil
- .oif_creation[oif_vif_index]);
+ pim_time_uptime(oif_uptime, sizeof(oif_uptime),
+ now -
+ s_route->c_oil.oif_creation[oif_vif_index]);
found_oif = 1;
if (ifp_out)
@@ -4751,7 +4760,7 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty, u_char uj)
src_str, grp_str, proto, in_ifname,
out_ifname, ttl, oif_uptime,
pim->vrf->name);
- if (first) {
+ if (first && !fill) {
src_str[0] = '\0';
grp_str[0] = '\0';
in_ifname[0] = '\0';
@@ -4777,36 +4786,47 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty, u_char uj)
DEFUN (show_ip_mroute,
show_ip_mroute_cmd,
- "show ip mroute [vrf NAME] [json]",
+ "show ip mroute [vrf NAME] [fill] [json]",
SHOW_STR
IP_STR
MROUTE_STR
VRF_CMD_HELP_STR
+ "Fill in Assumed data\n"
JSON_STR)
{
u_char uj = use_json(argc, argv);
+ bool fill = false;
int idx = 2;
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
if (!vrf)
return CMD_WARNING;
- show_mroute(vrf->info, vty, uj);
+ if (argv_find(argv, argc, "fill", &idx))
+ fill = true;
+
+ show_mroute(vrf->info, vty, fill, uj);
return CMD_SUCCESS;
}
DEFUN (show_ip_mroute_vrf_all,
show_ip_mroute_vrf_all_cmd,
- "show ip mroute vrf all [json]",
+ "show ip mroute vrf all [fill] [json]",
SHOW_STR
IP_STR
MROUTE_STR
VRF_CMD_HELP_STR
+ "Fill in Assumed data\n"
JSON_STR)
{
u_char uj = use_json(argc, argv);
+ int idx = 4;
struct vrf *vrf;
bool first = true;
+ bool fill = false;
+
+ if (argv_find(argv, argc, "fill", &idx))
+ fill = true;
if (uj)
vty_out(vty, "{ ");
@@ -4818,7 +4838,7 @@ DEFUN (show_ip_mroute_vrf_all,
first = false;
} else
vty_out(vty, "VRF: %s\n", vrf->name);
- show_mroute(vrf->info, vty, uj);
+ show_mroute(vrf->info, vty, fill, uj);
}
if (uj)
vty_out(vty, "}\n");
@@ -6470,7 +6490,7 @@ DEFUN(interface_ip_pim_boundary_oil,
"Generic multicast configuration options\n"
"Define multicast boundary\n"
"Filter OIL by group using prefix list\n"
- "Prefix list to filter OIL with")
+ "Prefix list to filter OIL with\n")
{
VTY_DECLVAR_CONTEXT(interface, iif);
struct pim_interface *pim_ifp;
@@ -6498,11 +6518,11 @@ DEFUN(interface_no_ip_pim_boundary_oil,
"Generic multicast configuration options\n"
"Define multicast boundary\n"
"Filter OIL by group using prefix list\n"
- "Prefix list to filter OIL with")
+ "Prefix list to filter OIL with\n")
{
VTY_DECLVAR_CONTEXT(interface, iif);
struct pim_interface *pim_ifp;
- int idx;
+ int idx = 0;
argv_find(argv, argc, "WORD", &idx);
diff --git a/pimd/pim_hello.c b/pimd/pim_hello.c
index 138a110d3a..08a1432bb0 100644
--- a/pimd/pim_hello.c
+++ b/pimd/pim_hello.c
@@ -125,9 +125,9 @@ static void tlv_trace_list(const char *label, const char *tlv_name,
}
}
-#define FREE_ADDR_LIST \
- if (hello_option_addr_list) { \
- list_delete(hello_option_addr_list); \
+#define FREE_ADDR_LIST \
+ if (hello_option_addr_list) { \
+ list_delete_and_null(&hello_option_addr_list); \
}
#define FREE_ADDR_LIST_THEN_RETURN(code) \
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index b8cbed7f93..8787145027 100644
--- a/pimd/pim_iface.c
+++ b/pimd/pim_iface.c
@@ -71,19 +71,19 @@ static void *if_list_clean(struct pim_interface *pim_ifp)
struct pim_ifchannel *ch;
if (pim_ifp->igmp_join_list)
- list_delete(pim_ifp->igmp_join_list);
+ list_delete_and_null(&pim_ifp->igmp_join_list);
if (pim_ifp->igmp_socket_list)
- list_delete(pim_ifp->igmp_socket_list);
+ list_delete_and_null(&pim_ifp->igmp_socket_list);
if (pim_ifp->pim_neighbor_list)
- list_delete(pim_ifp->pim_neighbor_list);
+ list_delete_and_null(&pim_ifp->pim_neighbor_list);
if (pim_ifp->upstream_switch_list)
- list_delete(pim_ifp->upstream_switch_list);
+ list_delete_and_null(&pim_ifp->upstream_switch_list);
if (pim_ifp->sec_addr_list)
- list_delete(pim_ifp->sec_addr_list);
+ list_delete_and_null(&pim_ifp->sec_addr_list);
while ((ch = RB_ROOT(pim_ifchannel_rb,
&pim_ifp->ifchannel_rb)) != NULL)
@@ -241,10 +241,10 @@ void pim_if_delete(struct interface *ifp)
pim_if_del_vif(ifp);
- list_delete(pim_ifp->igmp_socket_list);
- list_delete(pim_ifp->pim_neighbor_list);
- list_delete(pim_ifp->upstream_switch_list);
- list_delete(pim_ifp->sec_addr_list);
+ list_delete_and_null(&pim_ifp->igmp_socket_list);
+ list_delete_and_null(&pim_ifp->pim_neighbor_list);
+ list_delete_and_null(&pim_ifp->upstream_switch_list);
+ list_delete_and_null(&pim_ifp->sec_addr_list);
if (pim_ifp->boundary_oil_plist)
XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
@@ -1373,7 +1373,7 @@ int pim_if_igmp_join_del(struct interface *ifp, struct in_addr group_addr,
listnode_delete(pim_ifp->igmp_join_list, ij);
igmp_join_free(ij);
if (listcount(pim_ifp->igmp_join_list) < 1) {
- list_delete(pim_ifp->igmp_join_list);
+ list_delete_and_null(&pim_ifp->igmp_join_list);
pim_ifp->igmp_join_list = 0;
}
diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c
index bcf7d2318d..6aa5105c5f 100644
--- a/pimd/pim_ifchannel.c
+++ b/pimd/pim_ifchannel.c
@@ -169,7 +169,7 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
pim_ifchannel_remove_children(ch);
if (ch->sources)
- list_delete(ch->sources);
+ list_delete_and_null(&ch->sources);
listnode_delete(ch->upstream->ifchannels, ch);
@@ -571,7 +571,7 @@ struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp,
pim_ifchannel_remove_children(ch);
if (ch->sources)
- list_delete(ch->sources);
+ list_delete_and_null(&ch->sources);
THREAD_OFF(ch->t_ifjoin_expiry_timer);
THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c
index f6c8db7acb..7524119e52 100644
--- a/pimd/pim_igmp.c
+++ b/pimd/pim_igmp.c
@@ -696,7 +696,7 @@ void igmp_startup_mode_on(struct igmp_sock *igmp)
static void igmp_group_free(struct igmp_group *group)
{
- list_delete(group->group_source_list);
+ list_delete_and_null(&group->group_source_list);
XFREE(MTYPE_PIM_IGMP_GROUP, group);
}
@@ -748,7 +748,7 @@ void igmp_sock_free(struct igmp_sock *igmp)
zassert(igmp->igmp_group_list);
zassert(!listcount(igmp->igmp_group_list));
- list_delete(igmp->igmp_group_list);
+ list_delete_and_null(&igmp->igmp_group_list);
hash_free(igmp->igmp_group_hash);
XFREE(MTYPE_PIM_IGMP_SOCKET, igmp);
diff --git a/pimd/pim_instance.c b/pimd/pim_instance.c
index 42feae3361..1fccbaeafa 100644
--- a/pimd/pim_instance.c
+++ b/pimd/pim_instance.c
@@ -48,7 +48,7 @@ static void pim_instance_terminate(struct pim_instance *pim)
}
if (pim->static_routes)
- list_delete(pim->static_routes);
+ list_delete_and_null(&pim->static_routes);
pim_rp_free(pim);
diff --git a/pimd/pim_jp_agg.c b/pimd/pim_jp_agg.c
index 8e0b4ab5e8..7de3e4ca6c 100644
--- a/pimd/pim_jp_agg.c
+++ b/pimd/pim_jp_agg.c
@@ -32,7 +32,7 @@
void pim_jp_agg_group_list_free(struct pim_jp_agg_group *jag)
{
- list_delete(jag->sources);
+ list_delete_and_null(&jag->sources);
XFREE(MTYPE_PIM_JP_AGG_GROUP, jag);
}
@@ -108,8 +108,7 @@ void pim_jp_agg_clear_group(struct list *group)
js->up = NULL;
XFREE(MTYPE_PIM_JP_AGG_SOURCE, js);
}
- list_delete(jag->sources);
- jag->sources = NULL;
+ list_delete_and_null(&jag->sources);
listnode_delete(group, jag);
XFREE(MTYPE_PIM_JP_AGG_GROUP, jag);
}
@@ -169,8 +168,7 @@ void pim_jp_agg_remove_group(struct list *group, struct pim_upstream *up)
}
if (jag->sources->count == 0) {
- list_delete(jag->sources);
- jag->sources = NULL;
+ list_delete_and_null(&jag->sources);
listnode_delete(group, jag);
XFREE(MTYPE_PIM_JP_AGG_GROUP, jag);
}
diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c
index 4b049d90ad..53a3382987 100644
--- a/pimd/pim_msdp.c
+++ b/pimd/pim_msdp.c
@@ -1261,7 +1261,7 @@ static void pim_msdp_mg_free(struct pim_instance *pim, struct pim_msdp_mg *mg)
XFREE(MTYPE_PIM_MSDP_MG_NAME, mg->mesh_group_name);
if (mg->mbr_list)
- list_delete(mg->mbr_list);
+ list_delete_and_null(&mg->mbr_list);
XFREE(MTYPE_PIM_MSDP_MG, mg);
pim->msdp.mg = NULL;
@@ -1619,8 +1619,7 @@ void pim_msdp_exit(struct pim_instance *pim)
}
if (pim->msdp.peer_list) {
- list_delete(pim->msdp.peer_list);
- pim->msdp.peer_list = NULL;
+ list_delete_and_null(&pim->msdp.peer_list);
}
if (pim->msdp.sa_hash) {
@@ -1629,7 +1628,6 @@ void pim_msdp_exit(struct pim_instance *pim)
}
if (pim->msdp.sa_list) {
- list_delete(pim->msdp.sa_list);
- pim->msdp.sa_list = NULL;
+ list_delete_and_null(&pim->msdp.sa_list);
}
}
diff --git a/pimd/pim_neighbor.c b/pimd/pim_neighbor.c
index 04e3e10ff3..dd77e2b084 100644
--- a/pimd/pim_neighbor.c
+++ b/pimd/pim_neighbor.c
@@ -401,8 +401,7 @@ static void delete_prefix_list(struct pim_neighbor *neigh)
}
#endif
- list_delete(neigh->prefix_list);
- neigh->prefix_list = 0;
+ list_delete_and_null(&neigh->prefix_list);
}
}
@@ -412,7 +411,7 @@ void pim_neighbor_free(struct pim_neighbor *neigh)
delete_prefix_list(neigh);
- list_delete(neigh->upstream_jp_agg);
+ list_delete_and_null(&neigh->upstream_jp_agg);
THREAD_OFF(neigh->jp_timer);
XFREE(MTYPE_PIM_NEIGHBOR, neigh);
diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c
index 1e88ff13ff..a1de4837db 100644
--- a/pimd/pim_nht.c
+++ b/pimd/pim_nht.c
@@ -194,7 +194,7 @@ int pim_find_or_track_nexthop(struct pim_instance *pim, struct prefix *addr,
}
if (up != NULL)
- up = hash_get(pnc->upstream_hash, up, hash_alloc_intern);
+ hash_get(pnc->upstream_hash, up, hash_alloc_intern);
if (pnc && CHECK_FLAG(pnc->flags, PIM_NEXTHOP_VALID)) {
memcpy(out_pnc, pnc, sizeof(struct pim_nexthop_cache));
@@ -236,7 +236,7 @@ void pim_delete_tracked_nexthop(struct pim_instance *pim, struct prefix *addr,
pim_sendmsg_zebra_rnh(pim, zclient, pnc,
ZEBRA_NEXTHOP_UNREGISTER);
- list_delete(pnc->rp_list);
+ list_delete_and_null(&pnc->rp_list);
hash_free(pnc->upstream_hash);
hash_release(pim->rpf_hash, pnc);
diff --git a/pimd/pim_oil.c b/pimd/pim_oil.c
index 9ab0709d3e..c45b0ce14c 100644
--- a/pimd/pim_oil.c
+++ b/pimd/pim_oil.c
@@ -123,8 +123,7 @@ void pim_oil_init(struct pim_instance *pim)
void pim_oil_terminate(struct pim_instance *pim)
{
if (pim->channel_oil_list)
- list_delete(pim->channel_oil_list);
- pim->channel_oil_list = NULL;
+ list_delete_and_null(&pim->channel_oil_list);
if (pim->channel_oil_hash)
hash_free(pim->channel_oil_hash);
diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c
index 5c7561f586..cb722c17b2 100644
--- a/pimd/pim_rp.c
+++ b/pimd/pim_rp.c
@@ -51,8 +51,7 @@ void pim_rp_list_hash_clean(void *data)
{
struct pim_nexthop_cache *pnc = (struct pim_nexthop_cache *)data;
- list_delete(pnc->rp_list);
- pnc->rp_list = NULL;
+ list_delete_and_null(&pnc->rp_list);
hash_clean(pnc->upstream_hash, NULL);
hash_free(pnc->upstream_hash);
@@ -110,7 +109,7 @@ void pim_rp_init(struct pim_instance *pim)
pim->rp_table = route_table_init();
if (!pim->rp_table) {
zlog_err("Unable to alloc rp_table");
- list_delete(pim->rp_list);
+ list_delete_and_null(&pim->rp_list);
return;
}
@@ -119,13 +118,13 @@ void pim_rp_init(struct pim_instance *pim)
if (!rp_info) {
zlog_err("Unable to alloc rp_info");
route_table_finish(pim->rp_table);
- list_delete(pim->rp_list);
+ list_delete_and_null(&pim->rp_list);
return;
}
if (!str2prefix("224.0.0.0/4", &rp_info->group)) {
zlog_err("Unable to convert 224.0.0.0/4 to prefix");
- list_delete(pim->rp_list);
+ list_delete_and_null(&pim->rp_list);
route_table_finish(pim->rp_table);
XFREE(MTYPE_PIM_RP, rp_info);
return;
@@ -140,7 +139,7 @@ void pim_rp_init(struct pim_instance *pim)
rn = route_node_get(pim->rp_table, &rp_info->group);
if (!rn) {
zlog_err("Failure to get route node for pim->rp_table");
- list_delete(pim->rp_list);
+ list_delete_and_null(&pim->rp_list);
route_table_finish(pim->rp_table);
XFREE(MTYPE_PIM_RP, rp_info);
return;
@@ -155,8 +154,7 @@ void pim_rp_init(struct pim_instance *pim)
void pim_rp_free(struct pim_instance *pim)
{
if (pim->rp_list)
- list_delete(pim->rp_list);
- pim->rp_list = NULL;
+ list_delete_and_null(&pim->rp_list);
}
/*
diff --git a/pimd/pim_ssmpingd.c b/pimd/pim_ssmpingd.c
index 9e90a34687..8e7da0f121 100644
--- a/pimd/pim_ssmpingd.c
+++ b/pimd/pim_ssmpingd.c
@@ -50,10 +50,8 @@ void pim_ssmpingd_init(struct pim_instance *pim)
void pim_ssmpingd_destroy(struct pim_instance *pim)
{
- if (pim->ssmpingd_list) {
- list_delete(pim->ssmpingd_list);
- pim->ssmpingd_list = 0;
- }
+ if (pim->ssmpingd_list)
+ list_delete_and_null(&pim->ssmpingd_list);
}
static struct ssmpingd_sock *ssmpingd_find(struct pim_instance *pim,
diff --git a/pimd/pim_tlv.c b/pimd/pim_tlv.c
index 6d7adf2422..3c9ef28f5a 100644
--- a/pimd/pim_tlv.c
+++ b/pimd/pim_tlv.c
@@ -654,12 +654,12 @@ int pim_parse_addr_source(struct prefix_sg *sg, uint8_t *flags,
return addr - buf;
}
-#define FREE_ADDR_LIST(hello_option_addr_list) \
- { \
- if (hello_option_addr_list) { \
- list_delete(hello_option_addr_list); \
- hello_option_addr_list = 0; \
- } \
+#define FREE_ADDR_LIST(hello_option_addr_list) \
+ { \
+ if (hello_option_addr_list) { \
+ list_delete_and_null(&hello_option_addr_list); \
+ hello_option_addr_list = 0; \
+ } \
}
int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr,
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index 0bf2ce5d56..ed5d1ecaa2 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.c
@@ -82,8 +82,7 @@ static void pim_upstream_remove_children(struct pim_instance *pim,
if (child)
child->parent = NULL;
}
- list_delete(up->sources);
- up->sources = NULL;
+ list_delete_and_null(&up->sources);
}
/*
@@ -203,13 +202,12 @@ struct pim_upstream *pim_upstream_del(struct pim_instance *pim,
pim_upstream_remove_children(pim, up);
if (up->sources)
- list_delete(up->sources);
- up->sources = NULL;
+ list_delete_and_null(&up->sources);
+
pim_mroute_del(up->channel_oil, __PRETTY_FUNCTION__);
upstream_channel_oil_detach(up);
- list_delete(up->ifchannels);
- up->ifchannels = NULL;
+ list_delete_and_null(&up->ifchannels);
/*
notice that listnode_delete() can't be moved
@@ -696,9 +694,9 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim,
pim_upstream_remove_children(pim, up);
if (up->sources)
- list_delete(up->sources);
+ list_delete_and_null(&up->sources);
- list_delete(up->ifchannels);
+ list_delete_and_null(&up->ifchannels);
hash_release(pim->upstream_hash, up);
XFREE(MTYPE_PIM_UPSTREAM, up);
@@ -1548,8 +1546,7 @@ unsigned int pim_upstream_hash_key(void *arg)
void pim_upstream_terminate(struct pim_instance *pim)
{
if (pim->upstream_list)
- list_delete(pim->upstream_list);
- pim->upstream_list = NULL;
+ list_delete_and_null(&pim->upstream_list);
if (pim->upstream_hash)
hash_free(pim->upstream_hash);
diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c
index c1adbcc915..fc377b5a52 100644
--- a/pimd/pim_vty.c
+++ b/pimd/pim_vty.c
@@ -362,7 +362,7 @@ int pim_interface_config_write(struct vty *vty)
/* boundary */
if (pim_ifp->boundary_oil_plist) {
vty_out(vty,
- " ip pim boundary oil %s\n",
+ " ip multicast boundary oil %s\n",
pim_ifp->boundary_oil_plist);
++writes;
}
diff --git a/ripd/rip_debug.c b/ripd/rip_debug.c
index 56ba8e7f3e..2ce289e38f 100644
--- a/ripd/rip_debug.c
+++ b/ripd/rip_debug.c
@@ -93,13 +93,9 @@ DEFUN (debug_rip_packet_direct,
{
int idx_recv_send = 3;
rip_debug_packet |= RIP_DEBUG_PACKET;
- if (strncmp("send", argv[idx_recv_send]->arg,
- strlen(argv[idx_recv_send]->arg))
- == 0)
+ if (strcmp("send", argv[idx_recv_send]->text) == 0)
rip_debug_packet |= RIP_DEBUG_SEND;
- if (strncmp("recv", argv[idx_recv_send]->arg,
- strlen(argv[idx_recv_send]->arg))
- == 0)
+ if (strcmp("recv", argv[idx_recv_send]->text) == 0)
rip_debug_packet |= RIP_DEBUG_RECV;
return CMD_SUCCESS;
}
@@ -150,16 +146,12 @@ DEFUN (no_debug_rip_packet_direct,
"RIP option set for send packet\n")
{
int idx_recv_send = 4;
- if (strncmp("send", argv[idx_recv_send]->arg,
- strlen(argv[idx_recv_send]->arg))
- == 0) {
+ if (strcmp("send", argv[idx_recv_send]->text) == 0) {
if (IS_RIP_DEBUG_RECV)
rip_debug_packet &= ~RIP_DEBUG_SEND;
else
rip_debug_packet = 0;
- } else if (strncmp("recv", argv[idx_recv_send]->arg,
- strlen(argv[idx_recv_send]->arg))
- == 0) {
+ } else if (strcmp("recv", argv[idx_recv_send]->text) == 0) {
if (IS_RIP_DEBUG_SEND)
rip_debug_packet &= ~RIP_DEBUG_RECV;
else
diff --git a/ripd/rip_offset.c b/ripd/rip_offset.c
index 6b539046f5..0e0230c9d2 100644
--- a/ripd/rip_offset.c
+++ b/ripd/rip_offset.c
@@ -363,7 +363,7 @@ void rip_offset_init()
void rip_offset_clean()
{
- list_delete(rip_offset_list_master);
+ list_delete_and_null(&rip_offset_list_master);
rip_offset_list_master = list_new();
rip_offset_list_master->cmp = (int (*)(void *, void *))offset_list_cmp;
diff --git a/ripd/ripd.c b/ripd/ripd.c
index 921b65009a..bededba7fc 100644
--- a/ripd/ripd.c
+++ b/ripd/ripd.c
@@ -132,8 +132,7 @@ static int rip_garbage_collect(struct thread *t)
/* Unlock route_node. */
listnode_delete(rp->info, rinfo);
if (list_isempty((struct list *)rp->info)) {
- list_free(rp->info);
- rp->info = NULL;
+ list_delete_and_null((struct list **)&rp->info);
route_unlock_node(rp);
}
@@ -3809,7 +3808,7 @@ void rip_clean(void)
RIP_TIMER_OFF(rinfo->t_garbage_collect);
rip_info_free(rinfo);
}
- list_delete(list);
+ list_delete_and_null(&list);
rp->info = NULL;
route_unlock_node(rp);
}
diff --git a/ripngd/ripng_debug.c b/ripngd/ripng_debug.c
index 9ebc302b1b..c8cad23add 100644
--- a/ripngd/ripng_debug.c
+++ b/ripngd/ripng_debug.c
@@ -94,13 +94,9 @@ DEFUN (debug_ripng_packet_direct,
{
int idx_recv_send = 3;
ripng_debug_packet |= RIPNG_DEBUG_PACKET;
- if (strncmp("send", argv[idx_recv_send]->arg,
- strlen(argv[idx_recv_send]->arg))
- == 0)
+ if (strcmp("send", argv[idx_recv_send]->text) == 0)
ripng_debug_packet |= RIPNG_DEBUG_SEND;
- if (strncmp("recv", argv[idx_recv_send]->arg,
- strlen(argv[idx_recv_send]->arg))
- == 0)
+ if (strcmp("recv", argv[idx_recv_send]->text) == 0)
ripng_debug_packet |= RIPNG_DEBUG_RECV;
return CMD_SUCCESS;
@@ -152,16 +148,12 @@ DEFUN (no_debug_ripng_packet_direct,
"Debug option set for send packet\n")
{
int idx_recv_send = 4;
- if (strncmp("send", argv[idx_recv_send]->arg,
- strlen(argv[idx_recv_send]->arg))
- == 0) {
+ if (strcmp("send", argv[idx_recv_send]->text) == 0) {
if (IS_RIPNG_DEBUG_RECV)
ripng_debug_packet &= ~RIPNG_DEBUG_SEND;
else
ripng_debug_packet = 0;
- } else if (strncmp("recv", argv[idx_recv_send]->arg,
- strlen(argv[idx_recv_send]->arg))
- == 0) {
+ } else if (strcmp("recv", argv[idx_recv_send]->text) == 0) {
if (IS_RIPNG_DEBUG_SEND)
ripng_debug_packet &= ~RIPNG_DEBUG_RECV;
else
diff --git a/ripngd/ripng_nexthop.c b/ripngd/ripng_nexthop.c
index 75b3c9dfec..2e0841c5d4 100644
--- a/ripngd/ripng_nexthop.c
+++ b/ripngd/ripng_nexthop.c
@@ -72,7 +72,7 @@ struct list *ripng_rte_new(void)
void ripng_rte_free(struct list *ripng_rte_list)
{
- list_delete(ripng_rte_list);
+ list_delete_and_null(&ripng_rte_list);
}
/* Delete RTE */
diff --git a/ripngd/ripng_offset.c b/ripngd/ripng_offset.c
index efbdc1ffe8..82f8a7aa66 100644
--- a/ripngd/ripng_offset.c
+++ b/ripngd/ripng_offset.c
@@ -375,7 +375,7 @@ void ripng_offset_init(void)
void ripng_offset_clean(void)
{
- list_delete(ripng_offset_list_master);
+ list_delete_and_null(&ripng_offset_list_master);
ripng_offset_list_master = list_new();
ripng_offset_list_master->cmp =
diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c
index e4368c9f9f..7524061ad2 100644
--- a/ripngd/ripngd.c
+++ b/ripngd/ripngd.c
@@ -407,8 +407,7 @@ static int ripng_garbage_collect(struct thread *t)
/* Unlock route_node. */
listnode_delete(rp->info, rinfo);
if (list_isempty((struct list *)rp->info)) {
- list_free(rp->info);
- rp->info = NULL;
+ list_delete_and_null((struct list **)&rp->info);
route_unlock_node(rp);
}
@@ -843,6 +842,8 @@ static void ripng_route_process(struct rte *rte, struct sockaddr_in6 *from,
unusable). */
if (rte->metric != RIPNG_METRIC_INFINITY)
ripng_ecmp_add(&newinfo);
+ else
+ route_unlock_node(rp);
} else {
/* If there is an existing route, compare the next hop address
to the address of the router from which the datagram came.
@@ -2011,7 +2012,7 @@ DEFUN (show_ipv6_ripng,
len = 28 - len;
if (len > 0)
- len = vty_out(vty, "%*s", len, " ");
+ vty_out(vty, "%*s", len, " ");
/* from */
if ((rinfo->type == ZEBRA_ROUTE_RIPNG)
@@ -2150,7 +2151,7 @@ DEFUN (clear_ipv6_rip,
}
if (list_isempty(list)) {
- list_free(list);
+ list_delete_and_null(&list);
rp->info = NULL;
route_unlock_node(rp);
}
@@ -2829,7 +2830,7 @@ void ripng_clean()
rinfo->t_garbage_collect);
ripng_info_free(rinfo);
}
- list_delete(list);
+ list_delete_and_null(&list);
rp->info = NULL;
route_unlock_node(rp);
}
diff --git a/tests/isisd/test_fuzz_isis_tlv.c b/tests/isisd/test_fuzz_isis_tlv.c
index e61e9639ee..1f5abba392 100644
--- a/tests/isisd/test_fuzz_isis_tlv.c
+++ b/tests/isisd/test_fuzz_isis_tlv.c
@@ -166,7 +166,7 @@ static int test(FILE *input, FILE *output)
sbuf_push(&fragment_format, 0, "%s", isis_format_tlvs(tlvs));
isis_free_tlvs(tlvs);
}
- list_delete(fragments);
+ list_delete_and_null(&fragments);
stream_free(s);
char *fragment_content = sortlines((char *)sbuf_buf(&fragment_format));
diff --git a/tests/isisd/test_isis_vertex_queue.c b/tests/isisd/test_isis_vertex_queue.c
index 50436387b5..674482cd17 100644
--- a/tests/isisd/test_isis_vertex_queue.c
+++ b/tests/isisd/test_isis_vertex_queue.c
@@ -89,7 +89,7 @@ static void test_ordered(void)
assert(isis_vertex_queue_pop(&q) == vertices[1]);
assert(isis_find_vertex(&q, vertices[1]->N.id, vertices[1]->type) == NULL);
- assert(isis_vertex_queue_pop(&q) == vertices[4]);
+ isis_vertex_queue_delete(&q, vertices[4]);
assert(isis_find_vertex(&q, vertices[4]->N.id, vertices[4]->type) == NULL);
assert(isis_vertex_queue_count(&q) == 0);
diff --git a/tools/etc/iproute2/rt_protos.d/frr.conf b/tools/etc/iproute2/rt_protos.d/frr.conf
index 6b341f5161..2d3b884e7e 100644
--- a/tools/etc/iproute2/rt_protos.d/frr.conf
+++ b/tools/etc/iproute2/rt_protos.d/frr.conf
@@ -8,4 +8,3 @@
191 nhrp
192 eigrp
193 ldp
-194 babel
diff --git a/tools/frr b/tools/frr
index 4eb4a5c28c..78190aadb0 100755
--- a/tools/frr
+++ b/tools/frr
@@ -544,14 +544,22 @@ case "$1" in
if [ -z "$dmn" -o "$dmn" = "zebra" ]; then
echo "Removing all routes made by FRR."
- ip route flush proto bgp
- ip route flush proto ospf
- ip route flush proto static
- ip route flush proto rip
- ip route flush proto ripng
- ip route flush proto zebra
- ip route flush proto isis
-
+ # Specific values for each proto can be found
+ # in /etc/iproute2/rt_protos as well as FRR
+ # specific ones in /etc/iproute2/rt_protos.d
+ # Additionally if a new protocol is added
+ # we need to add it here as well as
+ # in rt_netlink.h( follow the directions! )
+ ip route flush proto 186
+ ip route flush proto 188
+ ip route flush proto 4
+ ip route flush proto 189
+ ip route flush proto 190
+ ip route flush proto 11
+ ip route flush proto 187
+ ip route flush proto 192
+ ip route flush proto 42
+ ip route flush proto 191
else
[ -n "$dmn" ] && eval "${dmn/-/_}=0"
start_watchfrr
diff --git a/tools/frr-reload.py b/tools/frr-reload.py
index afe66b6eaf..e19eeb04ee 100755
--- a/tools/frr-reload.py
+++ b/tools/frr-reload.py
@@ -940,6 +940,32 @@ def compare_context_objects(newconf, running):
return (lines_to_add, lines_to_del)
+
+def vtysh_config_available():
+ """
+ Return False if no frr daemon is running or some other vtysh session is
+ in 'configuration terminal' mode which will prevent us from making any
+ configuration changes.
+ """
+
+ try:
+ cmd = ['/usr/bin/vtysh', '-c', 'conf t']
+ output = subprocess.check_output(cmd, stderr=subprocess.STDOUT).strip()
+
+ if 'VTY configuration is locked by other VTY' in output:
+ print output
+ log.error("'%s' returned\n%s\n" % (' '.join(cmd), output))
+ return False
+
+ except subprocess.CalledProcessError as e:
+ msg = "vtysh could not connect with any frr daemons"
+ print msg
+ log.error(msg)
+ return False
+
+ return True
+
+
if __name__ == '__main__':
# Command line options
parser = argparse.ArgumentParser(description='Dynamically apply diff in frr configs')
@@ -1060,6 +1086,10 @@ if __name__ == '__main__':
elif args.reload:
+ # We will not be able to do anything, go ahead and exit(1)
+ if not vtysh_config_available():
+ sys.exit(1)
+
log.debug('New Frr Config\n%s', newconf.get_lines())
# This looks a little odd but we have to do this twice...here is why
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 3f86f3c929..061c25cea5 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -226,7 +226,8 @@ static int vtysh_client_run_all(struct vtysh_client *head_client,
wrong_instance++;
continue;
}
- correct_instance++;
+ if (client->fd > 0)
+ correct_instance++;
if (rc != CMD_SUCCESS) {
if (!continue_on_err)
return rc;
@@ -423,13 +424,22 @@ static int vtysh_execute_func(const char *line, int pager)
}
cmd_stat = CMD_SUCCESS;
+ struct vtysh_client *vc;
for (i = 0; i < array_size(vtysh_client); i++) {
if (cmd->daemon & vtysh_client[i].flag) {
if (vtysh_client[i].fd < 0
&& (cmd->daemon == vtysh_client[i].flag)) {
- fprintf(stderr, "%s is not running\n",
- vtysh_client[i].name);
- continue;
+ bool any_inst = false;
+ for (vc = &vtysh_client[i]; vc;
+ vc = vc->next)
+ any_inst = any_inst
+ || (vc->fd > 0);
+ if (!any_inst) {
+ fprintf(stderr,
+ "%s is not running\n",
+ vtysh_client[i].name);
+ continue;
+ }
}
cmd_stat = vtysh_client_execute(
&vtysh_client[i], line, fp);
@@ -1263,10 +1273,12 @@ DEFUNSH(VTYSH_RIPNGD, router_ripng, router_ripng_cmd, "router ripng",
return CMD_SUCCESS;
}
-DEFUNSH(VTYSH_OSPFD, router_ospf, router_ospf_cmd, "router ospf [(1-65535)]",
+DEFUNSH(VTYSH_OSPFD, router_ospf, router_ospf_cmd,
+ "router ospf [(1-65535)] [vrf NAME]",
"Enable a routing process\n"
"Start OSPF configuration\n"
- "Instance ID\n")
+ "Instance ID\n"
+ VRF_CMD_HELP_STR)
{
vty->node = OSPF_NODE;
return CMD_SUCCESS;
diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c
index d7e79d6b2c..138a446321 100644
--- a/vtysh/vtysh_config.c
+++ b/vtysh/vtysh_config.c
@@ -73,7 +73,7 @@ static int config_cmp(struct config *c1, struct config *c2)
static void config_del(struct config *config)
{
- list_delete(config->line);
+ list_delete_and_null(&config->line);
if (config->name)
XFREE(MTYPE_VTYSH_CONFIG_LINE, config->name);
XFREE(MTYPE_VTYSH_CONFIG, config);
@@ -131,6 +131,20 @@ static void config_add_line_uniq(struct list *config, const char *line)
listnode_add_sort(config, XSTRDUP(MTYPE_VTYSH_CONFIG_LINE, line));
}
+/*
+ * I want to explicitly move this command to the end of the line
+ */
+static void config_add_line_end(struct list *config, const char *line)
+{
+ struct listnode *node;
+ void *item = XSTRDUP(MTYPE_VTYSH_CONFIG_LINE, line);
+
+ listnode_add(config, item);
+ node = listnode_lookup(config, item);
+ if (node)
+ listnode_move_to_tail(config, node);
+}
+
void vtysh_config_parse_line(void *arg, const char *line)
{
char c;
@@ -161,6 +175,10 @@ void vtysh_config_parse_line(void *arg, const char *line)
== 0) {
config_add_line(config->line, line);
config->index = LINK_PARAMS_NODE;
+ } else if (strncmp(line,
+ " ip multicast boundary",
+ strlen(" ip multicast boundary")) == 0) {
+ config_add_line_end(config->line, line);
} else if (config->index == LINK_PARAMS_NODE
&& strncmp(line, " exit-link-params",
strlen(" exit"))
@@ -365,7 +383,7 @@ void vtysh_config_dump(FILE *fp)
for (i = 0; i < vector_active(configvec); i++)
if ((master = vector_slot(configvec, i)) != NULL) {
- list_delete(master);
+ list_delete_and_null(&master);
vector_slot(configvec, i) = NULL;
}
list_delete_all_node(config_top);
diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c
index 003853571f..8509a8a05a 100644
--- a/vtysh/vtysh_main.c
+++ b/vtysh/vtysh_main.c
@@ -404,9 +404,9 @@ int main(int argc, char **argv, char **env)
"NOT SUPPORTED since its\nresults are inconsistent!\n");
}
- snprintf(vtysh_config, sizeof(vtysh_config), "%s%s/%s", sysconfdir,
+ snprintf(vtysh_config, sizeof(vtysh_config), "%s%s%s", sysconfdir,
pathspace, VTYSH_CONFIG_NAME);
- snprintf(frr_config, sizeof(frr_config), "%s%s/%s", sysconfdir,
+ snprintf(frr_config, sizeof(frr_config), "%s%s%s", sysconfdir,
pathspace, FRR_CONFIG_NAME);
strlcat(vtydir, pathspace, sizeof(vtydir));
@@ -451,7 +451,7 @@ int main(int argc, char **argv, char **env)
exit(ret);
}
- if (dryrun && cmd) {
+ if (dryrun && cmd && cmd->line) {
vtysh_execute("enable");
while (cmd) {
struct cmd_rec *cr;
@@ -552,7 +552,7 @@ int main(int argc, char **argv, char **env)
}
/* If eval mode. */
- if (cmd) {
+ if (cmd && cmd->line) {
/* Enter into enable node. */
vtysh_execute("enable");
diff --git a/zebra/interface.c b/zebra/interface.c
index 664e493d84..a65dd21f63 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -64,7 +64,7 @@ static void zebra_if_node_destroy(route_table_delegate_t *delegate,
struct route_node *node)
{
if (node->info)
- list_delete(node->info);
+ list_delete_and_null((struct list **)&node->info);
route_node_destroy(delegate, table, node);
}
@@ -138,7 +138,7 @@ static int if_zebra_delete_hook(struct interface *ifp)
struct rtadvconf *rtadv;
rtadv = &zebra_if->rtadv;
- list_free(rtadv->AdvPrefixList);
+ list_delete_and_null(&rtadv->AdvPrefixList);
#endif /* HAVE_RTADV */
XFREE(MTYPE_TMP, zebra_if);
@@ -322,7 +322,7 @@ int if_subnet_delete(struct interface *ifp, struct connected *ifc)
}
/* Otherwise, free list and route node. */
- list_free(addr_list);
+ list_delete_and_null(&addr_list);
rn->info = NULL;
route_unlock_node(rn);
@@ -627,7 +627,7 @@ static void if_delete_connected(struct interface *ifp)
}
/* Free chain list and respective route node. */
- list_delete(addr_list);
+ list_delete_and_null(&addr_list);
rn->info = NULL;
route_unlock_node(rn);
} else if (cp.family == AF_INET6) {
diff --git a/zebra/irdp.h b/zebra/irdp.h
index ea190b574d..8aa9f3e4b3 100644
--- a/zebra/irdp.h
+++ b/zebra/irdp.h
@@ -111,6 +111,8 @@
*/
struct irdp_interface {
+ bool started;
+
unsigned long MaxAdvertInterval;
unsigned long MinAdvertInterval;
unsigned long Preference;
diff --git a/zebra/irdp_interface.c b/zebra/irdp_interface.c
index 34c78e2a48..8234ed6bdd 100644
--- a/zebra/irdp_interface.c
+++ b/zebra/irdp_interface.c
@@ -63,11 +63,28 @@ extern int irdp_sock;
DEFINE_MTYPE_STATIC(ZEBRA, IRDP_IF, "IRDP interface data")
+#define IRDP_CONFIGED \
+ do { \
+ if (!irdp) { \
+ vty_out(vty, "Please Configure IRDP before using this command\n"); \
+ return CMD_WARNING_CONFIG_FAILED; \
+ } \
+ } \
+ while (0)
+
static struct irdp_interface *irdp_if_get(struct interface *ifp)
{
struct zebra_if *zi = ifp->info;
+
+ if (!zi)
+ return NULL;
+
if (!zi->irdp)
zi->irdp = XCALLOC(MTYPE_IRDP_IF, sizeof(*zi->irdp));
+
+ if (!zi->irdp->started)
+ return NULL;
+
return zi->irdp;
}
@@ -203,6 +220,7 @@ static void irdp_if_start(struct interface *ifp, int multicast,
assert(irdp);
+ irdp->started = true;
if (irdp->flags & IF_ACTIVE) {
zlog_warn("IRDP: Interface is already active %s", ifp->name);
return;
@@ -293,8 +311,7 @@ static void irdp_if_stop(struct interface *ifp)
irdp_advert_off(ifp);
- list_delete(irdp->AdvPrefList);
- irdp->AdvPrefList = NULL;
+ list_delete_and_null(&irdp->AdvPrefList);
irdp->flags = 0;
}
@@ -307,6 +324,7 @@ static void irdp_if_shutdown(struct interface *ifp)
if (!irdp)
return;
+
if (irdp->flags & IF_SHUTDOWN) {
zlog_warn("IRDP: Interface is already shutdown %s", ifp->name);
return;
@@ -326,6 +344,9 @@ static void irdp_if_no_shutdown(struct interface *ifp)
{
struct irdp_interface *irdp = irdp_if_get(ifp);
+ if (!irdp)
+ return;
+
if (!(irdp->flags & IF_SHUTDOWN)) {
zlog_warn("IRDP: Interface is not shutdown %s", ifp->name);
return;
@@ -458,6 +479,8 @@ DEFUN (ip_irdp_holdtime,
VTY_DECLVAR_CONTEXT(interface, ifp);
struct irdp_interface *irdp = irdp_if_get(ifp);
+ IRDP_CONFIGED;
+
irdp->Lifetime = atoi(argv[idx_number]->arg);
return CMD_SUCCESS;
}
@@ -474,6 +497,8 @@ DEFUN (ip_irdp_minadvertinterval,
VTY_DECLVAR_CONTEXT(interface, ifp);
struct irdp_interface *irdp = irdp_if_get(ifp);
+ IRDP_CONFIGED;
+
if ((unsigned)atoi(argv[idx_number]->arg) <= irdp->MaxAdvertInterval) {
irdp->MinAdvertInterval = atoi(argv[idx_number]->arg);
return CMD_SUCCESS;
@@ -497,6 +522,8 @@ DEFUN (ip_irdp_maxadvertinterval,
VTY_DECLVAR_CONTEXT(interface, ifp);
struct irdp_interface *irdp = irdp_if_get(ifp);
+ IRDP_CONFIGED;
+
if (irdp->MinAdvertInterval <= (unsigned)atoi(argv[idx_number]->arg)) {
irdp->MaxAdvertInterval = atoi(argv[idx_number]->arg);
return CMD_SUCCESS;
@@ -525,6 +552,8 @@ DEFUN (ip_irdp_preference,
VTY_DECLVAR_CONTEXT(interface, ifp);
struct irdp_interface *irdp = irdp_if_get(ifp);
+ IRDP_CONFIGED;
+
irdp->Preference = atoi(argv[idx_number]->arg);
return CMD_SUCCESS;
}
@@ -549,6 +578,8 @@ DEFUN (ip_irdp_address_preference,
int ret;
struct Adv *adv;
+ IRDP_CONFIGED;
+
ret = inet_aton(argv[idx_ipv4]->arg, &ip);
if (!ret)
return CMD_WARNING_CONFIG_FAILED;
@@ -586,6 +617,8 @@ DEFUN (no_ip_irdp_address_preference,
int ret;
struct Adv *adv;
+ IRDP_CONFIGED;
+
ret = inet_aton(argv[idx_ipv4]->arg, &ip);
if (!ret)
return CMD_WARNING_CONFIG_FAILED;
@@ -611,6 +644,8 @@ DEFUN (ip_irdp_debug_messages,
VTY_DECLVAR_CONTEXT(interface, ifp);
struct irdp_interface *irdp = irdp_if_get(ifp);
+ IRDP_CONFIGED;
+
irdp->flags |= IF_DEBUG_MESSAGES;
return CMD_SUCCESS;
@@ -627,6 +662,8 @@ DEFUN (ip_irdp_debug_misc,
VTY_DECLVAR_CONTEXT(interface, ifp);
struct irdp_interface *irdp = irdp_if_get(ifp);
+ IRDP_CONFIGED;
+
irdp->flags |= IF_DEBUG_MISC;
return CMD_SUCCESS;
@@ -643,6 +680,8 @@ DEFUN (ip_irdp_debug_packet,
VTY_DECLVAR_CONTEXT(interface, ifp);
struct irdp_interface *irdp = irdp_if_get(ifp);
+ IRDP_CONFIGED;
+
irdp->flags |= IF_DEBUG_PACKET;
return CMD_SUCCESS;
@@ -660,6 +699,8 @@ DEFUN (ip_irdp_debug_disable,
VTY_DECLVAR_CONTEXT(interface, ifp);
struct irdp_interface *irdp = irdp_if_get(ifp);
+ IRDP_CONFIGED;
+
irdp->flags &= ~IF_DEBUG_PACKET;
irdp->flags &= ~IF_DEBUG_MESSAGES;
irdp->flags &= ~IF_DEBUG_MISC;
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c
index 015e11b3a5..a5c36b0dae 100644
--- a/zebra/kernel_netlink.c
+++ b/zebra/kernel_netlink.c
@@ -676,16 +676,21 @@ int netlink_talk(int (*filter)(struct sockaddr_nl *, struct nlmsghdr *, ns_id_t,
{
int status;
struct sockaddr_nl snl;
- struct iovec iov = {.iov_base = (void *)n, .iov_len = n->nlmsg_len};
- struct msghdr msg = {
- .msg_name = (void *)&snl,
- .msg_namelen = sizeof snl,
- .msg_iov = &iov,
- .msg_iovlen = 1,
- };
+ struct iovec iov;
+ struct msghdr msg;
int save_errno;
memset(&snl, 0, sizeof snl);
+ memset(&iov, 0, sizeof iov);
+ memset(&msg, 0, sizeof msg);
+
+ iov.iov_base = n;
+ iov.iov_len = n->nlmsg_len;
+ msg.msg_name = (void *)&snl;
+ msg.msg_namelen = sizeof snl;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+
snl.nl_family = AF_NETLINK;
n->nlmsg_seq = ++nl->seq;
diff --git a/zebra/label_manager.c b/zebra/label_manager.c
index 1ed5eacd80..6fbb751789 100644
--- a/zebra/label_manager.c
+++ b/zebra/label_manager.c
@@ -375,5 +375,5 @@ int release_daemon_chunks(u_char proto, u_short instance)
void label_manager_close()
{
- list_delete(lbl_mgr.lc_list);
+ list_delete_and_null(&lbl_mgr.lc_list);
}
diff --git a/zebra/main.c b/zebra/main.c
index 4864b4961d..5a2979c866 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -127,8 +127,8 @@ static void sigint(void)
frr_early_fini();
- zebra_ptm_finish();
list_delete_all_node(zebrad.client_list);
+ zebra_ptm_finish();
if (retain_mode)
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
@@ -145,7 +145,7 @@ static void sigint(void)
prefix_list_reset();
route_map_finish();
- list_delete(zebrad.client_list);
+ list_delete_and_null(&zebrad.client_list);
work_queue_free(zebrad.ribq);
if (zebrad.lsp_process_q)
work_queue_free(zebrad.lsp_process_q);
diff --git a/zebra/redistribute.c b/zebra/redistribute.c
index 890ad887da..cc679142f7 100644
--- a/zebra/redistribute.c
+++ b/zebra/redistribute.c
@@ -519,32 +519,20 @@ int zebra_add_import_table_entry(struct route_node *rn, struct route_entry *re,
if (same)
zebra_del_import_table_entry(rn, same);
- if (re->nexthop_num == 1) {
- rib_add(afi, SAFI_UNICAST, re->vrf_id,
- ZEBRA_ROUTE_TABLE, re->table, 0, &p,
- NULL, re->nexthop,
- zebrad.rtm_table_default, re->metric,
- re->mtu,
- zebra_import_table_distance[afi]
- [re->table]);
- } else if (re->nexthop_num > 1) {
- newre = XCALLOC(MTYPE_RE,
- sizeof(struct route_entry));
- newre->type = ZEBRA_ROUTE_TABLE;
- newre->distance =
- zebra_import_table_distance[afi][re->table];
- newre->flags = re->flags;
- newre->metric = re->metric;
- newre->mtu = re->mtu;
- newre->table = zebrad.rtm_table_default;
- newre->nexthop_num = 0;
- newre->uptime = time(NULL);
- newre->instance = re->table;
- route_entry_copy_nexthops(newre, re->nexthop);
-
- rib_add_multipath(afi, SAFI_UNICAST, &p,
- NULL, newre);
- }
+ newre = XCALLOC(MTYPE_RE,sizeof(struct route_entry));
+ newre->type = ZEBRA_ROUTE_TABLE;
+ newre->distance = zebra_import_table_distance[afi][re->table];
+ newre->flags = re->flags;
+ newre->metric = re->metric;
+ newre->mtu = re->mtu;
+ newre->table = zebrad.rtm_table_default;
+ newre->nexthop_num = 0;
+ newre->uptime = time(NULL);
+ newre->instance = re->table;
+ route_entry_copy_nexthops(newre, re->nexthop);
+
+ rib_add_multipath(afi, SAFI_UNICAST, &p, NULL, newre);
+
return 0;
}
@@ -557,7 +545,7 @@ int zebra_del_import_table_entry(struct route_node *rn, struct route_entry *re)
prefix_copy(&p, &rn->p);
rib_delete(afi, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE,
- re->table, re->flags, &p, NULL, NULL,
+ re->table, re->flags, &p, NULL, re->nexthop,
zebrad.rtm_table_default, re->metric, false);
return 0;
diff --git a/zebra/rib.h b/zebra/rib.h
index e3ed6210ca..61beebb409 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -71,7 +71,7 @@ struct route_entry {
u_int32_t nexthop_mtu;
/* Distance. */
- u_char distance;
+ uint8_t distance;
/* Flags of this route.
* This flag's definition is in lib/zebra.h ZEBRA_FLAG_* and is exposed
@@ -296,7 +296,7 @@ extern int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
u_short instance, int flags, struct prefix *p,
struct prefix_ipv6 *src_p, const struct nexthop *nh,
u_int32_t table_id, u_int32_t metric, u_int32_t mtu,
- u_char distance);
+ uint8_t distance);
extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *,
struct prefix_ipv6 *src_p, struct route_entry *);
@@ -330,7 +330,7 @@ extern void rib_unlink(struct route_node *, struct route_entry *);
extern int rib_gc_dest(struct route_node *rn);
extern struct route_table *rib_tables_iter_next(rib_tables_iter_t *iter);
-extern u_char route_distance(int type);
+extern uint8_t route_distance(int type);
/*
* Inline functions.
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 573f60f4ca..0cc2e0217f 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -267,7 +267,7 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
struct rtattr *tb[RTA_MAX + 1];
u_char flags = 0;
struct prefix p;
- struct prefix_ipv6 src_p;
+ struct prefix_ipv6 src_p = {};
vrf_id_t vrf_id = VRF_DEFAULT;
char anyaddr[16] = {0};
@@ -277,6 +277,7 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
int table;
int metric = 0;
u_int32_t mtu = 0;
+ uint8_t distance = 0;
void *dest = NULL;
void *gate = NULL;
@@ -405,16 +406,38 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
return 0;
}
+ /*
+ * For ZEBRA_ROUTE_KERNEL types:
+ *
+ * The metric/priority of the route received from the kernel
+ * is a 32 bit number. We are going to interpret the high
+ * order byte as the Admin Distance and the low order 3 bytes
+ * as the metric.
+ *
+ * This will allow us to do two things:
+ * 1) Allow the creation of kernel routes that can be
+ * overridden by zebra.
+ * 2) Allow the old behavior for 'most' kernel route types
+ * if a user enters 'ip route ...' v4 routes get a metric
+ * of 0 and v6 routes get a metric of 1024. Both of these
+ * values will end up with a admin distance of 0, which
+ * will cause them to win for the purposes of zebra.
+ */
+ if (proto == ZEBRA_ROUTE_KERNEL) {
+ distance = (metric >> 24) & 0xFF;
+ metric = (metric & 0x00FFFFFF);
+ }
+
if (IS_ZEBRA_DEBUG_KERNEL) {
char buf[PREFIX_STRLEN];
char buf2[PREFIX_STRLEN];
zlog_debug(
- "%s %s%s%s vrf %u", nl_msg_type_to_str(h->nlmsg_type),
+ "%s %s%s%s vrf %u metric: %d Admin Distance: %d", nl_msg_type_to_str(h->nlmsg_type),
prefix2str(&p, buf, sizeof(buf)),
src_p.prefixlen ? " from " : "",
src_p.prefixlen ? prefix2str(&src_p, buf2, sizeof(buf2))
: "",
- vrf_id);
+ vrf_id, metric, distance);
}
afi_t afi = AFI_IP;
@@ -454,7 +477,7 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
memcpy(&nh.gate, gate, sz);
rib_add(afi, SAFI_UNICAST, vrf_id, proto,
- 0, flags, &p, NULL, &nh, table, metric, mtu, 0);
+ 0, flags, &p, NULL, &nh, table, metric, mtu, distance);
} else {
/* This is a multipath route */
@@ -466,7 +489,7 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
re = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
re->type = proto;
- re->distance = 0;
+ re->distance = distance;
re->flags = flags;
re->metric = metric;
re->mtu = mtu;
@@ -822,7 +845,7 @@ static void _netlink_route_build_singlepath(const char *routedesc, int bytelen,
{
struct nexthop_label *nh_label;
mpls_lse_t out_lse[MPLS_MAX_LABELS];
- char label_buf[100];
+ char label_buf[256];
/*
* label_buf is *only* currently used within debugging.
@@ -853,12 +876,13 @@ static void _netlink_route_build_singlepath(const char *routedesc, int bytelen,
0, 0, bos);
if (IS_ZEBRA_DEBUG_KERNEL) {
if (!num_labels)
- sprintf(label_buf, "label %d",
+ sprintf(label_buf, "label %u",
nh_label->label[i]);
else {
- sprintf(label_buf1, "/%d",
+ sprintf(label_buf1, "/%u",
nh_label->label[i]);
- strcat(label_buf, label_buf1);
+ strlcat(label_buf, label_buf1,
+ sizeof(label_buf));
}
}
num_labels++;
@@ -1021,7 +1045,7 @@ static void _netlink_route_build_multipath(const char *routedesc, int bytelen,
{
struct nexthop_label *nh_label;
mpls_lse_t out_lse[MPLS_MAX_LABELS];
- char label_buf[100];
+ char label_buf[256];
rtnh->rtnh_len = sizeof(*rtnh);
rtnh->rtnh_flags = 0;
@@ -1057,12 +1081,13 @@ static void _netlink_route_build_multipath(const char *routedesc, int bytelen,
0, 0, bos);
if (IS_ZEBRA_DEBUG_KERNEL) {
if (!num_labels)
- sprintf(label_buf, "label %d",
+ sprintf(label_buf, "label %u",
nh_label->label[i]);
else {
- sprintf(label_buf1, "/%d",
+ sprintf(label_buf1, "/%u",
nh_label->label[i]);
- strcat(label_buf, label_buf1);
+ strlcat(label_buf, label_buf1,
+ sizeof(label_buf));
}
}
num_labels++;
@@ -1716,7 +1741,6 @@ static int netlink_macfdb_change(struct sockaddr_nl *snl, struct nlmsghdr *h,
struct ndmsg *ndm;
struct interface *ifp;
struct zebra_if *zif;
- struct zebra_vrf *zvrf;
struct rtattr *tb[NDA_MAX + 1];
struct interface *br_if;
struct ethaddr mac;
@@ -1730,20 +1754,14 @@ static int netlink_macfdb_change(struct sockaddr_nl *snl, struct nlmsghdr *h,
ndm = NLMSG_DATA(h);
+ /* We only process macfdb notifications if EVPN is enabled */
+ if (!is_evpn_enabled())
+ return 0;
+
/* The interface should exist. */
ifp = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
ndm->ndm_ifindex);
- if (!ifp)
- return 0;
-
- /* Locate VRF corresponding to interface. We only process MAC
- * notifications
- * if EVPN is enabled on this VRF.
- */
- zvrf = vrf_info_lookup(ifp->vrf_id);
- if (!zvrf || !EVPN_ENABLED(zvrf))
- return 0;
- if (!ifp->info)
+ if (!ifp || !ifp->info)
return 0;
/* The interface should be something we're interested in. */
@@ -2033,7 +2051,6 @@ static int netlink_ipneigh_change(struct sockaddr_nl *snl, struct nlmsghdr *h,
struct ndmsg *ndm;
struct interface *ifp;
struct zebra_if *zif;
- struct zebra_vrf *zvrf;
struct rtattr *tb[NDA_MAX + 1];
struct interface *link_if;
struct ethaddr mac;
@@ -2045,20 +2062,14 @@ static int netlink_ipneigh_change(struct sockaddr_nl *snl, struct nlmsghdr *h,
ndm = NLMSG_DATA(h);
+ /* We only process neigh notifications if EVPN is enabled */
+ if (!is_evpn_enabled())
+ return 0;
+
/* The interface should exist. */
ifp = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
ndm->ndm_ifindex);
- if (!ifp)
- return 0;
-
- /* Locate VRF corresponding to interface. We only process neigh
- * notifications
- * if EVPN is enabled on this VRF.
- */
- zvrf = vrf_info_lookup(ifp->vrf_id);
- if (!zvrf || !EVPN_ENABLED(zvrf))
- return 0;
- if (!ifp->info)
+ if (!ifp || !ifp->info)
return 0;
/* Drop "permanent" entries. */
diff --git a/zebra/rt_netlink.h b/zebra/rt_netlink.h
index e607dda6f9..980ff915cc 100644
--- a/zebra/rt_netlink.h
+++ b/zebra/rt_netlink.h
@@ -27,14 +27,26 @@
#define NL_DEFAULT_ROUTE_METRIC 20
-/* Additional protocol strings to push into routes */
+/*
+ * Additional protocol strings to push into routes
+ * If we add anything new here please make sure
+ * to update:
+ * zebra2proto Function
+ * proto2zebra Function
+ * is_selfroute Function
+ * tools/frr To flush the route upon exit
+ *
+ * Finally update this file to allow iproute2 to
+ * know about this new route.
+ * tools/etc/iproute2/rt_protos.d
+ */
#define RTPROT_BGP 186
#define RTPROT_ISIS 187
#define RTPROT_OSPF 188
#define RTPROT_RIP 189
#define RTPROT_RIPNG 190
#if !defined(RTPROT_BABEL)
-#define RTPROT_BABEL 42
+#define RTPROT_BABEL 42
#endif
#define RTPROT_NHRP 191
#define RTPROT_EIGRP 192
diff --git a/zebra/rtadv.c b/zebra/rtadv.c
index 6091c75e50..633604120c 100644
--- a/zebra/rtadv.c
+++ b/zebra/rtadv.c
@@ -176,11 +176,13 @@ static void rtadv_send_packet(int sock, struct interface *ifp)
*/
if (adata == NULL) {
/* XXX Free on shutdown. */
- adata = malloc(CMSG_SPACE(sizeof(struct in6_pktinfo)));
+ adata = calloc(1, CMSG_SPACE(sizeof(struct in6_pktinfo)));
- if (adata == NULL)
+ if (adata == NULL) {
zlog_err(
"rtadv_send_packet: can't malloc control data");
+ exit(-1);
+ }
}
/* Logging of packet. */
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
index 3c7319f35d..7b87355ed4 100644
--- a/zebra/zebra_mpls.c
+++ b/zebra/zebra_mpls.c
@@ -554,7 +554,7 @@ static zebra_fec_t *fec_add(struct route_table *table, struct prefix *p,
*/
static int fec_del(zebra_fec_t *fec)
{
- list_free(fec->client_list);
+ list_delete_and_null(&fec->client_list);
fec->rn->info = NULL;
route_unlock_node(fec->rn);
XFREE(MTYPE_FEC, fec);
@@ -2701,7 +2701,7 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf,
vty_out(vty, "\n");
}
- list_delete(lsp_list);
+ list_delete_and_null(&lsp_list);
}
/*
@@ -2740,7 +2740,7 @@ int zebra_mpls_write_lsp_config(struct vty *vty, struct zebra_vrf *zvrf)
}
}
- list_delete(slsp_list);
+ list_delete_and_null(&slsp_list);
return (zvrf->slsp_table->count ? 1 : 0);
}
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index fab8c3c932..d46e0730ee 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -129,9 +129,9 @@ _rnode_zlog(const char *_func, vrf_id_t vrf_id, struct route_node *rn,
#define rnode_info(node, ...) \
_rnode_zlog(__func__, vrf_id, node, LOG_INFO, __VA_ARGS__)
-u_char route_distance(int type)
+uint8_t route_distance(int type)
{
- u_char distance;
+ uint8_t distance;
if ((unsigned)type >= array_size(route_info))
distance = 150;
@@ -325,9 +325,11 @@ static void nexthop_set_resolved(afi_t afi, struct nexthop *newhop,
resolved_hop = nexthop_new();
SET_FLAG(resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
- /* If the resolving route specifies a gateway, use it */
- if (newhop->type == NEXTHOP_TYPE_IPV4
- || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX) {
+
+ switch (newhop->type) {
+ case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ /* If the resolving route specifies a gateway, use it */
resolved_hop->type = newhop->type;
resolved_hop->gate.ipv4 = newhop->gate.ipv4;
@@ -337,9 +339,9 @@ static void nexthop_set_resolved(afi_t afi, struct nexthop *newhop,
if (newhop->flags & NEXTHOP_FLAG_ONLINK)
resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
}
- }
- if (newhop->type == NEXTHOP_TYPE_IPV6
- || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX) {
+ break;
+ case NEXTHOP_TYPE_IPV6:
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
resolved_hop->type = newhop->type;
resolved_hop->gate.ipv6 = newhop->gate.ipv6;
@@ -347,18 +349,17 @@ static void nexthop_set_resolved(afi_t afi, struct nexthop *newhop,
resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
resolved_hop->ifindex = newhop->ifindex;
}
- }
-
- /* If the resolving route is an interface route,
- * it means the gateway we are looking up is connected
- * to that interface. (The actual network is _not_ onlink).
- * Therefore, the resolved route should have the original
- * gateway as nexthop as it is directly connected.
- *
- * On Linux, we have to set the onlink netlink flag because
- * otherwise, the kernel won't accept the route.
- */
- if (newhop->type == NEXTHOP_TYPE_IFINDEX) {
+ break;
+ case NEXTHOP_TYPE_IFINDEX:
+ /* If the resolving route is an interface route,
+ * it means the gateway we are looking up is connected
+ * to that interface. (The actual network is _not_ onlink).
+ * Therefore, the resolved route should have the original
+ * gateway as nexthop as it is directly connected.
+ *
+ * On Linux, we have to set the onlink netlink flag because
+ * otherwise, the kernel won't accept the route.
+ */
resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
if (afi == AFI_IP) {
resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
@@ -368,12 +369,13 @@ static void nexthop_set_resolved(afi_t afi, struct nexthop *newhop,
resolved_hop->gate.ipv6 = nexthop->gate.ipv6;
}
resolved_hop->ifindex = newhop->ifindex;
- }
-
- if (newhop->type == NEXTHOP_TYPE_BLACKHOLE) {
+ break;
+ case NEXTHOP_TYPE_BLACKHOLE:
resolved_hop->type = NEXTHOP_TYPE_BLACKHOLE;
resolved_hop->bh_type = nexthop->bh_type;
+ break;
}
+
resolved_hop->rparent = nexthop;
nexthop_add(&nexthop->resolved, resolved_hop);
}
@@ -1875,7 +1877,7 @@ void meta_queue_free(struct meta_queue *mq)
unsigned i;
for (i = 0; i < MQ_SIZE; i++)
- list_delete(mq->subq[i]);
+ list_delete_and_null(&mq->subq[i]);
XFREE(MTYPE_WORK_QUEUE, mq);
}
@@ -2463,7 +2465,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
int flags, struct prefix *p, struct prefix_ipv6 *src_p,
const struct nexthop *nh, u_int32_t table_id, u_int32_t metric,
- u_int32_t mtu, u_char distance)
+ u_int32_t mtu, uint8_t distance)
{
struct route_entry *re;
struct nexthop *nexthop;
diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c
index 4bc9caca5d..355fef94f4 100644
--- a/zebra/zebra_rnh.c
+++ b/zebra/zebra_rnh.c
@@ -160,9 +160,9 @@ struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type)
void zebra_free_rnh(struct rnh *rnh)
{
rnh->flags |= ZEBRA_NHT_DELETED;
- list_free(rnh->client_list);
- list_free(rnh->zebra_static_route_list);
- list_free(rnh->zebra_pseudowire_list);
+ list_delete_and_null(&rnh->client_list);
+ list_delete_and_null(&rnh->zebra_static_route_list);
+ list_delete_and_null(&rnh->zebra_pseudowire_list);
free_state(rnh->vrf_id, rnh->state, rnh->node);
XFREE(MTYPE_RNH, rnh);
}
@@ -304,6 +304,7 @@ static void addr2hostprefix(int af, const union g_addr *addr,
prefix->u.prefix6 = addr->ipv6;
break;
default:
+ memset(prefix, 0, sizeof(*prefix));
zlog_warn("%s: unknown address family %d", __func__, af);
break;
}
diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h
index 6e2dc613df..1dfc0b3eb8 100644
--- a/zebra/zebra_vrf.h
+++ b/zebra/zebra_vrf.h
@@ -102,13 +102,15 @@ struct zebra_vrf {
* VNI hash table (for EVPN). Only in default instance.
*/
struct hash *vni_table;
+
/*
- * Whether EVPN is enabled or not.
+ * Whether EVPN is enabled or not. Only in default instance.
*/
int advertise_all_vni;
/*
* Whether we are advertising g/w macip in EVPN or not.
+ * Only in default instance.
*/
int advertise_gw_macip;
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 04cd17cedb..d86cc88b42 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -455,7 +455,7 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
vty_out(vty, ", distance %u, metric %u", re->distance,
re->metric);
if (re->tag)
- vty_out(vty, ", tag %d", re->tag);
+ vty_out(vty, ", tag %u", re->tag);
if (re->mtu)
vty_out(vty, ", mtu %u", re->mtu);
if (re->vrf_id != VRF_DEFAULT) {
@@ -829,7 +829,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
/* Distance and metric display. */
if (re->type != ZEBRA_ROUTE_CONNECT)
- len += vty_out(vty, " [%d/%d]", re->distance,
+ len += vty_out(vty, " [%u/%u]", re->distance,
re->metric);
} else {
vty_out(vty, " %c%*c",
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index a3f43f947a..bd7b3cb8d0 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -67,7 +67,7 @@ static void zvni_print_mac_hash_all_vni(struct hash_backet *backet, void *ctxt);
static void zvni_print(zebra_vni_t *zvni, void **ctxt);
static void zvni_print_hash(struct hash_backet *backet, void *ctxt[]);
-static int zvni_macip_send_msg_to_client(struct zebra_vrf *zvrf, vni_t vni,
+static int zvni_macip_send_msg_to_client(vni_t vni,
struct ethaddr *macaddr,
struct ipaddr *ip, u_char flags,
u_int16_t cmd);
@@ -80,20 +80,20 @@ static int zvni_neigh_del(zebra_vni_t *zvni, zebra_neigh_t *n);
static int zvni_neigh_del_hash_entry(struct hash_backet *backet, void *arg);
static void zvni_neigh_del_from_vtep(zebra_vni_t *zvni, int uninstall,
struct in_addr *r_vtep_ip);
-static void zvni_neigh_del_all(struct zebra_vrf *zvrf, zebra_vni_t *zvni,
+static void zvni_neigh_del_all(zebra_vni_t *zvni,
int uninstall, int upd_client, u_int32_t flags);
static zebra_neigh_t *zvni_neigh_lookup(zebra_vni_t *zvni, struct ipaddr *ip);
-static int zvni_neigh_send_add_to_client(struct zebra_vrf *zvrf, vni_t vni,
+static int zvni_neigh_send_add_to_client(vni_t vni,
struct ipaddr *ip,
struct ethaddr *macaddr, u_char flags);
-static int zvni_neigh_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni,
+static int zvni_neigh_send_del_to_client(vni_t vni,
struct ipaddr *ip,
struct ethaddr *macaddr, u_char flags);
static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n);
static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n);
static zebra_vni_t *zvni_map_svi(struct interface *ifp,
struct interface *br_if);
-static struct interface *zvni_map_to_svi(struct zebra_vrf *zvrf, vlanid_t vid,
+static struct interface *zvni_map_to_svi(vlanid_t vid,
struct interface *br_if);
static unsigned int mac_hash_keymake(void *p);
@@ -104,12 +104,12 @@ static int zvni_mac_del(zebra_vni_t *zvni, zebra_mac_t *mac);
static int zvni_mac_del_hash_entry(struct hash_backet *backet, void *arg);
static void zvni_mac_del_from_vtep(zebra_vni_t *zvni, int uninstall,
struct in_addr *r_vtep_ip);
-static void zvni_mac_del_all(struct zebra_vrf *zvrf, zebra_vni_t *zvni,
+static void zvni_mac_del_all(zebra_vni_t *zvni,
int uninstall, int upd_client, u_int32_t flags);
static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *macaddr);
-static int zvni_mac_send_add_to_client(struct zebra_vrf *zvrf, vni_t vni,
+static int zvni_mac_send_add_to_client(vni_t vni,
struct ethaddr *macaddr, u_char flags);
-static int zvni_mac_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni,
+static int zvni_mac_send_del_to_client(vni_t vni,
struct ethaddr *macaddr, u_char flags);
static zebra_vni_t *zvni_map_vlan(struct interface *ifp,
struct interface *br_if, vlanid_t vid);
@@ -120,12 +120,12 @@ static void zvni_install_mac_hash(struct hash_backet *backet, void *ctxt);
static unsigned int vni_hash_keymake(void *p);
static int vni_hash_cmp(const void *p1, const void *p2);
static void *zvni_alloc(void *p);
-static zebra_vni_t *zvni_lookup(struct zebra_vrf *zvrf, vni_t vni);
-static zebra_vni_t *zvni_add(struct zebra_vrf *zvrf, vni_t vni);
-static int zvni_del(struct zebra_vrf *zvrf, zebra_vni_t *zvni);
-static int zvni_send_add_to_client(struct zebra_vrf *zvrf, zebra_vni_t *zvni);
-static int zvni_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni);
-static void zvni_build_hash_table(struct zebra_vrf *zvrf);
+static zebra_vni_t *zvni_lookup(vni_t vni);
+static zebra_vni_t *zvni_add(vni_t vni);
+static int zvni_del(zebra_vni_t *zvni);
+static int zvni_send_add_to_client(zebra_vni_t *zvni);
+static int zvni_send_del_to_client(vni_t vni);
+static void zvni_build_hash_table();
static int zvni_vtep_match(struct in_addr *vtep_ip, zebra_vtep_t *zvtep);
static zebra_vtep_t *zvni_vtep_find(zebra_vni_t *zvni, struct in_addr *vtep_ip);
static zebra_vtep_t *zvni_vtep_add(zebra_vni_t *zvni, struct in_addr *vtep_ip);
@@ -140,15 +140,44 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni,
struct ipaddr *ip);
struct interface *zebra_get_vrr_intf_for_svi(struct interface *ifp);
-static int advertise_gw_macip_enabled(struct zebra_vrf *zvrf,
- zebra_vni_t *zvni);
+static int advertise_gw_macip_enabled(zebra_vni_t *zvni);
static void zvni_deref_ip2mac(zebra_vni_t *zvni, zebra_mac_t *mac,
int uninstall);
/* Private functions */
-static int advertise_gw_macip_enabled(struct zebra_vrf *zvrf, zebra_vni_t *zvni)
+/*
+ * Return number of valid MACs in a VNI's MAC hash table - all
+ * remote MACs and non-internal (auto) local MACs count.
+ */
+static u_int32_t num_valid_macs(zebra_vni_t *zvni)
+{
+ unsigned int i;
+ u_int32_t num_macs = 0;
+ struct hash *hash;
+ struct hash_backet *hb;
+ zebra_mac_t *mac;
+
+ hash = zvni->mac_table;
+ if (!hash)
+ return num_macs;
+ for (i = 0; i < hash->size; i++) {
+ for (hb = hash->index[i]; hb; hb = hb->next) {
+ mac = (zebra_mac_t *)hb->data;
+ if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
+ || !CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO))
+ num_macs++;
+ }
+ }
+
+ return num_macs;
+}
+
+static int advertise_gw_macip_enabled(zebra_vni_t *zvni)
{
+ struct zebra_vrf *zvrf;
+
+ zvrf = vrf_info_lookup(VRF_DEFAULT);
if (zvrf && zvrf->advertise_gw_macip)
return 1;
@@ -541,7 +570,7 @@ static void zvni_print_mac_hash_all_vni(struct hash_backet *backet, void *ctxt)
/*We are iterating over a new VNI, set the count to 0*/
wctx->count = 0;
- num_macs = hashcount(zvni->mac_table);
+ num_macs = num_valid_macs(zvni);
if (!num_macs)
return;
@@ -600,7 +629,7 @@ static void zvni_print(zebra_vni_t *zvni, void **ctxt)
vty_out(vty, " VxLAN interface: unknown\n");
return;
}
- num_macs = hashcount(zvni->mac_table);
+ num_macs = num_valid_macs(zvni);
num_neigh = hashcount(zvni->neigh_table);
if (json == NULL)
vty_out(vty, " VxLAN interface: %s ifIndex: %u VTEP IP: %s\n",
@@ -682,7 +711,7 @@ static void zvni_print_hash(struct hash_backet *backet, void *ctxt[])
zvtep = zvtep->next;
}
- num_macs = hashcount(zvni->mac_table);
+ num_macs = num_valid_macs(zvni);
num_neigh = hashcount(zvni->neigh_table);
if (json == NULL)
vty_out(vty, "%-10u %-21s %-15s %-8u %-8u %-15u\n", zvni->vni,
@@ -719,7 +748,7 @@ static void zvni_print_hash(struct hash_backet *backet, void *ctxt[])
/*
* Inform BGP about local MACIP.
*/
-static int zvni_macip_send_msg_to_client(struct zebra_vrf *zvrf, vni_t vni,
+static int zvni_macip_send_msg_to_client(vni_t vni,
struct ethaddr *macaddr,
struct ipaddr *ip, u_char flags,
u_int16_t cmd)
@@ -738,7 +767,7 @@ static int zvni_macip_send_msg_to_client(struct zebra_vrf *zvrf, vni_t vni,
s = client->obuf;
stream_reset(s);
- zserv_create_header(s, cmd, zvrf_id(zvrf));
+ zserv_create_header(s, cmd, VRF_DEFAULT);
stream_putl(s, vni);
stream_put(s, macaddr->octet, ETH_ALEN);
if (ip) {
@@ -761,8 +790,8 @@ static int zvni_macip_send_msg_to_client(struct zebra_vrf *zvrf, vni_t vni,
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "%u:Send MACIP %s flags 0x%x MAC %s IP %s VNI %u to %s",
- zvrf_id(zvrf), (cmd == ZEBRA_MACIP_ADD) ? "Add" : "Del",
+ "Send MACIP %s flags 0x%x MAC %s IP %s VNI %u to %s",
+ (cmd == ZEBRA_MACIP_ADD) ? "Add" : "Del",
flags, prefix_mac2str(macaddr, buf, sizeof(buf)),
ipaddr2str(ip, buf2, sizeof(buf2)), vni,
zebra_route_string(client->proto));
@@ -882,8 +911,7 @@ static int zvni_neigh_del_hash_entry(struct hash_backet *backet, void *arg)
&& (n->flags & ZEBRA_NEIGH_REMOTE)
&& IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip))) {
if (wctx->upd_client && (n->flags & ZEBRA_NEIGH_LOCAL))
- zvni_neigh_send_del_to_client(wctx->zvrf,
- wctx->zvni->vni, &n->ip,
+ zvni_neigh_send_del_to_client(wctx->zvni->vni, &n->ip,
&n->emac, 0);
if (wctx->uninstall)
@@ -921,7 +949,7 @@ static void zvni_neigh_del_from_vtep(zebra_vni_t *zvni, int uninstall,
/*
* Delete all neighbor entries for this VNI.
*/
-static void zvni_neigh_del_all(struct zebra_vrf *zvrf, zebra_vni_t *zvni,
+static void zvni_neigh_del_all(zebra_vni_t *zvni,
int uninstall, int upd_client, u_int32_t flags)
{
struct neigh_walk_ctx wctx;
@@ -931,7 +959,6 @@ static void zvni_neigh_del_all(struct zebra_vrf *zvrf, zebra_vni_t *zvni,
memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
wctx.zvni = zvni;
- wctx.zvrf = zvrf;
wctx.uninstall = uninstall;
wctx.upd_client = upd_client;
wctx.flags = flags;
@@ -958,8 +985,7 @@ static zebra_neigh_t *zvni_neigh_lookup(zebra_vni_t *zvni, struct ipaddr *ip)
}
/* Process all neigh associated to a mac upon local mac add event */
-static void zvni_process_neigh_on_local_mac_add(struct zebra_vrf *zvrf,
- zebra_vni_t *zvni,
+static void zvni_process_neigh_on_local_mac_add(zebra_vni_t *zvni,
zebra_mac_t *zmac)
{
zebra_neigh_t *n = NULL;
@@ -974,8 +1000,7 @@ static void zvni_process_neigh_on_local_mac_add(struct zebra_vrf *zvrf,
if (IS_ZEBRA_NEIGH_INACTIVE(n)) {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "%u: neigh %s (MAC %s) on VNI %u is now ACTIVE",
- zvrf_id(zvrf),
+ "neigh %s (MAC %s) on VNI %u is now ACTIVE",
ipaddr2str(&n->ip, buf2,
sizeof(buf2)),
prefix_mac2str(&n->emac, buf,
@@ -984,12 +1009,11 @@ static void zvni_process_neigh_on_local_mac_add(struct zebra_vrf *zvrf,
ZEBRA_NEIGH_SET_ACTIVE(n);
zvni_neigh_send_add_to_client(
- zvrf, zvni->vni, &n->ip, &n->emac, 0);
+ zvni->vni, &n->ip, &n->emac, 0);
} else {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "%u: neigh %s (MAC %s) on VNI %u should NOT be ACTIVE",
- zvrf_id(zvrf),
+ "neigh %s (MAC %s) on VNI %u should NOT be ACTIVE",
ipaddr2str(&n->ip, buf2,
sizeof(buf2)),
prefix_mac2str(&n->emac, buf,
@@ -1003,8 +1027,7 @@ static void zvni_process_neigh_on_local_mac_add(struct zebra_vrf *zvrf,
}
/* Process all neigh associated to a mac upon local mac del event */
-static void zvni_process_neigh_on_local_mac_del(struct zebra_vrf *zvrf,
- zebra_vni_t *zvni,
+static void zvni_process_neigh_on_local_mac_del(zebra_vni_t *zvni,
zebra_mac_t *zmac)
{
zebra_neigh_t *n = NULL;
@@ -1017,8 +1040,7 @@ static void zvni_process_neigh_on_local_mac_del(struct zebra_vrf *zvrf,
if (IS_ZEBRA_NEIGH_ACTIVE(n)) {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "%u: neigh %s (MAC %s) on VNI %u is now INACTIVE",
- zvrf_id(zvrf),
+ "neigh %s (MAC %s) on VNI %u is now INACTIVE",
ipaddr2str(&n->ip, buf2,
sizeof(buf2)),
prefix_mac2str(&n->emac, buf,
@@ -1027,13 +1049,12 @@ static void zvni_process_neigh_on_local_mac_del(struct zebra_vrf *zvrf,
ZEBRA_NEIGH_SET_INACTIVE(n);
zvni_neigh_send_del_to_client(
- zvrf, zvni->vni, &n->ip, &n->emac, 0);
+ zvni->vni, &n->ip, &n->emac, 0);
}
} else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_err(
- "%u: local MAC %s getting deleted on VNI %u has remote neigh %s",
- zvrf_id(zvrf),
+ "local MAC %s getting deleted on VNI %u has remote neigh %s",
prefix_mac2str(&n->emac, buf,
sizeof(buf)),
zvni->vni,
@@ -1043,8 +1064,7 @@ static void zvni_process_neigh_on_local_mac_del(struct zebra_vrf *zvrf,
}
/* process all neigh associated to a mac entry upon remote mac add */
-static void zvni_process_neigh_on_remote_mac_add(struct zebra_vrf *zvrf,
- zebra_vni_t *zvni,
+static void zvni_process_neigh_on_remote_mac_add(zebra_vni_t *zvni,
zebra_mac_t *zmac)
{
zebra_neigh_t *n = NULL;
@@ -1057,8 +1077,7 @@ static void zvni_process_neigh_on_remote_mac_add(struct zebra_vrf *zvrf,
if (IS_ZEBRA_NEIGH_ACTIVE(n)) {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "%u: neigh %s (MAC %s) on VNI %u INACTIVE",
- zvrf_id(zvrf),
+ "neigh %s (MAC %s) on VNI %u INACTIVE",
ipaddr2str(&n->ip, buf2,
sizeof(buf2)),
prefix_mac2str(&n->emac, buf,
@@ -1067,15 +1086,14 @@ static void zvni_process_neigh_on_remote_mac_add(struct zebra_vrf *zvrf,
ZEBRA_NEIGH_SET_INACTIVE(n);
zvni_neigh_send_del_to_client(
- zvrf, zvni->vni, &n->ip, &n->emac, 0);
+ zvni->vni, &n->ip, &n->emac, 0);
}
}
}
}
/* process all neigh associated to mac entry upon remote mac del */
-static void zvni_process_neigh_on_remote_mac_del(struct zebra_vrf *zvrf,
- zebra_vni_t *zvni,
+static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t *zvni,
zebra_mac_t *zmac)
{
zebra_neigh_t *n = NULL;
@@ -1087,8 +1105,7 @@ static void zvni_process_neigh_on_remote_mac_del(struct zebra_vrf *zvrf,
if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_err(
- "%u: remote MAC %s getting deleted on VNI %u has local neigh %s",
- zvrf_id(zvrf),
+ "remote MAC %s getting deleted on VNI %u has local neigh %s",
prefix_mac2str(&n->emac, buf,
sizeof(buf)),
zvni->vni,
@@ -1100,22 +1117,22 @@ static void zvni_process_neigh_on_remote_mac_del(struct zebra_vrf *zvrf,
/*
* Inform BGP about local neighbor addition.
*/
-static int zvni_neigh_send_add_to_client(struct zebra_vrf *zvrf, vni_t vni,
+static int zvni_neigh_send_add_to_client(vni_t vni,
struct ipaddr *ip,
struct ethaddr *macaddr, u_char flags)
{
- return zvni_macip_send_msg_to_client(zvrf, vni, macaddr, ip, flags,
+ return zvni_macip_send_msg_to_client(vni, macaddr, ip, flags,
ZEBRA_MACIP_ADD);
}
/*
* Inform BGP about local neighbor deletion.
*/
-static int zvni_neigh_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni,
+static int zvni_neigh_send_del_to_client(vni_t vni,
struct ipaddr *ip,
struct ethaddr *macaddr, u_char flags)
{
- return zvni_macip_send_msg_to_client(zvrf, vni, macaddr, ip, flags,
+ return zvni_macip_send_msg_to_client(vni, macaddr, ip, flags,
ZEBRA_MACIP_DEL);
}
@@ -1124,7 +1141,6 @@ static int zvni_neigh_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni,
*/
static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n)
{
- struct zebra_vrf *zvrf;
struct zebra_if *zif;
struct zebra_l2info_vxlan *vxl;
struct interface *vlan_if;
@@ -1132,15 +1148,12 @@ static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n)
if (!(n->flags & ZEBRA_NEIGH_REMOTE))
return 0;
- zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
- assert(zvrf);
zif = zvni->vxlan_if->info;
if (!zif)
return -1;
vxl = &zif->l2info.vxl;
- vlan_if = zvni_map_to_svi(zvrf, vxl->access_vlan,
- zif->brslave_info.br_if);
+ vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
if (!vlan_if)
return -1;
@@ -1152,7 +1165,6 @@ static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n)
*/
static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n)
{
- struct zebra_vrf *zvrf;
struct zebra_if *zif;
struct zebra_l2info_vxlan *vxl;
struct interface *vlan_if;
@@ -1166,15 +1178,11 @@ static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n)
return -1;
}
- zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
- assert(zvrf);
-
zif = zvni->vxlan_if->info;
if (!zif)
return -1;
vxl = &zif->l2info.vxl;
- vlan_if = zvni_map_to_svi(zvrf, vxl->access_vlan,
- zif->brslave_info.br_if);
+ vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
if (!vlan_if)
return -1;
@@ -1225,15 +1233,10 @@ struct interface *zebra_get_vrr_intf_for_svi(struct interface *ifp)
static int zvni_del_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni)
{
- struct zebra_vrf *zvrf = NULL;
struct listnode *cnode = NULL, *cnnode = NULL;
struct connected *c = NULL;
struct ethaddr macaddr;
- zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
- if (!zvrf)
- return -1;
-
memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
@@ -1263,15 +1266,10 @@ static int zvni_del_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni)
static int zvni_add_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni)
{
- struct zebra_vrf *zvrf = NULL;
struct listnode *cnode = NULL, *cnnode = NULL;
struct connected *c = NULL;
struct ethaddr macaddr;
- zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
- if (!zvrf)
- return -1;
-
memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
@@ -1305,7 +1303,6 @@ static int zvni_add_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni)
static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
struct ethaddr *macaddr, struct ipaddr *ip)
{
- struct zebra_vrf *zvrf = NULL;
struct zebra_if *zif = NULL;
struct zebra_l2info_vxlan *vxl = NULL;
zebra_neigh_t *n = NULL;
@@ -1313,10 +1310,6 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
char buf[ETHER_ADDR_STRLEN];
char buf2[INET6_ADDRSTRLEN];
- zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
- if (!zvrf)
- return -1;
-
zif = zvni->vxlan_if->info;
if (!zif)
return -1;
@@ -1327,8 +1320,7 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
if (!mac) {
mac = zvni_mac_add(zvni, macaddr);
if (!mac) {
- zlog_err("%u:Failed to add MAC %s intf %s(%u) VID %u",
- ifp->vrf_id,
+ zlog_err("Failed to add MAC %s intf %s(%u) VID %u",
prefix_mac2str(macaddr, buf, sizeof(buf)),
ifp->name, ifp->ifindex, vxl->access_vlan);
return -1;
@@ -1347,8 +1339,8 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
n = zvni_neigh_add(zvni, ip, macaddr);
if (!n) {
zlog_err(
- "%u:Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
- ifp->vrf_id, ipaddr2str(ip, buf2, sizeof(buf2)),
+ "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
+ ipaddr2str(ip, buf2, sizeof(buf2)),
prefix_mac2str(macaddr, buf, sizeof(buf)),
ifp->name, ifp->ifindex, zvni->vni);
return -1;
@@ -1362,12 +1354,12 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "%u:SVI %s(%u) VNI %u, sending GW MAC %s IP %s add to BGP",
- ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni,
+ "SVI %s(%u) VNI %u, sending GW MAC %s IP %s add to BGP",
+ ifp->name, ifp->ifindex, zvni->vni,
prefix_mac2str(macaddr, buf, sizeof(buf)),
ipaddr2str(ip, buf2, sizeof(buf2)));
- zvni_neigh_send_add_to_client(zvrf, zvni->vni, ip, macaddr,
+ zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr,
ZEBRA_MAC_TYPE_GW);
return 0;
@@ -1379,16 +1371,11 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni,
struct ipaddr *ip)
{
- struct zebra_vrf *zvrf = NULL;
zebra_neigh_t *n = NULL;
zebra_mac_t *mac = NULL;
char buf1[ETHER_ADDR_STRLEN];
char buf2[INET6_ADDRSTRLEN];
- zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
- if (!zvrf)
- return -1;
-
/* If the neigh entry is not present nothing to do*/
n = zvni_neigh_lookup(zvni, ip);
if (!n)
@@ -1397,8 +1384,7 @@ static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni,
/* mac entry should be present */
mac = zvni_mac_lookup(zvni, &n->emac);
if (!mac) {
- zlog_err("%u: MAC %s doesnt exists for neigh %s on VNI %u",
- ifp->vrf_id,
+ zlog_err("MAC %s doesnt exists for neigh %s on VNI %u",
prefix_mac2str(&n->emac, buf1, sizeof(buf1)),
ipaddr2str(ip, buf2, sizeof(buf2)), zvni->vni);
return -1;
@@ -1410,13 +1396,13 @@ static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni,
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "%u:SVI %s(%u) VNI %u, sending GW MAC %s IP %s del to BGP",
- ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni,
+ "SVI %s(%u) VNI %u, sending GW MAC %s IP %s del to BGP",
+ ifp->name, ifp->ifindex, zvni->vni,
prefix_mac2str(&(n->emac), buf1, sizeof(buf1)),
ipaddr2str(ip, buf2, sizeof(buf2)));
/* Remove neighbor from BGP. */
- zvni_neigh_send_del_to_client(zvrf, zvni->vni, &n->ip, &n->emac,
+ zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac,
ZEBRA_MAC_TYPE_GW);
/* Delete this neighbor entry. */
@@ -1430,7 +1416,7 @@ static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni,
}
static void zvni_gw_macip_del_for_vni_hash(struct hash_backet *backet,
- void *zvrf)
+ void *ctxt)
{
zebra_vni_t *zvni = NULL;
struct zebra_if *zif = NULL;
@@ -1455,8 +1441,7 @@ static void zvni_gw_macip_del_for_vni_hash(struct hash_backet *backet,
zl2_info = zif->l2info.vxl;
- vlan_if = zvni_map_to_svi(zvrf, zl2_info.access_vlan,
- zif->brslave_info.br_if);
+ vlan_if = zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if);
if (!vlan_if)
return;
@@ -1472,7 +1457,7 @@ static void zvni_gw_macip_del_for_vni_hash(struct hash_backet *backet,
}
static void zvni_gw_macip_add_for_vni_hash(struct hash_backet *backet,
- void *zvrf)
+ void *ctxt)
{
zebra_vni_t *zvni = NULL;
struct zebra_if *zif = NULL;
@@ -1485,7 +1470,7 @@ static void zvni_gw_macip_add_for_vni_hash(struct hash_backet *backet,
if (!zvni)
return;
- if (!advertise_gw_macip_enabled(zvrf, zvni))
+ if (!advertise_gw_macip_enabled(zvni))
return;
ifp = zvni->vxlan_if;
@@ -1498,14 +1483,11 @@ static void zvni_gw_macip_add_for_vni_hash(struct hash_backet *backet,
return;
zl2_info = zif->l2info.vxl;
- vlan_if = zvni_map_to_svi(zvrf, zl2_info.access_vlan,
+ vlan_if = zvni_map_to_svi(zl2_info.access_vlan,
zif->brslave_info.br_if);
if (!vlan_if)
return;
- if (!advertise_gw_macip_enabled(zvrf, zvni))
- return;
-
/* Add primary SVI MAC-IP */
zvni_add_macip_for_intf(vlan_if, zvni);
@@ -1587,7 +1569,7 @@ static int zvni_mac_del(zebra_vni_t *zvni, zebra_mac_t *mac)
{
zebra_mac_t *tmp_mac;
- list_delete(mac->neigh_list);
+ list_delete_and_null(&mac->neigh_list);
/* Free the VNI hash entry and allocated memory. */
tmp_mac = hash_release(zvni->mac_table, mac);
@@ -1617,7 +1599,7 @@ static int zvni_mac_del_hash_entry(struct hash_backet *backet, void *arg)
sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1
: 0;
zvni_mac_send_del_to_client(
- wctx->zvrf, wctx->zvni->vni, &mac->macaddr,
+ wctx->zvni->vni, &mac->macaddr,
(sticky ? ZEBRA_MAC_TYPE_STICKY : 0));
}
@@ -1655,7 +1637,7 @@ static void zvni_mac_del_from_vtep(zebra_vni_t *zvni, int uninstall,
/*
* Delete all MAC entries for this VNI.
*/
-static void zvni_mac_del_all(struct zebra_vrf *zvrf, zebra_vni_t *zvni,
+static void zvni_mac_del_all(zebra_vni_t *zvni,
int uninstall, int upd_client, u_int32_t flags)
{
struct mac_walk_ctx wctx;
@@ -1665,7 +1647,6 @@ static void zvni_mac_del_all(struct zebra_vrf *zvrf, zebra_vni_t *zvni,
memset(&wctx, 0, sizeof(struct mac_walk_ctx));
wctx.zvni = zvni;
- wctx.zvrf = zvrf;
wctx.uninstall = uninstall;
wctx.upd_client = upd_client;
wctx.flags = flags;
@@ -1693,43 +1674,39 @@ static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *mac)
/*
* Inform BGP about local MAC addition.
*/
-static int zvni_mac_send_add_to_client(struct zebra_vrf *zvrf, vni_t vni,
+static int zvni_mac_send_add_to_client(vni_t vni,
struct ethaddr *macaddr, u_char flags)
{
- return zvni_macip_send_msg_to_client(zvrf, vni, macaddr, NULL, flags,
+ return zvni_macip_send_msg_to_client(vni, macaddr, NULL, flags,
ZEBRA_MACIP_ADD);
}
/*
* Inform BGP about local MAC deletion.
*/
-static int zvni_mac_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni,
+static int zvni_mac_send_del_to_client(vni_t vni,
struct ethaddr *macaddr, u_char flags)
{
- return zvni_macip_send_msg_to_client(zvrf, vni, macaddr, NULL, flags,
+ return zvni_macip_send_msg_to_client(vni, macaddr, NULL, flags,
ZEBRA_MACIP_DEL);
}
/*
* Map port or (port, VLAN) to a VNI. This is invoked upon getting MAC
- * notifications, to see if there are of interest.
- * TODO: Need to make this as a hash table.
+ * notifications, to see if they are of interest.
*/
static zebra_vni_t *zvni_map_vlan(struct interface *ifp,
struct interface *br_if, vlanid_t vid)
{
- struct zebra_vrf *zvrf;
- struct listnode *node;
- struct interface *tmp_if;
+ struct zebra_ns *zns;
+ struct route_node *rn;
+ struct interface *tmp_if = NULL;
struct zebra_if *zif;
struct zebra_l2info_bridge *br;
- struct zebra_l2info_vxlan *vxl;
+ struct zebra_l2info_vxlan *vxl = NULL;
u_char bridge_vlan_aware;
zebra_vni_t *zvni;
-
- /* Locate VRF corresponding to interface. */
- zvrf = vrf_info_lookup(ifp->vrf_id);
- assert(zvrf);
+ int found = 0;
/* Determine if bridge is VLAN-aware or not */
zif = br_if->info;
@@ -1739,7 +1716,11 @@ static zebra_vni_t *zvni_map_vlan(struct interface *ifp,
/* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
/* TODO: Optimize with a hash. */
- for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf)), node, tmp_if)) {
+ zns = zebra_ns_lookup(NS_DEFAULT);
+ for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
+ tmp_if = (struct interface *)rn->info;
+ if (!tmp_if)
+ continue;
zif = tmp_if->info;
if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
continue;
@@ -1750,36 +1731,35 @@ static zebra_vni_t *zvni_map_vlan(struct interface *ifp,
if (zif->brslave_info.br_if != br_if)
continue;
- if (!bridge_vlan_aware)
- break;
-
- if (vxl->access_vlan == vid)
+ if (!bridge_vlan_aware || vxl->access_vlan == vid) {
+ found = 1;
break;
+ }
}
- if (!tmp_if)
+ if (!found)
return NULL;
- zvni = zvni_lookup(zvrf, vxl->vni);
+ zvni = zvni_lookup(vxl->vni);
return zvni;
}
/*
* Map SVI and associated bridge to a VNI. This is invoked upon getting
* neighbor notifications, to see if they are of interest.
- * TODO: Need to make this as a hash table.
*/
static zebra_vni_t *zvni_map_svi(struct interface *ifp, struct interface *br_if)
{
- struct zebra_vrf *zvrf;
- struct listnode *node;
- struct interface *tmp_if;
+ struct zebra_ns *zns;
+ struct route_node *rn;
+ struct interface *tmp_if = NULL;
struct zebra_if *zif;
struct zebra_l2info_bridge *br;
- struct zebra_l2info_vxlan *vxl;
+ struct zebra_l2info_vxlan *vxl = NULL;
u_char bridge_vlan_aware;
vlanid_t vid = 0;
zebra_vni_t *zvni;
+ int found = 0;
if (!br_if)
return NULL;
@@ -1788,10 +1768,6 @@ static zebra_vni_t *zvni_map_svi(struct interface *ifp, struct interface *br_if)
if (!IS_ZEBRA_IF_BRIDGE(br_if))
return NULL;
- /* Locate VRF corresponding to interface. */
- zvrf = vrf_info_lookup(ifp->vrf_id);
- assert(zvrf);
-
/* Determine if bridge is VLAN-aware or not */
zif = br_if->info;
assert(zif);
@@ -1811,7 +1787,11 @@ static zebra_vni_t *zvni_map_svi(struct interface *ifp, struct interface *br_if)
/* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
/* TODO: Optimize with a hash. */
- for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf)), node, tmp_if)) {
+ zns = zebra_ns_lookup(NS_DEFAULT);
+ for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
+ tmp_if = (struct interface *)rn->info;
+ if (!tmp_if)
+ continue;
zif = tmp_if->info;
if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
continue;
@@ -1822,17 +1802,16 @@ static zebra_vni_t *zvni_map_svi(struct interface *ifp, struct interface *br_if)
if (zif->brslave_info.br_if != br_if)
continue;
- if (!bridge_vlan_aware)
- break;
-
- if (vxl->access_vlan == vid)
+ if (!bridge_vlan_aware || vxl->access_vlan == vid) {
+ found = 1;
break;
+ }
}
- if (!tmp_if)
+ if (!found)
return NULL;
- zvni = zvni_lookup(zvrf, vxl->vni);
+ zvni = zvni_lookup(vxl->vni);
return zvni;
}
@@ -1843,15 +1822,16 @@ static zebra_vni_t *zvni_map_svi(struct interface *ifp, struct interface *br_if)
* (b) In the case of a VLAN-unaware bridge, the SVI is the bridge inteface
* itself
*/
-static struct interface *zvni_map_to_svi(struct zebra_vrf *zvrf, vlanid_t vid,
- struct interface *br_if)
+static struct interface *zvni_map_to_svi(vlanid_t vid, struct interface *br_if)
{
- struct listnode *node;
- struct interface *tmp_if;
+ struct zebra_ns *zns;
+ struct route_node *rn;
+ struct interface *tmp_if = NULL;
struct zebra_if *zif;
struct zebra_l2info_bridge *br;
struct zebra_l2info_vlan *vl;
u_char bridge_vlan_aware;
+ int found = 0;
/* Defensive check, caller expected to invoke only with valid bridge. */
if (!br_if)
@@ -1869,9 +1849,11 @@ static struct interface *zvni_map_to_svi(struct zebra_vrf *zvrf, vlanid_t vid,
/* Identify corresponding VLAN interface. */
/* TODO: Optimize with a hash. */
- for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf)), node, tmp_if)) {
+ zns = zebra_ns_lookup(NS_DEFAULT);
+ for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
+ tmp_if = (struct interface *)rn->info;
/* Check oper status of the SVI. */
- if (!if_is_operative(tmp_if))
+ if (!tmp_if || !if_is_operative(tmp_if))
continue;
zif = tmp_if->info;
if (!zif || zif->zif_type != ZEBRA_IF_VLAN
@@ -1879,11 +1861,13 @@ static struct interface *zvni_map_to_svi(struct zebra_vrf *zvrf, vlanid_t vid,
continue;
vl = (struct zebra_l2info_vlan *)&zif->l2info.vl;
- if (vl->vid == vid)
+ if (vl->vid == vid) {
+ found = 1;
break;
+ }
}
- return tmp_if;
+ return found ? tmp_if : NULL;
}
/*
@@ -1986,9 +1970,10 @@ static void zvni_deref_ip2mac(zebra_vni_t *zvni, zebra_mac_t *mac,
/*
* Read and populate local MACs and neighbors corresponding to this VNI.
*/
-static void zvni_read_mac_neigh(struct zebra_vrf *zvrf, zebra_vni_t *zvni,
+static void zvni_read_mac_neigh(zebra_vni_t *zvni,
struct interface *ifp)
{
+ struct zebra_ns *zns;
struct zebra_if *zif;
struct interface *vlan_if;
struct zebra_l2info_vxlan *vxl;
@@ -1996,19 +1981,19 @@ static void zvni_read_mac_neigh(struct zebra_vrf *zvrf, zebra_vni_t *zvni,
zif = ifp->info;
vxl = &zif->l2info.vxl;
+ zns = zebra_ns_lookup(NS_DEFAULT);
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "%u:Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
- ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni,
+ "Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
+ ifp->name, ifp->ifindex, zvni->vni,
zif->brslave_info.bridge_ifindex);
- macfdb_read_for_bridge(zvrf->zns, ifp, zif->brslave_info.br_if);
- vlan_if = zvni_map_to_svi(zvrf, vxl->access_vlan,
- zif->brslave_info.br_if);
+ macfdb_read_for_bridge(zns, ifp, zif->brslave_info.br_if);
+ vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
if (vlan_if) {
- if (advertise_gw_macip_enabled(zvrf, zvni)) {
+ if (advertise_gw_macip_enabled(zvni)) {
/* Add SVI MAC-IP */
zvni_add_macip_for_intf(vlan_if, zvni);
@@ -2018,7 +2003,7 @@ static void zvni_read_mac_neigh(struct zebra_vrf *zvrf, zebra_vni_t *zvni,
zvni_add_macip_for_intf(vrr_if, zvni);
}
- neigh_read_for_vlan(zvrf->zns, vlan_if);
+ neigh_read_for_vlan(zns, vlan_if);
}
}
@@ -2059,11 +2044,14 @@ static void *zvni_alloc(void *p)
/*
* Look up VNI hash entry.
*/
-static zebra_vni_t *zvni_lookup(struct zebra_vrf *zvrf, vni_t vni)
+static zebra_vni_t *zvni_lookup(vni_t vni)
{
+ struct zebra_vrf *zvrf;
zebra_vni_t tmp_vni;
zebra_vni_t *zvni = NULL;
+ zvrf = vrf_info_lookup(VRF_DEFAULT);
+ assert(zvrf);
memset(&tmp_vni, 0, sizeof(zebra_vni_t));
tmp_vni.vni = vni;
zvni = hash_lookup(zvrf->vni_table, &tmp_vni);
@@ -2074,11 +2062,14 @@ static zebra_vni_t *zvni_lookup(struct zebra_vrf *zvrf, vni_t vni)
/*
* Add VNI hash entry.
*/
-static zebra_vni_t *zvni_add(struct zebra_vrf *zvrf, vni_t vni)
+static zebra_vni_t *zvni_add(vni_t vni)
{
+ struct zebra_vrf *zvrf;
zebra_vni_t tmp_zvni;
zebra_vni_t *zvni = NULL;
+ zvrf = vrf_info_lookup(VRF_DEFAULT);
+ assert(zvrf);
memset(&tmp_zvni, 0, sizeof(zebra_vni_t));
tmp_zvni.vni = vni;
zvni = hash_get(zvrf->vni_table, &tmp_zvni, zvni_alloc);
@@ -2098,10 +2089,14 @@ static zebra_vni_t *zvni_add(struct zebra_vrf *zvrf, vni_t vni)
/*
* Delete VNI hash entry.
*/
-static int zvni_del(struct zebra_vrf *zvrf, zebra_vni_t *zvni)
+static int zvni_del(zebra_vni_t *zvni)
{
+ struct zebra_vrf *zvrf;
zebra_vni_t *tmp_zvni;
+ zvrf = vrf_info_lookup(VRF_DEFAULT);
+ assert(zvrf);
+
zvni->vxlan_if = NULL;
/* Free the neighbor hash table. */
@@ -2123,7 +2118,7 @@ static int zvni_del(struct zebra_vrf *zvrf, zebra_vni_t *zvni)
/*
* Inform BGP about local VNI addition.
*/
-static int zvni_send_add_to_client(struct zebra_vrf *zvrf, zebra_vni_t *zvni)
+static int zvni_send_add_to_client(zebra_vni_t *zvni)
{
struct zserv *client;
struct stream *s;
@@ -2136,7 +2131,7 @@ static int zvni_send_add_to_client(struct zebra_vrf *zvrf, zebra_vni_t *zvni)
s = client->obuf;
stream_reset(s);
- zserv_create_header(s, ZEBRA_VNI_ADD, zvrf_id(zvrf));
+ zserv_create_header(s, ZEBRA_VNI_ADD, VRF_DEFAULT);
stream_putl(s, zvni->vni);
stream_put_in_addr(s, &zvni->local_vtep_ip);
@@ -2144,7 +2139,7 @@ static int zvni_send_add_to_client(struct zebra_vrf *zvrf, zebra_vni_t *zvni)
stream_putw_at(s, 0, stream_get_endp(s));
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug("%u:Send VNI_ADD %u %s to %s", zvrf_id(zvrf),
+ zlog_debug("Send VNI_ADD %u %s to %s",
zvni->vni, inet_ntoa(zvni->local_vtep_ip),
zebra_route_string(client->proto));
@@ -2155,7 +2150,7 @@ static int zvni_send_add_to_client(struct zebra_vrf *zvrf, zebra_vni_t *zvni)
/*
* Inform BGP about local VNI deletion.
*/
-static int zvni_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni)
+static int zvni_send_del_to_client(vni_t vni)
{
struct zserv *client;
struct stream *s;
@@ -2168,14 +2163,14 @@ static int zvni_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni)
s = client->obuf;
stream_reset(s);
- zserv_create_header(s, ZEBRA_VNI_DEL, zvrf_id(zvrf));
+ zserv_create_header(s, ZEBRA_VNI_DEL, VRF_DEFAULT);
stream_putl(s, vni);
/* Write packet size. */
stream_putw_at(s, 0, stream_get_endp(s));
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug("%u:Send VNI_DEL %u to %s", zvrf_id(zvrf), vni,
+ zlog_debug("Send VNI_DEL %u to %s", vni,
zebra_route_string(client->proto));
client->vnidel_cnt++;
@@ -2186,18 +2181,23 @@ static int zvni_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni)
* Build the VNI hash table by going over the VxLAN interfaces. This
* is called when EVPN (advertise-all-vni) is enabled.
*/
-static void zvni_build_hash_table(struct zebra_vrf *zvrf)
+static void zvni_build_hash_table()
{
- struct listnode *node;
+ struct zebra_ns *zns;
+ struct route_node *rn;
struct interface *ifp;
/* Walk VxLAN interfaces and create VNI hash. */
- for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf)), node, ifp)) {
+ zns = zebra_ns_lookup(NS_DEFAULT);
+ for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
struct zebra_if *zif;
struct zebra_l2info_vxlan *vxl;
zebra_vni_t *zvni;
vni_t vni;
+ ifp = (struct interface *)rn->info;
+ if (!ifp)
+ continue;
zif = ifp->info;
if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
continue;
@@ -2207,24 +2207,24 @@ static void zvni_build_hash_table(struct zebra_vrf *zvrf)
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "%u:Create VNI hash for intf %s(%u) VNI %u local IP %s",
- zvrf_id(zvrf), ifp->name, ifp->ifindex, vni,
+ "Create VNI hash for intf %s(%u) VNI %u local IP %s",
+ ifp->name, ifp->ifindex, vni,
inet_ntoa(vxl->vtep_ip));
/* VNI hash entry is not expected to exist. */
- zvni = zvni_lookup(zvrf, vni);
+ zvni = zvni_lookup(vni);
if (zvni) {
zlog_err(
- "VNI hash already present for VRF %d IF %s(%u) VNI %u",
- zvrf_id(zvrf), ifp->name, ifp->ifindex, vni);
+ "VNI hash already present for IF %s(%u) VNI %u",
+ ifp->name, ifp->ifindex, vni);
continue;
}
- zvni = zvni_add(zvrf, vni);
+ zvni = zvni_add(vni);
if (!zvni) {
zlog_err(
- "Failed to add VNI hash, VRF %d IF %s(%u) VNI %u",
- zvrf_id(zvrf), ifp->name, ifp->ifindex, vni);
+ "Failed to add VNI hash, IF %s(%u) VNI %u",
+ ifp->name, ifp->ifindex, vni);
return;
}
@@ -2233,7 +2233,7 @@ static void zvni_build_hash_table(struct zebra_vrf *zvrf)
/* Inform BGP if interface is up and mapped to bridge. */
if (if_is_operative(ifp) && zif->brslave_info.br_if)
- zvni_send_add_to_client(zvrf, zvni);
+ zvni_send_add_to_client(zvni);
}
}
@@ -2359,14 +2359,14 @@ static void zvni_cleanup_all(struct hash_backet *backet, void *zvrf)
return;
/* Free up all neighbors and MACs, if any. */
- zvni_neigh_del_all(zvrf, zvni, 1, 0, DEL_ALL_NEIGH);
- zvni_mac_del_all(zvrf, zvni, 1, 0, DEL_ALL_MAC);
+ zvni_neigh_del_all(zvni, 1, 0, DEL_ALL_NEIGH);
+ zvni_mac_del_all(zvni, 1, 0, DEL_ALL_MAC);
/* Free up all remote VTEPs, if any. */
zvni_vtep_del_all(zvni, 1);
/* Delete the hash entry. */
- zvni_del(zvrf, zvni);
+ zvni_del(zvni);
}
@@ -2383,9 +2383,9 @@ void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf,
struct neigh_walk_ctx wctx;
json_object *json = NULL;
- if (!EVPN_ENABLED(zvrf))
+ if (!is_evpn_enabled())
return;
- zvni = zvni_lookup(zvrf, vni);
+ zvni = zvni_lookup(vni);
if (!zvni) {
if (use_json)
vty_out(vty, "{}\n");
@@ -2437,7 +2437,7 @@ void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
json_object *json = NULL;
void *args[2];
- if (!EVPN_ENABLED(zvrf))
+ if (!is_evpn_enabled())
return;
if (use_json)
@@ -2467,9 +2467,9 @@ void zebra_vxlan_print_specific_neigh_vni(struct vty *vty,
zebra_neigh_t *n;
json_object *json = NULL;
- if (!EVPN_ENABLED(zvrf))
+ if (!is_evpn_enabled())
return;
- zvni = zvni_lookup(zvrf, vni);
+ zvni = zvni_lookup(vni);
if (!zvni) {
if (use_json)
vty_out(vty, "{}\n");
@@ -2510,9 +2510,9 @@ void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
struct neigh_walk_ctx wctx;
json_object *json = NULL;
- if (!EVPN_ENABLED(zvrf))
+ if (!is_evpn_enabled())
return;
- zvni = zvni_lookup(zvrf, vni);
+ zvni = zvni_lookup(vni);
if (!zvni) {
if (use_json)
vty_out(vty, "{}\n");
@@ -2551,9 +2551,9 @@ void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf,
json_object *json = NULL;
json_object *json_mac = NULL;
- if (!EVPN_ENABLED(zvrf))
+ if (!is_evpn_enabled())
return;
- zvni = zvni_lookup(zvrf, vni);
+ zvni = zvni_lookup(vni);
if (!zvni) {
if (use_json)
vty_out(vty, "{}\n");
@@ -2561,7 +2561,7 @@ void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf,
vty_out(vty, "%% VNI %u does not exist\n", vni);
return;
}
- num_macs = hashcount(zvni->mac_table);
+ num_macs = num_valid_macs(zvni);
if (!num_macs)
return;
@@ -2603,7 +2603,7 @@ void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
struct mac_walk_ctx wctx;
json_object *json = NULL;
- if (!EVPN_ENABLED(zvrf)) {
+ if (!is_evpn_enabled()) {
if (use_json)
vty_out(vty, "{}\n");
return;
@@ -2634,7 +2634,7 @@ void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty,
struct mac_walk_ctx wctx;
json_object *json = NULL;
- if (!EVPN_ENABLED(zvrf))
+ if (!is_evpn_enabled())
return;
if (use_json)
@@ -2663,9 +2663,9 @@ void zebra_vxlan_print_specific_mac_vni(struct vty *vty, struct zebra_vrf *zvrf,
zebra_vni_t *zvni;
zebra_mac_t *mac;
- if (!EVPN_ENABLED(zvrf))
+ if (!is_evpn_enabled())
return;
- zvni = zvni_lookup(zvrf, vni);
+ zvni = zvni_lookup(vni);
if (!zvni) {
vty_out(vty, "%% VNI %u does not exist\n", vni);
return;
@@ -2693,9 +2693,9 @@ void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
json_object *json = NULL;
json_object *json_mac = NULL;
- if (!EVPN_ENABLED(zvrf))
+ if (!is_evpn_enabled())
return;
- zvni = zvni_lookup(zvrf, vni);
+ zvni = zvni_lookup(vni);
if (!zvni) {
if (use_json)
vty_out(vty, "{}\n");
@@ -2703,7 +2703,7 @@ void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
vty_out(vty, "%% VNI %u does not exist\n", vni);
return;
}
- num_macs = hashcount(zvni->mac_table);
+ num_macs = num_valid_macs(zvni);
if (!num_macs)
return;
@@ -2741,9 +2741,9 @@ void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni,
json_object *json = NULL;
void *args[2];
- if (!EVPN_ENABLED(zvrf))
+ if (!is_evpn_enabled())
return;
- zvni = zvni_lookup(zvrf, vni);
+ zvni = zvni_lookup(vni);
if (!zvni) {
if (use_json)
vty_out(vty, "{}\n");
@@ -2773,7 +2773,7 @@ void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf,
json_object *json = NULL;
void *args[2];
- if (!EVPN_ENABLED(zvrf))
+ if (!is_evpn_enabled())
return;
num_vnis = hashcount(zvrf->vni_table);
if (!num_vnis) {
@@ -2819,7 +2819,6 @@ int zebra_vxlan_local_neigh_del(struct interface *ifp,
{
zebra_vni_t *zvni;
zebra_neigh_t *n;
- struct zebra_vrf *zvrf;
char buf[INET6_ADDRSTRLEN];
char buf2[ETHER_ADDR_STRLEN];
zebra_mac_t *zmac;
@@ -2838,8 +2837,8 @@ int zebra_vxlan_local_neigh_del(struct interface *ifp,
}
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug("%u:Del neighbor %s intf %s(%u) -> VNI %u",
- ifp->vrf_id, ipaddr2str(ip, buf, sizeof(buf)),
+ zlog_debug("Del neighbor %s intf %s(%u) -> VNI %u",
+ ipaddr2str(ip, buf, sizeof(buf)),
ifp->name, ifp->ifindex, zvni->vni);
/* If entry doesn't exist, nothing to do. */
@@ -2851,8 +2850,8 @@ int zebra_vxlan_local_neigh_del(struct interface *ifp,
if (!zmac) {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_err(
- "%u: trying to del a neigh %s without a mac %s on VNI %u",
- ifp->vrf_id, ipaddr2str(ip, buf, sizeof(buf)),
+ "Trying to del a neigh %s without a mac %s on VNI %u",
+ ipaddr2str(ip, buf, sizeof(buf)),
prefix_mac2str(&n->emac, buf2, sizeof(buf2)),
zvni->vni);
@@ -2867,13 +2866,9 @@ int zebra_vxlan_local_neigh_del(struct interface *ifp,
return 0;
}
- /* Locate VRF corresponding to interface. */
- zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
- assert(zvrf);
-
/* Remove neighbor from BGP. */
if (IS_ZEBRA_NEIGH_ACTIVE(n))
- zvni_neigh_send_del_to_client(zvrf, zvni->vni, &n->ip, &n->emac,
+ zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac,
0);
/* Delete this neighbor entry. */
@@ -2899,7 +2894,6 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp,
{
zebra_vni_t *zvni;
zebra_neigh_t *n;
- struct zebra_vrf *zvrf;
zebra_mac_t *zmac, *old_zmac;
char buf[ETHER_ADDR_STRLEN];
char buf2[INET6_ADDRSTRLEN];
@@ -2911,15 +2905,11 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp,
if (!zvni)
return 0;
- /* Locate VRF corresponding to interface. */
- zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
- assert(zvrf);
-
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "%u:Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x "
+ "Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x "
"%s-> VNI %u",
- ifp->vrf_id, ipaddr2str(ip, buf2, sizeof(buf2)),
+ ipaddr2str(ip, buf2, sizeof(buf2)),
prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
ifp->ifindex, state, ext_learned ? "ext-learned " : "",
zvni->vni);
@@ -2929,15 +2919,13 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp,
if (!zmac) {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "%u: AUTO MAC %s created for neigh %s on VNI %u",
- ifp->vrf_id,
+ "AUTO MAC %s created for neigh %s on VNI %u",
prefix_mac2str(macaddr, buf, sizeof(buf)),
ipaddr2str(ip, buf2, sizeof(buf2)), zvni->vni);
zmac = zvni_mac_add(zvni, macaddr);
if (!zmac) {
- zlog_warn("%u:Failed to add MAC %s VNI %u",
- zvrf_id(zvrf),
+ zlog_warn("Failed to add MAC %s VNI %u",
prefix_mac2str(macaddr, buf, sizeof(buf)),
zvni->vni);
return -1;
@@ -2969,7 +2957,7 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp,
* as this means a different MACIP route.
* Also, need to do some unlinking/relinking.
*/
- zvni_neigh_send_del_to_client(zvrf, zvni->vni, &n->ip,
+ zvni_neigh_send_del_to_client(zvni->vni, &n->ip,
&n->emac, 0);
old_zmac = zvni_mac_lookup(zvni, &n->emac);
if (old_zmac) {
@@ -3002,8 +2990,8 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp,
n = zvni_neigh_add(zvni, ip, macaddr);
if (!n) {
zlog_err(
- "%u:Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
- ifp->vrf_id, ipaddr2str(ip, buf2, sizeof(buf2)),
+ "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
+ ipaddr2str(ip, buf2, sizeof(buf2)),
prefix_mac2str(macaddr, buf, sizeof(buf)),
ifp->name, ifp->ifindex, zvni->vni);
return -1;
@@ -3018,8 +3006,8 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp,
if (!CHECK_FLAG(zmac->flags, ZEBRA_MAC_LOCAL)) {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "%u: Skipping neigh %s add to client as MAC %s is not local on VNI %u",
- ifp->vrf_id, ipaddr2str(ip, buf2, sizeof(buf2)),
+ "Skipping neigh %s add to client as MAC %s is not local on VNI %u",
+ ipaddr2str(ip, buf2, sizeof(buf2)),
prefix_mac2str(macaddr, buf, sizeof(buf)),
zvni->vni);
@@ -3028,13 +3016,13 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp,
/* Inform BGP. */
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug("%u: neigh %s (MAC %s) is now ACTIVE on VNI %u",
- ifp->vrf_id, ipaddr2str(ip, buf2, sizeof(buf2)),
+ zlog_debug("neigh %s (MAC %s) is now ACTIVE on VNI %u",
+ ipaddr2str(ip, buf2, sizeof(buf2)),
prefix_mac2str(macaddr, buf, sizeof(buf)),
zvni->vni);
ZEBRA_NEIGH_SET_ACTIVE(n);
- return zvni_neigh_send_add_to_client(zvrf, zvni->vni, ip, macaddr, 0);
+ return zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, 0);
}
@@ -3082,21 +3070,20 @@ int zebra_vxlan_remote_macip_del(struct zserv *client, int sock, u_short length,
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "%u:Recv MACIP Del MAC %s IP %s VNI %u Remote VTEP %s from %s",
- zvrf_id(zvrf),
+ "Recv MACIP Del MAC %s IP %s VNI %u Remote VTEP %s from %s",
prefix_mac2str(&macaddr, buf, sizeof(buf)),
ipaddr2str(&ip, buf1, sizeof(buf1)), vni,
inet_ntoa(vtep_ip),
zebra_route_string(client->proto));
/* Locate VNI hash entry - expected to exist. */
- zvni = zvni_lookup(zvrf, vni);
+ zvni = zvni_lookup(vni);
if (!zvni) {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
"Failed to locate VNI hash upon remote MACIP DEL, "
- "VRF %d VNI %u",
- zvrf_id(zvrf), vni);
+ "VNI %u",
+ vni);
continue;
}
ifp = zvni->vxlan_if;
@@ -3129,10 +3116,9 @@ int zebra_vxlan_remote_macip_del(struct zserv *client, int sock, u_short length,
if (n && !mac) {
zlog_err(
- "failed to locate MAC %s for neigh %s in VRF %u VNI %u",
+ "Failed to locate MAC %s for neigh %s VNI %u",
prefix_mac2str(&macaddr, buf, sizeof(buf)),
- ipaddr2str(&ip, buf1, sizeof(buf1)),
- zvrf_id(zvrf), vni);
+ ipaddr2str(&ip, buf1, sizeof(buf1)), vni);
continue;
}
@@ -3163,7 +3149,7 @@ int zebra_vxlan_remote_macip_del(struct zserv *client, int sock, u_short length,
}
} else {
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
- zvni_process_neigh_on_remote_mac_del(zvrf, zvni,
+ zvni_process_neigh_on_remote_mac_del(zvni,
mac);
if (list_isempty(mac->neigh_list)) {
@@ -3234,19 +3220,19 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, int sock, u_short length,
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "%u:Recv MACIP Add %sMAC %s IP %s VNI %u Remote VTEP %s from %s",
- zvrf_id(zvrf), sticky ? "sticky " : "",
+ "Recv MACIP Add %sMAC %s IP %s VNI %u Remote VTEP %s from %s",
+ sticky ? "sticky " : "",
prefix_mac2str(&macaddr, buf, sizeof(buf)),
ipaddr2str(&ip, buf1, sizeof(buf1)), vni,
inet_ntoa(vtep_ip),
zebra_route_string(client->proto));
/* Locate VNI hash entry - expected to exist. */
- zvni = zvni_lookup(zvrf, vni);
+ zvni = zvni_lookup(vni);
if (!zvni) {
zlog_err(
- "Failed to locate VNI hash upon remote MACIP ADD, VRF %d VNI %u",
- zvrf_id(zvrf), vni);
+ "Failed to locate VNI hash upon remote MACIP ADD, VNI %u",
+ vni);
continue;
}
ifp = zvni->vxlan_if;
@@ -3272,8 +3258,8 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, int sock, u_short length,
if (!zvtep) {
if (zvni_vtep_add(zvni, &vtep_ip) == NULL) {
zlog_err(
- "Failed to add remote VTEP, VRF %d VNI %u zvni %p",
- zvrf_id(zvrf), vni, zvni);
+ "Failed to add remote VTEP, VNI %u zvni %p",
+ vni, zvni);
continue;
}
@@ -3298,8 +3284,7 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, int sock, u_short length,
mac = zvni_mac_add(zvni, &macaddr);
if (!mac) {
zlog_warn(
- "%u:Failed to add MAC %s VNI %u Remote VTEP %s",
- zvrf_id(zvrf),
+ "Failed to add MAC %s VNI %u Remote VTEP %s",
prefix_mac2str(&macaddr, buf,
sizeof(buf)),
vni, inet_ntoa(vtep_ip));
@@ -3322,7 +3307,7 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, int sock, u_short length,
else
UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
- zvni_process_neigh_on_remote_mac_add(zvrf, zvni, mac);
+ zvni_process_neigh_on_remote_mac_add(zvni, mac);
/* Install the entry. */
zvni_mac_install(zvni, mac);
@@ -3350,8 +3335,7 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, int sock, u_short length,
n = zvni_neigh_add(zvni, &ip, &macaddr);
if (!n) {
zlog_warn(
- "%u:Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
- zvrf_id(zvrf),
+ "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
ipaddr2str(&ip, buf1,
sizeof(buf1)),
prefix_mac2str(&macaddr, buf,
@@ -3397,7 +3381,6 @@ int zebra_vxlan_check_del_local_mac(struct interface *ifp,
struct ethaddr *macaddr, vlanid_t vid)
{
struct zebra_if *zif;
- struct zebra_vrf *zvrf;
struct zebra_l2info_vxlan *vxl;
vni_t vni;
zebra_vni_t *zvni;
@@ -3410,16 +3393,12 @@ int zebra_vxlan_check_del_local_mac(struct interface *ifp,
vxl = &zif->l2info.vxl;
vni = vxl->vni;
- /* Locate VRF corresponding to interface. */
- zvrf = vrf_info_lookup(ifp->vrf_id);
- assert(zvrf);
-
- /* If EVPN is not enabled, nothing to do. */
- if (!EVPN_ENABLED(zvrf))
+ /* Check if EVPN is enabled. */
+ if (!is_evpn_enabled())
return 0;
/* Locate hash entry; it is expected to exist. */
- zvni = zvni_lookup(zvrf, vni);
+ zvni = zvni_lookup(vni);
if (!zvni)
return 0;
@@ -3434,13 +3413,13 @@ int zebra_vxlan_check_del_local_mac(struct interface *ifp,
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "%u:Add/update remote MAC %s intf %s(%u) VNI %u - del local",
- ifp->vrf_id, prefix_mac2str(macaddr, buf, sizeof(buf)),
+ "Add/update remote MAC %s intf %s(%u) VNI %u - del local",
+ prefix_mac2str(macaddr, buf, sizeof(buf)),
ifp->name, ifp->ifindex, vni);
/* Remove MAC from BGP. */
sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0;
- zvni_mac_send_del_to_client(zvrf, zvni->vni, macaddr,
+ zvni_mac_send_del_to_client(zvni->vni, macaddr,
(sticky ? ZEBRA_MAC_TYPE_STICKY : 0));
/*
@@ -3467,7 +3446,6 @@ int zebra_vxlan_check_readd_remote_mac(struct interface *ifp,
struct ethaddr *macaddr, vlanid_t vid)
{
struct zebra_if *zif;
- struct zebra_vrf *zvrf;
struct zebra_l2info_vxlan *vxl;
vni_t vni;
zebra_vni_t *zvni;
@@ -3479,16 +3457,12 @@ int zebra_vxlan_check_readd_remote_mac(struct interface *ifp,
vxl = &zif->l2info.vxl;
vni = vxl->vni;
- /* Locate VRF corresponding to interface. */
- zvrf = vrf_info_lookup(ifp->vrf_id);
- assert(zvrf);
-
- /* If EVPN is not enabled, nothing to do. */
- if (!EVPN_ENABLED(zvrf))
+ /* Check if EVPN is enabled. */
+ if (!is_evpn_enabled())
return 0;
/* Locate hash entry; it is expected to exist. */
- zvni = zvni_lookup(zvrf, vni);
+ zvni = zvni_lookup(vni);
if (!zvni)
return 0;
@@ -3502,8 +3476,7 @@ int zebra_vxlan_check_readd_remote_mac(struct interface *ifp,
return 0;
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug("%u:Del remote MAC %s intf %s(%u) VNI %u - readd",
- ifp->vrf_id,
+ zlog_debug("Del remote MAC %s intf %s(%u) VNI %u - readd",
prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
ifp->ifindex, vni);
@@ -3519,7 +3492,6 @@ int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if,
{
zebra_vni_t *zvni;
zebra_mac_t *mac;
- struct zebra_vrf *zvrf;
char buf[ETHER_ADDR_STRLEN];
u_char sticky;
@@ -3536,8 +3508,7 @@ int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if,
}
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug("%u:Del MAC %s intf %s(%u) VID %u -> VNI %u",
- ifp->vrf_id,
+ zlog_debug("Del MAC %s intf %s(%u) VID %u -> VNI %u",
prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
ifp->ifindex, vid, zvni->vni);
@@ -3550,17 +3521,13 @@ int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if,
if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
return 0;
- /* Locate VRF corresponding to interface. */
- zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
- assert(zvrf);
-
/* Remove MAC from BGP. */
sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0;
- zvni_mac_send_del_to_client(zvrf, zvni->vni, macaddr,
+ zvni_mac_send_del_to_client(zvni->vni, macaddr,
(sticky ? ZEBRA_MAC_TYPE_STICKY : 0));
/* Update all the neigh entries associated with this mac */
- zvni_process_neigh_on_local_mac_del(zvrf, zvni, mac);
+ zvni_process_neigh_on_local_mac_del(zvni, mac);
/*
* If there are no neigh associated with the mac delete the mac
@@ -3586,7 +3553,6 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp,
{
zebra_vni_t *zvni;
zebra_mac_t *mac;
- struct zebra_vrf *zvrf;
char buf[ETHER_ADDR_STRLEN];
int add = 1;
u_char mac_sticky;
@@ -3598,8 +3564,8 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp,
if (!zvni) {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "%u:Add/Update %sMAC %s intf %s(%u) VID %u, could not find VNI",
- ifp->vrf_id, sticky ? "sticky " : "",
+ "Add/Update %sMAC %s intf %s(%u) VID %u, could not find VNI",
+ sticky ? "sticky " : "",
prefix_mac2str(macaddr, buf, sizeof(buf)),
ifp->name, ifp->ifindex, vid);
return 0;
@@ -3613,8 +3579,8 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp,
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "%u:Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u",
- ifp->vrf_id, sticky ? "sticky " : "",
+ "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u",
+ sticky ? "sticky " : "",
prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
ifp->ifindex, vid, zvni->vni);
@@ -3638,9 +3604,8 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp,
&& mac->fwd_info.local.vid == vid) {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "%u:Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, "
+ "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, "
"entry exists and has not changed ",
- ifp->vrf_id,
sticky ? "sticky " : "",
prefix_mac2str(macaddr, buf,
sizeof(buf)),
@@ -3671,15 +3636,10 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp,
}
}
- /* Locate VRF corresponding to interface. */
- zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
- assert(zvrf);
-
if (!mac) {
mac = zvni_mac_add(zvni, macaddr);
if (!mac) {
- zlog_err("%u:Failed to add MAC %s intf %s(%u) VID %u",
- ifp->vrf_id,
+ zlog_err("Failed to add MAC %s intf %s(%u) VID %u",
prefix_mac2str(macaddr, buf, sizeof(buf)),
ifp->name, ifp->ifindex, vid);
return -1;
@@ -3701,8 +3661,8 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp,
/* Inform BGP if required. */
if (add) {
- zvni_process_neigh_on_local_mac_add(zvrf, zvni, mac);
- return zvni_mac_send_add_to_client(zvrf, zvni->vni, macaddr,
+ zvni_process_neigh_on_local_mac_add(zvni, mac);
+ return zvni_mac_send_add_to_client(zvni->vni, macaddr,
sticky);
}
@@ -3724,6 +3684,13 @@ int zebra_vxlan_remote_vtep_del(struct zserv *client, int sock, u_short length,
struct interface *ifp;
struct zebra_if *zif;
+ assert(is_evpn_enabled());
+ if (zvrf_id(zvrf) != VRF_DEFAULT) {
+ zlog_err("Recv MACIP DEL for non-default VRF %u",
+ zvrf_id(zvrf));
+ return -1;
+ }
+
s = client->ibuf;
while (l < length) {
@@ -3734,18 +3701,18 @@ int zebra_vxlan_remote_vtep_del(struct zserv *client, int sock, u_short length,
l += IPV4_MAX_BYTELEN;
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug("%u:Recv VTEP_DEL %s VNI %u from %s",
- zvrf_id(zvrf), inet_ntoa(vtep_ip), vni,
+ zlog_debug("Recv VTEP_DEL %s VNI %u from %s",
+ inet_ntoa(vtep_ip), vni,
zebra_route_string(client->proto));
/* Locate VNI hash entry - expected to exist. */
- zvni = zvni_lookup(zvrf, vni);
+ zvni = zvni_lookup(vni);
if (!zvni) {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
"Failed to locate VNI hash upon remote VTEP DEL, "
- "VRF %d VNI %u",
- zvrf_id(zvrf), vni);
+ "VNI %u",
+ vni);
continue;
}
@@ -3795,7 +3762,12 @@ int zebra_vxlan_remote_vtep_add(struct zserv *client, int sock, u_short length,
struct interface *ifp;
struct zebra_if *zif;
- assert(EVPN_ENABLED(zvrf));
+ assert(is_evpn_enabled());
+ if (zvrf_id(zvrf) != VRF_DEFAULT) {
+ zlog_err("Recv MACIP ADD for non-default VRF %u",
+ zvrf_id(zvrf));
+ return -1;
+ }
s = client->ibuf;
@@ -3807,16 +3779,16 @@ int zebra_vxlan_remote_vtep_add(struct zserv *client, int sock, u_short length,
l += IPV4_MAX_BYTELEN;
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug("%u:Recv VTEP_ADD %s VNI %u from %s",
- zvrf_id(zvrf), inet_ntoa(vtep_ip), vni,
+ zlog_debug("Recv VTEP_ADD %s VNI %u from %s",
+ inet_ntoa(vtep_ip), vni,
zebra_route_string(client->proto));
/* Locate VNI hash entry - expected to exist. */
- zvni = zvni_lookup(zvrf, vni);
+ zvni = zvni_lookup(vni);
if (!zvni) {
zlog_err(
- "Failed to locate VNI hash upon remote VTEP ADD, VRF %d VNI %u",
- zvrf_id(zvrf), vni);
+ "Failed to locate VNI hash upon remote VTEP ADD, VNI %u",
+ vni);
continue;
}
@@ -3841,8 +3813,8 @@ int zebra_vxlan_remote_vtep_add(struct zserv *client, int sock, u_short length,
if (zvni_vtep_add(zvni, &vtep_ip) == NULL) {
zlog_err(
- "Failed to add remote VTEP, VRF %d VNI %u zvni %p",
- zvrf_id(zvrf), vni, zvni);
+ "Failed to add remote VTEP, VNI %u zvni %p",
+ vni, zvni);
continue;
}
@@ -3866,16 +3838,12 @@ int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p,
struct ipaddr ip;
struct ethaddr macaddr;
zebra_vni_t *zvni = NULL;
- struct zebra_vrf *zvrf = NULL;
memset(&ip, 0, sizeof(struct ipaddr));
memset(&macaddr, 0, sizeof(struct ethaddr));
- zvrf = vrf_info_lookup(ifp->vrf_id);
- if (!zvrf)
- return -1;
-
- if (!EVPN_ENABLED(zvrf))
+ /* Check if EVPN is enabled. */
+ if (!is_evpn_enabled())
return 0;
if (IS_ZEBRA_IF_MACVLAN(ifp)) {
@@ -3896,8 +3864,8 @@ int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p,
svi_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
ifp_zif->link_ifindex);
if (!svi_if) {
- zlog_err("%u:MACVLAN %s(%u) without link information",
- ifp->vrf_id, ifp->name, ifp->ifindex);
+ zlog_err("MACVLAN %s(%u) without link information",
+ ifp->name, ifp->ifindex);
return -1;
}
@@ -3948,7 +3916,7 @@ int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p,
/* check if we are advertising gw macip routes */
- if (!advertise_gw_macip_enabled(zvrf, zvni))
+ if (!advertise_gw_macip_enabled(zvni))
return 0;
memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
@@ -4002,8 +3970,8 @@ int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if)
}
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug("%u:SVI %s(%u) VNI %u is UP, installing neighbors",
- ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni);
+ zlog_debug("SVI %s(%u) VNI %u is UP, installing neighbors",
+ ifp->name, ifp->ifindex, zvni->vni);
/* Install any remote neighbors for this VNI. */
memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx));
@@ -4020,17 +3988,12 @@ int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if)
int zebra_vxlan_if_down(struct interface *ifp)
{
struct zebra_if *zif;
- struct zebra_vrf *zvrf;
zebra_vni_t *zvni;
struct zebra_l2info_vxlan *vxl;
vni_t vni;
- /* Locate VRF corresponding to interface. */
- zvrf = vrf_info_lookup(ifp->vrf_id);
- assert(zvrf);
-
- /* If EVPN is not enabled, nothing further to be done. */
- if (!EVPN_ENABLED(zvrf))
+ /* Check if EVPN is enabled. */
+ if (!is_evpn_enabled())
return 0;
zif = ifp->info;
@@ -4039,26 +4002,26 @@ int zebra_vxlan_if_down(struct interface *ifp)
vni = vxl->vni;
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug("%u:Intf %s(%u) VNI %u is DOWN", ifp->vrf_id,
+ zlog_debug("Intf %s(%u) VNI %u is DOWN",
ifp->name, ifp->ifindex, vni);
/* Locate hash entry; it is expected to exist. */
- zvni = zvni_lookup(zvrf, vni);
+ zvni = zvni_lookup(vni);
if (!zvni) {
zlog_err(
- "Failed to locate VNI hash at DOWN, VRF %d IF %s(%u) VNI %u",
- ifp->vrf_id, ifp->name, ifp->ifindex, vni);
+ "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u",
+ ifp->name, ifp->ifindex, vni);
return -1;
}
assert(zvni->vxlan_if == ifp);
/* Delete this VNI from BGP. */
- zvni_send_del_to_client(zvrf, zvni->vni);
+ zvni_send_del_to_client(zvni->vni);
/* Free up all neighbors and MACs, if any. */
- zvni_neigh_del_all(zvrf, zvni, 1, 0, DEL_ALL_NEIGH);
- zvni_mac_del_all(zvrf, zvni, 1, 0, DEL_ALL_MAC);
+ zvni_neigh_del_all(zvni, 1, 0, DEL_ALL_NEIGH);
+ zvni_mac_del_all(zvni, 1, 0, DEL_ALL_MAC);
/* Free up all remote VTEPs, if any. */
zvni_vtep_del_all(zvni, 1);
@@ -4072,17 +4035,12 @@ int zebra_vxlan_if_down(struct interface *ifp)
int zebra_vxlan_if_up(struct interface *ifp)
{
struct zebra_if *zif;
- struct zebra_vrf *zvrf;
zebra_vni_t *zvni;
struct zebra_l2info_vxlan *vxl;
vni_t vni;
- /* Locate VRF corresponding to interface. */
- zvrf = vrf_info_lookup(ifp->vrf_id);
- assert(zvrf);
-
- /* If EVPN is not enabled, nothing further to be done. */
- if (!EVPN_ENABLED(zvrf))
+ /* Check if EVPN is enabled. */
+ if (!is_evpn_enabled())
return 0;
zif = ifp->info;
@@ -4091,15 +4049,15 @@ int zebra_vxlan_if_up(struct interface *ifp)
vni = vxl->vni;
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug("%u:Intf %s(%u) VNI %u is UP", ifp->vrf_id,
+ zlog_debug("Intf %s(%u) VNI %u is UP",
ifp->name, ifp->ifindex, vni);
/* Locate hash entry; it is expected to exist. */
- zvni = zvni_lookup(zvrf, vni);
+ zvni = zvni_lookup(vni);
if (!zvni) {
zlog_err(
- "Failed to locate VNI hash at UP, VRF %d IF %s(%u) VNI %u",
- ifp->vrf_id, ifp->name, ifp->ifindex, vni);
+ "Failed to locate VNI hash at UP, IF %s(%u) VNI %u",
+ ifp->name, ifp->ifindex, vni);
return -1;
}
@@ -4108,8 +4066,8 @@ int zebra_vxlan_if_up(struct interface *ifp)
/* If part of a bridge, inform BGP about this VNI. */
/* Also, read and populate local MACs and neighbors. */
if (zif->brslave_info.br_if) {
- zvni_send_add_to_client(zvrf, zvni);
- zvni_read_mac_neigh(zvrf, zvni, ifp);
+ zvni_send_add_to_client(zvni);
+ zvni_read_mac_neigh(zvni, ifp);
}
return 0;
@@ -4122,17 +4080,12 @@ int zebra_vxlan_if_up(struct interface *ifp)
int zebra_vxlan_if_del(struct interface *ifp)
{
struct zebra_if *zif;
- struct zebra_vrf *zvrf;
zebra_vni_t *zvni;
struct zebra_l2info_vxlan *vxl;
vni_t vni;
- /* Locate VRF corresponding to interface. */
- zvrf = vrf_info_lookup(ifp->vrf_id);
- assert(zvrf);
-
- /* If EVPN is not enabled, nothing further to be done. */
- if (!EVPN_ENABLED(zvrf))
+ /* Check if EVPN is enabled. */
+ if (!is_evpn_enabled())
return 0;
zif = ifp->info;
@@ -4141,32 +4094,32 @@ int zebra_vxlan_if_del(struct interface *ifp)
vni = vxl->vni;
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug("%u:Del VNI %u intf %s(%u)", ifp->vrf_id, vni,
- ifp->name, ifp->ifindex);
+ zlog_debug("Del VNI %u intf %s(%u)",
+ vni, ifp->name, ifp->ifindex);
/* Locate hash entry; it is expected to exist. */
- zvni = zvni_lookup(zvrf, vni);
+ zvni = zvni_lookup(vni);
if (!zvni) {
zlog_err(
- "Failed to locate VNI hash at del, VRF %d IF %s(%u) VNI %u",
- ifp->vrf_id, ifp->name, ifp->ifindex, vni);
+ "Failed to locate VNI hash at del, IF %s(%u) VNI %u",
+ ifp->name, ifp->ifindex, vni);
return 0;
}
/* Delete VNI from BGP. */
- zvni_send_del_to_client(zvrf, zvni->vni);
+ zvni_send_del_to_client(zvni->vni);
/* Free up all neighbors and MAC, if any. */
- zvni_neigh_del_all(zvrf, zvni, 0, 0, DEL_ALL_NEIGH);
- zvni_mac_del_all(zvrf, zvni, 0, 0, DEL_ALL_MAC);
+ zvni_neigh_del_all(zvni, 0, 0, DEL_ALL_NEIGH);
+ zvni_mac_del_all(zvni, 0, 0, DEL_ALL_MAC);
/* Free up all remote VTEPs, if any. */
zvni_vtep_del_all(zvni, 0);
/* Delete the hash entry. */
- if (zvni_del(zvrf, zvni)) {
- zlog_err("Failed to del VNI hash %p, VRF %d IF %s(%u) VNI %u",
- zvni, ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni);
+ if (zvni_del(zvni)) {
+ zlog_err("Failed to del VNI hash %p, IF %s(%u) VNI %u",
+ zvni, ifp->name, ifp->ifindex, zvni->vni);
return -1;
}
@@ -4179,17 +4132,12 @@ int zebra_vxlan_if_del(struct interface *ifp)
int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags)
{
struct zebra_if *zif;
- struct zebra_vrf *zvrf;
zebra_vni_t *zvni;
struct zebra_l2info_vxlan *vxl;
vni_t vni;
- /* Locate VRF corresponding to interface. */
- zvrf = vrf_info_lookup(ifp->vrf_id);
- assert(zvrf);
-
- /* If EVPN is not enabled, nothing further to be done. */
- if (!EVPN_ENABLED(zvrf))
+ /* Check if EVPN is enabled. */
+ if (!is_evpn_enabled())
return 0;
zif = ifp->info;
@@ -4198,19 +4146,19 @@ int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags)
vni = vxl->vni;
/* Update VNI hash. */
- zvni = zvni_lookup(zvrf, vni);
+ zvni = zvni_lookup(vni);
if (!zvni) {
zlog_err(
- "Failed to find VNI hash on update, VRF %d IF %s(%u) VNI %u",
- ifp->vrf_id, ifp->name, ifp->ifindex, vni);
+ "Failed to find VNI hash on update, IF %s(%u) VNI %u",
+ ifp->name, ifp->ifindex, vni);
return -1;
}
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "%u:Update VNI %u intf %s(%u) VLAN %u local IP %s "
+ "Update VNI %u intf %s(%u) VLAN %u local IP %s "
"master %u chg 0x%x",
- ifp->vrf_id, vni, ifp->name, ifp->ifindex,
+ vni, ifp->name, ifp->ifindex,
vxl->access_vlan, inet_ntoa(vxl->vtep_ip),
zif->brslave_info.bridge_ifindex, chgflags);
@@ -4219,9 +4167,9 @@ int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags)
&& (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) {
/* Delete from client, remove all remote VTEPs */
/* Also, free up all MACs and neighbors. */
- zvni_send_del_to_client(zvrf, zvni->vni);
- zvni_neigh_del_all(zvrf, zvni, 1, 0, DEL_ALL_NEIGH);
- zvni_mac_del_all(zvrf, zvni, 1, 0, DEL_ALL_MAC);
+ zvni_send_del_to_client(zvni->vni);
+ zvni_neigh_del_all(zvni, 1, 0, DEL_ALL_NEIGH);
+ zvni_mac_del_all(zvni, 1, 0, DEL_ALL_MAC);
zvni_vtep_del_all(zvni, 1);
return 0;
}
@@ -4231,8 +4179,8 @@ int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags)
/* Remove all existing local neighbors and MACs for this VNI
* (including from BGP)
*/
- zvni_neigh_del_all(zvrf, zvni, 0, 1, DEL_LOCAL_MAC);
- zvni_mac_del_all(zvrf, zvni, 0, 1, DEL_LOCAL_MAC);
+ zvni_neigh_del_all(zvni, 0, 1, DEL_LOCAL_MAC);
+ zvni_mac_del_all(zvni, 0, 1, DEL_LOCAL_MAC);
}
zvni->local_vtep_ip = vxl->vtep_ip;
@@ -4248,19 +4196,19 @@ int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags)
/* Inform BGP, if there is a change of interest. */
if (chgflags
& (ZEBRA_VXLIF_MASTER_CHANGE | ZEBRA_VXLIF_LOCAL_IP_CHANGE))
- zvni_send_add_to_client(zvrf, zvni);
+ zvni_send_add_to_client(zvni);
/* If there is a valid new master or a VLAN mapping change, read and
* populate local MACs and neighbors. Also, reinstall any remote MACs
* and neighbors for this VNI (based on new VLAN).
*/
if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
- zvni_read_mac_neigh(zvrf, zvni, ifp);
+ zvni_read_mac_neigh(zvni, ifp);
else if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
struct mac_walk_ctx m_wctx;
struct neigh_walk_ctx n_wctx;
- zvni_read_mac_neigh(zvrf, zvni, ifp);
+ zvni_read_mac_neigh(zvni, ifp);
memset(&m_wctx, 0, sizeof(struct mac_walk_ctx));
m_wctx.zvni = zvni;
@@ -4281,17 +4229,12 @@ int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags)
int zebra_vxlan_if_add(struct interface *ifp)
{
struct zebra_if *zif;
- struct zebra_vrf *zvrf;
zebra_vni_t *zvni;
struct zebra_l2info_vxlan *vxl;
vni_t vni;
- /* Locate VRF corresponding to interface. */
- zvrf = vrf_info_lookup(ifp->vrf_id);
- assert(zvrf);
-
- /* If EVPN is not enabled, nothing further to be done. */
- if (!EVPN_ENABLED(zvrf))
+ /* Check if EVPN is enabled. */
+ if (!is_evpn_enabled())
return 0;
zif = ifp->info;
@@ -4301,19 +4244,19 @@ int zebra_vxlan_if_add(struct interface *ifp)
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "%u:Add VNI %u intf %s(%u) VLAN %u local IP %s master %u",
- ifp->vrf_id, vni, ifp->name, ifp->ifindex,
+ "Add VNI %u intf %s(%u) VLAN %u local IP %s master %u",
+ vni, ifp->name, ifp->ifindex,
vxl->access_vlan, inet_ntoa(vxl->vtep_ip),
zif->brslave_info.bridge_ifindex);
/* Create or update VNI hash. */
- zvni = zvni_lookup(zvrf, vni);
+ zvni = zvni_lookup(vni);
if (!zvni) {
- zvni = zvni_add(zvrf, vni);
+ zvni = zvni_add(vni);
if (!zvni) {
zlog_err(
- "Failed to add VNI hash, VRF %d IF %s(%u) VNI %u",
- ifp->vrf_id, ifp->name, ifp->ifindex, vni);
+ "Failed to add VNI hash, IF %s(%u) VNI %u",
+ ifp->name, ifp->ifindex, vni);
return -1;
}
}
@@ -4326,10 +4269,10 @@ int zebra_vxlan_if_add(struct interface *ifp)
return 0;
/* Inform BGP */
- zvni_send_add_to_client(zvrf, zvni);
+ zvni_send_add_to_client(zvni);
/* Read and populate local MACs and neighbors */
- zvni_read_mac_neigh(zvrf, zvni, ifp);
+ zvni_read_mac_neigh(zvni, ifp);
return 0;
}
@@ -4347,16 +4290,21 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, int sock,
zebra_vni_t *zvni = NULL;
struct interface *ifp = NULL;
+ if (zvrf_id(zvrf) != VRF_DEFAULT) {
+ zlog_err("EVPN GW-MACIP Adv for non-default VRF %u",
+ zvrf_id(zvrf));
+ return -1;
+ }
+
s = client->ibuf;
advertise = stream_getc(s);
vni = stream_get3(s);
if (!vni) {
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug("%u:EVPN gateway macip Adv %s, currently %s",
- zvrf_id(zvrf),
+ zlog_debug("EVPN gateway macip Adv %s, currently %s",
advertise ? "enabled" : "disabled",
- advertise_gw_macip_enabled(zvrf, NULL)
+ advertise_gw_macip_enabled(NULL)
? "enabled"
: "disabled");
@@ -4365,12 +4313,12 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, int sock,
zvrf->advertise_gw_macip = advertise;
- if (advertise_gw_macip_enabled(zvrf, zvni))
+ if (advertise_gw_macip_enabled(zvni))
hash_iterate(zvrf->vni_table,
- zvni_gw_macip_add_for_vni_hash, zvrf);
+ zvni_gw_macip_add_for_vni_hash, NULL);
else
hash_iterate(zvrf->vni_table,
- zvni_gw_macip_del_for_vni_hash, zvrf);
+ zvni_gw_macip_del_for_vni_hash, NULL);
} else {
struct zebra_if *zif = NULL;
@@ -4380,14 +4328,13 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, int sock,
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "%u:EVPN gateway macip Adv %s on VNI %d , currently %s",
- zvrf_id(zvrf),
+ "EVPN gateway macip Adv %s on VNI %d , currently %s",
advertise ? "enabled" : "disabled", vni,
- advertise_gw_macip_enabled(zvrf, zvni)
+ advertise_gw_macip_enabled(zvni)
? "enabled"
: "disabled");
- zvni = zvni_lookup(zvrf, vni);
+ zvni = zvni_lookup(vni);
if (!zvni)
return 0;
@@ -4408,12 +4355,12 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, int sock,
zl2_info = zif->l2info.vxl;
- vlan_if = zvni_map_to_svi(zvrf, zl2_info.access_vlan,
+ vlan_if = zvni_map_to_svi(zl2_info.access_vlan,
zif->brslave_info.br_if);
if (!vlan_if)
return 0;
- if (advertise_gw_macip_enabled(zvrf, zvni)) {
+ if (advertise_gw_macip_enabled(zvni)) {
/* Add primary SVI MAC-IP */
zvni_add_macip_for_intf(vlan_if, zvni);
@@ -4448,25 +4395,31 @@ int zebra_vxlan_advertise_all_vni(struct zserv *client, int sock,
struct stream *s;
int advertise;
+ if (zvrf_id(zvrf) != VRF_DEFAULT) {
+ zlog_err("EVPN VNI Adv for non-default VRF %u",
+ zvrf_id(zvrf));
+ return -1;
+ }
+
s = client->ibuf;
advertise = stream_getc(s);
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug("%u:EVPN VNI Adv %s, currently %s", zvrf_id(zvrf),
+ zlog_debug("EVPN VNI Adv %s, currently %s",
advertise ? "enabled" : "disabled",
- EVPN_ENABLED(zvrf) ? "enabled" : "disabled");
+ is_evpn_enabled() ? "enabled" : "disabled");
if (zvrf->advertise_all_vni == advertise)
return 0;
zvrf->advertise_all_vni = advertise;
- if (EVPN_ENABLED(zvrf)) {
+ if (is_evpn_enabled()) {
/* Build VNI hash table and inform BGP. */
- zvni_build_hash_table(zvrf);
+ zvni_build_hash_table();
/* Add all SVI (L3 GW) MACs to BGP*/
hash_iterate(zvrf->vni_table, zvni_gw_macip_add_for_vni_hash,
- zvrf);
+ NULL);
/* Read the MAC FDB */
macfdb_read(zvrf->zns);
@@ -4498,6 +4451,8 @@ void zebra_vxlan_init_tables(struct zebra_vrf *zvrf)
/* Close all VNI handling */
void zebra_vxlan_close_tables(struct zebra_vrf *zvrf)
{
+ if (!zvrf)
+ return;
hash_iterate(zvrf->vni_table, zvni_cleanup_all, zvrf);
hash_free(zvrf->vni_table);
}
diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h
index f7c1afc959..8b43615bb3 100644
--- a/zebra/zebra_vxlan.h
+++ b/zebra/zebra_vxlan.h
@@ -35,6 +35,14 @@
/* Is EVPN enabled? */
#define EVPN_ENABLED(zvrf) (zvrf)->advertise_all_vni
+static inline int
+is_evpn_enabled()
+{
+ struct zebra_vrf *zvrf = NULL;
+ zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
+ return zvrf ? zvrf->advertise_all_vni : 0;
+}
+
/* VxLAN interface change flags of interest. */
#define ZEBRA_VXLIF_LOCAL_IP_CHANGE 0x1
diff --git a/zebra/zserv.c b/zebra/zserv.c
index fd2c5dd97c..f888207818 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -825,6 +825,7 @@ static int zserv_fec_register(struct zserv *client, int sock, u_short length)
while (l < length) {
flags = stream_getw(s);
+ memset(&p, 0, sizeof(p));
p.family = stream_getw(s);
if (p.family != AF_INET && p.family != AF_INET6) {
zlog_err(
@@ -875,6 +876,7 @@ static int zserv_fec_unregister(struct zserv *client, int sock, u_short length)
while (l < length) {
// flags = stream_getw(s);
(void)stream_getw(s);
+ memset(&p, 0, sizeof(p));
p.family = stream_getw(s);
if (p.family != AF_INET && p.family != AF_INET6) {
zlog_err(