summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--babeld/babel_zebra.c2
-rw-r--r--bfdd/ptm_adapter.c17
-rw-r--r--bgpd/bgp_evpn.c69
-rw-r--r--bgpd/bgp_evpn_vty.c20
-rw-r--r--bgpd/bgp_fsm.c10
-rw-r--r--bgpd/bgp_mplsvpn.c8
-rw-r--r--bgpd/bgp_nexthop.c2
-rw-r--r--bgpd/bgp_route.c34
-rw-r--r--bgpd/bgp_routemap.c4
-rw-r--r--bgpd/bgp_vty.c105
-rw-r--r--bgpd/bgp_zebra.c2
-rw-r--r--bgpd/bgpd.h1
-rw-r--r--bgpd/rfapi/vnc_zebra.c2
-rwxr-xr-xconfigure.ac2
-rw-r--r--doc/developer/building-libyang.rst20
-rw-r--r--doc/user/installation.rst18
-rw-r--r--doc/user/ospfd.rst9
-rw-r--r--eigrpd/eigrp_zebra.c2
-rw-r--r--isisd/isis_lsp.c40
-rw-r--r--isisd/isis_zebra.c14
-rw-r--r--isisd/isisd.c188
-rw-r--r--isisd/isisd.h28
-rw-r--r--ldpd/lde.c2
-rw-r--r--ldpd/ldp_zebra.c2
-rw-r--r--lib/command.h1
-rw-r--r--lib/zclient.c6
-rw-r--r--lib/zclient.h17
-rw-r--r--nhrpd/nhrp_route.c2
-rw-r--r--ospf6d/ospf6_zebra.c2
-rw-r--r--ospfd/ospf_memory.c1
-rw-r--r--ospfd/ospf_memory.h1
-rw-r--r--ospfd/ospf_ri.c576
-rw-r--r--ospfd/ospf_ri.h66
-rw-r--r--ospfd/ospf_te.c8
-rw-r--r--ospfd/ospf_zebra.c2
-rw-r--r--pbrd/pbr_zebra.c2
-rw-r--r--pimd/pim_zebra.c2
-rw-r--r--pimd/pim_zlookup.c2
-rw-r--r--ripd/rip_zebra.c2
-rw-r--r--ripngd/ripng_zebra.c2
-rw-r--r--sharpd/sharp_zebra.c2
-rw-r--r--staticd/static_zebra.c2
-rw-r--r--tests/.gitignore1
-rw-r--r--tests/bgpd/test_mpath.c2
-rw-r--r--tests/isisd/test_isis_lspdb.c87
-rw-r--r--tests/isisd/test_isis_lspdb.py6
-rw-r--r--tests/subdir.am6
-rw-r--r--tests/test_lblmgr.c2
-rw-r--r--tools/etc/frr/daemons.conf3
-rwxr-xr-xtools/frr.in10
-rw-r--r--vtysh/vtysh.c2
-rw-r--r--zebra/label_manager.c2
-rw-r--r--zebra/zebra_vty.c3
-rw-r--r--zebra/zebra_vxlan.c36
54 files changed, 853 insertions, 604 deletions
diff --git a/babeld/babel_zebra.c b/babeld/babel_zebra.c
index 8dea1431e..e909f8ea7 100644
--- a/babeld/babel_zebra.c
+++ b/babeld/babel_zebra.c
@@ -237,7 +237,7 @@ babel_zebra_connected (struct zclient *zclient)
void babelz_zebra_init(void)
{
- zclient = zclient_new_notify(master, &zclient_options_default);
+ zclient = zclient_new(master, &zclient_options_default);
zclient_init(zclient, ZEBRA_ROUTE_BABEL, 0, &babeld_privs);
zclient->zebra_connected = babel_zebra_connected;
diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c
index a5fae3383..f9c7c16fb 100644
--- a/bfdd/ptm_adapter.c
+++ b/bfdd/ptm_adapter.c
@@ -381,6 +381,21 @@ static int _ptm_msg_read(struct stream *msg, int command,
if (bpc->bpc_has_localif) {
STREAM_GET(bpc->bpc_localif, msg, ifnamelen);
bpc->bpc_localif[ifnamelen] = 0;
+
+ /*
+ * IPv6 link-local addresses must use scope id,
+ * otherwise the session lookup will always fail
+ * and we'll have multiple sessions showing up.
+ *
+ * This problem only happens with single hop
+ * since it is not possible to have link-local
+ * address for multi hop sessions.
+ */
+ if (bpc->bpc_ipv4 == false
+ && IN6_IS_ADDR_LINKLOCAL(
+ &bpc->bpc_peer.sa_sin6.sin6_addr))
+ bpc->bpc_peer.sa_sin6.sin6_scope_id =
+ ptm_bfd_fetch_ifindex(bpc->bpc_localif);
}
}
@@ -566,7 +581,7 @@ static void bfdd_zebra_connected(struct zclient *zc)
void bfdd_zclient_init(struct zebra_privs_t *bfdd_priv)
{
- zclient = zclient_new_notify(master, &zclient_options_default);
+ zclient = zclient_new(master, &zclient_options_default);
assert(zclient != NULL);
zclient_init(zclient, ZEBRA_ROUTE_BFD, 0, bfdd_priv);
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index c91a2ab6b..cff050a9e 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -1693,6 +1693,58 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
}
/*
+ * If the local route was not selected evict it and tell zebra to re-add
+ * the best remote dest.
+ *
+ * Typically a local path added by zebra is expected to be selected as
+ * best. In which case when a remote path wins as best (later)
+ * evpn_route_select_install itself evicts the older-local-best path.
+ *
+ * However if bgp's add and zebra's add cross paths (race condition) it
+ * is possible that the local path is no longer the "older" best path.
+ * It is a path that was never designated as best and hence requires
+ * additional handling to prevent bgp from injecting and holding on to a
+ * non-best local path.
+ */
+static void evpn_cleanup_local_non_best_route(struct bgp *bgp,
+ struct bgpevpn *vpn,
+ struct bgp_node *rn,
+ struct bgp_path_info *local_pi)
+{
+ struct bgp_path_info *tmp_pi;
+ struct bgp_path_info *curr_select = NULL;
+ uint8_t flags = 0;
+ char buf[PREFIX_STRLEN];
+
+ /* local path was not picked as the winner; kick it out */
+ if (bgp_debug_zebra(NULL)) {
+ zlog_debug("evicting local evpn prefix %s as remote won",
+ prefix2str(&rn->p, buf, sizeof(buf)));
+ }
+ evpn_delete_old_local_route(bgp, vpn, rn, local_pi);
+ bgp_path_info_reap(rn, local_pi);
+
+ /* tell zebra to re-add the best remote path */
+ for (tmp_pi = rn->info; tmp_pi; tmp_pi = tmp_pi->next) {
+ if (CHECK_FLAG(tmp_pi->flags, BGP_PATH_SELECTED)) {
+ curr_select = tmp_pi;
+ break;
+ }
+ }
+ if (curr_select &&
+ curr_select->type == ZEBRA_ROUTE_BGP
+ && curr_select->sub_type == BGP_ROUTE_IMPORTED) {
+ if (curr_select->attr->sticky)
+ SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
+ if (curr_select->attr->default_gw)
+ SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
+ evpn_zebra_install(bgp, vpn, (struct prefix_evpn *)&rn->p,
+ curr_select->attr->nexthop, flags,
+ mac_mobility_seqnum(curr_select->attr));
+ }
+}
+
+/*
* Create or update EVPN route (of type based on prefix) for specified VNI
* and schedule for processing.
*/
@@ -1754,10 +1806,23 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
assert(pi);
attr_new = pi->attr;
+ /* lock ri to prevent freeing in evpn_route_select_install */
+ bgp_path_info_lock(pi);
/* Perform route selection; this is just to set the flags correctly
* as local route in the VNI always wins.
*/
evpn_route_select_install(bgp, vpn, rn);
+ /*
+ * If the new local route was not selected evict it and tell zebra
+ * to re-add the best remote dest. BGP doesn't retain non-best local
+ * routes.
+ */
+ if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
+ route_change = 0;
+ evpn_cleanup_local_non_best_route(bgp, vpn, rn, pi);
+ }
+ bgp_path_info_unlock(pi);
+
bgp_unlock_node(rn);
/* If this is a new route or some attribute has changed, export the
@@ -1928,8 +1993,10 @@ static int delete_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
/* Delete route entry in the VNI route table. This can just be removed.
*/
delete_evpn_route_entry(bgp, afi, safi, rn, &pi);
- if (pi)
+ if (pi) {
bgp_path_info_reap(rn, pi);
+ evpn_route_select_install(bgp, vpn, rn);
+ }
bgp_unlock_node(rn);
return 0;
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index 29f9f64cc..aa5eabead 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -3195,7 +3195,7 @@ DEFUN (no_bgp_evpn_advertise_type5,
*/
DEFUN(show_bgp_l2vpn_evpn_vni,
show_bgp_l2vpn_evpn_vni_cmd,
- "show bgp l2vpn evpn vni [(1-16777215)] [json]",
+ "show bgp l2vpn evpn vni [" CMD_VNI_RANGE "] [json]",
SHOW_STR
BGP_STR
L2VPN_HELP_STR
@@ -3623,7 +3623,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_esi,
* Display per-VNI EVPN routing table.
*/
DEFUN(show_bgp_l2vpn_evpn_route_vni, show_bgp_l2vpn_evpn_route_vni_cmd,
- "show bgp l2vpn evpn route vni (1-16777215) [<type <macip|multicast> | vtep A.B.C.D>] [json]",
+ "show bgp l2vpn evpn route vni " CMD_VNI_RANGE " [<type <macip|multicast> | vtep A.B.C.D>] [json]",
SHOW_STR
BGP_STR
L2VPN_HELP_STR
@@ -3696,7 +3696,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni, show_bgp_l2vpn_evpn_route_vni_cmd,
*/
DEFUN(show_bgp_l2vpn_evpn_route_vni_macip,
show_bgp_l2vpn_evpn_route_vni_macip_cmd,
- "show bgp l2vpn evpn route vni (1-16777215) mac WORD [ip WORD] [json]",
+ "show bgp l2vpn evpn route vni " CMD_VNI_RANGE " mac WORD [ip WORD] [json]",
SHOW_STR
BGP_STR
L2VPN_HELP_STR
@@ -3766,7 +3766,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni_macip,
*/
DEFUN(show_bgp_l2vpn_evpn_route_vni_multicast,
show_bgp_l2vpn_evpn_route_vni_multicast_cmd,
- "show bgp l2vpn evpn route vni (1-16777215) multicast A.B.C.D [json]",
+ "show bgp l2vpn evpn route vni " CMD_VNI_RANGE " multicast A.B.C.D [json]",
SHOW_STR
BGP_STR
L2VPN_HELP_STR
@@ -4019,7 +4019,7 @@ DEFUN(test_withdraw_evpn_type4_route,
}
ALIAS_HIDDEN(show_bgp_l2vpn_evpn_vni, show_bgp_evpn_vni_cmd,
- "show bgp evpn vni [(1-16777215)]", SHOW_STR BGP_STR EVPN_HELP_STR
+ "show bgp evpn vni [" CMD_VNI_RANGE "]", SHOW_STR BGP_STR EVPN_HELP_STR
"Show VNI\n"
"VNI number\n")
@@ -4060,7 +4060,7 @@ ALIAS_HIDDEN(
ALIAS_HIDDEN(
show_bgp_l2vpn_evpn_route_vni, show_bgp_evpn_route_vni_cmd,
- "show bgp evpn route vni (1-16777215) [<type <macip|multicast> | vtep A.B.C.D>]",
+ "show bgp evpn route vni " CMD_VNI_RANGE " [<type <macip|multicast> | vtep A.B.C.D>]",
SHOW_STR BGP_STR EVPN_HELP_STR
"EVPN route information\n"
"VXLAN Network Identifier\n"
@@ -4073,7 +4073,7 @@ ALIAS_HIDDEN(
ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_macip,
show_bgp_evpn_route_vni_macip_cmd,
- "show bgp evpn route vni (1-16777215) mac WORD [ip WORD]",
+ "show bgp evpn route vni " CMD_VNI_RANGE " mac WORD [ip WORD]",
SHOW_STR BGP_STR EVPN_HELP_STR
"EVPN route information\n"
"VXLAN Network Identifier\n"
@@ -4085,7 +4085,7 @@ ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_macip,
ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_multicast,
show_bgp_evpn_route_vni_multicast_cmd,
- "show bgp evpn route vni (1-16777215) multicast A.B.C.D",
+ "show bgp evpn route vni " CMD_VNI_RANGE " multicast A.B.C.D",
SHOW_STR BGP_STR EVPN_HELP_STR
"EVPN route information\n"
"VXLAN Network Identifier\n"
@@ -4108,7 +4108,7 @@ ALIAS_HIDDEN(show_bgp_l2vpn_evpn_import_rt, show_bgp_evpn_import_rt_cmd,
DEFUN_NOSH (bgp_evpn_vni,
bgp_evpn_vni_cmd,
- "vni (1-16777215)",
+ "vni " CMD_VNI_RANGE,
"VXLAN Network Identifier\n"
"VNI number\n")
{
@@ -4134,7 +4134,7 @@ DEFUN_NOSH (bgp_evpn_vni,
DEFUN (no_bgp_evpn_vni,
no_bgp_evpn_vni_cmd,
- "no vni (1-16777215)",
+ "no vni " CMD_VNI_RANGE,
NO_STR
"VXLAN Network Identifier\n"
"VNI number\n")
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index 8aa35eddf..1f0cfd6e2 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -1043,8 +1043,9 @@ int bgp_stop(struct peer *peer)
"%%ADJCHANGE: neighbor %s(%s) in vrf %s Down %s",
peer->host,
(peer->hostname) ? peer->hostname : "Unknown",
- vrf ? ((vrf->vrf_id != VRF_DEFAULT) ? vrf->name
- : "Default")
+ vrf ? ((vrf->vrf_id != VRF_DEFAULT)
+ ? vrf->name
+ : VRF_DEFAULT_NAME)
: "",
peer_down_str[(int)peer->last_reset]);
}
@@ -1564,8 +1565,9 @@ static int bgp_establish(struct peer *peer)
zlog_info("%%ADJCHANGE: neighbor %s(%s) in vrf %s Up",
peer->host,
(peer->hostname) ? peer->hostname : "Unknown",
- vrf ? ((vrf->vrf_id != VRF_DEFAULT) ? vrf->name
- : "Default")
+ vrf ? ((vrf->vrf_id != VRF_DEFAULT)
+ ? vrf->name
+ : VRF_DEFAULT_NAME)
: "");
}
/* assign update-group/subgroup */
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index 385716970..d4204126e 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -1492,7 +1492,7 @@ void vrf_import_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
struct ecommunity *ecom;
bool first_export = false;
- export_name = to_bgp->name ? to_bgp->name : BGP_DEFAULT_NAME;
+ export_name = to_bgp->name ? to_bgp->name : VRF_DEFAULT_NAME;
idir = BGP_VPN_POLICY_DIR_FROMVPN;
edir = BGP_VPN_POLICY_DIR_TOVPN;
@@ -1501,7 +1501,7 @@ void vrf_import_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
* any VRF is importing from "import_vrf".
*/
vname = (from_bgp->name ? XSTRDUP(MTYPE_TMP, from_bgp->name)
- : XSTRDUP(MTYPE_TMP, BGP_DEFAULT_NAME));
+ : XSTRDUP(MTYPE_TMP, VRF_DEFAULT_NAME));
listnode_add(to_bgp->vpn_policy[afi].import_vrf, vname);
@@ -1557,8 +1557,8 @@ void vrf_unimport_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
struct ecommunity *ecom;
struct listnode *node;
- export_name = to_bgp->name ? to_bgp->name : BGP_DEFAULT_NAME;
- tmp_name = from_bgp->name ? from_bgp->name : BGP_DEFAULT_NAME;
+ export_name = to_bgp->name ? to_bgp->name : VRF_DEFAULT_NAME;
+ tmp_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
idir = BGP_VPN_POLICY_DIR_FROMVPN;
edir = BGP_VPN_POLICY_DIR_TOVPN;
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c
index 2ef792e12..1cb7e4c5e 100644
--- a/bgpd/bgp_nexthop.c
+++ b/bgpd/bgp_nexthop.c
@@ -666,7 +666,7 @@ static void bgp_show_all_instances_nexthops_vty(struct vty *vty)
for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
vty_out(vty, "\nInstance %s:\n",
(bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
- ? "Default"
+ ? VRF_DEFAULT_NAME
: bgp->name);
bgp_show_nexthops(vty, bgp, 0);
}
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index a407ffba4..8ae74a008 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -453,6 +453,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
char exist_buf[PATH_ADDPATH_STR_BUFFER];
uint32_t new_mm_seq;
uint32_t exist_mm_seq;
+ int nh_cmp;
*paths_eq = 0;
@@ -545,6 +546,28 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
exist_mm_seq);
return 0;
}
+
+ /*
+ * if sequence numbers are the same path with the lowest IP
+ * wins
+ */
+ nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
+ if (nh_cmp < 0) {
+ if (debug)
+ zlog_debug(
+ "%s: %s wins over %s due to same MM seq %u and lower IP %s",
+ pfx_buf, new_buf, exist_buf, new_mm_seq,
+ inet_ntoa(new->attr->nexthop));
+ return 1;
+ }
+ if (nh_cmp > 0) {
+ if (debug)
+ zlog_debug(
+ "%s: %s loses to %s due to same MM seq %u and higher IP %s",
+ pfx_buf, new_buf, exist_buf, new_mm_seq,
+ inet_ntoa(new->attr->nexthop));
+ return 0;
+ }
}
/* 1. Weight check. */
@@ -8365,8 +8388,9 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
"{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
",\n \"routerId\": \"%s\",\n \"routes\": { ",
bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
- bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT ? "Default"
- : bgp->name,
+ bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
+ ? VRF_DEFAULT_NAME
+ : bgp->name,
table->version, inet_ntoa(bgp->router_id));
*json_header_depth = 2;
if (rd) {
@@ -8742,12 +8766,12 @@ static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
vty_out(vty, "\"%s\":",
(bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
- ? "Default"
+ ? VRF_DEFAULT_NAME
: bgp->name);
} else {
vty_out(vty, "\nInstance %s:\n",
(bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
- ? "Default"
+ ? VRF_DEFAULT_NAME
: bgp->name);
}
bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
@@ -8882,7 +8906,7 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
vty_out(vty, ", table %s",
(bgp->inst_type
== BGP_INSTANCE_TYPE_DEFAULT)
- ? "Default-IP-Routing-Table"
+ ? VRF_DEFAULT_NAME
: bgp->name);
} else
vty_out(vty, ", no best path");
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index 60a4e994c..f7c417538 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -3438,7 +3438,7 @@ DEFUN (no_match_evpn_route_type,
DEFUN (match_evpn_vni,
match_evpn_vni_cmd,
- "match evpn vni (1-16777215)",
+ "match evpn vni " CMD_VNI_RANGE,
MATCH_STR
EVPN_HELP_STR
"Match VNI\n"
@@ -3450,7 +3450,7 @@ DEFUN (match_evpn_vni,
DEFUN (no_match_evpn_vni,
no_match_evpn_vni_cmd,
- "no match evpn vni (1-16777215)",
+ "no match evpn vni " CMD_VNI_RANGE,
NO_STR
MATCH_STR
EVPN_HELP_STR
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 45136cf45..c57cd3815 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -822,6 +822,87 @@ DEFUN_HIDDEN (no_bgp_multiple_instance,
return CMD_SUCCESS;
}
+DEFUN_HIDDEN (bgp_local_mac,
+ bgp_local_mac_cmd,
+ "bgp local-mac vni " CMD_VNI_RANGE " mac WORD seq (0-4294967295)",
+ BGP_STR
+ "Local MAC config\n"
+ "VxLAN Network Identifier\n"
+ "VNI number\n"
+ "local mac\n"
+ "mac address\n"
+ "mac-mobility sequence\n"
+ "seq number\n")
+{
+ int rv;
+ vni_t vni;
+ struct ethaddr mac;
+ struct ipaddr ip;
+ uint32_t seq;
+ struct bgp *bgp;
+
+ vni = strtoul(argv[3]->arg, NULL, 10);
+ if (!prefix_str2mac(argv[5]->arg, &mac)) {
+ vty_out(vty, "%% Malformed MAC address\n");
+ return CMD_WARNING;
+ }
+ memset(&ip, 0, sizeof(ip));
+ seq = strtoul(argv[7]->arg, NULL, 10);
+
+ bgp = bgp_get_default();
+ if (!bgp) {
+ vty_out(vty, "Default BGP instance is not there\n");
+ return CMD_WARNING;
+ }
+
+ rv = bgp_evpn_local_macip_add(bgp, vni, &mac, &ip, 0 /* flags */, seq);
+ if (rv < 0) {
+ vty_out(vty, "Internal error\n");
+ return CMD_WARNING;
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN_HIDDEN (no_bgp_local_mac,
+ no_bgp_local_mac_cmd,
+ "no bgp local-mac vni " CMD_VNI_RANGE " mac WORD",
+ NO_STR
+ BGP_STR
+ "Local MAC config\n"
+ "VxLAN Network Identifier\n"
+ "VNI number\n"
+ "local mac\n"
+ "mac address\n")
+{
+ int rv;
+ vni_t vni;
+ struct ethaddr mac;
+ struct ipaddr ip;
+ struct bgp *bgp;
+
+ vni = strtoul(argv[4]->arg, NULL, 10);
+ if (!prefix_str2mac(argv[6]->arg, &mac)) {
+ vty_out(vty, "%% Malformed MAC address\n");
+ return CMD_WARNING;
+ }
+ memset(&ip, 0, sizeof(ip));
+
+ bgp = bgp_get_default();
+ if (!bgp) {
+ vty_out(vty, "Default BGP instance is not there\n");
+ return CMD_WARNING;
+ }
+
+ rv = bgp_evpn_local_macip_del(bgp, vni, &mac, &ip);
+ if (rv < 0) {
+ vty_out(vty, "Internal error\n");
+ return CMD_WARNING;
+ }
+
+ return CMD_SUCCESS;
+}
+
#if (CONFDATE > 20190601)
CPP_NOTICE("bgpd: time to remove deprecated cli bgp config-type cisco")
CPP_NOTICE("This includes BGP_OPT_CISCO_CONFIG")
@@ -6784,7 +6865,7 @@ DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd,
safi = bgp_node_safi(vty);
if (((BGP_INSTANCE_TYPE_DEFAULT == bgp->inst_type)
- && (strcmp(import_name, BGP_DEFAULT_NAME) == 0))
+ && (strcmp(import_name, VRF_DEFAULT_NAME) == 0))
|| (bgp->name && (strcmp(import_name, bgp->name) == 0))) {
vty_out(vty, "%% Cannot %s vrf %s into itself\n",
remove ? "unimport" : "import", import_name);
@@ -6806,7 +6887,7 @@ DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd,
vrf_bgp = bgp_lookup_by_name(import_name);
if (!vrf_bgp) {
- if (strcmp(import_name, BGP_DEFAULT_NAME) == 0)
+ if (strcmp(import_name, VRF_DEFAULT_NAME) == 0)
vrf_bgp = bgp_default;
else
/* Auto-create assuming the same AS */
@@ -7403,7 +7484,7 @@ DEFUN (show_bgp_vrfs,
}
if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
- name = "Default";
+ name = VRF_DEFAULT_NAME;
type = "DFLT";
} else {
name = bgp->name;
@@ -7770,7 +7851,7 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
json, "vrfName",
(bgp->inst_type
== BGP_INSTANCE_TYPE_DEFAULT)
- ? "Default"
+ ? VRF_DEFAULT_NAME
: bgp->name);
} else {
vty_out(vty,
@@ -8197,12 +8278,12 @@ static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi,
vty_out(vty, "\"%s\":",
(bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
- ? "Default"
+ ? VRF_DEFAULT_NAME
: bgp->name);
} else {
vty_out(vty, "\nInstance %s:\n",
(bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
- ? "Default"
+ ? VRF_DEFAULT_NAME
: bgp->name);
}
bgp_show_summary_afi_safi(vty, bgp, afi, safi, use_json, json);
@@ -10852,7 +10933,7 @@ static void bgp_show_all_instances_neighbors_vty(struct vty *vty,
json_object_string_add(
json, "vrfName",
(bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
- ? "Default"
+ ? VRF_DEFAULT_NAME
: bgp->name);
if (!is_first)
@@ -10862,12 +10943,12 @@ static void bgp_show_all_instances_neighbors_vty(struct vty *vty,
vty_out(vty, "\"%s\":",
(bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
- ? "Default"
+ ? VRF_DEFAULT_NAME
: bgp->name);
} else {
vty_out(vty, "\nInstance %s:\n",
(bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
- ? "Default"
+ ? VRF_DEFAULT_NAME
: bgp->name);
}
@@ -11301,7 +11382,7 @@ static void bgp_show_all_instances_updgrps_vty(struct vty *vty, afi_t afi,
for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
vty_out(vty, "\nInstance %s:\n",
(bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
- ? "Default"
+ ? VRF_DEFAULT_NAME
: bgp->name);
update_group_show(bgp, afi, safi, vty, 0);
}
@@ -12593,6 +12674,10 @@ void bgp_vty_init(void)
install_element(CONFIG_NODE, &bgp_config_type_cmd);
install_element(CONFIG_NODE, &no_bgp_config_type_cmd);
+ /* "bgp local-mac" hidden commands. */
+ install_element(CONFIG_NODE, &bgp_local_mac_cmd);
+ install_element(CONFIG_NODE, &no_bgp_local_mac_cmd);
+
/* bgp route-map delay-timer commands. */
install_element(CONFIG_NODE, &bgp_set_route_map_delay_timer_cmd);
install_element(CONFIG_NODE, &no_bgp_set_route_map_delay_timer_cmd);
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 50b790eb1..62f977eee 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -2574,7 +2574,7 @@ void bgp_zebra_init(struct thread_master *master, unsigned short instance)
zclient_num_connects = 0;
/* Set default values. */
- zclient = zclient_new_notify(master, &zclient_options_default);
+ zclient = zclient_new(master, &zclient_options_default);
zclient_init(zclient, ZEBRA_ROUTE_BGP, 0, &bgpd_privs);
zclient->zebra_connected = bgp_zebra_connected;
zclient->router_id_update = bgp_router_id_update;
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index c04fe6903..e14b0f39e 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -368,7 +368,6 @@ struct bgp {
/* vrf-route leaking flags */
#define BGP_CONFIG_VRF_TO_VRF_IMPORT (1 << 7)
#define BGP_CONFIG_VRF_TO_VRF_EXPORT (1 << 8)
-#define BGP_DEFAULT_NAME "default"
/* Route table for next-hop lookup cache. */
struct bgp_table *nexthop_cache_table[AFI_MAX];
diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c
index 97d520eda..a43cf1f6a 100644
--- a/bgpd/rfapi/vnc_zebra.c
+++ b/bgpd/rfapi/vnc_zebra.c
@@ -913,7 +913,7 @@ extern struct zebra_privs_t bgpd_privs;
void vnc_zebra_init(struct thread_master *master)
{
/* Set default values. */
- zclient_vnc = zclient_new_notify(master, &zclient_options_default);
+ zclient_vnc = zclient_new(master, &zclient_options_default);
zclient_init(zclient_vnc, ZEBRA_ROUTE_VNC, 0, &bgpd_privs);
zclient_vnc->redistribute_route_add = vnc_zebra_read_route;
diff --git a/configure.ac b/configure.ac
index 6782c539e..3a6e7883f 100755
--- a/configure.ac
+++ b/configure.ac
@@ -522,7 +522,7 @@ AC_CHECK_LIB(json-c, json_object_get, LIBS="$LIBS -ljson-c", [], [-lm])
if test "$ac_cv_lib_json_c_json_object_get" = no; then
AC_CHECK_LIB(json, json_object_get, LIBS="$LIBS -ljson")
if test "$ac_cv_lib_json_json_object_get" = no; then
- AC_MSG_ERROR([lib json is needed to compile])
+ AC_MSG_ERROR([libjson is needed to compile])
fi
fi
])
diff --git a/doc/developer/building-libyang.rst b/doc/developer/building-libyang.rst
index 9757ad454..005b6ba78 100644
--- a/doc/developer/building-libyang.rst
+++ b/doc/developer/building-libyang.rst
@@ -40,23 +40,3 @@ When building libyang on CentOS 6, it's also necessary to pass the
Note: please check the `libyang build requirements
<https://github.com/CESNET/libyang/blob/master/README.md#build-requirements>`_
first.
-
-Libyang uses loadable libraries an YANG modules. It supports
-environment variables to allow overriding the load paths for each of
-these. With FRR, this override currently must be done at the time of
-running FRR's configure command using new options. The new options are:
-
-.. code-block:: shell
-
- --with-yangmodelsdir=DIR
- yang models directory (${datarootdir}/yang)
- --with-libyang-pluginsdir=DIR
- yangmodule plugins directory
- (${libdir}/frr/libyang_plugins)
-
-an example which uses the compile directory is:
-
-.. code-block:: shell
-
- ./configure --with-libyang-pluginsdir="`pwd`/yang/libyang_plugins/.libs" \
- --with-yangmodelsdir="`pwd`/yang"
diff --git a/doc/user/installation.rst b/doc/user/installation.rst
index b7f0712a1..0a8cef53e 100644
--- a/doc/user/installation.rst
+++ b/doc/user/installation.rst
@@ -255,6 +255,24 @@ options to the configuration script.
Configure zebra to use `dir` for local state files, such as pid files and
unix sockets.
+.. option:: --with-yangmodelsdir <dir>
+
+ Look for YANG modules in `dir` [`prefix`/share/yang]. Note that the FRR
+ YANG modules will be installed here.
+
+.. option:: --with-libyang-pluginsdir <dir>
+
+ Look for libyang plugins in `dir` [`prefix`/lib/frr/libyang_plugins].
+ Note that the FRR libyang plugins will be installed here.
+
+When it's desired to run FRR without installing it in the system, it's possible
+to configure it as follows to look for YANG modules and libyang plugins in the
+compile directory:
+.. code-block:: shell
+
+ ./configure --with-libyang-pluginsdir="`pwd`/yang/libyang_plugins/.libs" \
+ --with-yangmodelsdir="`pwd`/yang"
+
.. _least-privilege-support:
Least-Privilege Support
diff --git a/doc/user/ospfd.rst b/doc/user/ospfd.rst
index e84313639..b6a7cd5de 100644
--- a/doc/user/ospfd.rst
+++ b/doc/user/ospfd.rst
@@ -979,14 +979,17 @@ Traffic Engineering
Router Information
==================
-.. index:: router-info [as | area <A.B.C.D>]
-.. clicmd:: router-info [as | area <A.B.C.D>]
+.. index:: router-info [as | area]
+.. clicmd:: router-info [as | area]
.. index:: no router-info
.. clicmd:: no router-info
Enable Router Information (:rfc:`4970`) LSA advertisement with AS scope
- (default) or Area scope flooding when area is specified.
+ (default) or Area scope flooding when area is specified. Old syntax
+ `router-info area <A.B.C.D>` is always supported but mark as deprecated
+ as the area ID is no more necessary. Indeed, router information support
+ multi-area and detect automatically the areas.
.. index:: pce address <A.B.C.D>
.. clicmd:: pce address <A.B.C.D>
diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c
index 3a3d6aae1..29bd23b51 100644
--- a/eigrpd/eigrp_zebra.c
+++ b/eigrpd/eigrp_zebra.c
@@ -116,7 +116,7 @@ void eigrp_zebra_init(void)
{
struct zclient_options opt = {.receive_notify = false};
- zclient = zclient_new_notify(master, &opt);
+ zclient = zclient_new(master, &opt);
zclient_init(zclient, ZEBRA_ROUTE_EIGRP, 0, &eigrpd_privs);
zclient->zebra_connected = eigrp_zebra_connected;
diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c
index bb090f42e..f71973afe 100644
--- a/isisd/isis_lsp.c
+++ b/isisd/isis_lsp.c
@@ -578,29 +578,17 @@ void lsp_insert(struct isis_lsp *lsp, dict_t *lspdb)
void lsp_build_list_nonzero_ht(uint8_t *start_id, uint8_t *stop_id,
struct list *list, dict_t *lspdb)
{
- dnode_t *first, *last, *curr;
+ for (dnode_t *curr = dict_lower_bound(lspdb, start_id);
+ curr; curr = dict_next(lspdb, curr)) {
+ struct isis_lsp *lsp = curr->dict_data;
- first = dict_lower_bound(lspdb, start_id);
- if (!first)
- return;
-
- last = dict_upper_bound(lspdb, stop_id);
-
- curr = first;
-
- if (((struct isis_lsp *)(curr->dict_data))->hdr.rem_lifetime)
- listnode_add(list, first->dict_data);
-
- while (curr) {
- curr = dict_next(lspdb, curr);
- if (curr
- && ((struct isis_lsp *)(curr->dict_data))->hdr.rem_lifetime)
- listnode_add(list, curr->dict_data);
- if (curr == last)
+ if (memcmp(lsp->hdr.lsp_id, stop_id,
+ ISIS_SYS_ID_LEN + 2) > 0)
break;
- }
- return;
+ if (lsp->hdr.rem_lifetime)
+ listnode_add(list, lsp);
+ }
}
static void lsp_set_time(struct isis_lsp *lsp)
@@ -1361,7 +1349,7 @@ static int lsp_refresh(struct thread *thread)
if ((area->is_type & level) == 0)
return ISIS_ERROR;
- if (monotime_since(&area->last_lsp_refresh_event[level - 1], NULL) < 50000L) {
+ if (monotime_since(&area->last_lsp_refresh_event[level - 1], NULL) < 100000L) {
sched_debug("ISIS (%s): Still unstable, postpone LSP L%d refresh",
area->area_tag, level);
_lsp_regenerate_schedule(area, level, 0, false,
@@ -1999,13 +1987,13 @@ void lsp_set_all_srmflags(struct isis_lsp *lsp, bool set)
void lsp_flood(struct isis_lsp *lsp, struct isis_circuit *circuit)
{
- if (!fabricd) {
+ if (!fabricd)
lsp_set_all_srmflags(lsp, true);
- if (circuit)
- isis_tx_queue_del(circuit->tx_queue, lsp);
- } else {
+ else
fabricd_lsp_flood(lsp);
- }
+
+ if (circuit)
+ isis_tx_queue_del(circuit->tx_queue, lsp);
}
static int lsp_handle_adj_state_change(struct isis_adjacency *adj)
diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c
index 33d8a0f77..101bd57cc 100644
--- a/isisd/isis_zebra.c
+++ b/isisd/isis_zebra.c
@@ -87,12 +87,6 @@ static int isis_zebra_if_add(int command, struct zclient *zclient,
ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
- if (isis->debugs & DEBUG_ZEBRA)
- zlog_debug(
- "Zebra I/F add: %s index %d flags %ld metric %d mtu %d",
- ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric,
- ifp->mtu);
-
if (if_is_operative(ifp))
isis_csm_state_change(IF_UP_FROM_Z, circuit_scan_by_ifp(ifp),
ifp);
@@ -116,12 +110,6 @@ static int isis_zebra_if_del(int command, struct zclient *zclient,
zlog_warn("Zebra: got delete of %s, but interface is still up",
ifp->name);
- if (isis->debugs & DEBUG_ZEBRA)
- zlog_debug(
- "Zebra I/F delete: %s index %d flags %ld metric %d mtu %d",
- ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric,
- ifp->mtu);
-
isis_csm_state_change(IF_DOWN_FROM_Z, circuit_scan_by_ifp(ifp), ifp);
/* Cannot call if_delete because we should retain the pseudo interface
@@ -425,7 +413,7 @@ static void isis_zebra_connected(struct zclient *zclient)
void isis_zebra_init(struct thread_master *master)
{
- zclient = zclient_new_notify(master, &zclient_options_default);
+ zclient = zclient_new(master, &zclient_options_default);
zclient_init(zclient, PROTO_TYPE, 0, &isisd_privs);
zclient->zebra_connected = isis_zebra_connected;
zclient->router_id_update = isis_router_id_update_zebra;
diff --git a/isisd/isisd.c b/isisd/isisd.c
index 54bdbf3eb..ce45ba65e 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -720,24 +720,11 @@ void print_debug(struct vty *vty, int flags, int onoff)
vty_out(vty,
"IS-IS Adjacency related packets debugging is %s\n",
onoffs);
- if (flags & DEBUG_CHECKSUM_ERRORS)
- vty_out(vty, "IS-IS checksum errors debugging is %s\n", onoffs);
- if (flags & DEBUG_LOCAL_UPDATES)
- vty_out(vty, "IS-IS local updates debugging is %s\n", onoffs);
- if (flags & DEBUG_PROTOCOL_ERRORS)
- vty_out(vty, "IS-IS protocol errors debugging is %s\n", onoffs);
if (flags & DEBUG_SNP_PACKETS)
vty_out(vty, "IS-IS CSNP/PSNP packets debugging is %s\n",
onoffs);
if (flags & DEBUG_SPF_EVENTS)
vty_out(vty, "IS-IS SPF events debugging is %s\n", onoffs);
- if (flags & DEBUG_SPF_STATS)
- vty_out(vty,
- "IS-IS SPF Timing and Statistics Data debugging is %s\n",
- onoffs);
- if (flags & DEBUG_SPF_TRIGGERS)
- vty_out(vty, "IS-IS SPF triggering events debugging is %s\n",
- onoffs);
if (flags & DEBUG_UPDATE_PACKETS)
vty_out(vty, "IS-IS Update related packet debugging is %s\n",
onoffs);
@@ -784,18 +771,6 @@ static int config_write_debug(struct vty *vty)
vty_out(vty, "debug " PROTO_NAME " adj-packets\n");
write++;
}
- if (flags & DEBUG_CHECKSUM_ERRORS) {
- vty_out(vty, "debug " PROTO_NAME " checksum-errors\n");
- write++;
- }
- if (flags & DEBUG_LOCAL_UPDATES) {
- vty_out(vty, "debug " PROTO_NAME " local-updates\n");
- write++;
- }
- if (flags & DEBUG_PROTOCOL_ERRORS) {
- vty_out(vty, "debug " PROTO_NAME " protocol-errors\n");
- write++;
- }
if (flags & DEBUG_SNP_PACKETS) {
vty_out(vty, "debug " PROTO_NAME " snp-packets\n");
write++;
@@ -804,14 +779,6 @@ static int config_write_debug(struct vty *vty)
vty_out(vty, "debug " PROTO_NAME " spf-events\n");
write++;
}
- if (flags & DEBUG_SPF_STATS) {
- vty_out(vty, "debug " PROTO_NAME " spf-statistics\n");
- write++;
- }
- if (flags & DEBUG_SPF_TRIGGERS) {
- vty_out(vty, "debug " PROTO_NAME " spf-triggers\n");
- write++;
- }
if (flags & DEBUG_UPDATE_PACKETS) {
vty_out(vty, "debug " PROTO_NAME " update-packets\n");
write++;
@@ -876,87 +843,6 @@ DEFUN (no_debug_isis_adj,
return CMD_SUCCESS;
}
-DEFUN (debug_isis_csum,
- debug_isis_csum_cmd,
- "debug " PROTO_NAME " checksum-errors",
- DEBUG_STR
- PROTO_HELP
- "IS-IS LSP checksum errors\n")
-{
- isis->debugs |= DEBUG_CHECKSUM_ERRORS;
- print_debug(vty, DEBUG_CHECKSUM_ERRORS, 1);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (no_debug_isis_csum,
- no_debug_isis_csum_cmd,
- "no debug " PROTO_NAME " checksum-errors",
- NO_STR
- UNDEBUG_STR
- PROTO_HELP
- "IS-IS LSP checksum errors\n")
-{
- isis->debugs &= ~DEBUG_CHECKSUM_ERRORS;
- print_debug(vty, DEBUG_CHECKSUM_ERRORS, 0);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (debug_isis_lupd,
- debug_isis_lupd_cmd,
- "debug " PROTO_NAME " local-updates",
- DEBUG_STR
- PROTO_HELP
- "IS-IS local update packets\n")
-{
- isis->debugs |= DEBUG_LOCAL_UPDATES;
- print_debug(vty, DEBUG_LOCAL_UPDATES, 1);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (no_debug_isis_lupd,
- no_debug_isis_lupd_cmd,
- "no debug " PROTO_NAME " local-updates",
- NO_STR
- UNDEBUG_STR
- PROTO_HELP
- "IS-IS local update packets\n")
-{
- isis->debugs &= ~DEBUG_LOCAL_UPDATES;
- print_debug(vty, DEBUG_LOCAL_UPDATES, 0);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (debug_isis_err,
- debug_isis_err_cmd,
- "debug " PROTO_NAME " protocol-errors",
- DEBUG_STR
- PROTO_HELP
- "IS-IS LSP protocol errors\n")
-{
- isis->debugs |= DEBUG_PROTOCOL_ERRORS;
- print_debug(vty, DEBUG_PROTOCOL_ERRORS, 1);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (no_debug_isis_err,
- no_debug_isis_err_cmd,
- "no debug " PROTO_NAME " protocol-errors",
- NO_STR
- UNDEBUG_STR
- PROTO_HELP
- "IS-IS LSP protocol errors\n")
-{
- isis->debugs &= ~DEBUG_PROTOCOL_ERRORS;
- print_debug(vty, DEBUG_PROTOCOL_ERRORS, 0);
-
- return CMD_SUCCESS;
-}
-
DEFUN (debug_isis_snp,
debug_isis_snp_cmd,
"debug " PROTO_NAME " snp-packets",
@@ -1038,60 +924,6 @@ DEFUN (no_debug_isis_spfevents,
return CMD_SUCCESS;
}
-DEFUN (debug_isis_spfstats,
- debug_isis_spfstats_cmd,
- "debug " PROTO_NAME " spf-statistics ",
- DEBUG_STR
- PROTO_HELP
- "IS-IS SPF Timing and Statistic Data\n")
-{
- isis->debugs |= DEBUG_SPF_STATS;
- print_debug(vty, DEBUG_SPF_STATS, 1);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (no_debug_isis_spfstats,
- no_debug_isis_spfstats_cmd,
- "no debug " PROTO_NAME " spf-statistics",
- NO_STR
- UNDEBUG_STR
- PROTO_HELP
- "IS-IS SPF Timing and Statistic Data\n")
-{
- isis->debugs &= ~DEBUG_SPF_STATS;
- print_debug(vty, DEBUG_SPF_STATS, 0);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (debug_isis_spftrigg,
- debug_isis_spftrigg_cmd,
- "debug " PROTO_NAME " spf-triggers",
- DEBUG_STR
- PROTO_HELP
- "IS-IS SPF triggering events\n")
-{
- isis->debugs |= DEBUG_SPF_TRIGGERS;
- print_debug(vty, DEBUG_SPF_TRIGGERS, 1);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (no_debug_isis_spftrigg,
- no_debug_isis_spftrigg_cmd,
- "no debug " PROTO_NAME " spf-triggers",
- NO_STR
- UNDEBUG_STR
- PROTO_HELP
- "IS-IS SPF triggering events\n")
-{
- isis->debugs &= ~DEBUG_SPF_TRIGGERS;
- print_debug(vty, DEBUG_SPF_TRIGGERS, 0);
-
- return CMD_SUCCESS;
-}
-
DEFUN (debug_isis_rtevents,
debug_isis_rtevents_cmd,
"debug " PROTO_NAME " route-events",
@@ -2229,22 +2061,12 @@ void isis_init()
install_element(ENABLE_NODE, &debug_isis_adj_cmd);
install_element(ENABLE_NODE, &no_debug_isis_adj_cmd);
- install_element(ENABLE_NODE, &debug_isis_csum_cmd);
- install_element(ENABLE_NODE, &no_debug_isis_csum_cmd);
- install_element(ENABLE_NODE, &debug_isis_lupd_cmd);
- install_element(ENABLE_NODE, &no_debug_isis_lupd_cmd);
- install_element(ENABLE_NODE, &debug_isis_err_cmd);
- install_element(ENABLE_NODE, &no_debug_isis_err_cmd);
install_element(ENABLE_NODE, &debug_isis_snp_cmd);
install_element(ENABLE_NODE, &no_debug_isis_snp_cmd);
install_element(ENABLE_NODE, &debug_isis_upd_cmd);
install_element(ENABLE_NODE, &no_debug_isis_upd_cmd);
install_element(ENABLE_NODE, &debug_isis_spfevents_cmd);
install_element(ENABLE_NODE, &no_debug_isis_spfevents_cmd);
- install_element(ENABLE_NODE, &debug_isis_spfstats_cmd);
- install_element(ENABLE_NODE, &no_debug_isis_spfstats_cmd);
- install_element(ENABLE_NODE, &debug_isis_spftrigg_cmd);
- install_element(ENABLE_NODE, &no_debug_isis_spftrigg_cmd);
install_element(ENABLE_NODE, &debug_isis_rtevents_cmd);
install_element(ENABLE_NODE, &no_debug_isis_rtevents_cmd);
install_element(ENABLE_NODE, &debug_isis_events_cmd);
@@ -2260,22 +2082,12 @@ void isis_init()
install_element(CONFIG_NODE, &debug_isis_adj_cmd);
install_element(CONFIG_NODE, &no_debug_isis_adj_cmd);
- install_element(CONFIG_NODE, &debug_isis_csum_cmd);
- install_element(CONFIG_NODE, &no_debug_isis_csum_cmd);
- install_element(CONFIG_NODE, &debug_isis_lupd_cmd);
- install_element(CONFIG_NODE, &no_debug_isis_lupd_cmd);
- install_element(CONFIG_NODE, &debug_isis_err_cmd);
- install_element(CONFIG_NODE, &no_debug_isis_err_cmd);
install_element(CONFIG_NODE, &debug_isis_snp_cmd);
install_element(CONFIG_NODE, &no_debug_isis_snp_cmd);
install_element(CONFIG_NODE, &debug_isis_upd_cmd);
install_element(CONFIG_NODE, &no_debug_isis_upd_cmd);
install_element(CONFIG_NODE, &debug_isis_spfevents_cmd);
install_element(CONFIG_NODE, &no_debug_isis_spfevents_cmd);
- install_element(CONFIG_NODE, &debug_isis_spfstats_cmd);
- install_element(CONFIG_NODE, &no_debug_isis_spfstats_cmd);
- install_element(CONFIG_NODE, &debug_isis_spftrigg_cmd);
- install_element(CONFIG_NODE, &no_debug_isis_spftrigg_cmd);
install_element(CONFIG_NODE, &debug_isis_rtevents_cmd);
install_element(CONFIG_NODE, &no_debug_isis_rtevents_cmd);
install_element(CONFIG_NODE, &debug_isis_events_cmd);
diff --git a/isisd/isisd.h b/isisd/isisd.h
index 51b359aad..fe9abff93 100644
--- a/isisd/isisd.h
+++ b/isisd/isisd.h
@@ -204,22 +204,16 @@ int isis_area_passwd_hmac_md5_set(struct isis_area *area, int level,
extern struct thread_master *master;
#define DEBUG_ADJ_PACKETS (1<<0)
-#define DEBUG_CHECKSUM_ERRORS (1<<1)
-#define DEBUG_LOCAL_UPDATES (1<<2)
-#define DEBUG_PROTOCOL_ERRORS (1<<3)
-#define DEBUG_SNP_PACKETS (1<<4)
-#define DEBUG_UPDATE_PACKETS (1<<5)
-#define DEBUG_SPF_EVENTS (1<<6)
-#define DEBUG_SPF_STATS (1<<7)
-#define DEBUG_SPF_TRIGGERS (1<<8)
-#define DEBUG_RTE_EVENTS (1<<9)
-#define DEBUG_EVENTS (1<<10)
-#define DEBUG_ZEBRA (1<<11)
-#define DEBUG_PACKET_DUMP (1<<12)
-#define DEBUG_LSP_GEN (1<<13)
-#define DEBUG_LSP_SCHED (1<<14)
-#define DEBUG_FABRICD_FLOODING (1<<15)
-#define DEBUG_BFD (1<<16)
+#define DEBUG_SNP_PACKETS (1<<1)
+#define DEBUG_UPDATE_PACKETS (1<<2)
+#define DEBUG_SPF_EVENTS (1<<3)
+#define DEBUG_RTE_EVENTS (1<<4)
+#define DEBUG_EVENTS (1<<5)
+#define DEBUG_PACKET_DUMP (1<<6)
+#define DEBUG_LSP_GEN (1<<7)
+#define DEBUG_LSP_SCHED (1<<8)
+#define DEBUG_FABRICD_FLOODING (1<<9)
+#define DEBUG_BFD (1<<10)
#define lsp_debug(...) \
do { \
@@ -233,7 +227,7 @@ extern struct thread_master *master;
zlog_debug(__VA_ARGS__); \
} while (0)
-#define DEBUG_TE (1<<13)
+#define DEBUG_TE DEBUG_LSP_GEN
#define IS_DEBUG_ISIS(x) (isis->debugs & x)
diff --git a/ldpd/lde.c b/ldpd/lde.c
index 4f74d9304..2aa96546e 100644
--- a/ldpd/lde.c
+++ b/ldpd/lde.c
@@ -1627,7 +1627,7 @@ lde_address_list_free(struct lde_nbr *ln)
static void zclient_sync_init(unsigned short instance)
{
/* Initialize special zclient for synchronous message exchanges. */
- zclient_sync = zclient_new_notify(master, &zclient_options_default);
+ zclient_sync = zclient_new(master, &zclient_options_default);
zclient_sync->sock = -1;
zclient_sync->redist_default = ZEBRA_ROUTE_LDP;
zclient_sync->instance = instance;
diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c
index c8b775cb8..9dc567735 100644
--- a/ldpd/ldp_zebra.c
+++ b/ldpd/ldp_zebra.c
@@ -533,7 +533,7 @@ void
ldp_zebra_init(struct thread_master *master)
{
/* Set default values. */
- zclient = zclient_new_notify(master, &zclient_options_default);
+ zclient = zclient_new(master, &zclient_options_default);
zclient_init(zclient, ZEBRA_ROUTE_LDP, 0, &ldpd_privs);
/* set callbacks */
diff --git a/lib/command.h b/lib/command.h
index 873ecdda9..11514fd5e 100644
--- a/lib/command.h
+++ b/lib/command.h
@@ -378,6 +378,7 @@ struct cmd_node {
#define WATCHFRR_STR "watchfrr information\n"
#define ZEBRA_STR "Zebra information\n"
+#define CMD_VNI_RANGE "(1-16777215)"
#define CONF_BACKUP_EXT ".sav"
/* Command warnings. */
diff --git a/lib/zclient.c b/lib/zclient.c
index 45a9f7be9..b879326d7 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -58,8 +58,8 @@ int zclient_debug = 0;
struct zclient_options zclient_options_default = {.receive_notify = false};
/* Allocate zclient structure. */
-struct zclient *zclient_new_notify(struct thread_master *master,
- struct zclient_options *opt)
+struct zclient *zclient_new(struct thread_master *master,
+ struct zclient_options *opt)
{
struct zclient *zclient;
zclient = XCALLOC(MTYPE_ZCLIENT, sizeof(struct zclient));
@@ -199,7 +199,7 @@ void zclient_reset(struct zclient *zclient)
* @param zclient a pointer to zclient structure
* @return socket fd just to make sure that connection established
* @see zclient_init
- * @see zclient_new_notify
+ * @see zclient_new
*/
int zclient_socket_connect(struct zclient *zclient)
{
diff --git a/lib/zclient.h b/lib/zclient.h
index 97ebb0811..07fe512a3 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -422,23 +422,10 @@ struct zclient_options {
bool receive_notify;
};
-/* Prototypes of zebra client service functions. */
-extern struct zclient *zclient_new(struct thread_master *);
-
-/* clang-format off */
-#if CONFDATE > 20181101
-CPP_NOTICE("zclient_new_notify can take over or zclient_new now");
-#endif
-/* clang-format on */
-
extern struct zclient_options zclient_options_default;
-extern struct zclient *zclient_new_notify(struct thread_master *m,
- struct zclient_options *opt);
-
-#define zclient_new(A) \
- zclient_new_notify((A), &zclient_options_default); \
- CPP_WARN("Please transition to using zclient_new_notify");
+extern struct zclient *zclient_new(struct thread_master *m,
+ struct zclient_options *opt);
extern void zclient_init(struct zclient *, int, unsigned short,
struct zebra_privs_t *privs);
diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c
index e7b187f3b..dae00bbce 100644
--- a/nhrpd/nhrp_route.c
+++ b/nhrpd/nhrp_route.c
@@ -344,7 +344,7 @@ void nhrp_zebra_init(void)
zebra_rib[AFI_IP] = route_table_init();
zebra_rib[AFI_IP6] = route_table_init();
- zclient = zclient_new_notify(master, &zclient_options_default);
+ zclient = zclient_new(master, &zclient_options_default);
zclient->zebra_connected = nhrp_zebra_connected;
zclient->interface_add = nhrp_interface_add;
zclient->interface_delete = nhrp_interface_delete;
diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c
index c968b35d9..5db9b529e 100644
--- a/ospf6d/ospf6_zebra.c
+++ b/ospf6d/ospf6_zebra.c
@@ -586,7 +586,7 @@ static void ospf6_zebra_connected(struct zclient *zclient)
void ospf6_zebra_init(struct thread_master *master)
{
/* Allocate zebra structure. */
- zclient = zclient_new_notify(master, &zclient_options_default);
+ zclient = zclient_new(master, &zclient_options_default);
zclient_init(zclient, ZEBRA_ROUTE_OSPF6, 0, &ospf6d_privs);
zclient->zebra_connected = ospf6_zebra_connected;
zclient->router_id_update = ospf6_router_id_update_zebra;
diff --git a/ospfd/ospf_memory.c b/ospfd/ospf_memory.c
index 1332104b0..c4dc0136e 100644
--- a/ospfd/ospf_memory.c
+++ b/ospfd/ospf_memory.c
@@ -52,6 +52,7 @@ DEFINE_MTYPE(OSPFD, OSPF_IF_INFO, "OSPF if info")
DEFINE_MTYPE(OSPFD, OSPF_IF_PARAMS, "OSPF if params")
DEFINE_MTYPE(OSPFD, OSPF_MESSAGE, "OSPF message")
DEFINE_MTYPE(OSPFD, OSPF_MPLS_TE, "OSPF MPLS parameters")
+DEFINE_MTYPE(OSPFD, OSPF_ROUTER_INFO, "OSPF Router Info parameters")
DEFINE_MTYPE(OSPFD, OSPF_PCE_PARAMS, "OSPF PCE parameters")
DEFINE_MTYPE(OSPFD, OSPF_EXT_PARAMS, "OSPF Extended parameters")
DEFINE_MTYPE(OSPFD, OSPF_SR_PARAMS, "OSPF Segment Routing parameters")
diff --git a/ospfd/ospf_memory.h b/ospfd/ospf_memory.h
index 50c6f33ec..861de64c2 100644
--- a/ospfd/ospf_memory.h
+++ b/ospfd/ospf_memory.h
@@ -51,6 +51,7 @@ DECLARE_MTYPE(OSPF_IF_INFO)
DECLARE_MTYPE(OSPF_IF_PARAMS)
DECLARE_MTYPE(OSPF_MESSAGE)
DECLARE_MTYPE(OSPF_MPLS_TE)
+DECLARE_MTYPE(OSPF_ROUTER_INFO)
DECLARE_MTYPE(OSPF_PCE_PARAMS)
DECLARE_MTYPE(OSPF_SR_PARAMS)
DECLARE_MTYPE(OSPF_EXT_PARAMS)
diff --git a/ospfd/ospf_ri.c b/ospfd/ospf_ri.c
index bef16761f..72f6dbe08 100644
--- a/ospfd/ospf_ri.c
+++ b/ospfd/ospf_ri.c
@@ -59,60 +59,6 @@
#include "ospfd/ospf_ri.h"
#include "ospfd/ospf_errors.h"
-/* Store Router Information PCE TLV and SubTLV in network byte order. */
-struct ospf_pce_info {
- bool enabled;
- struct ri_tlv_pce pce_header;
- struct ri_pce_subtlv_address pce_address;
- struct ri_pce_subtlv_path_scope pce_scope;
- struct list *pce_domain;
- struct list *pce_neighbor;
- struct ri_pce_subtlv_cap_flag pce_cap_flag;
-};
-
-/*
- * Store Router Information Segment Routing TLV and SubTLV
- * in network byte order
- */
-struct ospf_ri_sr_info {
- bool enabled;
- /* Algorithms supported by the node */
- struct ri_sr_tlv_sr_algorithm algo;
- /*
- * Segment Routing Global Block i.e. label range
- * Only one range supported in this code
- */
- struct ri_sr_tlv_sid_label_range range;
- /* Maximum SID Depth supported by the node */
- struct ri_sr_tlv_node_msd msd;
-};
-
-/* Following structure are internal use only. */
-struct ospf_router_info {
- bool enabled;
-
- uint8_t registered;
- uint8_t scope;
-
-/* Flags to manage this router information. */
-#define RIFLG_LSA_ENGAGED 0x1
-#define RIFLG_LSA_FORCED_REFRESH 0x2
- uint32_t flags;
-
- /* area pointer if flooding is Type 10 Null if flooding is AS scope */
- struct ospf_area *area;
- struct in_addr area_id;
-
- /* Store Router Information Capabilities LSA */
- struct ri_tlv_router_cap router_cap;
-
- /* Store PCE capability LSA */
- struct ospf_pce_info pce_info;
-
- /* Store SR capability LSA */
- struct ospf_ri_sr_info sr_info;
-};
-
/*
* Global variable to manage Opaque-LSA/Router Information on this node.
* Note that all parameter values are stored in network byte order.
@@ -126,28 +72,29 @@ static struct ospf_router_info OspfRI;
static void ospf_router_info_ism_change(struct ospf_interface *oi,
int old_status);
-static void ospf_router_info_nsm_change(struct ospf_neighbor *nbr,
- int old_status);
static void ospf_router_info_config_write_router(struct vty *vty);
static void ospf_router_info_show_info(struct vty *vty, struct ospf_lsa *lsa);
static int ospf_router_info_lsa_originate(void *arg);
static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa);
-static void ospf_router_info_lsa_schedule(enum lsa_opcode opcode);
+static void ospf_router_info_lsa_schedule(struct ospf_ri_area_info *ai,
+ enum lsa_opcode opcode);
static void ospf_router_info_register_vty(void);
static int ospf_router_info_lsa_update(struct ospf_lsa *lsa);
+static void del_area_info(void *val);
static void del_pce_info(void *val);
int ospf_router_info_init(void)
{
- zlog_info("RI -> Initialize Router Information");
+ zlog_info("RI (%s): Initialize Router Information", __func__);
memset(&OspfRI, 0, sizeof(struct ospf_router_info));
OspfRI.enabled = false;
OspfRI.registered = 0;
OspfRI.scope = OSPF_OPAQUE_AS_LSA;
- OspfRI.area_id.s_addr = 0;
- OspfRI.flags = 0;
+ OspfRI.as_flags = RIFLG_LSA_INACTIVE;
+ OspfRI.area_info = list_new();
+ OspfRI.area_info->del = del_area_info;
/* Initialize pce domain and neighbor list */
OspfRI.pce_info.enabled = false;
@@ -171,13 +118,15 @@ static int ospf_router_info_register(uint8_t scope)
if (OspfRI.registered)
return rc;
- zlog_info("RI -> Register Router Information with scope %s(%d)",
+ zlog_info("RI (%s): Register Router Information with scope %s(%d)",
+ __func__,
scope == OSPF_OPAQUE_AREA_LSA ? "Area" : "AS", scope);
rc = ospf_register_opaque_functab(
scope, OPAQUE_TYPE_ROUTER_INFORMATION_LSA,
NULL, /* new interface */
NULL, /* del interface */
- ospf_router_info_ism_change, ospf_router_info_nsm_change,
+ ospf_router_info_ism_change,
+ NULL, /* NSM change */
ospf_router_info_config_write_router,
NULL, /* Config. write interface */
NULL, /* Config. write debug */
@@ -188,7 +137,7 @@ static int ospf_router_info_register(uint8_t scope)
if (rc != 0) {
flog_warn(
EC_OSPF_OPAQUE_REGISTRATION,
- "ospf_router_info_init: Failed to register functions");
+ "RI (%s): Failed to register functions", __func__);
return rc;
}
@@ -235,10 +184,14 @@ void ospf_router_info_finish(void)
OspfRI.enabled = false;
}
+static void del_area_info(void *val)
+{
+ XFREE(MTYPE_OSPF_ROUTER_INFO, val);
+}
+
static void del_pce_info(void *val)
{
XFREE(MTYPE_OSPF_PCE_PARAMS, val);
- return;
}
/* Catch RI LSA flooding Scope for ospf_ext.[h,c] code */
@@ -248,14 +201,26 @@ struct scope_info ospf_router_info_get_flooding_scope(void)
if (OspfRI.scope == OSPF_OPAQUE_AS_LSA) {
flooding_scope.scope = OSPF_OPAQUE_AS_LSA;
- flooding_scope.area_id.s_addr = 0;
+ flooding_scope.areas = NULL;
return flooding_scope;
}
flooding_scope.scope = OSPF_OPAQUE_AREA_LSA;
- flooding_scope.area_id.s_addr = OspfRI.area_id.s_addr;
+ flooding_scope.areas = OspfRI.area_info;
return flooding_scope;
}
+static struct ospf_ri_area_info *lookup_by_area(struct ospf_area *area)
+{
+ struct listnode *node, *nnode;
+ struct ospf_ri_area_info *ai;
+
+ for (ALL_LIST_ELEMENTS(OspfRI.area_info, node, nnode, ai))
+ if (ai->area == area)
+ return ai;
+
+ return NULL;
+}
+
/*------------------------------------------------------------------------*
* Followings are control functions for ROUTER INFORMATION parameters
*management.
@@ -525,6 +490,9 @@ static void initialize_params(struct ospf_router_info *ori)
{
uint32_t cap = 0;
struct ospf *top;
+ struct listnode *node, *nnode;
+ struct ospf_area *area;
+ struct ospf_ri_area_info *new;
/*
* Initialize default Router Information Capabilities.
@@ -536,14 +504,22 @@ static void initialize_params(struct ospf_router_info *ori)
/* If Area address is not null and exist, retrieve corresponding
* structure */
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));
+ zlog_info("RI (%s): Initialize Router Info for %s scope", __func__,
+ OspfRI.scope == OSPF_OPAQUE_AREA_LSA ? "Area" : "AS");
- /* Try to get the Area context at this step. Do it latter if not
- * available */
- if ((OspfRI.scope == OSPF_OPAQUE_AREA_LSA) && (OspfRI.area == NULL))
- OspfRI.area = ospf_area_lookup_by_area_id(top, OspfRI.area_id);
+ /* Try to get available Area's context from ospf at this step.
+ * Do it latter if not available */
+ if (OspfRI.scope == OSPF_OPAQUE_AREA_LSA) {
+ for (ALL_LIST_ELEMENTS(top->areas, node, nnode, area)) {
+ zlog_debug("RI (%s): Add area %s to Router Information",
+ __func__, inet_ntoa(area->area_id));
+ new = XCALLOC(MTYPE_OSPF_ROUTER_INFO,
+ sizeof(struct ospf_ri_area_info));
+ new->area = area;
+ new->flags = RIFLG_LSA_INACTIVE;
+ listnode_add(OspfRI.area_info, new);
+ }
+ }
/*
* Initialize default PCE Information values
@@ -597,16 +573,31 @@ static int is_mandated_params_set(struct ospf_router_info ori)
*/
void ospf_router_info_update_sr(bool enable, struct sr_srgb srgb, uint8_t msd)
{
+ struct listnode *node, *nnode;
+ struct ospf_ri_area_info *ai;
+
+ /* First, check if Router Information is registered or not */
+ if (!OspfRI.registered)
+ ospf_router_info_register(OSPF_OPAQUE_AREA_LSA);
+
+ /* Verify that scope is AREA */
+ if (OspfRI.scope != OSPF_OPAQUE_AREA_LSA) {
+ zlog_err(
+ "RI (%s): Router Info is %s flooding: Change scope to Area flooding for Segment Routing",
+ __func__,
+ OspfRI.scope == OSPF_OPAQUE_AREA_LSA ? "Area" : "AS");
+ return;
+ }
- /* First activate and initialize Router Information is necessary */
+ /* Then, activate and initialize Router Information if necessary */
if (!OspfRI.enabled) {
OspfRI.enabled = true;
initialize_params(&OspfRI);
}
if (IS_DEBUG_OSPF_SR)
- zlog_debug("RI-> %s Routing Information for Segment Routing",
- enable ? "Enable" : "Disable");
+ zlog_debug("RI (%s): %s Routing Information for Segment Routing",
+ __func__, enable ? "Enable" : "Disable");
/* Unset or Set SR parameters */
if (!enable) {
@@ -626,10 +617,14 @@ void ospf_router_info_update_sr(bool enable, struct sr_srgb srgb, uint8_t msd)
}
/* Refresh if already engaged or originate RI LSA */
- if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
- ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
- else
- ospf_router_info_lsa_schedule(REORIGINATE_THIS_LSA);
+ for (ALL_LIST_ELEMENTS(OspfRI.area_info, node, nnode, ai)) {
+ if (CHECK_FLAG(ai->flags, RIFLG_LSA_ENGAGED))
+ ospf_router_info_lsa_schedule(ai, REFRESH_THIS_LSA);
+ else
+ ospf_router_info_lsa_schedule(ai,
+ REORIGINATE_THIS_LSA);
+
+ }
}
/*------------------------------------------------------------------------*
@@ -638,14 +633,22 @@ void ospf_router_info_update_sr(bool enable, struct sr_srgb srgb, uint8_t msd)
static void ospf_router_info_ism_change(struct ospf_interface *oi,
int old_state)
{
- /* So far, nothing to do here. */
- return;
-}
-static void ospf_router_info_nsm_change(struct ospf_neighbor *nbr,
- int old_state)
-{
- /* So far, nothing to do here. */
+ struct ospf_ri_area_info *ai;
+
+ /* Collect area information */
+ ai = lookup_by_area(oi->area);
+
+ /* Check if area is not yet registered */
+ if (ai != NULL)
+ return;
+
+ /* Add this new area to the list */
+ ai = XCALLOC(MTYPE_OSPF_ROUTER_INFO, sizeof(struct ospf_ri_area_info));
+ ai->area = oi->area;
+ ai->flags = RIFLG_LSA_INACTIVE;
+ listnode_add(OspfRI.area_info, ai);
+
return;
}
@@ -723,7 +726,7 @@ static void ospf_router_info_lsa_body_set(struct stream *s)
}
/* Create new opaque-LSA. */
-static struct ospf_lsa *ospf_router_info_lsa_new()
+static struct ospf_lsa *ospf_router_info_lsa_new(struct ospf_area *area)
{
struct ospf *top;
struct stream *s;
@@ -768,8 +771,7 @@ static struct ospf_lsa *ospf_router_info_lsa_new()
/* Now, create an OSPF LSA instance. */
new = ospf_lsa_new_and_data(length);
- new->area = OspfRI.area; /* Area must be null if the Opaque type is AS
- scope, fulfill otherwise */
+ new->area = area;
if (new->area && new->area->ospf)
new->vrf_id = new->area->ospf->vrf_id;
@@ -783,36 +785,31 @@ static struct ospf_lsa *ospf_router_info_lsa_new()
return new;
}
-static int ospf_router_info_lsa_originate1(void *arg)
+static int ospf_router_info_lsa_originate_as(void *arg)
{
struct ospf_lsa *new;
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 */
+ /* Sanity Check */
if (OspfRI.scope == OSPF_OPAQUE_AREA_LSA) {
- area = (struct ospf_area *)arg;
- if (area->area_id.s_addr != OspfRI.area_id.s_addr) {
- zlog_debug(
- "RI -> This is not the Router Information Area. Stop processing");
- return rc;
- }
- OspfRI.area = area;
- if (area->ospf)
- vrf_id = area->ospf->vrf_id;
+ flog_warn(
+ EC_OSPF_LSA_INSTALL_FAILURE,
+ "RI (%s): wrong flooding scope AREA instead of AS ?",
+ __func__);
+ return rc;
}
/* Create new Opaque-LSA/ROUTER INFORMATION instance. */
- new = ospf_router_info_lsa_new();
- new->vrf_id = vrf_id;
+ new = ospf_router_info_lsa_new(NULL);
+ new->vrf_id = VRF_DEFAULT;
+ top = (struct ospf *)arg;
- /* Get ospf info */
- top = ospf_lookup_by_vrf_id(vrf_id);
+ /* Check ospf info */
if (top == NULL) {
- zlog_debug("%s: ospf instance not found for vrf id %u",
- __PRETTY_FUNCTION__, vrf_id);
+ zlog_debug("RI (%s): ospf instance not found for vrf id %u",
+ __func__, vrf_id);
ospf_lsa_unlock(&new);
return rc;
}
@@ -821,22 +818,86 @@ static int ospf_router_info_lsa_originate1(void *arg)
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
flog_warn(
EC_OSPF_LSA_INSTALL_FAILURE,
- "ospf_router_info_lsa_originate1: ospf_lsa_install() ?");
+ "RI (%s): ospf_lsa_install() ?", __func__);
+ ospf_lsa_unlock(&new);
+ return rc;
+ }
+
+ /* Update new LSA origination count. */
+ top->lsa_originate_count++;
+
+ /* Flood new LSA through AREA or AS. */
+ SET_FLAG(OspfRI.as_flags, RIFLG_LSA_ENGAGED);
+ ospf_flood_through_as(top, NULL /*nbr */, new);
+
+ if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
+ zlog_debug(
+ "LSA[Type%d:%s]: Originate Opaque-LSA/ROUTER INFORMATION",
+ new->data->type, inet_ntoa(new->data->id));
+ ospf_lsa_header_dump(new->data);
+ }
+
+ rc = 0;
+ return rc;
+}
+
+static int ospf_router_info_lsa_originate_area(void *arg)
+{
+ struct ospf_lsa *new;
+ struct ospf *top;
+ struct ospf_ri_area_info *ai = NULL;
+ int rc = -1;
+ vrf_id_t vrf_id = VRF_DEFAULT;
+
+ /* Sanity Check */
+ if (OspfRI.scope == OSPF_OPAQUE_AS_LSA) {
+ flog_warn(
+ EC_OSPF_LSA_INSTALL_FAILURE,
+ "RI (%s): wrong flooding scope AS instead of AREA ?",
+ __func__);
+ return rc;
+ }
+
+ /* Create new Opaque-LSA/ROUTER INFORMATION instance. */
+ ai = lookup_by_area((struct ospf_area *)arg);
+ if (ai == NULL) {
+ zlog_debug(
+ "RI (%s): There is no context for this Router Information. Stop processing",
+ __func__);
+ return rc;
+ }
+ if (ai->area->ospf) {
+ vrf_id = ai->area->ospf->vrf_id;
+ top = ai->area->ospf;
+ } else {
+ top = ospf_lookup_by_vrf_id(vrf_id);
+ }
+ new = ospf_router_info_lsa_new(ai->area);
+ new->vrf_id = vrf_id;
+
+ /* Check ospf info */
+ if (top == NULL) {
+ zlog_debug("RI (%s): ospf instance not found for vrf id %u",
+ __func__, vrf_id);
ospf_lsa_unlock(&new);
return rc;
}
- /* Now this Router Info parameter entry has associated LSA. */
- SET_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED);
+ /* Install this LSA into LSDB. */
+ if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
+ flog_warn(
+ EC_OSPF_LSA_INSTALL_FAILURE,
+ "RI (%s): ospf_lsa_install() ?", __func__);
+ ospf_lsa_unlock(&new);
+ return rc;
+ }
/* Update new LSA origination count. */
top->lsa_originate_count++;
- /* Flood new LSA through AS. */
- if (OspfRI.scope == OSPF_OPAQUE_AS_LSA)
- ospf_flood_through_as(top, NULL /*nbr */, new);
- else
- ospf_flood_through_area(OspfRI.area, NULL /*nbr */, new);
+ /* Flood new LSA through AREA or AS. */
+ SET_FLAG(ai->flags, RIFLG_LSA_ENGAGED);
+ ospf_flood_through_area(ai->area, NULL /*nbr */, new);
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
zlog_debug(
@@ -852,38 +913,62 @@ static int ospf_router_info_lsa_originate1(void *arg)
static int ospf_router_info_lsa_originate(void *arg)
{
+ struct ospf_ri_area_info *ai;
int rc = -1;
if (!OspfRI.enabled) {
- zlog_info(
- "ospf_router_info_lsa_originate: ROUTER INFORMATION is disabled now.");
+ zlog_info("RI (%s): ROUTER INFORMATION is disabled now.",
+ __func__);
rc = 0; /* This is not an error case. */
return rc;
}
/* Check if Router Information LSA is already engaged */
- if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED)) {
- if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_FORCED_REFRESH)) {
- UNSET_FLAG(OspfRI.flags, RIFLG_LSA_FORCED_REFRESH);
- ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
+ if (OspfRI.scope == OSPF_OPAQUE_AS_LSA) {
+ if ((CHECK_FLAG(OspfRI.as_flags, RIFLG_LSA_ENGAGED))
+ && (CHECK_FLAG(OspfRI.as_flags,
+ RIFLG_LSA_FORCED_REFRESH))) {
+ UNSET_FLAG(OspfRI.as_flags, RIFLG_LSA_FORCED_REFRESH);
+ ospf_router_info_lsa_schedule(NULL, REFRESH_THIS_LSA);
+ rc = 0;
+ return rc;
}
} else {
- if (!is_mandated_params_set(OspfRI))
+ ai = lookup_by_area((struct ospf_area *)arg);
+ if (ai == NULL) {
flog_warn(
EC_OSPF_LSA,
- "ospf_router_info_lsa_originate: lacks mandated ROUTER INFORMATION parameters");
-
- /* Ok, let's try to originate an LSA */
- if (ospf_router_info_lsa_originate1(arg) != 0)
+ "RI (%s): Missing area information", __func__);
return rc;
+ }
+ if ((CHECK_FLAG(ai->flags, RIFLG_LSA_ENGAGED))
+ && (CHECK_FLAG(ai->flags, RIFLG_LSA_FORCED_REFRESH))) {
+ UNSET_FLAG(ai->flags, RIFLG_LSA_FORCED_REFRESH);
+ ospf_router_info_lsa_schedule(ai, REFRESH_THIS_LSA);
+ rc = 0;
+ return rc;
+ }
}
- rc = 0;
+ /* Router Information is not yet Engaged, check parameters */
+ if (!is_mandated_params_set(OspfRI))
+ flog_warn(
+ EC_OSPF_LSA,
+ "RI (%s): lacks mandated ROUTER INFORMATION parameters",
+ __func__);
+
+ /* Ok, let's try to originate an LSA */
+ if (OspfRI.scope == OSPF_OPAQUE_AS_LSA)
+ rc = ospf_router_info_lsa_originate_as(arg);
+ else
+ rc = ospf_router_info_lsa_originate_area(arg);
+
return rc;
}
static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa)
{
+ struct ospf_ri_area_info *ai = NULL;
struct ospf_lsa *new = NULL;
struct ospf *top;
@@ -893,8 +978,8 @@ static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa)
* status change.
* It seems a slip among routers in the routing domain.
*/
- zlog_info(
- "ospf_router_info_lsa_refresh: ROUTER INFORMATION is disabled now.");
+ zlog_info("RI (%s): ROUTER INFORMATION is disabled now.",
+ __func__);
lsa->data->ls_age =
htons(OSPF_LSA_MAXAGE); /* Flush it anyway. */
}
@@ -903,37 +988,66 @@ static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa)
if (GET_OPAQUE_ID(ntohl(lsa->data->id.s_addr)) != 0) {
flog_warn(
EC_OSPF_LSA,
- "ospf_router_info_lsa_refresh: Unsupported Router Information ID");
+ "RI (%s): Unsupported Router Information ID",
+ __func__);
return NULL;
}
- /* If the lsa's age reached to MaxAge, start flushing procedure. */
- if (IS_LSA_MAXAGE(lsa)) {
- UNSET_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED);
- ospf_opaque_lsa_flush_schedule(lsa);
- return NULL;
- }
-
- /* Create new Opaque-LSA/ROUTER INFORMATION instance. */
- new = ospf_router_info_lsa_new();
- 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_by_vrf_id(lsa->vrf_id);
- if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
- flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
- "ospf_router_info_lsa_refresh: ospf_lsa_install() ?");
- ospf_lsa_unlock(&new);
- return new;
- }
-
- /* Flood updated LSA through AS or AREA depending of OspfRI.scope. */
- if (OspfRI.scope == OSPF_OPAQUE_AS_LSA)
+ /* Process LSA depending of the flooding scope */
+ if (OspfRI.scope == OSPF_OPAQUE_AREA_LSA) {
+ /* Get context AREA context */
+ ai = lookup_by_area(lsa->area);
+ if (ai == NULL) {
+ flog_warn(
+ EC_OSPF_LSA,
+ "RI (%s): No associated Area", __func__);
+ return NULL;
+ }
+ /* Flush LSA, if the lsa's age reached to MaxAge. */
+ if (IS_LSA_MAXAGE(lsa)) {
+ UNSET_FLAG(ai->flags, RIFLG_LSA_ENGAGED);
+ ospf_opaque_lsa_flush_schedule(lsa);
+ return NULL;
+ }
+ /* Create new Opaque-LSA/ROUTER INFORMATION instance. */
+ new = ospf_router_info_lsa_new(ai->area);
+ 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_by_vrf_id(lsa->vrf_id);
+ if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
+ flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
+ "RI (%s): ospf_lsa_install() ?", __func__);
+ ospf_lsa_unlock(&new);
+ return new;
+ }
+ /* Flood updated LSA through AREA */
+ ospf_flood_through_area(ai->area, NULL /*nbr */, new);
+
+ } else { /* AS Flooding scope */
+ /* Flush LSA, if the lsa's age reached to MaxAge. */
+ if (IS_LSA_MAXAGE(lsa)) {
+ UNSET_FLAG(OspfRI.as_flags, RIFLG_LSA_ENGAGED);
+ ospf_opaque_lsa_flush_schedule(lsa);
+ return NULL;
+ }
+ /* Create new Opaque-LSA/ROUTER INFORMATION instance. */
+ new = ospf_router_info_lsa_new(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_by_vrf_id(lsa->vrf_id);
+ if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
+ flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
+ "RI (%s): ospf_lsa_install() ?", __func__);
+ ospf_lsa_unlock(&new);
+ return new;
+ }
+ /* Flood updated LSA through AS */
ospf_flood_through_as(top, NULL /*nbr */, new);
- else
- ospf_flood_through_area(OspfRI.area, NULL /*nbr */, new);
+ }
/* Debug logging. */
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
@@ -946,7 +1060,8 @@ static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa)
return new;
}
-static void ospf_router_info_lsa_schedule(enum lsa_opcode opcode)
+static void ospf_router_info_lsa_schedule(struct ospf_ri_area_info *ai,
+ enum lsa_opcode opcode)
{
struct ospf_lsa lsa;
struct lsa_header lsah;
@@ -956,28 +1071,44 @@ static void ospf_router_info_lsa_schedule(enum lsa_opcode opcode)
memset(&lsa, 0, sizeof(lsa));
memset(&lsah, 0, sizeof(lsah));
- zlog_debug("RI-> LSA schedule %s%s%s",
+ zlog_debug("RI (%s): LSA schedule %s%s%s", __func__,
opcode == REORIGINATE_THIS_LSA ? "Re-Originate" : "",
opcode == REFRESH_THIS_LSA ? "Refresh" : "",
opcode == FLUSH_THIS_LSA ? "Flush" : "");
- /* Check LSA flags state coherence */
- if (!CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED)
- && (opcode != REORIGINATE_THIS_LSA))
- return;
+ /* Check LSA flags state coherence and collect area information */
+ if (OspfRI.scope == OSPF_OPAQUE_AREA_LSA) {
+ if ((ai == NULL) || (ai->area == NULL)) {
+ flog_warn(
+ EC_OSPF_LSA,
+ "RI (%s): Router Info is Area scope flooding but area is not set",
+ __func__);
+ return;
+ }
- if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED)
- && (opcode == REORIGINATE_THIS_LSA))
- opcode = REFRESH_THIS_LSA;
+ if (!CHECK_FLAG(ai->flags, RIFLG_LSA_ENGAGED)
+ && (opcode != REORIGINATE_THIS_LSA))
+ return;
- top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
- if ((OspfRI.scope == OSPF_OPAQUE_AREA_LSA) && (OspfRI.area == NULL)) {
- flog_warn(
- EC_OSPF_LSA,
- "ospf_router_info_lsa_schedule(): Router Info is Area scope flooding but area is not set");
- OspfRI.area = ospf_area_lookup_by_area_id(top, OspfRI.area_id);
+ if (CHECK_FLAG(ai->flags, RIFLG_LSA_ENGAGED)
+ && (opcode == REORIGINATE_THIS_LSA))
+ opcode = REFRESH_THIS_LSA;
+
+ lsa.area = ai->area;
+ top = ai->area->ospf;
+ } else {
+ if (!CHECK_FLAG(OspfRI.as_flags, RIFLG_LSA_ENGAGED)
+ && (opcode != REORIGINATE_THIS_LSA))
+ return;
+
+ if (CHECK_FLAG(OspfRI.as_flags, RIFLG_LSA_ENGAGED)
+ && (opcode == REORIGINATE_THIS_LSA))
+ opcode = REFRESH_THIS_LSA;
+
+ top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ lsa.area = NULL;
}
- lsa.area = OspfRI.area;
+
lsa.data = &lsah;
lsah.type = OspfRI.scope;
@@ -989,7 +1120,7 @@ static void ospf_router_info_lsa_schedule(enum lsa_opcode opcode)
case REORIGINATE_THIS_LSA:
if (OspfRI.scope == OSPF_OPAQUE_AREA_LSA)
ospf_opaque_lsa_reoriginate_schedule(
- (void *)OspfRI.area, OSPF_OPAQUE_AREA_LSA,
+ (void *)ai->area, OSPF_OPAQUE_AREA_LSA,
OPAQUE_TYPE_ROUTER_INFORMATION_LSA);
else
ospf_opaque_lsa_reoriginate_schedule(
@@ -1000,7 +1131,10 @@ static void ospf_router_info_lsa_schedule(enum lsa_opcode opcode)
ospf_opaque_lsa_refresh_schedule(&lsa);
break;
case FLUSH_THIS_LSA:
- UNSET_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED);
+ if (OspfRI.scope == OSPF_OPAQUE_AREA_LSA)
+ UNSET_FLAG(ai->flags, RIFLG_LSA_ENGAGED);
+ else
+ UNSET_FLAG(OspfRI.as_flags, RIFLG_LSA_ENGAGED);
ospf_opaque_lsa_flush_schedule(&lsa);
break;
}
@@ -1014,7 +1148,7 @@ static int ospf_router_info_lsa_update(struct ospf_lsa *lsa)
/* Sanity Check */
if (lsa == NULL) {
- flog_warn(EC_OSPF_LSA, "OSPF-RI (%s): Abort! LSA is NULL",
+ flog_warn(EC_OSPF_LSA, "RI (%s): Abort! LSA is NULL",
__func__);
return -1;
}
@@ -1356,8 +1490,7 @@ static void ospf_router_info_config_write_router(struct vty *vty)
if (OspfRI.scope == OSPF_OPAQUE_AS_LSA)
vty_out(vty, " router-info as\n");
else
- vty_out(vty, " router-info area %s\n",
- inet_ntoa(OspfRI.area_id));
+ vty_out(vty, " router-info area\n");
if (OspfRI.pce_info.enabled) {
@@ -1405,43 +1538,53 @@ static void ospf_router_info_config_write_router(struct vty *vty)
/*------------------------------------------------------------------------*
* Followings are vty command functions.
*------------------------------------------------------------------------*/
+/* Simple wrapper schedule RI LSA action in function of the scope */
+static void ospf_router_info_schedule(enum lsa_opcode opcode)
+{
+ struct listnode *node, *nnode;
+ struct ospf_ri_area_info *ai;
+
+ if (OspfRI.scope == OSPF_OPAQUE_AS_LSA) {
+ if (CHECK_FLAG(OspfRI.as_flags, RIFLG_LSA_ENGAGED))
+ ospf_router_info_lsa_schedule(NULL, opcode);
+ else if (opcode == REORIGINATE_THIS_LSA)
+ ospf_router_info_lsa_schedule(NULL, opcode);
+ } else {
+ for (ALL_LIST_ELEMENTS(OspfRI.area_info, node, nnode, ai)) {
+ if (CHECK_FLAG(ai->flags, RIFLG_LSA_ENGAGED))
+ ospf_router_info_lsa_schedule(ai, opcode);
+ }
+ }
+}
DEFUN (router_info,
router_info_area_cmd,
- "router-info <as|area A.B.C.D>",
+ "router-info <as|area [A.B.C.D]>",
OSPF_RI_STR
"Enable the Router Information functionality with AS flooding scope\n"
"Enable the Router Information functionality with Area flooding scope\n"
- "OSPF area ID in IP format\n")
+ "OSPF area ID in IP format (deprecated)\n")
{
- int idx_ipv4 = 2;
- char *area = (argc == 3) ? argv[idx_ipv4]->arg : NULL;
-
+ int idx_mode = 1;
uint8_t scope;
if (OspfRI.enabled)
return CMD_SUCCESS;
/* Check and get Area value if present */
- if (area) {
- if (!inet_aton(area, &OspfRI.area_id)) {
- vty_out(vty, "%% specified Area ID %s is invalid\n",
- area);
- return CMD_WARNING_CONFIG_FAILED;
- }
- scope = OSPF_OPAQUE_AREA_LSA;
- } else {
- OspfRI.area_id.s_addr = 0;
+ if (strncmp(argv[idx_mode]->arg, "as", 2) == 0)
scope = OSPF_OPAQUE_AS_LSA;
- }
+ else
+ scope = OSPF_OPAQUE_AREA_LSA;
/* First start to register Router Information callbacks */
- if ((ospf_router_info_register(scope)) != 0) {
+ if (!OspfRI.registered && (ospf_router_info_register(scope)) != 0) {
vty_out(vty,
"%% Unable to register Router Information callbacks.");
flog_err(
EC_OSPF_INIT_FAIL,
- "Unable to register Router Information callbacks. Abort!");
+ "RI (%s): Unable to register Router Information callbacks. Abort!",
+ __func__);
return CMD_WARNING_CONFIG_FAILED;
}
@@ -1463,14 +1606,8 @@ DEFUN (router_info,
initialize_params(&OspfRI);
- /* Refresh RI LSA if already engaged */
- if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED)) {
- zlog_debug("RI-> Refresh LSA following configuration");
- ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
- } else {
- zlog_debug("RI-> Initial origination following configuration");
- ospf_router_info_lsa_schedule(REORIGINATE_THIS_LSA);
- }
+ /* Originate or Refresh RI LSA if already engaged */
+ ospf_router_info_schedule(REORIGINATE_THIS_LSA);
return CMD_SUCCESS;
}
@@ -1488,8 +1625,7 @@ DEFUN (no_router_info,
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("RI-> Router Information: ON -> OFF");
- if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
- ospf_router_info_lsa_schedule(FLUSH_THIS_LSA);
+ ospf_router_info_schedule(FLUSH_THIS_LSA);
OspfRI.enabled = false;
@@ -1533,8 +1669,7 @@ DEFUN (pce_address,
set_pce_address(value, pi);
/* Refresh RI LSA if already engaged */
- if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
- ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
+ ospf_router_info_schedule(REFRESH_THIS_LSA);
}
return CMD_SUCCESS;
@@ -1552,8 +1687,7 @@ DEFUN (no_pce_address,
unset_param(&OspfRI.pce_info.pce_address);
/* Refresh RI LSA if already engaged */
- if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
- ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
+ ospf_router_info_schedule(REFRESH_THIS_LSA);
return CMD_SUCCESS;
}
@@ -1583,8 +1717,7 @@ DEFUN (pce_path_scope,
set_pce_path_scope(scope, pi);
/* Refresh RI LSA if already engaged */
- if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
- ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
+ ospf_router_info_schedule(REFRESH_THIS_LSA);
}
return CMD_SUCCESS;
@@ -1602,8 +1735,7 @@ DEFUN (no_pce_path_scope,
unset_param(&OspfRI.pce_info.pce_address);
/* Refresh RI LSA if already engaged */
- if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
- ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
+ ospf_router_info_schedule(REFRESH_THIS_LSA);
return CMD_SUCCESS;
}
@@ -1641,8 +1773,7 @@ DEFUN (pce_domain,
set_pce_domain(PCE_DOMAIN_TYPE_AS, as, pce);
/* Refresh RI LSA if already engaged */
- if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
- ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
+ ospf_router_info_schedule(REFRESH_THIS_LSA);
return CMD_SUCCESS;
}
@@ -1671,8 +1802,7 @@ DEFUN (no_pce_domain,
unset_pce_domain(PCE_DOMAIN_TYPE_AS, as, pce);
/* Refresh RI LSA if already engaged */
- if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
- ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
+ ospf_router_info_schedule(REFRESH_THIS_LSA);
return CMD_SUCCESS;
}
@@ -1711,8 +1841,7 @@ DEFUN (pce_neigbhor,
set_pce_neighbor(PCE_DOMAIN_TYPE_AS, as, pce);
/* Refresh RI LSA if already engaged */
- if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
- ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
+ ospf_router_info_schedule(REFRESH_THIS_LSA);
return CMD_SUCCESS;
}
@@ -1741,8 +1870,7 @@ DEFUN (no_pce_neighbor,
unset_pce_neighbor(PCE_DOMAIN_TYPE_AS, as, pce);
/* Refresh RI LSA if already engaged */
- if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
- ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
+ ospf_router_info_schedule(REFRESH_THIS_LSA);
return CMD_SUCCESS;
}
@@ -1773,8 +1901,7 @@ DEFUN (pce_cap_flag,
set_pce_cap_flag(cap, pce);
/* Refresh RI LSA if already engaged */
- if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
- ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
+ ospf_router_info_schedule(REFRESH_THIS_LSA);
}
return CMD_SUCCESS;
@@ -1791,8 +1918,7 @@ DEFUN (no_pce_cap_flag,
unset_param(&OspfRI.pce_info.pce_cap_flag);
/* Refresh RI LSA if already engaged */
- if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED))
- ospf_router_info_lsa_schedule(REFRESH_THIS_LSA);
+ ospf_router_info_schedule(REFRESH_THIS_LSA);
return CMD_SUCCESS;
}
diff --git a/ospfd/ospf_ri.h b/ospfd/ospf_ri.h
index 26bcc1b62..84511ac5e 100644
--- a/ospfd/ospf_ri.h
+++ b/ospfd/ospf_ri.h
@@ -170,7 +170,71 @@ struct ri_pce_subtlv_cap_flag {
/* Structure to share flooding scope info for Segment Routing */
struct scope_info {
uint8_t scope;
- struct in_addr area_id;
+ struct list *areas;
+};
+
+/* Flags to manage the Router Information LSA. */
+#define RIFLG_LSA_INACTIVE 0x0
+#define RIFLG_LSA_ENGAGED 0x1
+#define RIFLG_LSA_FORCED_REFRESH 0x2
+
+/* Store Router Information PCE TLV and SubTLV in network byte order. */
+struct ospf_pce_info {
+ bool enabled;
+ struct ri_tlv_pce pce_header;
+ struct ri_pce_subtlv_address pce_address;
+ struct ri_pce_subtlv_path_scope pce_scope;
+ struct list *pce_domain;
+ struct list *pce_neighbor;
+ struct ri_pce_subtlv_cap_flag pce_cap_flag;
+};
+
+/*
+ * Store Router Information Segment Routing TLV and SubTLV
+ * in network byte order
+ */
+struct ospf_ri_sr_info {
+ bool enabled;
+ /* Algorithms supported by the node */
+ struct ri_sr_tlv_sr_algorithm algo;
+ /*
+ * Segment Routing Global Block i.e. label range
+ * Only one range supported in this code
+ */
+ struct ri_sr_tlv_sid_label_range range;
+ /* Maximum SID Depth supported by the node */
+ struct ri_sr_tlv_node_msd msd;
+};
+
+/* Store area information to flood LSA per area */
+struct ospf_ri_area_info {
+
+ uint32_t flags;
+
+ /* area pointer if flooding is Type 10 Null if flooding is AS scope */
+ struct ospf_area *area;
+};
+
+/* Following structure are internal use only. */
+struct ospf_router_info {
+ bool enabled;
+
+ uint8_t registered;
+ uint8_t scope;
+ /* LSA flags are only used when scope is AS flooding */
+ uint32_t as_flags;
+
+ /* List of area info to flood RI LSA */
+ struct list *area_info;
+
+ /* Store Router Information Capabilities LSA */
+ struct ri_tlv_router_cap router_cap;
+
+ /* Store PCE capability LSA */
+ struct ospf_pce_info pce_info;
+
+ /* Store SR capability LSA */
+ struct ospf_ri_sr_info sr_info;
};
/* Prototypes. */
diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c
index 02698d770..16347f1c5 100644
--- a/ospfd/ospf_te.c
+++ b/ospfd/ospf_te.c
@@ -2398,16 +2398,16 @@ DEFUN (no_ospf_mpls_te_inter_as,
zlog_debug("MPLS-TE: Inter-AS support OFF");
if ((OspfMplsTE.enabled) && (OspfMplsTE.inter_as != Off)) {
- OspfMplsTE.inter_as = Off;
/* Flush all Inter-AS LSA */
for (ALL_LIST_ELEMENTS(OspfMplsTE.iflist, node, nnode, lp))
if (IS_INTER_AS(lp->type)
&& CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED))
ospf_mpls_te_lsa_schedule(lp, FLUSH_THIS_LSA);
- }
- /* Deregister the Callbacks for Inter-AS support */
- ospf_mpls_te_unregister();
+ /* Deregister the Callbacks for Inter-AS support */
+ ospf_mpls_te_unregister();
+ OspfMplsTE.inter_as = Off;
+ }
return CMD_SUCCESS;
}
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index ed19ae4f3..c7bde55cd 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -1577,7 +1577,7 @@ static void ospf_zebra_connected(struct zclient *zclient)
void ospf_zebra_init(struct thread_master *master, unsigned short instance)
{
/* Allocate zebra structure. */
- zclient = zclient_new_notify(master, &zclient_options_default);
+ zclient = zclient_new(master, &zclient_options_default);
zclient_init(zclient, ZEBRA_ROUTE_OSPF, instance, &ospfd_privs);
zclient->zebra_connected = ospf_zebra_connected;
zclient->router_id_update = ospf_router_id_update_zebra;
diff --git a/pbrd/pbr_zebra.c b/pbrd/pbr_zebra.c
index b7391a171..9db3edacb 100644
--- a/pbrd/pbr_zebra.c
+++ b/pbrd/pbr_zebra.c
@@ -391,7 +391,7 @@ void pbr_zebra_init(void)
{
struct zclient_options opt = { .receive_notify = true };
- zclient = zclient_new_notify(master, &opt);
+ zclient = zclient_new(master, &opt);
zclient_init(zclient, ZEBRA_ROUTE_PBR, 0, &pbr_privs);
zclient->zebra_connected = zebra_connected;
diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c
index 23001031e..3dfc36a0c 100644
--- a/pimd/pim_zebra.c
+++ b/pimd/pim_zebra.c
@@ -746,7 +746,7 @@ static void pim_zebra_connected(struct zclient *zclient)
void pim_zebra_init(void)
{
/* Socket for receiving updates from Zebra daemon */
- zclient = zclient_new_notify(master, &zclient_options_default);
+ zclient = zclient_new(master, &zclient_options_default);
zclient->zebra_connected = pim_zebra_connected;
zclient->router_id_update = pim_router_id_update_zebra;
diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c
index 0e7486611..6b4531308 100644
--- a/pimd/pim_zlookup.c
+++ b/pimd/pim_zlookup.c
@@ -120,7 +120,7 @@ void zclient_lookup_free(void)
void zclient_lookup_new(void)
{
- zlookup = zclient_new_notify(master, &zclient_options_default);
+ zlookup = zclient_new(master, &zclient_options_default);
if (!zlookup) {
flog_err(EC_LIB_ZAPI_SOCKET, "%s: zclient_new() failure",
__PRETTY_FUNCTION__);
diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c
index 2a56cd7b1..20f543a25 100644
--- a/ripd/rip_zebra.c
+++ b/ripd/rip_zebra.c
@@ -211,7 +211,7 @@ static void rip_zebra_connected(struct zclient *zclient)
void rip_zclient_init(struct thread_master *master)
{
/* Set default value to the zebra client structure. */
- zclient = zclient_new_notify(master, &zclient_options_default);
+ zclient = zclient_new(master, &zclient_options_default);
zclient_init(zclient, ZEBRA_ROUTE_RIP, 0, &ripd_privs);
zclient->zebra_connected = rip_zebra_connected;
zclient->interface_add = rip_interface_add;
diff --git a/ripngd/ripng_zebra.c b/ripngd/ripng_zebra.c
index a8cc9ee12..f2b69c85a 100644
--- a/ripngd/ripng_zebra.c
+++ b/ripngd/ripng_zebra.c
@@ -414,7 +414,7 @@ static void ripng_zebra_connected(struct zclient *zclient)
void zebra_init(struct thread_master *master)
{
/* Allocate zebra structure. */
- zclient = zclient_new_notify(master, &zclient_options_default);
+ zclient = zclient_new(master, &zclient_options_default);
zclient_init(zclient, ZEBRA_ROUTE_RIPNG, 0, &ripngd_privs);
zclient->zebra_connected = ripng_zebra_connected;
diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c
index 286f32087..12bab73c5 100644
--- a/sharpd/sharp_zebra.c
+++ b/sharpd/sharp_zebra.c
@@ -281,7 +281,7 @@ void sharp_zebra_init(void)
{
struct zclient_options opt = {.receive_notify = true};
- zclient = zclient_new_notify(master, &opt);
+ zclient = zclient_new(master, &opt);
zclient_init(zclient, ZEBRA_ROUTE_SHARP, 0, &sharp_privs);
zclient->zebra_connected = zebra_connected;
diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c
index 4e168e142..fd4201e56 100644
--- a/staticd/static_zebra.c
+++ b/staticd/static_zebra.c
@@ -465,7 +465,7 @@ void static_zebra_init(void)
{
struct zclient_options opt = { .receive_notify = true };
- zclient = zclient_new_notify(master, &opt);
+ zclient = zclient_new(master, &opt);
zclient_init(zclient, ZEBRA_ROUTE_STATIC, 0, &static_privs);
zclient->zebra_capabilities = static_zebra_capabilities;
diff --git a/tests/.gitignore b/tests/.gitignore
index 37cd245de..49a4b6e47 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -12,6 +12,7 @@
/bgpd/test_peer_attr
/isisd/test_fuzz_isis_tlv
/isisd/test_fuzz_isis_tlv_tests.h
+/isisd/test_isis_lspdb
/isisd/test_isis_vertex_queue
/lib/cli/test_cli
/lib/cli/test_cli_clippy.c
diff --git a/tests/bgpd/test_mpath.c b/tests/bgpd/test_mpath.c
index f0797827c..04fbda42e 100644
--- a/tests/bgpd/test_mpath.c
+++ b/tests/bgpd/test_mpath.c
@@ -379,7 +379,7 @@ static int global_test_init(void)
{
qobj_init();
master = thread_master_create(NULL);
- zclient = zclient_new_notify(master, &zclient_options_default);
+ zclient = zclient_new(master, &zclient_options_default);
bgp_master_init(master);
vrf_init(NULL, NULL, NULL, NULL, NULL);
bgp_option_set(BGP_OPT_NO_LISTEN);
diff --git a/tests/isisd/test_isis_lspdb.c b/tests/isisd/test_isis_lspdb.c
new file mode 100644
index 000000000..b9c6f2bbb
--- /dev/null
+++ b/tests/isisd/test_isis_lspdb.c
@@ -0,0 +1,87 @@
+#include <zebra.h>
+
+#include "isisd/isis_lsp.c"
+
+struct thread_master *master;
+
+int isis_sock_init(struct isis_circuit *circuit);
+int isis_sock_init(struct isis_circuit *circuit)
+{
+ return 0;
+}
+
+struct zebra_privs_t isisd_privs;
+
+static void test_lsp_build_list_nonzero_ht(void)
+{
+ uint8_t lsp_id1[8] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00
+ };
+ uint8_t lsp_id_end[8] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x5f, 0x00
+ };
+ uint8_t lsp_id2[8] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00
+ };
+
+ struct isis_area *area = calloc(sizeof(*area), 1);
+
+ area->lsp_mtu = 1500;
+
+ dict_t *lspdb = lsp_db_init();
+
+ struct isis_lsp *lsp1 = lsp_new(area, lsp_id1, 6000, 0, 0, 0, NULL,
+ ISIS_LEVEL2);
+
+ lsp_insert(lsp1, lspdb);
+
+ struct isis_lsp *lsp2 = lsp_new(area, lsp_id2, 6000, 0, 0, 0, NULL,
+ ISIS_LEVEL2);
+
+ lsp_insert(lsp2, lspdb);
+
+ struct list *list = list_new();
+
+ lsp_build_list_nonzero_ht(lsp_id1, lsp_id_end, list, lspdb);
+ assert(list->count == 1);
+ assert(listgetdata(listhead(list)) == lsp1);
+ list_delete_all_node(list);
+
+ lsp_id_end[5] = 0x03;
+ lsp_id_end[6] = 0x00;
+
+ lsp_build_list_nonzero_ht(lsp_id1, lsp_id_end, list, lspdb);
+ assert(list->count == 2);
+ assert(listgetdata(listhead(list)) == lsp1);
+ assert(listgetdata(listtail(list)) == lsp2);
+ list_delete_all_node(list);
+
+ memcpy(lsp_id1, lsp_id2, sizeof(lsp_id1));
+
+ lsp_build_list_nonzero_ht(lsp_id1, lsp_id_end, list, lspdb);
+ assert(list->count == 1);
+ assert(listgetdata(listhead(list)) == lsp2);
+ list_delete_all_node(list);
+
+ lsp_id1[5] = 0x03;
+ lsp_id_end[5] = 0x04;
+
+ lsp_build_list_nonzero_ht(lsp_id1, lsp_id_end, list, lspdb);
+ assert(list->count == 0);
+ list_delete_all_node(list);
+
+ lsp_id1[5] = 0x00;
+
+ lsp_build_list_nonzero_ht(lsp_id1, lsp_id_end, list, lspdb);
+ assert(list->count == 2);
+ assert(listgetdata(listhead(list)) == lsp1);
+ assert(listgetdata(listtail(list)) == lsp2);
+ list_delete_all_node(list);
+}
+
+int main(int argc, char **argv)
+{
+ isis = calloc(sizeof(*isis), 1);
+ test_lsp_build_list_nonzero_ht();
+ return 0;
+}
diff --git a/tests/isisd/test_isis_lspdb.py b/tests/isisd/test_isis_lspdb.py
new file mode 100644
index 000000000..cd0b5345c
--- /dev/null
+++ b/tests/isisd/test_isis_lspdb.py
@@ -0,0 +1,6 @@
+import frrtest
+
+class TestIsisLSPDB(frrtest.TestMultiOut):
+ program = './test_isis_lspdb'
+
+TestIsisLSPDB.exit_cleanly()
diff --git a/tests/subdir.am b/tests/subdir.am
index a4a754b08..7a693ac0f 100644
--- a/tests/subdir.am
+++ b/tests/subdir.am
@@ -24,6 +24,7 @@ TESTS_ISISD =
else
TESTS_ISISD = \
tests/isisd/test_fuzz_isis_tlv \
+ tests/isisd/test_isis_lspdb \
tests/isisd/test_isis_vertex_queue \
# end
endif
@@ -155,6 +156,10 @@ tests_isisd_test_fuzz_isis_tlv_CPPFLAGS = $(TESTS_CPPFLAGS) -I$(top_builddir)/te
tests_isisd_test_fuzz_isis_tlv_LDADD = $(ISISD_TEST_LDADD)
tests_isisd_test_fuzz_isis_tlv_SOURCES = tests/isisd/test_fuzz_isis_tlv.c
nodist_tests_isisd_test_fuzz_isis_tlv_SOURCES = tests/isisd/test_fuzz_isis_tlv_tests.h
+tests_isisd_test_isis_lspdb_CFLAGS = $(TESTS_CFLAGS)
+tests_isisd_test_isis_lspdb_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_isisd_test_isis_lspdb_LDADD = $(ISISD_TEST_LDADD)
+tests_isisd_test_isis_lspdb_SOURCES = tests/isisd/test_isis_lspdb.c
tests_isisd_test_isis_vertex_queue_CFLAGS = $(TESTS_CFLAGS)
tests_isisd_test_isis_vertex_queue_CPPFLAGS = $(TESTS_CPPFLAGS)
tests_isisd_test_isis_vertex_queue_LDADD = $(ISISD_TEST_LDADD)
@@ -267,6 +272,7 @@ EXTRA_DIST += \
tests/helpers/python/frrtest.py \
tests/isisd/test_fuzz_isis_tlv.py \
tests/isisd/test_fuzz_isis_tlv_tests.h.gz \
+ tests/isisd/test_isis_lspdb.py \
tests/isisd/test_isis_vertex_queue.py \
tests/lib/cli/test_commands.in \
tests/lib/cli/test_commands.py \
diff --git a/tests/test_lblmgr.c b/tests/test_lblmgr.c
index 9d1c05436..e71e680fa 100644
--- a/tests/test_lblmgr.c
+++ b/tests/test_lblmgr.c
@@ -119,7 +119,7 @@ void init_zclient(struct thread_master *master, char *lm_zserv_path)
{
frr_zclient_addr(&zclient_addr, &zclient_addr_len, lm_zserv_path);
- zclient = zclient_new_notify(master, &zclient_options_default);
+ zclient = zclient_new(master, &zclient_options_default);
/* zclient_init(zclient, ZEBRA_LABEL_MANAGER, 0); */
zclient->sock = -1;
zclient->redist_default = ZEBRA_ROUTE_LDP;
diff --git a/tools/etc/frr/daemons.conf b/tools/etc/frr/daemons.conf
index bd0e370d1..94221301e 100644
--- a/tools/etc/frr/daemons.conf
+++ b/tools/etc/frr/daemons.conf
@@ -24,7 +24,8 @@ fabricd_options=" --daemon -A 127.0.0.1"
# The list of daemons to watch is automatically generated by the init script.
watchfrr_enable=yes
-watchfrr_options=(-d -r /usr/sbin/servicebBfrrbBrestartbB%s -s /usr/sbin/servicebBfrrbBstartbB%s -k /usr/sbin/servicebBfrrbBstopbB%s -b bB)
+
+watchfrr_options=(-d -r /usr/lib/frr/frrbBrestartbB%s -s /usr/lib/frr/frrbBstartbB%s -k /usr/lib/frr/frrbBstopbB%s -b bB)
# If valgrind_enable is 'yes' the frr daemons will be started via valgrind.
# The use case for doing so is tracking down memory leaks, etc in frr.
diff --git a/tools/frr.in b/tools/frr.in
index ee8dc883d..ec383bc5a 100755
--- a/tools/frr.in
+++ b/tools/frr.in
@@ -127,6 +127,7 @@ start()
echo -n " $1"
fi
+
${SSD} \
--start \
--pidfile=`pidfile $1` \
@@ -148,7 +149,6 @@ start()
-- \
`eval echo "$""$1""_options"` -n "$2"
else
- echo -n " $1"
if ! check_daemon $1; then
echo -n " (binary does not exist)"
return;
@@ -210,7 +210,6 @@ stop()
# Now we have to wait until $DAEMON has _really_ stopped.
#
if test -n "$PID" && kill -0 $PID 2>/dev/null; then
- echo -n " (waiting) ."
cnt=0
while kill -0 $PID 2>/dev/null; do
cnt=`expr $cnt + 1`
@@ -220,10 +219,8 @@ stop()
break
fi
sleep 2
- echo -n "."
done
fi
- echo -n " $inst"
rm -f `pidfile $inst`
rm -f `vtyfile $inst`
@@ -305,7 +302,6 @@ start_watchfrr()
# Start if at least one daemon is activated.
if [ $found_one -eq 1 ]; then
- echo -n "Starting Frr monitor daemon:"
start watchfrr
echo "."
fi
@@ -408,8 +404,6 @@ start_prio()
wanted_prio=$1
daemon_list=${daemon:-$DAEMONS}
- echo -n "Starting Frr daemons (prio:$wanted_prio):"
-
for prio_i in `seq 1 $wanted_prio`; do
for daemon_name in $daemon_list; do
eval daemon_prio=\$${daemon_name}
@@ -447,7 +441,6 @@ start_prio()
eval "file_list_suffix="$V_PATH"/"$daemon_name-*""
for pidfile in $file_list_suffix.pid; do
${SSD} --stop --quiet --oknodo --pidfile "$pidfile"
- echo -n "."
rm -rf "$pidfile"
done
for vtyfile in $file_list_suffix.vty; do
@@ -459,7 +452,6 @@ start_prio()
fi
done
done
- echo "."
}
check_status()
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 35f719fa5..cd78551cb 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -1458,7 +1458,7 @@ DEFUNSH_HIDDEN(VTYSH_BGPD, address_family_evpn2, address_family_evpn2_cmd,
}
#endif
-DEFUNSH(VTYSH_BGPD, bgp_evpn_vni, bgp_evpn_vni_cmd, "vni (1-16777215)",
+DEFUNSH(VTYSH_BGPD, bgp_evpn_vni, bgp_evpn_vni_cmd, "vni " CMD_VNI_RANGE,
"VXLAN Network Identifier\n"
"VNI number\n")
{
diff --git a/zebra/label_manager.c b/zebra/label_manager.c
index 8afb1a0b7..bfad8ea64 100644
--- a/zebra/label_manager.c
+++ b/zebra/label_manager.c
@@ -318,7 +318,7 @@ static void lm_zclient_init(char *lm_zserv_path)
lm_zserv_path);
/* Set default values. */
- zclient = zclient_new_notify(zebrad.master, &zclient_options_default);
+ zclient = zclient_new(zebrad.master, &zclient_options_default);
zclient->privs = &zserv_privs;
zclient->sock = -1;
zclient->t_connect = NULL;
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 4fff37637..263cb3d22 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -68,9 +68,6 @@ static void vty_show_ip_route_summary(struct vty *vty,
static void vty_show_ip_route_summary_prefix(struct vty *vty,
struct route_table *table);
-/* VNI range as per RFC 7432 */
-#define CMD_VNI_RANGE "(1-16777215)"
-
DEFUN (ip_multicast_mode,
ip_multicast_mode_cmd,
"ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 0bc1ea50b..d372d3e83 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -148,8 +148,7 @@ static void zvni_mac_del_all(zebra_vni_t *zvni, int uninstall, int upd_client,
static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *macaddr);
static int zvni_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr,
uint8_t flags, uint32_t seq);
-static int zvni_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr,
- uint8_t flags);
+static int zvni_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr);
static zebra_vni_t *zvni_map_vlan(struct interface *ifp,
struct interface *br_if, vlanid_t vid);
static int zvni_mac_install(zebra_vni_t *zvni, zebra_mac_t *mac);
@@ -2305,6 +2304,7 @@ static int zvni_remote_neigh_update(zebra_vni_t *zvni,
UNSET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
+ ZEBRA_NEIGH_SET_ACTIVE(n);
n->r_vtep_ip = zmac->fwd_info.r_vtep_ip;
}
@@ -2407,7 +2407,7 @@ static void zvni_mac_del_hash_entry(struct hash_backet *backet, void *arg)
&wctx->r_vtep_ip))) {
if (wctx->upd_client && (mac->flags & ZEBRA_MAC_LOCAL)) {
zvni_mac_send_del_to_client(wctx->zvni->vni,
- &mac->macaddr, mac->flags);
+ &mac->macaddr);
}
if (wctx->uninstall)
@@ -2494,18 +2494,10 @@ static int zvni_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr,
/*
* Inform BGP about local MAC deletion.
*/
-static int zvni_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr,
- uint8_t mac_flags)
+static int zvni_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr)
{
- uint8_t flags = 0;
-
- if (CHECK_FLAG(mac_flags, ZEBRA_MAC_STICKY))
- SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
- if (CHECK_FLAG(mac_flags, ZEBRA_MAC_DEF_GW))
- SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
-
- return zvni_macip_send_msg_to_client(vni, macaddr, NULL, flags,
- 0, ZEBRA_MACIP_DEL);
+ return zvni_macip_send_msg_to_client(vni, macaddr, NULL, 0 /* flags */,
+ 0 /* seq */, ZEBRA_MACIP_DEL);
}
/*
@@ -4304,6 +4296,10 @@ static void process_remote_macip_add(vni_t vni,
}
}
+ /* Remove local MAC from BGP. */
+ if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
+ zvni_mac_send_del_to_client(zvni->vni, macaddr);
+
/* Set "auto" and "remote" forwarding info. */
UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
@@ -4324,6 +4320,7 @@ static void process_remote_macip_add(vni_t vni,
/* Install the entry. */
zvni_mac_install(zvni, mac);
+
}
/* Update seq number. */
@@ -4522,6 +4519,13 @@ static void process_remote_macip_del(vni_t vni,
} else {
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
zvni_process_neigh_on_remote_mac_del(zvni, mac);
+ /*
+ * the remote sequence number in the auto mac entry
+ * needs to be reset to 0 as the mac entry may have
+ * been removed on all VTEPs (including
+ * the originating one)
+ */
+ mac->rem_seq = 0;
/* If all remote neighbors referencing a remote MAC
* go away, we need to uninstall the MAC.
@@ -5730,7 +5734,7 @@ int zebra_vxlan_check_del_local_mac(struct interface *ifp,
ifp->ifindex, vni);
/* Remove MAC from BGP. */
- zvni_mac_send_del_to_client(zvni->vni, macaddr, mac->flags);
+ zvni_mac_send_del_to_client(zvni->vni, macaddr);
/*
* If there are no neigh associated with the mac delete the mac
@@ -5841,7 +5845,7 @@ int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if,
zvni_process_neigh_on_local_mac_del(zvni, mac);
/* Remove MAC from BGP. */
- zvni_mac_send_del_to_client(zvni->vni, macaddr, mac->flags);
+ zvni_mac_send_del_to_client(zvni->vni, macaddr);
/*
* If there are no neigh associated with the mac delete the mac