vector_set (babel_enable_if, strdup (ifname));
- ifp = if_lookup_by_name(ifname, vrf_lookup_by_id(VRF_DEFAULT));
+ ifp = if_lookup_by_name(ifname, VRF_DEFAULT);
if (ifp != NULL)
interface_recalculate(ifp);
free (str);
vector_unset (babel_enable_if, babel_enable_if_index);
- ifp = if_lookup_by_name(ifname, vrf_lookup_by_id(VRF_DEFAULT));
+ ifp = if_lookup_by_name(ifname, VRF_DEFAULT);
if (ifp != NULL)
interface_reset(ifp);
show_babel_interface_sub (vty, ifp);
return CMD_SUCCESS;
}
- if ((ifp = if_lookup_by_name (argv[3]->arg,
- vrf_lookup_by_id(VRF_DEFAULT))) == NULL)
+ if ((ifp = if_lookup_by_name (argv[3]->arg, VRF_DEFAULT)) == NULL)
{
vty_out (vty, "No such interface name\n");
return CMD_WARNING;
}
return CMD_SUCCESS;
}
- if ((ifp = if_lookup_by_name (argv[3]->arg,
- vrf_lookup_by_id(VRF_DEFAULT))) == NULL)
+ if ((ifp = if_lookup_by_name (argv[3]->arg, VRF_DEFAULT)) == NULL)
{
vty_out (vty, "No such interface name\n");
return CMD_WARNING;
if (! dist->ifname)
return;
- ifp = if_lookup_by_name (dist->ifname, vrf_lookup_by_id(VRF_DEFAULT));
+ ifp = if_lookup_by_name (dist->ifname, VRF_DEFAULT);
if (ifp == NULL)
return;
if (bs->key.ifname[0]) {
if (vrf)
- ifp = if_lookup_by_name(bs->key.ifname, vrf);
+ ifp = if_lookup_by_name(bs->key.ifname, vrf->vrf_id);
else
ifp = if_lookup_by_name_all_vrf(bs->key.ifname);
if (ifp == NULL) {
return 0;
}
if (bs->key.ifname[0] && !vrf) {
- vrf = ifp->vrf;
+ vrf = vrf_lookup_by_id(ifp->vrf_id);
if (vrf == NULL) {
log_error(
"session-enable: specified VRF doesn't exists.");
{
struct bfd_session_observer *bso;
struct bfd_session *bs;
- struct vrf *vrf = ifp->vrf;
-
- if (!vrf)
- return;
+ struct vrf *vrf;
TAILQ_FOREACH(bso, &bglobal.bg_obslist, bso_entry) {
bs = bso->bso_bs;
/* Interface name mismatch. */
if (strcmp(ifp->name, bs->key.ifname))
continue;
+ vrf = vrf_lookup_by_id(ifp->vrf_id);
+ if (!vrf)
+ continue;
if (bs->key.vrfname[0] &&
strcmp(vrf->name, bs->key.vrfname))
continue;
static int bfdd_interface_vrf_update(ZAPI_CALLBACK_ARGS)
{
struct interface *ifp;
- struct vrf *nvrf;
vrf_id_t nvrfid;
ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id, &nvrfid);
if (ifp == NULL)
return 0;
- nvrf = vrf_lookup_by_id(nvrfid);
- if_update_to_new_vrf(ifp, nvrf);
+
+ if_update_to_new_vrf(ifp, nvrfid);
return 0;
}
bgp_evpn_show_route_header(vty, bgp,
tbl_ver,
json);
+ vty_out(vty, "%19s Extended Community\n"
+ , " ");
header = 0;
}
{
const char *export_name;
vpn_policy_direction_t idir, edir;
- char *vname;
- char buf[1000];
+ char *vname, *tmp_name;
+ char buf[RD_ADDRSTRLEN];
struct ecommunity *ecom;
bool first_export = false;
int debug;
+ struct listnode *node;
+ bool is_inst_match = false;
export_name = to_bgp->name ? to_bgp->name : VRF_DEFAULT_NAME;
idir = BGP_VPN_POLICY_DIR_FROMVPN;
vname = (from_bgp->name ? XSTRDUP(MTYPE_TMP, from_bgp->name)
: XSTRDUP(MTYPE_TMP, VRF_DEFAULT_NAME));
- listnode_add(to_bgp->vpn_policy[afi].import_vrf, vname);
+ /* Check the import_vrf list of destination vrf for the source vrf name,
+ * insert otherwise.
+ */
+ for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi].import_vrf,
+ node, tmp_name)) {
+ if (strcmp(vname, tmp_name) == 0) {
+ is_inst_match = true;
+ break;
+ }
+ }
+ if (!is_inst_match)
+ listnode_add(to_bgp->vpn_policy[afi].import_vrf,
+ vname);
- if (!listcount(from_bgp->vpn_policy[afi].export_vrf))
- first_export = true;
+ /* Check if the source vrf already exports to any vrf,
+ * first time export requires to setup auto derived RD/RT values.
+ * Add the destination vrf name to export vrf list if it is
+ * not present.
+ */
+ is_inst_match = false;
vname = XSTRDUP(MTYPE_TMP, export_name);
- listnode_add(from_bgp->vpn_policy[afi].export_vrf, vname);
-
+ if (!listcount(from_bgp->vpn_policy[afi].export_vrf)) {
+ first_export = true;
+ } else {
+ for (ALL_LIST_ELEMENTS_RO(from_bgp->vpn_policy[afi].export_vrf,
+ node, tmp_name)) {
+ if (strcmp(vname, tmp_name) == 0) {
+ is_inst_match = true;
+ break;
+ }
+ }
+ }
+ if (!is_inst_match)
+ listnode_add(from_bgp->vpn_policy[afi].export_vrf,
+ vname);
/* Update import RT for current VRF using export RT of the VRF we're
* importing from. First though, make sure "import_vrf" has that
* set.
const char *export_name, *tmp_name;
vpn_policy_direction_t idir, edir;
char *vname;
- struct ecommunity *ecom;
+ struct ecommunity *ecom = NULL;
struct listnode *node;
int debug;
if (to_bgp->vpn_policy[afi].import_vrf->count == 0) {
UNSET_FLAG(to_bgp->af_flags[afi][safi],
BGP_CONFIG_VRF_TO_VRF_IMPORT);
- ecommunity_free(&to_bgp->vpn_policy[afi].rtlist[idir]);
+ if (to_bgp->vpn_policy[afi].rtlist[idir])
+ ecommunity_free(&to_bgp->vpn_policy[afi].rtlist[idir]);
} else {
ecom = from_bgp->vpn_policy[afi].rtlist[edir];
- ecommunity_del_val(to_bgp->vpn_policy[afi].rtlist[idir],
+ if (ecom)
+ ecommunity_del_val(to_bgp->vpn_policy[afi].rtlist[idir],
(struct ecommunity_val *)ecom->val);
vpn_leak_postchange(idir, afi, bgp_get_default(), to_bgp);
}
*
* import_vrf and export_vrf must match in having
* the in/out names as appropriate.
+ * export_vrf list could have been cleaned up
+ * as part of no router bgp source instnace.
*/
- assert(vname);
+ if (!vname)
+ return;
listnode_delete(from_bgp->vpn_policy[afi].export_vrf, vname);
XFREE(MTYPE_TMP, vname);
bgp);
}
}
+
+/* When a bgp vrf instance is unconfigured, remove its routes
+ * from the VPN table and this vrf could be importing routes from other
+ * bgp vrf instnaces, unimport them.
+ * VRF X and VRF Y are exporting routes to each other.
+ * When VRF X is deleted, unimport its routes from all target vrfs,
+ * also VRF Y should unimport its routes from VRF X table.
+ * This will ensure VPN table is cleaned up appropriately.
+ */
+int bgp_vpn_leak_unimport(struct bgp *from_bgp, struct vty *vty)
+{
+ struct bgp *to_bgp;
+ const char *tmp_name;
+ char *vname;
+ struct listnode *node, *next;
+ safi_t safi = SAFI_UNICAST;
+ afi_t afi;
+ bool is_vrf_leak_bind;
+ int debug;
+
+ if (from_bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
+ return 0;
+
+ debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
+ BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
+
+ tmp_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
+
+ for (afi = 0; afi < AFI_MAX; ++afi) {
+ /* vrf leak is for IPv4 and IPv6 Unicast only */
+ if (afi != AFI_IP && afi != AFI_IP6)
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, to_bgp)) {
+ if (from_bgp == to_bgp)
+ continue;
+
+ /* Unimport and remove source vrf from the
+ * other vrfs import list.
+ */
+ struct vpn_policy *to_vpolicy;
+
+ is_vrf_leak_bind = false;
+ to_vpolicy = &(to_bgp->vpn_policy[afi]);
+ for (ALL_LIST_ELEMENTS_RO(to_vpolicy->import_vrf, node,
+ vname)) {
+ if (strcmp(vname, tmp_name) == 0) {
+ is_vrf_leak_bind = true;
+ break;
+ }
+ }
+ /* skip this bgp instance as there is no leak to this
+ * vrf instance.
+ */
+ if (!is_vrf_leak_bind)
+ continue;
+
+ if (debug)
+ zlog_debug("%s: unimport routes from %s to_bgp %s afi %s import vrfs count %u",
+ __func__, from_bgp->name_pretty,
+ to_bgp->name_pretty, afi2str(afi),
+ to_vpolicy->import_vrf->count);
+
+ vrf_unimport_from_vrf(to_bgp, from_bgp, afi, safi);
+
+ /* readd vrf name as unimport removes import vrf name
+ * from the destination vrf's import list where the
+ * `import vrf` configuration still exist.
+ */
+ vname = XSTRDUP(MTYPE_TMP, tmp_name);
+ listnode_add(to_bgp->vpn_policy[afi].import_vrf,
+ vname);
+ SET_FLAG(to_bgp->af_flags[afi][safi],
+ BGP_CONFIG_VRF_TO_VRF_IMPORT);
+
+ /* If to_bgp exports its routes to the bgp vrf
+ * which is being deleted, un-import the
+ * to_bgp routes from VPN.
+ */
+ for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi]
+ .export_vrf, node,
+ vname)) {
+ if (strcmp(vname, tmp_name) == 0) {
+ vrf_unimport_from_vrf(from_bgp, to_bgp,
+ afi, safi);
+ break;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+/* When a router bgp is configured, there could be a bgp vrf
+ * instance importing routes from this newly configured
+ * bgp vrf instance. Export routes from configured
+ * bgp vrf to VPN.
+ * VRF Y has import from bgp vrf x,
+ * when a bgp vrf x instance is created, export its routes
+ * to VRF Y instance.
+ */
+void bgp_vpn_leak_export(struct bgp *from_bgp)
+{
+ afi_t afi;
+ const char *export_name;
+ char *vname;
+ struct listnode *node, *next;
+ struct ecommunity *ecom;
+ vpn_policy_direction_t idir, edir;
+ safi_t safi = SAFI_UNICAST;
+ struct bgp *to_bgp;
+ int debug;
+
+ debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
+ BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
+
+ idir = BGP_VPN_POLICY_DIR_FROMVPN;
+ edir = BGP_VPN_POLICY_DIR_TOVPN;
+
+ export_name = (from_bgp->name ? XSTRDUP(MTYPE_TMP, from_bgp->name)
+ : XSTRDUP(MTYPE_TMP, VRF_DEFAULT_NAME));
+
+ for (afi = 0; afi < AFI_MAX; ++afi) {
+ /* vrf leak is for IPv4 and IPv6 Unicast only */
+ if (afi != AFI_IP && afi != AFI_IP6)
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, to_bgp)) {
+ if (from_bgp == to_bgp)
+ continue;
+
+ /* bgp instance has import list, check to see if newly
+ * configured bgp instance is the list.
+ */
+ struct vpn_policy *to_vpolicy;
+
+ to_vpolicy = &(to_bgp->vpn_policy[afi]);
+ for (ALL_LIST_ELEMENTS_RO(to_vpolicy->import_vrf,
+ node, vname)) {
+ if (strcmp(vname, export_name) != 0)
+ continue;
+
+ if (debug)
+ zlog_debug("%s: found from_bgp %s in to_bgp %s import list, import routes.",
+ __func__,
+ export_name, to_bgp->name_pretty);
+
+ ecom = from_bgp->vpn_policy[afi].rtlist[edir];
+ /* remove import rt, it will be readded
+ * as part of import from vrf.
+ */
+ if (ecom)
+ ecommunity_del_val(
+ to_vpolicy->rtlist[idir],
+ (struct ecommunity_val *)
+ ecom->val);
+ vrf_import_from_vrf(to_bgp, from_bgp,
+ afi, safi);
+ break;
+
+ }
+ }
+ }
+}
extern void vpn_leak_postchange_all(void);
extern void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw,
bool is_config);
+extern int bgp_vpn_leak_unimport(struct bgp *from_bgp, struct vty *vty);
+extern void bgp_vpn_leak_export(struct bgp *from_bgp);
#endif /* _QUAGGA_BGP_MPLSVPN_H */
if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
continue;
- ifp = if_lookup_by_name(name,
- vrf_lookup_by_id(bgp->vrf_id));
+ ifp = if_lookup_by_name(name, bgp->vrf_id);
if (ifp) {
*bgp_inst = bgp;
return 0;
/* Source is specified with interface name. */
if (peer->update_if) {
- ifp = if_lookup_by_name(peer->update_if,
- vrf_lookup_by_id(peer->bgp->vrf_id));
+ ifp = if_lookup_by_name(peer->update_if, peer->bgp->vrf_id);
if (!ifp)
return -1;
char pfx_buf[PREFIX2STR_BUFFER];
int debug = 0;
+ if (bgp_flag_check(bgp, BGP_FLAG_DELETE_IN_PROGRESS)) {
+ if (rn)
+ debug = bgp_debug_bestpath(&rn->p);
+ if (debug) {
+ prefix2str(&rn->p, pfx_buf, sizeof(pfx_buf));
+ zlog_debug(
+ "%s: bgp delete in progress, ignoring event, p=%s",
+ __func__, pfx_buf);
+ }
+ return;
+ }
/* Is it end of initial update? (after startup) */
if (!rn) {
quagga_timestamp(3, bgp->update_delay_zebra_resume_time,
json_object *json_nexthops = NULL;
json_object *json_nexthop_global = NULL;
json_object *json_nexthop_ll = NULL;
+ json_object *json_ext_community = NULL;
char vrf_id_str[VRF_NAMSIZ] = {0};
bool nexthop_self =
CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
vty_out(vty, "%s", bgp_origin_str[attr->origin]);
if (json_paths) {
+ if (safi == SAFI_EVPN &&
+ attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
+ json_ext_community = json_object_new_object();
+ json_object_string_add(json_ext_community,
+ "string",
+ attr->ecommunity->str);
+ json_object_object_add(json_path,
+ "extendedCommunity",
+ json_ext_community);
+ }
+
if (nexthop_self)
json_object_boolean_true_add(json_path,
"announceNexthopSelf");
json_object_array_add(json_paths, json_path);
} else {
vty_out(vty, "\n");
+
+ if (safi == SAFI_EVPN &&
+ attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
+ vty_out(vty, "%*s", 20, " ");
+ vty_out(vty, "%s\n", attr->ecommunity->str);
+ }
+
#if ENABLE_BGP_VNC
/* prints an additional line, indented, with VNC info, if
* present */
if (is_new_bgp && inst_type == BGP_INSTANCE_TYPE_DEFAULT)
vpn_leak_postchange_all();
+ if (inst_type == BGP_INSTANCE_TYPE_VRF)
+ bgp_vpn_leak_export(bgp);
/* Pending: handle when user tries to change a view to vrf n vv.
*/
}
}
}
+ if (bgp_vpn_leak_unimport(bgp, vty))
+ return CMD_WARNING_CONFIG_FAILED;
+
bgp_delete(bgp);
return CMD_SUCCESS;
json_object_array_add(json_import_vrfs,
json_object_new_string(vname));
+ json_object_object_add(json, "importFromVrfs",
+ json_import_vrfs);
dir = BGP_VPN_POLICY_DIR_FROMVPN;
- ecom_str = ecommunity_ecom2str(
+ if (bgp->vpn_policy[afi].rtlist[dir]) {
+ ecom_str = ecommunity_ecom2str(
bgp->vpn_policy[afi].rtlist[dir],
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
- json_object_object_add(json, "importFromVrfs",
- json_import_vrfs);
- json_object_string_add(json, "importRts", ecom_str);
-
- XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
+ json_object_string_add(json, "importRts",
+ ecom_str);
+ XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
+ } else
+ json_object_string_add(json, "importRts",
+ "none");
}
if (!CHECK_FLAG(bgp->af_flags[afi][safi],
buf1, RD_ADDRSTRLEN));
dir = BGP_VPN_POLICY_DIR_TOVPN;
- ecom_str = ecommunity_ecom2str(
+ if (bgp->vpn_policy[afi].rtlist[dir]) {
+ ecom_str = ecommunity_ecom2str(
bgp->vpn_policy[afi].rtlist[dir],
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
- json_object_string_add(json, "exportRts", ecom_str);
-
- XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
+ json_object_string_add(json, "exportRts",
+ ecom_str);
+ XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
+ } else
+ json_object_string_add(json, "exportRts",
+ "none");
}
if (use_json) {
vty_out(vty, " %s\n", vname);
dir = BGP_VPN_POLICY_DIR_FROMVPN;
- ecom_str = ecommunity_ecom2str(
+ ecom_str = NULL;
+ if (bgp->vpn_policy[afi].rtlist[dir]) {
+ ecom_str = ecommunity_ecom2str(
bgp->vpn_policy[afi].rtlist[dir],
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
- vty_out(vty, "Import RT(s): %s\n", ecom_str);
+ vty_out(vty, "Import RT(s): %s\n", ecom_str);
- XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
+ XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
+ } else
+ vty_out(vty, "Import RT(s):\n");
}
if (!CHECK_FLAG(bgp->af_flags[afi][safi],
buf1, RD_ADDRSTRLEN));
dir = BGP_VPN_POLICY_DIR_TOVPN;
- ecom_str = ecommunity_ecom2str(
+ if (bgp->vpn_policy[afi].rtlist[dir]) {
+ ecom_str = ecommunity_ecom2str(
bgp->vpn_policy[afi].rtlist[dir],
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
- vty_out(vty, "Export RT: %s\n", ecom_str);
- XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
+ vty_out(vty, "Export RT: %s\n", ecom_str);
+ XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
+ } else
+ vty_out(vty, "Import RT(s):\n");
}
}
DEFUN (no_bgp_redistribute_ipv4_ospf,
no_bgp_redistribute_ipv4_ospf_cmd,
- "no redistribute <ospf|table> (1-65535) [metric (0-4294967295)] [route-map WORD]",
+ "no redistribute <ospf|table> (1-65535) [{metric (0-4294967295)|route-map WORD}]",
NO_STR
"Redistribute information from another routing protocol\n"
"Open Shortest Path First (OSPFv2)\n"
ALIAS_HIDDEN(
no_bgp_redistribute_ipv4_ospf, no_bgp_redistribute_ipv4_ospf_hidden_cmd,
- "no redistribute <ospf|table> (1-65535) [metric (0-4294967295)] [route-map WORD]",
+ "no redistribute <ospf|table> (1-65535) [{metric (0-4294967295)|route-map WORD}]",
NO_STR
"Redistribute information from another routing protocol\n"
"Open Shortest Path First (OSPFv2)\n"
DEFUN (no_bgp_redistribute_ipv4,
no_bgp_redistribute_ipv4_cmd,
- "no redistribute " FRR_IP_REDIST_STR_BGPD " [metric (0-4294967295)] [route-map WORD]",
+ "no redistribute " FRR_IP_REDIST_STR_BGPD " [{metric (0-4294967295)|route-map WORD}]",
NO_STR
"Redistribute information from another routing protocol\n"
FRR_IP_REDIST_HELP_STR_BGPD
ALIAS_HIDDEN(
no_bgp_redistribute_ipv4, no_bgp_redistribute_ipv4_hidden_cmd,
"no redistribute " FRR_IP_REDIST_STR_BGPD
- " [metric (0-4294967295)] [route-map WORD]",
+ " [{metric (0-4294967295)|route-map WORD}]",
NO_STR
"Redistribute information from another routing protocol\n" FRR_IP_REDIST_HELP_STR_BGPD
"Metric for redistributed routes\n"
DEFUN (no_bgp_redistribute_ipv6,
no_bgp_redistribute_ipv6_cmd,
- "no redistribute " FRR_IP6_REDIST_STR_BGPD " [metric (0-4294967295)] [route-map WORD]",
+ "no redistribute " FRR_IP6_REDIST_STR_BGPD " [{metric (0-4294967295)|route-map WORD}]",
NO_STR
"Redistribute information from another routing protocol\n"
FRR_IP6_REDIST_HELP_STR_BGPD
}
}
- if_update_to_new_vrf(ifp, vrf_lookup_by_id(new_vrf_id));
+ if_update_to_new_vrf(ifp, new_vrf_id);
bgp = bgp_lookup_by_vrf_id(new_vrf_id);
if (!bgp)
nexthop->v4 = local->sin.sin_addr;
if (peer->update_if)
ifp = if_lookup_by_name(peer->update_if,
- vrf_lookup_by_id(peer->bgp->vrf_id));
+ peer->bgp->vrf_id);
else
ifp = if_lookup_by_ipv4_exact(&local->sin.sin_addr,
peer->bgp->vrf_id);
ifp = if_lookup_by_name(peer->conf_if
? peer->conf_if
: peer->ifname,
- vrf_lookup_by_id(
- peer->bgp->vrf_id));
+ peer->bgp->vrf_id);
} else if (peer->update_if)
ifp = if_lookup_by_name(peer->update_if,
- vrf_lookup_by_id(peer->bgp->vrf_id));
+ peer->bgp->vrf_id);
else
ifp = if_lookup_by_ipv6_exact(&local->sin6.sin6_addr,
local->sin6.sin6_scope_id,
head = &(bgp_pbr_cfg->ifaces_by_name_ipv4);
RB_FOREACH (pbr_if, bgp_pbr_interface_head, head) {
- ifp = if_lookup_by_name(pbr_if->name,
- vrf_lookup_by_id(bgp->vrf_id));
+ ifp = if_lookup_by_name(pbr_if->name, bgp->vrf_id);
if (ifp)
stream_putl(s, ifp->ifindex);
}
head = &(bgp_pbr_cfg->ifaces_by_name_ipv4);
RB_FOREACH (pbr_if, bgp_pbr_interface_head, head) {
- if (if_lookup_by_name(pbr_if->name,
- vrf_lookup_by_id(bgp->vrf_id)))
+ if (if_lookup_by_name(pbr_if->name, bgp->vrf_id))
cnt++;
}
return cnt;
hash_release(peer->bgp->peerhash, peer);
prev_family = peer->su.sa.sa_family;
- if ((ifp = if_lookup_by_name(peer->conf_if,
- vrf_lookup_by_id(peer->bgp->vrf_id)))) {
+ if ((ifp = if_lookup_by_name(peer->conf_if, peer->bgp->vrf_id))) {
peer->ifp = ifp;
/* If BGP unnumbered is not "v6only", we first see if we can
* derive the
struct rfapi_monitor_vpn *moved;
afi_t afi;
+ if (bgp == NULL) {
+ vnc_zlog_debug_verbose(
+ "%s: NULL BGP pointer, assume shutdown race condition!!!",
+ __func__);
+ return 0;
+ }
+ if (bgp_flag_check(bgp, BGP_FLAG_DELETE_IN_PROGRESS)) {
+ vnc_zlog_debug_verbose(
+ "%s: BGP delete in progress, assume shutdown race condition!!!",
+ __func__);
+ return 0;
+ }
assert(wcb->node);
assert(bpi);
assert(wcb->import_table);
urib-only
Lookup in the Unicast Rib only.
+.. index:: ip igmp generate-query-once [version (2-3)]
+.. clicmd:: ip igmp generate-query-once [version (2-3)]
+
+ Generate IGMP query (v2/v3) on user requirement. This will not depend on
+ the existing IGMP general query timer.If no version is provided in the cli,
+ it will be considered as default v2 query.This is a hidden command.
.. _pim-interface-configuration:
cont
goto next route-map entry
+.. _route-map-show-command:
+
+.. index:: show route-map [WORD]
+.. clicmd:: show route-map [WORD]
+
+ Display data about each daemons knowledge of individual route-maps.
+ If WORD is supplied narrow choice to that particular route-map.
+
+.. _route-map-clear-counter-command:
+
+.. index:: clear route-map counter [WORD]
+.. clicmd:: clear route-map counter [WORD]
+
+ Clear counters that are being stored about the route-map utilization
+ so that subsuquent show commands will indicate since the last clear.
+ If WORD is specified clear just that particular route-map's counters.
+
.. _route-map-command:
Route Map Command
Proceed processing the route-map at the first entry whose order is >= N
+
Route Map Examples
==================
return;
}
- ifp = if_lookup_by_name(dist->ifname,
- vrf_lookup_by_id(VRF_DEFAULT));
+ ifp = if_lookup_by_name(dist->ifname, VRF_DEFAULT);
if (ifp == NULL)
return;
struct route_map *rmap;
struct eigrp *e;
- ifp = if_lookup_by_name(if_rmap->ifname, vrf_lookup_by_id(VRF_DEFAULT));
+ ifp = if_lookup_by_name(if_rmap->ifname);
if (ifp == NULL)
return;
stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
/* And look it up. */
- return if_lookup_by_name(ifname_tmp,
- vrf_lookup_by_id(VRF_DEFAULT));
+ return if_lookup_by_name(ifname_tmp, VRF_DEFAULT);
}
void eigrp_zebra_route_add(struct prefix *p, struct list *successors,
/* add callbacks to delete each of the circuits listed
*/
const char *vrf_name =
- circuit->interface->vrf->name;
+ vrf_lookup_by_id(circuit->interface->vrf_id)
+ ->name;
snprintf(
temp_xpath, XPATH_MAXLEN,
"/frr-interface:lib/interface[name='%s'][vrf='%s']/frr-isisd:isis",
vrfname = yang_dnode_get_string(dnode->parent->parent, "./vrf");
vrf = vrf_lookup_by_name(vrfname);
assert(vrf);
- ifp = if_lookup_by_name(ifname, vrf);
+ ifp = if_lookup_by_name(ifname, vrf->vrf_id);
if (!ifp)
return NB_OK;
circuit = circuit_lookup_by_ifp(ifp, isis->init_circ_list);
vrfname = yang_dnode_get_string(dnode->parent->parent, "./vrf");
vrf = vrf_lookup_by_name(vrfname);
assert(vrf);
- ifp = if_lookup_by_name(ifname, vrf);
+ ifp = if_lookup_by_name(ifname, vrf->vrf_id);
if (!ifp)
break;
circuit = circuit_lookup_by_ifp(ifp, isis->init_circ_list);
}
} else {
/* Interface name is specified. */
- ifp = if_lookup_by_name(argv[idx_interface]->arg,
- vrf_lookup_by_id(VRF_DEFAULT));
+ ifp = if_lookup_by_name(argv[idx_interface]->arg, VRF_DEFAULT);
if (ifp == NULL)
vty_out(vty, "No such interface name\n");
else {
%code requires {
#include "config.h"
+ #include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
static void
cleanup (struct parser_ctx *ctx);
+ static void loopcheck(struct parser_ctx *ctx, struct subgraph *sg);
+
#define scanner ctx->scanner
}
* just use [{a|b}] if neccessary, that will work perfectly fine, and reason
* #1 is good enough to keep it this way. */
+ loopcheck(ctx, &$$);
cmd_token_varname_set ($2.end->data, $4);
XFREE (MTYPE_LEX, $4);
};
/* parser helper functions */
+static bool loopcheck_inner(struct graph_node *start, struct graph_node *node,
+ struct graph_node *end, size_t depth)
+{
+ size_t i;
+ bool ret;
+
+ /* safety check */
+ if (depth++ == 64)
+ return true;
+
+ for (i = 0; i < vector_active(node->to); i++) {
+ struct graph_node *next = vector_slot(node->to, i);
+ struct cmd_token *tok = next->data;
+
+ if (next == end || next == start)
+ return true;
+ if (tok->type < SPECIAL_TKN)
+ continue;
+ ret = loopcheck_inner(start, next, end, depth);
+ if (ret)
+ return true;
+ }
+ return false;
+}
+
+static void loopcheck(struct parser_ctx *ctx, struct subgraph *sg)
+{
+ if (loopcheck_inner(sg->start, sg->start, sg->end, 0))
+ zlog_err("FATAL: '%s': {} contains an empty path! Use [{...}]",
+ ctx->el->string);
+}
+
void
yyerror (CMD_YYLTYPE *loc, struct parser_ctx *ctx, char const *msg)
{
}
/* Create new interface structure. */
-struct interface *if_create(const char *name, struct vrf *vrf)
+struct interface *if_create(const char *name, vrf_id_t vrf_id)
{
+ struct vrf *vrf = vrf_get(vrf_id, NULL);
struct interface *ifp;
ifp = XCALLOC(MTYPE_IF, sizeof(struct interface));
assert(name);
strlcpy(ifp->name, name, sizeof(ifp->name));
- ifp->vrf = vrf;
+ ifp->vrf_id = vrf_id;
IFNAME_RB_INSERT(vrf, ifp);
ifp->connected = list_new();
ifp->connected->del = (void (*)(void *))connected_free;
return ifp;
}
-/* Create new interface structure.
- * vrf must be created outside of this routing
- */
-void if_update_to_new_vrf(struct interface *ifp, struct vrf *vrf)
+/* Create new interface structure. */
+void if_update_to_new_vrf(struct interface *ifp, vrf_id_t vrf_id)
{
- struct vrf *old_vrf;
+ struct vrf *old_vrf, *vrf;
- if (!vrf) {
- flog_err(EC_LIB_INTERFACE, "interface %s. Unknown VRF",
- ifp->name);
- return;
- }
/* remove interface from old master vrf list */
- old_vrf = ifp->vrf;
+ old_vrf = vrf_lookup_by_id(ifp->vrf_id);
if (old_vrf) {
IFNAME_RB_REMOVE(old_vrf, ifp);
if (ifp->ifindex != IFINDEX_INTERNAL)
IFINDEX_RB_REMOVE(old_vrf, ifp);
}
- ifp->vrf = vrf;
+ ifp->vrf_id = vrf_id;
+ vrf = vrf_get(ifp->vrf_id, NULL);
IFNAME_RB_INSERT(vrf, ifp);
if (ifp->ifindex != IFINDEX_INTERNAL)
IFINDEX_RB_INSERT(vrf, ifp);
- if (!old_vrf->name)
- return;
/*
* HACK: Change the interface VRF in the running configuration directly,
* bypassing the northbound layer. This is necessary to avoid deleting
/* Delete and free interface structure. */
void if_delete(struct interface *ifp)
{
- struct vrf *vrf = ifp->vrf;
+ struct vrf *vrf;
+ vrf = vrf_lookup_by_id(ifp->vrf_id);
assert(vrf);
IFNAME_RB_REMOVE(vrf, ifp);
ifindex_t ifname2ifindex(const char *name, vrf_id_t vrf_id)
{
struct interface *ifp;
- struct vrf *vrf = vrf_lookup_by_id(vrf_id);
- return ((ifp = if_lookup_by_name(name, vrf)) != NULL)
+ return ((ifp = if_lookup_by_name(name, vrf_id)) != NULL)
? ifp->ifindex
: IFINDEX_INTERNAL;
}
/* Interface existance check by interface name. */
-struct interface *if_lookup_by_name(const char *name, struct vrf *vrf)
+struct interface *if_lookup_by_name(const char *name, vrf_id_t vrf_id)
{
+ struct vrf *vrf = vrf_lookup_by_id(vrf_id);
struct interface if_tmp;
if (!vrf || !name
return NULL;
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
- ifp = if_lookup_by_name(name, vrf);
+ ifp = if_lookup_by_name(name, vrf->vrf_id);
if (ifp)
return ifp;
}
/* Get interface by name if given name interface doesn't exist create
one. */
-struct interface *if_get_by_name(const char *name, struct vrf *vrf)
+struct interface *if_get_by_name(const char *name, vrf_id_t vrf_id)
{
struct interface *ifp;
switch (vrf_get_backend()) {
case VRF_BACKEND_UNKNOWN:
case VRF_BACKEND_NETNS:
- ifp = if_lookup_by_name(name, vrf);
+ ifp = if_lookup_by_name(name, vrf_id);
if (ifp)
return ifp;
- return if_create(name, vrf);
+ return if_create(name, vrf_id);
case VRF_BACKEND_VRF_LITE:
ifp = if_lookup_by_name_all_vrf(name);
if (ifp) {
- if (ifp->vrf == vrf)
+ if (ifp->vrf_id == vrf_id)
return ifp;
/* If it came from the kernel or by way of zclient,
* believe it and update the ifp accordingly.
*/
- if_update_to_new_vrf(ifp, vrf);
+ if_update_to_new_vrf(ifp, vrf_id);
return ifp;
}
- return if_create(name, vrf);
+ return if_create(name, vrf_id);
}
return NULL;
{
struct vrf *vrf;
- vrf = ifp->vrf;
+ vrf = vrf_lookup_by_id(ifp->vrf_id);
assert(vrf);
if (ifp->ifindex == ifindex)
zlog_info(
"Interface %s vrf %u index %d metric %d mtu %d "
"mtu6 %d %s",
- ifp->name, vrf_to_id(ifp->vrf),
- ifp->ifindex, ifp->metric,
+ ifp->name, ifp->vrf_id, ifp->ifindex, ifp->metric,
ifp->mtu, ifp->mtu6, if_flag_dump(ifp->flags));
}
* if not:
* - no idea, just get the name in its entirety.
*/
-static struct interface *if_sunwzebra_get(const char *name, struct vrf *vrf)
+static struct interface *if_sunwzebra_get(const char *name, vrf_id_t vrf_id)
{
struct interface *ifp;
char *cp;
- if ((ifp = if_lookup_by_name(name, vrf)) != NULL)
+ if ((ifp = if_lookup_by_name(name, vrf_id)) != NULL)
return ifp;
/* hunt the primary interface name... */
if (cp)
*cp = '\0';
- return if_get_by_name(name, vrf);
+ return if_get_by_name(name, vrf_id);
}
#endif /* SUNOS_5 */
p = connected->address;
snprintf(logbuf, BUFSIZ, "%s interface %s vrf %u %s %s/%d ", str,
- ifp->name, vrf_to_id(ifp->vrf),
- prefix_family_str(p),
+ ifp->name, ifp->vrf_id, prefix_family_str(p),
inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen);
p = connected->destination;
VRF_CMD_HELP_STR)
{
char xpath_list[XPATH_MAXLEN];
- struct interface *ifp = NULL;
+ vrf_id_t vrf_id;
+ struct interface *ifp;
int ret;
- struct vrf *vrf;
if (!vrfname)
vrfname = VRF_DEFAULT_NAME;
* interface is found, then a new one should be created on the default
* VRF.
*/
- VRF_GET_INSTANCE(vrf, vrfname, false, true);
- /*
- * within vrf context, vrf_id may be unknown
- * this happens on daemons relying on zebra
- * on this specific case, interface creation may
- * be forced
- */
- if (vrf && (vrf->vrf_id == VRF_UNKNOWN ||
- vrf_get_backend() == VRF_BACKEND_UNKNOWN))
- ifp = if_lookup_by_name(ifname, vrf);
- else
- ifp = if_lookup_by_name_all_vrf(ifname);
- if (ifp && ifp->vrf != vrf) {
+ VRF_GET_ID(vrf_id, vrfname, false);
+ ifp = if_lookup_by_name_all_vrf(ifname);
+ if (ifp && ifp->vrf_id != vrf_id) {
+ struct vrf *vrf;
+
/*
* Special case 1: a VRF name was specified, but the found
* interface is associated to different VRF. Reject the command.
*/
- if (vrf->vrf_id != VRF_DEFAULT) {
+ if (vrf_id != VRF_DEFAULT) {
vty_out(vty, "%% interface %s not in %s vrf\n", ifname,
vrfname);
return CMD_WARNING_CONFIG_FAILED;
* interface is associated to a VRF other than the default one.
* Update vrf_id and vrfname to account for that.
*/
- vrf = ifp->vrf;
+ vrf = vrf_lookup_by_id(ifp->vrf_id);
assert(vrf);
+ vrf_id = ifp->vrf_id;
vrfname = vrf->name;
}
* all interface-level commands are converted to the new
* northbound model.
*/
- ifp = if_lookup_by_name(ifname, vrf);
+ ifp = if_lookup_by_name(ifname, vrf_id);
if (ifp)
VTY_PUSH_CONTEXT(INTERFACE_NODE, ifp);
}
const char *ifname;
const char *vrfname;
struct vrf *vrf;
- struct interface *ifp = NULL;
+ struct interface *ifp;
ifname = yang_dnode_get_string(dnode, "./name");
vrfname = yang_dnode_get_string(dnode, "./vrf");
vrfname);
return NB_ERR_VALIDATION;
}
- if (vrf->vrf_id == VRF_UNKNOWN)
- zlog_warn("%s: VRF %s is not active. Using interface however.",
- __func__, vrf->name);
+ if (vrf->vrf_id == VRF_UNKNOWN) {
+ zlog_warn("%s: VRF %s is not active", __func__,
+ vrf->name);
+ return NB_ERR_VALIDATION;
+ }
/* if VRF is netns or not yet known - init for instance
* then assumption is that passed config is exact
*/
if (vrf_get_backend() == VRF_BACKEND_VRF_LITE) {
ifp = if_lookup_by_name_all_vrf(ifname);
- if (ifp && ifp->vrf != vrf) {
+ if (ifp && ifp->vrf_id != vrf->vrf_id) {
zlog_warn(
"%s: interface %s already exists in another VRF",
__func__, ifp->name);
vrf = vrf_lookup_by_name(vrfname);
assert(vrf);
#ifdef SUNOS_5
- ifp = if_sunwzebra_get(ifname, vrf);
+ ifp = if_sunwzebra_get(ifname, vrf->vrf_id);
#else
- ifp = if_get_by_name(ifname, vrf);
+ ifp = if_get_by_name(ifname, vrf->vrf_id);
#endif /* SUNOS_5 */
nb_running_set_entry(dnode, ifp);
break;
DECLARE_MTYPE(CONNECTED_LABEL)
-struct vrf;
-
/* Interface link-layer type, if known. Derived from:
*
* net/if_arp.h on various platforms - Linux especially.
#endif /* HAVE_NET_RT_IFLIST */
struct route_node *node;
- struct vrf *vrf;
+ vrf_id_t vrf_id;
QOBJ_FIELDS
};
RB_PROTOTYPE(if_index_head, interface, index_entry, if_cmp_func)
DECLARE_QOBJ_TYPE(interface)
-#define IFNAME_RB_INSERT(_vrf, _ifp) \
- if (RB_INSERT(if_name_head, &(_vrf)->ifaces_by_name, (_ifp))) \
+#define IFNAME_RB_INSERT(vrf, ifp) \
+ if (RB_INSERT(if_name_head, &vrf->ifaces_by_name, (ifp))) \
flog_err(EC_LIB_INTERFACE, \
"%s(%s): corruption detected -- interface with this " \
"name exists already in VRF %u!", \
- __func__, (_ifp)->name, (_ifp)->vrf ? \
- (_ifp)->vrf->vrf_id : VRF_UNKNOWN);
+ __func__, (ifp)->name, (ifp)->vrf_id);
-#define IFNAME_RB_REMOVE(_vrf, _ifp) \
- if (RB_REMOVE(if_name_head, &(_vrf)->ifaces_by_name, (_ifp)) == NULL) \
+#define IFNAME_RB_REMOVE(vrf, ifp) \
+ if (RB_REMOVE(if_name_head, &vrf->ifaces_by_name, (ifp)) == NULL) \
flog_err(EC_LIB_INTERFACE, \
"%s(%s): corruption detected -- interface with this " \
"name doesn't exist in VRF %u!", \
- __func__, (_ifp)->name, (_ifp)->vrf ? \
- (_ifp)->vrf->vrf_id : VRF_UNKNOWN);
+ __func__, (ifp)->name, (ifp)->vrf_id);
-#define IFINDEX_RB_INSERT(_vrf, _ifp) \
- if (RB_INSERT(if_index_head, &(_vrf)->ifaces_by_index, (_ifp))) \
+#define IFINDEX_RB_INSERT(vrf, ifp) \
+ if (RB_INSERT(if_index_head, &vrf->ifaces_by_index, (ifp))) \
flog_err(EC_LIB_INTERFACE, \
"%s(%u): corruption detected -- interface with this " \
"ifindex exists already in VRF %u!", \
- __func__, (_ifp)->ifindex, (_ifp)->vrf ? \
- (_ifp)->vrf->vrf_id : VRF_UNKNOWN);
+ __func__, (ifp)->ifindex, (ifp)->vrf_id);
-#define IFINDEX_RB_REMOVE(_vrf, _ifp) \
- if (RB_REMOVE(if_index_head, &(_vrf)->ifaces_by_index, (_ifp)) == NULL)\
+#define IFINDEX_RB_REMOVE(vrf, ifp) \
+ if (RB_REMOVE(if_index_head, &vrf->ifaces_by_index, (ifp)) == NULL) \
flog_err(EC_LIB_INTERFACE, \
"%s(%u): corruption detected -- interface with this " \
"ifindex doesn't exist in VRF %u!", \
- __func__, (_ifp)->ifindex, (_ifp)->vrf ? \
- (_ifp)->vrf->vrf_id : VRF_UNKNOWN);
+ __func__, (ifp)->ifindex, (ifp)->vrf_id);
#define FOR_ALL_INTERFACES(vrf, ifp) \
if (vrf) \
* This is useful for vrf route-leaking. So more than anything
* else think before you use VRF_UNKNOWN
*/
-extern void if_update_to_new_vrf(struct interface *, struct vrf *vrf);
-extern struct interface *if_create(const char *name, struct vrf *vrf);
+extern void if_update_to_new_vrf(struct interface *, vrf_id_t vrf_id);
+extern struct interface *if_create(const char *name, vrf_id_t vrf_id);
extern struct interface *if_lookup_by_index(ifindex_t, vrf_id_t vrf_id);
extern struct interface *if_lookup_exact_address(void *matchaddr, int family,
vrf_id_t vrf_id);
/* These 3 functions are to be used when the ifname argument is terminated
by a '\0' character: */
extern struct interface *if_lookup_by_name_all_vrf(const char *ifname);
-extern struct interface *if_lookup_by_name(const char *ifname, struct vrf *vrf);
-extern struct interface *if_get_by_name(const char *ifname, struct vrf *vrf);
+extern struct interface *if_lookup_by_name(const char *ifname, vrf_id_t vrf_id);
+extern struct interface *if_get_by_name(const char *ifname, vrf_id_t vrf_id);
extern void if_set_index(struct interface *ifp, ifindex_t ifindex);
/* Delete the interface, but do not free the structure, and leave it in the
struct route_map_rule *rule;
vty_out(vty, "route-map: %s Invoked: %" PRIu64 "\n",
- map->name, map->applied);
+ map->name, map->applied - map->applied_clear);
for (index = map->head; index; index = index->next) {
vty_out(vty, " %s, sequence %d Invoked %" PRIu64 "\n",
route_map_type_str(index->type), index->pref,
- index->applied);
+ index->applied - index->applied_clear);
/* Description */
if (index->description)
return no_rmap_onmatch_goto(self, vty, argc, argv);
}
+static void clear_route_map_helper(struct route_map *map)
+{
+ struct route_map_index *index;
+
+ map->applied_clear = map->applied;
+ for (index = map->head; index; index = index->next)
+ index->applied_clear = index->applied;
+}
+
+DEFUN (rmap_clear_counters,
+ rmap_clear_counters_cmd,
+ "clear route-map counters [WORD]",
+ CLEAR_STR
+ "route-map information\n"
+ "counters associated with the specified route-map\n"
+ "route-map name\n")
+{
+ int idx_word = 2;
+ struct route_map *map;
+
+ const char *name = (argc == 3 ) ? argv[idx_word]->arg : NULL;
+
+ if (name) {
+ map = route_map_lookup_by_name(name);
+
+ if (map)
+ clear_route_map_helper(map);
+ else {
+ vty_out(vty, "%s: 'route-map %s' not found\n",
+ frr_protonameinst, name);
+ return CMD_SUCCESS;
+ }
+ } else {
+ for (map = route_map_master.head; map; map = map->next)
+ clear_route_map_helper(map);
+ }
+
+ return CMD_SUCCESS;
+
+}
DEFUN (rmap_show_name,
rmap_show_name_cmd,
struct route_map_rule *rule;
int first = 1;
int write = 0;
+ struct listnode *ln;
+ struct list *maplist = list_new();
for (map = route_map_master.head; map; map = map->next)
+ listnode_add(maplist, map);
+
+ list_sort(maplist, sort_route_map);
+
+ for (ALL_LIST_ELEMENTS_RO(maplist, ln, map))
for (index = map->head; index; index = index->next) {
if (!first)
vty_out(vty, "!\n");
write++;
}
+
+ list_delete(&maplist);
return write;
}
install_element(RMAP_NODE, &no_rmap_description_cmd);
/* Install show command */
+ install_element(ENABLE_NODE, &rmap_clear_counters_cmd);
+
install_element(ENABLE_NODE, &rmap_show_name_cmd);
install_element(ENABLE_NODE, &rmap_show_unused_cmd);
/* Keep track how many times we've try to apply */
uint64_t applied;
+ uint64_t applied_clear;
QOBJ_FIELDS
};
/* How many times have we applied this route-map */
uint64_t applied;
+ uint64_t applied_clear;
/* Counter to track active usage of this route-map */
uint16_t use_count;
name, vrf_id, vrf->vrf_id);
return NULL;
}
- /* look for duplicates. case is followine one:
- * - a vrf is configured per name -> vrfA
- * - netlink discovery creates a vrf with vrf_id ->vrfB
- * - then, netlink discovers vrf, and associated vrf_id and name
- * -> so vrfA and vrfB must be merged
- */
- if (vrf && vrf_id != VRF_UNKNOWN
- && vrf->vrf_id == VRF_UNKNOWN) {
- struct vrf *vrf2 = vrf_lookup_by_id(vrf_id);
- struct interface *ifp;
-
- if (vrf2 && !vrf2->name && vrf2 != vrf) {
- /* move vrf2 context to vrf */
- FOR_ALL_INTERFACES (vrf2, ifp)
- if_update_to_new_vrf(ifp, vrf);
- vrf_delete(vrf2);
- }
- }
/* Try to find VRF both by ID and name */
if (!vrf && vrf_id != VRF_UNKNOWN)
vrf = vrf_lookup_by_id(vrf_id);
{
int ret = 0;
struct interface *ifp;
- struct vrf *vrf = vrf_lookup_by_id(vrf_id);
- if (fd < 0 || name == NULL || !vrf)
+ if (fd < 0 || name == NULL)
return fd;
/* the device should exist
* otherwise we should return
* case ifname = vrf in netns mode => return
*/
- ifp = if_lookup_by_name(name, vrf);
+ ifp = if_lookup_by_name(name, vrf_id);
if (!ifp)
return fd;
#ifdef SO_BINDTODEVICE
return ++vrf_id_local;
}
-
-vrf_id_t vrf_to_id(struct vrf *vrf)
-{
- return vrf ? vrf->vrf_id : VRF_UNKNOWN;
-}
-
-const char *vrf_to_name(struct vrf *vrf)
-{
- return vrf ? vrf->name : "NIL";
-}
extern struct vrf *vrf_get(vrf_id_t, const char *);
extern const char *vrf_id_to_name(vrf_id_t vrf_id);
extern vrf_id_t vrf_name_to_id(const char *);
-extern vrf_id_t vrf_to_id(struct vrf *vrf);
-extern const char *vrf_to_name(struct vrf *vrf);
-
-/* vrf context is searched and created
- */
-#define VRF_GET_INSTANCE(V, NAME, USE_JSON, FORCE_CREATION) \
- do { \
- struct vrf *_vrf; \
- \
- if (!(_vrf = vrf_lookup_by_name(NAME))) { \
- if (!FORCE_CREATION) { \
- if (USE_JSON) { \
- vty_out(vty, "{}\n"); \
- } else { \
- vty_out(vty, "%% VRF %s not found\n", \
- NAME); \
- } \
- return CMD_WARNING; \
- } \
- _vrf = vrf_get(VRF_UNKNOWN, NAME); \
- } \
- if (_vrf->vrf_id == VRF_UNKNOWN) { \
- if (USE_JSON) { \
- vty_out(vty, "{}\n"); \
- } else { \
- vty_out(vty, "%% VRF %s not active\n", NAME); \
- } \
- } \
- (V) = _vrf; \
- } while (0)
#define VRF_GET_ID(V, NAME, USE_JSON) \
do { \
int vty_sock = THREAD_FD(thread);
struct vty *vty = THREAD_ARG(thread);
- vty->t_read = NULL;
/* Read raw data from socket */
if ((nbytes = read(vty->fd, buf, VTY_READ_BUFSIZ)) <= 0) {
int vty_sock = THREAD_FD(thread);
struct vty *vty = THREAD_ARG(thread);
- vty->t_write = NULL;
-
/* Tempolary disable read thread. */
- if ((vty->lines == 0) && vty->t_read) {
- thread_cancel(vty->t_read);
- vty->t_read = NULL;
- }
+ if (vty->lines == 0)
+ THREAD_OFF(vty->t_read);
/* Function execution continue. */
erase = ((vty->status == VTY_MORE || vty->status == VTY_MORELINE));
if (!stdio_vty)
return;
- if (stdio_vty->t_write)
- thread_cancel(stdio_vty->t_write);
- if (stdio_vty->t_read)
- thread_cancel(stdio_vty->t_read);
- if (stdio_vty->t_timeout)
- thread_cancel(stdio_vty->t_timeout);
+ THREAD_OFF(stdio_vty->t_write);
+ THREAD_OFF(stdio_vty->t_read);
+ THREAD_OFF(stdio_vty->t_timeout);
if (stdio_termios)
tcsetattr(0, TCSANOW, &stdio_orig_termios);
sock = THREAD_FD(thread);
vty = THREAD_ARG(thread);
- vty->t_read = NULL;
if ((nbytes = read(sock, buf, VTY_READ_BUFSIZ)) <= 0) {
if (nbytes < 0) {
{
struct vty *vty = THREAD_ARG(thread);
- vty->t_write = NULL;
vtysh_flush(vty);
return 0;
}
bool was_stdio = false;
/* Cancel threads.*/
- if (vty->t_read)
- thread_cancel(vty->t_read);
- if (vty->t_write)
- thread_cancel(vty->t_write);
- if (vty->t_timeout)
- thread_cancel(vty->t_timeout);
+ THREAD_OFF(vty->t_read);
+ THREAD_OFF(vty->t_write);
+ THREAD_OFF(vty->t_timeout);
/* Flush buffer. */
buffer_flush_all(vty->obuf, vty->wfd);
struct vty *vty;
vty = THREAD_ARG(thread);
- vty->t_timeout = NULL;
vty->v_timeout = 0;
/* Clear buffer*/
vector_set_index(Vvty_serv_thread, sock, vty_serv_thread);
break;
case VTYSH_READ:
- vty->t_read = NULL;
thread_add_read(vty_master, vtysh_read, vty, sock,
&vty->t_read);
break;
case VTYSH_WRITE:
- vty->t_write = NULL;
thread_add_write(vty_master, vtysh_write, vty, sock,
&vty->t_write);
break;
#endif /* VTYSH */
case VTY_READ:
- vty->t_read = NULL;
thread_add_read(vty_master, vty_read, vty, sock, &vty->t_read);
/* Time out treatment. */
if (vty->v_timeout) {
- if (vty->t_timeout)
- thread_cancel(vty->t_timeout);
- vty->t_timeout = NULL;
+ THREAD_OFF(vty->t_timeout);
thread_add_timer(vty_master, vty_timeout, vty,
vty->v_timeout, &vty->t_timeout);
}
&vty->t_write);
break;
case VTY_TIMEOUT_RESET:
- if (vty->t_timeout) {
- thread_cancel(vty->t_timeout);
- vty->t_timeout = NULL;
- }
- if (vty->v_timeout) {
- vty->t_timeout = NULL;
+ THREAD_OFF(vty->t_timeout);
+ if (vty->v_timeout)
thread_add_timer(vty_master, vty_timeout, vty,
vty->v_timeout, &vty->t_timeout);
- }
break;
}
}
for (i = 0; i < vector_active(Vvty_serv_thread); i++)
if ((vty_serv_thread = vector_slot(Vvty_serv_thread, i))
!= NULL) {
- thread_cancel(vty_serv_thread);
+ THREAD_OFF(vty_serv_thread);
vector_slot(Vvty_serv_thread, i) = NULL;
close(i);
}
{
struct interface *ifp;
char ifname_tmp[INTERFACE_NAMSIZ];
- struct vrf *vrf = vrf_lookup_by_id(vrf_id);
/* Read interface name. */
stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
/* Lookup/create interface by name. */
- ifp = if_get_by_name(ifname_tmp, vrf);
-
- /* update vrf_id of interface */
- if (ifp->vrf->vrf_id == VRF_UNKNOWN &&
- vrf->vrf_id != VRF_UNKNOWN)
- ifp->vrf = vrf;
+ ifp = if_get_by_name(ifname_tmp, vrf_id);
zebra_interface_if_set_value(s, ifp);
stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
/* Lookup this by interface index. */
- ifp = if_lookup_by_name(ifname_tmp,
- vrf_lookup_by_id(vrf_id));
+ ifp = if_lookup_by_name(ifname_tmp, vrf_id);
if (ifp == NULL) {
flog_err(EC_LIB_ZAPI_ENCODE,
"INTERFACE_STATE: Cannot find IF %s in VRF %d",
ifindex = stream_getl(s);
- struct interface *ifp = if_lookup_by_index(ifindex,
- vrf_id);
+ struct interface *ifp = if_lookup_by_index(ifindex, vrf_id);
if (ifp == NULL) {
flog_err(EC_LIB_ZAPI_ENCODE,
stream_get(ifname, s, INTERFACE_NAMSIZ);
/* Lookup interface. */
- ifp = if_lookup_by_name(ifname,
- vrf_lookup_by_id(vrf_id));
+ ifp = if_lookup_by_name(ifname, vrf_id);
if (ifp == NULL) {
flog_err(EC_LIB_ZAPI_ENCODE,
"INTERFACE_VRF_UPDATE: Cannot find IF %s in VRF %d",
s = client->obuf;
stream_reset(s);
- zclient_create_header(s, ZEBRA_INTERFACE_SET_MASTER,
- vrf_to_id(master->vrf));
+ zclient_create_header(s, ZEBRA_INTERFACE_SET_MASTER, master->vrf_id);
- stream_putl(s, vrf_to_id(master->vrf));
+ stream_putl(s, master->vrf_id);
stream_putl(s, master->ifindex);
- stream_putl(s, vrf_to_id(slave->vrf));
+ stream_putl(s, slave->vrf_id);
stream_putl(s, slave->ifindex);
stream_putw_at(s, 0, stream_get_endp(s));
sockunion_family(&nbma) = AF_UNSPEC;
if (nifp->source)
- nbmaifp = if_lookup_by_name(nifp->source,
- vrf_lookup_by_id(VRF_DEFAULT));
+ nbmaifp = if_lookup_by_name(nifp->source, VRF_DEFAULT);
switch (ifp->ll_type) {
case ZEBRA_LLT_IPGRE: {
if (type == RMAP_OSPF6) {
ei = ((struct ospf6_route *)object)->route_option;
- ifp = if_lookup_by_name((char *)rule,
- vrf_lookup_by_id(VRF_DEFAULT));
+ ifp = if_lookup_by_name((char *)rule, VRF_DEFAULT);
if (ifp != NULL && ei->ifindex == ifp->ifindex)
return RMAP_MATCH;
struct interface *ifp;
if (argc == 5) {
- ifp = if_lookup_by_name(argv[idx_ifname]->arg,
- vrf_lookup_by_id(VRF_DEFAULT));
+ ifp = if_lookup_by_name(argv[idx_ifname]->arg, VRF_DEFAULT);
if (ifp == NULL) {
vty_out(vty, "No such Interface: %s\n",
argv[idx_ifname]->arg);
if (argv_find(argv, argc, "IFNAME", &idx_ifname)) {
intf_name = argv[idx_ifname]->arg;
- ifp = if_lookup_by_name(intf_name,
- vrf_lookup_by_id(VRF_DEFAULT));
+ ifp = if_lookup_by_name(intf_name, VRF_DEFAULT);
if (ifp == NULL) {
vty_out(vty, "No such Interface: %s\n", intf_name);
return CMD_WARNING;
struct interface *ifp;
struct ospf6_interface *oi;
- ifp = if_lookup_by_name(argv[idx_ifname]->arg,
- vrf_lookup_by_id(VRF_DEFAULT));
+ ifp = if_lookup_by_name(argv[idx_ifname]->arg, VRF_DEFAULT);
if (ifp == NULL) {
vty_out(vty, "No such Interface: %s\n", argv[idx_ifname]->arg);
return CMD_WARNING;
} else /* Interface name is specified. */
{
if ((ifp = if_lookup_by_name(argv[idx_ifname]->arg,
- vrf_lookup_by_id(VRF_DEFAULT)))
+ VRF_DEFAULT))
== NULL) {
vty_out(vty, "No such Interface: %s\n",
argv[idx_ifname]->arg);
struct ospf6_interface *oi;
struct interface *ifp;
uint32_t area_id;
- struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
/* find/create ospf6 interface */
- ifp = if_get_by_name(argv[idx_ifname]->arg, vrf);
+ ifp = if_get_by_name(argv[idx_ifname]->arg, VRF_DEFAULT);
oi = (struct ospf6_interface *)ifp->info;
if (oi == NULL)
oi = ospf6_interface_create(ifp);
struct interface *ifp;
uint32_t area_id;
- ifp = if_lookup_by_name(argv[idx_ifname]->arg,
- vrf_lookup_by_id(VRF_DEFAULT));
+ ifp = if_lookup_by_name(argv[idx_ifname]->arg, VRF_DEFAULT);
if (ifp == NULL) {
vty_out(vty, "No such interface %s\n", argv[idx_ifname]->arg);
return CMD_SUCCESS;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("%s: ospf interface %s vrf %s id %u deleted",
__PRETTY_FUNCTION__, oi->ifp->name,
- vrf_to_name(oi->ifp->vrf),
- vrf_to_id(oi->ifp->vrf));
+ ospf_vrf_id_to_name(oi->ifp->vrf_id),
+ oi->ifp->vrf_id);
ospf_delete_from_if(oi->ifp, oi);
struct in_addr area_id;
struct connected *co;
struct prefix_ipv4 *p;
- struct vrf *vrf;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_vl_new(): Start");
ospf->vrf_id);
snprintf(ifname, sizeof(ifname), "VLINK%u", vlink_count);
- vrf = vrf_lookup_by_id(ospf->vrf_id);
- vi = if_create(ifname, vrf);
+ vi = if_create(ifname, ospf->vrf_id);
/*
* if_create sets ZEBRA_INTERFACE_LINKDETECTION
* virtual links don't need this.
if (idx_interface) {
ifp = if_lookup_by_name(
argv[idx_interface]->arg,
- vrf_lookup_by_id(ospf->vrf_id));
+ ospf->vrf_id);
if (ifp == NULL) {
vty_out(vty, "No such interface name in vrf %s\n",
vrf->name);
int ret;
struct ospf_if_params *params;
struct route_node *rn;
- struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id);
if (strmatch(argv[1]->text, "default")) {
ospf_passive_interface_default(ospf, OSPF_IF_PASSIVE);
return CMD_SUCCESS;
}
if (ospf->vrf_id != VRF_UNKNOWN)
- ifp = if_get_by_name(argv[1]->arg, vrf);
+ 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);
struct ospf_if_params *params;
int ret;
struct route_node *rn;
- struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id);
if (strmatch(argv[2]->text, "default")) {
ospf_passive_interface_default(ospf, OSPF_IF_ACTIVE);
}
if (ospf->vrf_id != VRF_UNKNOWN)
- ifp = if_get_by_name(argv[2]->arg, vrf);
+ ifp = if_get_by_name(argv[2]->arg, ospf->vrf_id);
if (ifp == NULL) {
vty_out(vty, "interface %s not found.\n", (char *)argv[2]->arg);
json_interface);
} else {
/* Interface name is specified. */
- ifp = if_lookup_by_name(intf_name,
- vrf_lookup_by_id(ospf->vrf_id));
+ ifp = if_lookup_by_name(intf_name, ospf->vrf_id);
if (ifp == NULL) {
if (use_json)
json_object_boolean_true_add(json_vrf,
}
} else {
/* Interface name is specified. */
- ifp = if_lookup_by_name(intf_name,
- vrf_lookup_by_id(ospf->vrf_id));
+ ifp = if_lookup_by_name(intf_name, ospf->vrf_id);
if (ifp != NULL) {
struct route_node *rn;
struct ospf_interface *oi;
ospf_show_vrf_name(ospf, vty, json, use_vrf);
- ifp = if_lookup_by_name(argv[arg_base]->arg,
- vrf_lookup_by_id(ospf->vrf_id));
+ ifp = if_lookup_by_name(argv[arg_base]->arg, ospf->vrf_id);
if (!ifp) {
if (use_json)
json_object_boolean_true_add(json, "noSuchIface");
argv_find(argv, argc, "IFNAME", &idx_ifname);
- ifp = if_lookup_by_name(argv[idx_ifname]->arg,
- vrf_lookup_by_id(vrf_id));
+ ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id);
if (!ifp)
return ret;
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
}
- ifp = if_lookup_by_name(argv[arg_base]->arg,
- vrf_lookup_by_id(ospf->vrf_id));
+ ifp = if_lookup_by_name(argv[arg_base]->arg, ospf->vrf_id);
if (!ifp) {
if (!use_json)
vty_out(vty, "No such interface.\n");
if (nbr_str) {
struct ospf *ospf = NULL;
- ospf = ospf_lookup_by_vrf(ifp->vrf);
+ ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
if (ospf) {
oi = ospf_if_lookup_by_local_addr(ospf, ifp, addr);
if (oi)
if (argc == 1) {
struct ospf *ospf = NULL;
- ospf = ospf_lookup_by_vrf(ifp->vrf);
+ ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
if (ospf) {
oi = ospf_if_lookup_by_local_addr(ospf, ifp, addr);
if (oi)
argv_find(argv, argc, "area", &idx);
areaid = argv[idx + 1]->arg;
- if (ifp->vrf && ifp->vrf->vrf_id && !instance)
- ospf = ospf_lookup_by_vrf(ifp->vrf);
+ if (ifp->vrf_id && !instance)
+ ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
else
ospf = ospf_lookup_instance(instance);
if (argv_find(argv, argc, "(1-65535)", &idx))
instance = strtol(argv[idx]->arg, NULL, 10);
- if (ifp->vrf && ifp->vrf->vrf_id && !instance)
- ospf = ospf_lookup_by_vrf(ifp->vrf);
+ if (ifp->vrf_id && !instance)
+ ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
else
ospf = ospf_lookup_instance(instance);
continue;
vty_frame(vty, "!\n");
- if (ifp->vrf->vrf_id == VRF_DEFAULT)
+ if (ifp->vrf_id == VRF_DEFAULT)
vty_frame(vty, "interface %s\n", ifp->name);
else
vty_frame(vty, "interface %s vrf %s\n", ifp->name,
}
} else {
/* Interface name is specified. */
- ifp = if_lookup_by_name(argv[idx_ifname]->arg,
- vrf_lookup_by_id(vrf_id));
+ ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id);
if (ifp == NULL)
vty_out(vty, "No such interface name\n");
else
if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
zlog_debug(
"Zebra: interface add %s vrf %s[%u] index %d flags %llx metric %d mtu %d speed %u",
- ifp->name, vrf_to_name(ifp->vrf),
- vrf_to_id(ifp->vrf), ifp->ifindex,
+ ifp->name, ospf_vrf_id_to_name(ifp->vrf_id),
+ ifp->vrf_id, ifp->ifindex,
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu,
ifp->speed);
if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
zlog_debug(
"Zebra: interface delete %s vrf %s[%u] index %d flags %llx metric %d mtu %d",
- ifp->name, vrf_to_name(ifp->vrf),
- vrf_to_id(ifp->vrf), ifp->ifindex,
+ 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);
stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
/* And look it up. */
- return if_lookup_by_name(ifname_tmp,
- vrf_lookup_by_id(vrf_id));
+ return if_lookup_by_name(ifname_tmp, vrf_id);
}
static int ospf_interface_state_up(ZAPI_CALLBACK_ARGS)
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, vrf_lookup_by_id(new_vrf_id));
+ if_update_to_new_vrf(ifp, new_vrf_id);
return 0;
}
vrf = vrf_lookup_by_id(vrf_id);
if (!vrf)
return NULL;
- return ospf_lookup_by_vrf(vrf);
-}
-
-struct ospf *ospf_lookup_by_vrf(struct vrf *vrf)
-{
return (vrf->info) ? (struct ospf *)vrf->info : NULL;
}
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
- "%s: interface %s ifp->vrf->vrf_id %u ospf vrf %s vrf_id %u router_id %s",
- __PRETTY_FUNCTION__, ifp->name, vrf_to_id(ifp->vrf),
+ "%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));
extern struct ospf *ospf_lookup_by_inst_name(unsigned short instance,
const char *name);
extern struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id);
-extern struct ospf *ospf_lookup_by_vrf(struct vrf *vrf);
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,
sg.src = source_addr;
sg.grp = group_addr;
ch = pim_ifchannel_add(ifp, &sg, 0, 0);
- if (!ch) {
- zlog_warn(
- "%s: (S,G)=%s failure creating channel on interface %s",
- __PRETTY_FUNCTION__, pim_str_sg_dump(&sg), ifp->name);
- return -1;
- }
switch (ch->ifassert_state) {
case PIM_IFASSERT_NOINFO:
}
bsgrp = XCALLOC(MTYPE_PIM_BSGRP_NODE, sizeof(struct bsgrp_node));
- if (!bsgrp) {
- if (PIM_DEBUG_BSM)
- zlog_debug("%s: bsgrp alloc failed",
- __PRETTY_FUNCTION__);
- route_unlock_node(rn);
- return NULL;
- }
-
rn->info = bsgrp;
bsgrp->bsrp_list = pim_alloc_bsrp_list();
bsgrp->partial_bsrp_list = pim_alloc_bsrp_list();
pak_start = XCALLOC(MTYPE_PIM_BSM_PKT_VAR_MEM, pim_mtu);
- if (!pak_start) {
- if (PIM_DEBUG_BSM)
- zlog_debug("%s: malloc failed", __PRETTY_FUNCTION__);
- return false;
- }
-
pkt = pak_start;
/* Fill PIM header later before sending packet to calc checksum */
/*memory allocation for bsm_rpinfo */
bsm_rpinfo = XCALLOC(MTYPE_PIM_BSRP_NODE, sizeof(*bsm_rpinfo));
- if (!bsm_rpinfo) {
- if (PIM_DEBUG_BSM)
- zlog_debug("%s, Memory allocation failed.\r\n",
- __PRETTY_FUNCTION__);
- return false;
- }
-
bsm_rpinfo->rp_prio = rp->rp_pri;
bsm_rpinfo->rp_holdtime = rp->rp_holdtime;
memcpy(&bsm_rpinfo->rp_address, &rp->rpaddr.addr,
if (!no_fwd) {
pim_bsm_fwd_whole_sz(pim_ifp->pim, buf, buf_size, sz);
bsminfo = XCALLOC(MTYPE_PIM_BSM_INFO, sizeof(struct bsm_info));
- if (!bsminfo) {
- zlog_warn("%s: bsminfo alloc failed",
- __PRETTY_FUNCTION__);
- return 0;
- }
bsminfo->bsm = XCALLOC(MTYPE_PIM_BSM_PKT_VAR_MEM, buf_size);
- if (!bsminfo->bsm) {
- zlog_warn("%s: bsm alloc failed", __PRETTY_FUNCTION__);
- XFREE(MTYPE_PIM_BSM_INFO, bsminfo);
- return 0;
- }
bsminfo->size = buf_size;
memcpy(bsminfo->bsm, buf, buf_size);
pim_ifp = ifp->info;
if (!pim_ifp) {
- pim_ifp = pim_if_new(ifp, true, false, false,
- false /*vxlan_term*/);
- if (!pim_ifp) {
- vty_out(vty, "Could not enable IGMP on interface %s\n",
- ifp->name);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ (void)pim_if_new(ifp, true, false, false, false);
need_startup = 1;
} else {
if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
return CMD_SUCCESS;
}
+DEFPY_HIDDEN (interface_ip_igmp_query_generate,
+ interface_ip_igmp_query_generate_cmd,
+ "ip igmp generate-query-once [version (2-3)]",
+ IP_STR
+ IFACE_IGMP_STR
+ "Generate igmp general query once\n"
+ "IGMP version\n"
+ "IGMP version number\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ int igmp_version = 2;
+
+ if (!ifp->info) {
+ vty_out(vty, "IGMP/PIM is not enabled on the interface %s\n",
+ ifp->name);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ if (argc > 3)
+ igmp_version = atoi(argv[4]->arg);
+
+ igmp_send_query_on_intf(ifp, igmp_version);
+
+ return CMD_SUCCESS;
+}
+
static int pim_cmd_interface_add(struct interface *ifp)
{
struct pim_interface *pim_ifp = ifp->info;
- if (!pim_ifp) {
- pim_ifp = pim_if_new(ifp, false, true, false,
- false /*vxlan_term*/);
- if (!pim_ifp) {
- return 0;
- }
- } else {
+ if (!pim_ifp)
+ (void)pim_if_new(ifp, false, true, false, false);
+ else
PIM_IF_DO_PIM(pim_ifp->options);
- }
pim_if_addr_add_all(ifp);
pim_if_membership_refresh(ifp);
pim = pim_ifp->pim;
oifname = argv[idx_interface]->arg;
- oif = if_lookup_by_name(oifname, pim->vrf);
+ oif = if_lookup_by_name(oifname, pim->vrf_id);
if (!oif) {
vty_out(vty, "No such interface name %s\n", oifname);
return CMD_WARNING;
pim = pim_ifp->pim;
oifname = argv[idx_interface]->arg;
- oif = if_lookup_by_name(oifname, pim->vrf);
+ oif = if_lookup_by_name(oifname, pim->vrf_id);
if (!oif) {
vty_out(vty, "No such interface name %s\n", oifname);
return CMD_WARNING;
pim = pim_ifp->pim;
oifname = argv[idx_interface]->arg;
- oif = if_lookup_by_name(oifname, pim->vrf);
+ oif = if_lookup_by_name(oifname, pim->vrf_id);
if (!oif) {
vty_out(vty, "No such interface name %s\n", oifname);
return CMD_WARNING;
pim = pim_ifp->pim;
oifname = argv[idx_interface]->arg;
- oif = if_lookup_by_name(oifname, pim->vrf);
+ oif = if_lookup_by_name(oifname, pim->vrf_id);
if (!oif) {
vty_out(vty, "No such interface name %s\n", oifname);
return CMD_WARNING;
idx = 3;
peerlink = argv[idx]->arg;
- ifp = if_lookup_by_name(peerlink, vrf_lookup_by_id(VRF_DEFAULT));
+ ifp = if_lookup_by_name(peerlink, VRF_DEFAULT);
if (!ifp) {
vty_out(vty, "No such interface name %s\n", peerlink);
return CMD_WARNING;
install_element(INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
install_element(INTERFACE_NODE, &interface_ip_pim_boundary_oil_cmd);
install_element(INTERFACE_NODE, &interface_no_ip_pim_boundary_oil_cmd);
+ install_element(INTERFACE_NODE, &interface_ip_igmp_query_generate_cmd);
// Static mroutes NEB
install_element(INTERFACE_NODE, &interface_ip_mroute_cmd);
pim_ifp = XCALLOC(MTYPE_PIM_INTERFACE, sizeof(*pim_ifp));
pim_ifp->options = 0;
- pim_ifp->pim = pim_get_pim_instance(vrf_to_id(ifp->vrf));
+ pim_ifp->pim = pim_get_pim_instance(ifp->vrf_id);
pim_ifp->mroute_vif_index = -1;
pim_ifp->igmp_version = IGMP_DEFAULT_VERSION;
struct connected *ifc;
struct listnode *node;
struct listnode *nextnode;
- struct vrf *vrf = ifp->vrf;
+ struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id);
struct pim_instance *pim;
if (!vrf)
int v4_addrs = 0;
int v6_addrs = 0;
struct pim_interface *pim_ifp = ifp->info;
- struct vrf *vrf = ifp->vrf;
+ struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id);
if (!vrf)
return addr;
if (!v4_addrs && v6_addrs && !if_is_loopback(ifp)) {
struct interface *lo_ifp;
// DBS - Come back and check here
- if (!ifp->vrf || ifp->vrf->vrf_id == VRF_DEFAULT)
- lo_ifp = if_lookup_by_name("lo", vrf);
+ if (ifp->vrf_id == VRF_DEFAULT)
+ lo_ifp = if_lookup_by_name("lo", vrf->vrf_id);
else
- lo_ifp = if_lookup_by_name(vrf->name, vrf);
+ lo_ifp = if_lookup_by_name(vrf->name, vrf->vrf_id);
if (lo_ifp)
return pim_find_primary_addr(lo_ifp);
return ferr_ok();
}
- ij = igmp_join_new(ifp, group_addr, source_addr);
- if (!ij) {
- return ferr_cfg_invalid(
- "Failure to create new join data structure, see log file for more information");
- }
+ (void)igmp_join_new(ifp, group_addr, source_addr);
if (PIM_DEBUG_IGMP_EVENTS) {
char group_str[INET_ADDRSTRLEN];
snprintf(pimreg_name, sizeof(pimreg_name), "pimreg%u",
pim->vrf->data.l.table_id);
- pim->regiface = if_create(pimreg_name, pim->vrf);
+ pim->regiface = if_create(pimreg_name, pim->vrf_id);
pim->regiface->ifindex = PIM_OIF_PIM_REGISTER_VIF;
pim_if_new(pim->regiface, false, false, true,
if (ch->upstream->channel_oil) {
uint32_t mask = PIM_OIF_FLAG_PROTO_PIM;
if (ch->upstream->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
- mask = PIM_OIF_FLAG_PROTO_IGMP;
+ mask |= PIM_OIF_FLAG_PROTO_IGMP;
/*
* A S,G RPT channel can have an empty oil, we also
* being inherited. So let's figure out what
* needs to be done here
*/
- if (pim_upstream_evaluate_join_desired_interface(
- ch->upstream, ch, ch->parent))
+ if ((ch->sg.src.s_addr != INADDR_ANY) &&
+ pim_upstream_evaluate_join_desired_interface(
+ ch->upstream, ch, ch->parent))
pim_channel_add_oif(ch->upstream->channel_oil,
- ch->interface, mask);
- else
- pim_channel_del_oif(ch->upstream->channel_oil,
- ch->interface, mask);
+ ch->interface,
+ PIM_OIF_FLAG_PROTO_STAR);
+
+ pim_channel_del_oif(ch->upstream->channel_oil,
+ ch->interface, mask);
/*
* Do we have any S,G's that are inheriting?
* Nuke from on high too.
while (!RB_EMPTY(pim_ifchannel_rb, &pim_ifp->ifchannel_rb)) {
ch = RB_ROOT(pim_ifchannel_rb, &pim_ifp->ifchannel_rb);
+ pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__,
+ ch, PIM_IFJOIN_NOINFO);
pim_ifchannel_delete(ch);
}
}
ch = pim_ifchannel_add(ifp, sg, source_flags,
PIM_UPSTREAM_FLAG_MASK_SRC_PIM);
- if (!ch)
- return;
/*
RFC 4601: 4.6.1. (S,G) Assert Message State Machine
ch = pim_ifchannel_add(ifp, sg, source_flags,
PIM_UPSTREAM_FLAG_MASK_SRC_PIM);
- if (!ch)
- return;
pim_ifp = ifp->info;
}
ch = pim_ifchannel_add(ifp, sg, 0, PIM_UPSTREAM_FLAG_MASK_SRC_IGMP);
- if (!ch) {
- if (PIM_DEBUG_EVENTS)
- zlog_debug("%s:%s Unable to add ifchannel",
- __PRETTY_FUNCTION__,
- pim_str_sg_dump(sg));
- return 0;
- }
ifmembership_set(ch, PIM_IFMEMBERSHIP_INCLUDE);
return -1;
}
+ if (!pim_if_connected_to_source(ifp, from)) {
+ if (PIM_DEBUG_IGMP_PACKETS)
+ zlog_debug("Recv IGMP query on interface: %s from a non-connected source: %s",
+ ifp->name, from_str);
+ return 0;
+ }
+
/* Collecting IGMP Rx stats */
switch (query_version) {
case 1:
group_addr, query_max_response_time_dsec);
}
}
+
+void igmp_send_query_on_intf(struct interface *ifp, int igmp_ver)
+{
+ struct pim_interface *pim_ifp = ifp->info;
+ struct listnode *sock_node = NULL;
+ struct igmp_sock *igmp = NULL;
+ struct in_addr dst_addr;
+ struct in_addr group_addr;
+ int query_buf_size;
+
+ if (!igmp_ver)
+ igmp_ver = 2;
+
+ if (igmp_ver == 3)
+ query_buf_size = PIM_IGMP_BUFSIZE_WRITE;
+ else
+ query_buf_size = IGMP_V12_MSG_SIZE;
+
+ dst_addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP);
+ group_addr.s_addr = PIM_NET_INADDR_ANY;
+
+ if (PIM_DEBUG_IGMP_TRACE)
+ zlog_debug("Issuing general query on request on %s",
+ ifp->name);
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
+
+ char query_buf[query_buf_size];
+
+ igmp_send_query(igmp_ver, 0 /* igmp_group */, igmp->fd,
+ igmp->interface->name, query_buf,
+ sizeof(query_buf), 0 /* num_sources */,
+ dst_addr, group_addr,
+ pim_ifp->igmp_query_max_response_time_dsec,
+ 1 /* s_flag: always set for general queries */,
+ igmp->querier_robustness_variable,
+ igmp->querier_query_interval);
+ }
+}
uint8_t querier_robustness_variable,
uint16_t querier_query_interval);
void igmp_group_delete(struct igmp_group *group);
+
+void igmp_send_query_on_intf(struct interface *ifp, int igmp_ver);
#endif /* PIM_IGMP_H */
* Let's blackhole those packets for the moment
* As that they will be coming up to the cpu
* and causing us to consider them.
+ *
+ * This *will* create a dangling channel_oil
+ * that I see no way to get rid of. Just noting
+ * this for future reference.
*/
c_oil = pim_channel_oil_add(pim_ifp->pim, &sg,
pim_ifp->mroute_vif_index,
up = pim_upstream_find_or_add(&sg, ifp, PIM_UPSTREAM_FLAG_MASK_FHR,
__PRETTY_FUNCTION__);
- if (!up) {
- if (PIM_DEBUG_MROUTE) {
- zlog_debug(
- "%s: Failure to add upstream information for %s",
- __PRETTY_FUNCTION__, pim_str_sg_dump(&sg));
- }
- return 0;
- }
/*
* I moved this debug till after the actual add because
if (pim->vrf_id != VRF_DEFAULT) {
struct interface *ifp =
- if_lookup_by_name(pim->vrf->name, pim->vrf);
+ if_lookup_by_name(pim->vrf->name, pim->vrf_id);
if (!ifp) {
flog_err(EC_LIB_INTERFACE,
"%s: Unable to lookup vrf interface: %s",
if (mp->pim->vrf_id != VRF_DEFAULT) {
struct interface *ifp =
- if_lookup_by_name(mp->pim->vrf->name, mp->pim->vrf);
+ if_lookup_by_name(mp->pim->vrf->name, mp->pim->vrf_id);
if (!ifp) {
flog_err(EC_LIB_INTERFACE,
"%s: Unable to lookup vrf interface: %s",
return -4;
}
#endif
- if (iif->vrf != oif->vrf) {
+ if (iif->vrf_id != oif->vrf_id) {
return -3;
}
* back if it fails.
*/
original_s_route = static_route_alloc();
- if (!original_s_route) {
- return -5;
- }
memcpy(original_s_route, s_route,
sizeof(struct static_route));
up->channel_oil = pim_channel_oil_add(
pim, &up->sg, pim_ifp->mroute_vif_index,
__PRETTY_FUNCTION__);
+ else {
+ /*
+ * Yeah this should not happen
+ * but let's be sure that we are not
+ * doing something stupid, all paths
+ * through upstream creation will
+ * create a channel oil
+ */
+ up->channel_oil = pim_channel_oil_add(
+ pim, &up->sg, MAXVIFS,
+ __PRETTY_FUNCTION__);
+ }
}
}
*/
if (sscanf(ifp->name, "pimreg%" SCNu32, &table_id) == 1) {
struct vrf *vrf;
-
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
if ((table_id == vrf->data.l.table_id)
- && (ifp->vrf != vrf)) {
+ && (ifp->vrf_id != vrf->vrf_id)) {
struct interface *master = if_lookup_by_name(
- vrf->name, vrf);
+ vrf->name, vrf->vrf_id);
if (!master) {
zlog_debug(
__PRETTY_FUNCTION__,
ifp->name, vrf_id, new_vrf_id);
- if_update_to_new_vrf(ifp, vrf_lookup_by_id(new_vrf_id));
+ if_update_to_new_vrf(ifp, new_vrf_id);
return 0;
}
/*Create a dummy channel oil */
source->source_channel_oil = pim_channel_oil_add(
pim, &sg, MAXVIFS, __PRETTY_FUNCTION__);
-
- if (!source->source_channel_oil) {
- if (PIM_DEBUG_IGMP_TRACE) {
- zlog_debug(
- "%s %s: could not create OIL for channel (S,G)=%s",
- __FILE__, __PRETTY_FUNCTION__,
- pim_str_sg_dump(&sg));
- }
- return;
- }
}
else {
pim, &up->sg, MAXVIFS, __PRETTY_FUNCTION__);
}
- else {
+ else
up->channel_oil = pim_channel_oil_add(
pim, &up->sg, input_iface_vif_index,
__PRETTY_FUNCTION__);
- if (!up->channel_oil) {
- if (PIM_DEBUG_PIM_TRACE)
- zlog_debug(
- "%s %s: could not create OIL for channel (S,G)=%s",
- __FILE__, __PRETTY_FUNCTION__,
- up->sg_str);
- return;
- }
- }
if (PIM_DEBUG_TRACE) {
struct interface *in_intf = pim_if_find_by_vif_index(
up->channel_oil =
pim_channel_oil_add(pim, &up->sg, input_iface_vif_index,
__PRETTY_FUNCTION__);
- if (!up->channel_oil) {
- if (PIM_DEBUG_PIM_TRACE)
- zlog_debug(
- "%s %s: could not create OIL for channel (S,G)=%s",
- __FILE__, __PRETTY_FUNCTION__,
- up->sg_str);
- return;
- }
}
if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
if (IS_RIP_DEBUG_ZEBRA)
zlog_debug(
"interface %s vrf %u index %d flags %llx metric %d mtu %d is down",
- ifp->name, ifp->vrf->vrf_id, ifp->ifindex,
+ ifp->name, ifp->vrf_id, ifp->ifindex,
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
return 0;
if (IS_RIP_DEBUG_ZEBRA)
zlog_debug(
"interface %s vrf %u index %d flags %#llx metric %d mtu %d is up",
- ifp->name, ifp->vrf->vrf_id, ifp->ifindex,
+ ifp->name, ifp->vrf_id, ifp->ifindex,
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
rip_interface_sync(ifp);
if (IS_RIP_DEBUG_ZEBRA)
zlog_debug(
"interface add %s vrf %u index %d flags %#llx metric %d mtu %d",
- ifp->name, ifp->vrf->vrf_id, ifp->ifindex,
+ ifp->name, ifp->vrf_id, ifp->ifindex,
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
/* Check if this interface is RIP enabled or not.*/
zlog_info(
"interface delete %s vrf %u index %d flags %#llx metric %d mtu %d",
- ifp->name, ifp->vrf->vrf_id, ifp->ifindex,
+ ifp->name, ifp->vrf_id, ifp->ifindex,
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
/* To support pseudo interface do not free interface structure. */
{
struct interface *ifp;
vrf_id_t new_vrf_id;
- struct vrf *new_vrf;
ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id,
&new_vrf_id);
if (!ifp)
return 0;
- new_vrf = vrf_lookup_by_id(new_vrf_id);
-
if (IS_RIP_DEBUG_ZEBRA)
zlog_debug("interface %s VRF change vrf_id %u new vrf id %u",
ifp->name, vrf_id, new_vrf_id);
- if_update_to_new_vrf(ifp, new_vrf);
-
+ if_update_to_new_vrf(ifp, new_vrf_id);
rip_interface_sync(ifp);
return 0;
{
struct vrf *vrf;
- vrf = ifp->vrf;
+ vrf = vrf_lookup_by_id(ifp->vrf_id);
if (vrf) {
struct rip_interface *ri;
if (type == RMAP_RIP) {
ifname = rule;
- ifp = if_lookup_by_name(ifname,
- vrf_lookup_by_id(VRF_DEFAULT));
+ ifp = if_lookup_by_name(ifname, VRF_DEFAULT);
if (!ifp)
return RMAP_NOMATCH;
if (!ctx->vrf || !dist->ifname)
return;
- ifp = if_lookup_by_name(dist->ifname, ctx->vrf);
+ ifp = if_lookup_by_name(dist->ifname, ctx->vrf->vrf_id);
if (ifp == NULL)
return;
if (ctx->name)
vrf = vrf_lookup_by_name(ctx->name);
if (vrf)
- ifp = if_lookup_by_name(if_rmap->ifname, vrf);
+ ifp = if_lookup_by_name(if_rmap->ifname, vrf->vrf_id);
if (ifp == NULL)
return;
if (!rip)
return;
- if (ifp->vrf && ifp->vrf->vrf_id == VRF_UNKNOWN)
- return;
ctx = rip->if_rmap_ctx;
if (!ctx)
return;
if (IS_RIPNG_DEBUG_ZEBRA)
zlog_debug(
"interface up %s vrf %u index %d flags %llx metric %d mtu %d",
- ifp->name, ifp->vrf->vrf_id, ifp->ifindex,
+ ifp->name, ifp->vrf_id, ifp->ifindex,
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu6);
ripng_interface_sync(ifp);
if (IS_RIPNG_DEBUG_ZEBRA)
zlog_debug(
"interface down %s vrf %u index %d flags %#llx metric %d mtu %d",
- ifp->name, ifp->vrf->vrf_id, ifp->ifindex,
+ ifp->name, ifp->vrf_id, ifp->ifindex,
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu6);
return 0;
if (IS_RIPNG_DEBUG_ZEBRA)
zlog_debug(
"RIPng interface add %s vrf %u index %d flags %#llx metric %d mtu %d",
- ifp->name, ifp->vrf->vrf_id, ifp->ifindex,
+ ifp->name, ifp->vrf_id, ifp->ifindex,
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu6);
/* Check is this interface is RIP enabled or not.*/
zlog_info(
"interface delete %s vrf %u index %d flags %#llx metric %d mtu %d",
- ifp->name, ifp->vrf->vrf_id, ifp->ifindex,
+ ifp->name, ifp->vrf_id, ifp->ifindex,
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu6);
/* To support pseudo interface do not free interface structure. */
{
struct interface *ifp;
vrf_id_t new_vrf_id;
- struct vrf *new_vrf;
ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id,
&new_vrf_id);
if (!ifp)
return 0;
- new_vrf = vrf_lookup_by_id(new_vrf_id);
-
if (IS_RIPNG_DEBUG_ZEBRA)
zlog_debug("interface %s VRF change vrf_id %u new vrf id %u",
ifp->name, vrf_id, new_vrf_id);
- if_update_to_new_vrf(ifp, new_vrf);
-
+ if_update_to_new_vrf(ifp, new_vrf_id);
ripng_interface_sync(ifp);
return 0;
{
struct vrf *vrf;
- vrf = ifp->vrf;
+ vrf = vrf_lookup_by_id(ifp->vrf_id);
if (vrf) {
struct ripng_interface *ri;
if (type == RMAP_RIPNG) {
ifname = rule;
- ifp = if_lookup_by_name(ifname,
- vrf_lookup_by_id(VRF_DEFAULT));
+ ifp = if_lookup_by_name(ifname, VRF_DEFAULT);
if (!ifp)
return RMAP_NOMATCH;
if (!ctx->vrf || !dist->ifname)
return;
- ifp = if_lookup_by_name(dist->ifname, ctx->vrf);
+ ifp = if_lookup_by_name(dist->ifname, ctx->vrf->vrf_id);
if (ifp == NULL)
return;
if (ctx->name)
vrf = vrf_lookup_by_name(ctx->name);
if (vrf)
- ifp = if_lookup_by_name(if_rmap->ifname, vrf);
+ ifp = if_lookup_by_name(if_rmap->ifname, vrf->vrf_id);
if (ifp == NULL)
return;
struct if_rmap *if_rmap;
struct if_rmap_ctx *ctx;
- if (ifp->vrf && ifp->vrf->vrf_id == VRF_UNKNOWN)
- return;
if (!ripng)
return;
ctx = ripng->if_rmap_ctx;
/* For registering threads. */
extern struct thread_master *master;
-static struct interface *zebra_interface_if_lookup(struct stream *s, vrf_id_t vrf_id)
+static struct interface *zebra_interface_if_lookup(struct stream *s)
{
char ifname_tmp[INTERFACE_NAMSIZ];
stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
/* And look it up. */
- return if_lookup_by_name(ifname_tmp,
- vrf_lookup_by_id(vrf_id));
+ return if_lookup_by_name(ifname_tmp, VRF_DEFAULT);
}
/* Inteface addition message from zebra. */
static int interface_state_up(ZAPI_CALLBACK_ARGS)
{
- zebra_interface_if_lookup(zclient->ibuf, vrf_id);
+ zebra_interface_if_lookup(zclient->ibuf);
return 0;
}
struct static_route *si;
struct static_vrf *svrf;
struct route_node *rn;
- bool orig;
- bool reinstall;
svrf = vrf->info;
if (!svrf)
return;
for (rn = route_top(stable); rn; rn = route_next(rn)) {
- reinstall = false;
for (si = rn->info; si; si = si->next) {
if (si->nh_vrf_id != nh_vrf_id)
continue;
&& si->type != STATIC_IPV6_GATEWAY_IFNAME)
continue;
- orig = si->nh_valid;
if (p->family == AF_INET
&& p->u.prefix4.s_addr == si->addr.ipv4.s_addr)
si->nh_valid = !!nh_num;
&& memcmp(&p->u.prefix6, &si->addr.ipv6, 16) == 0)
si->nh_valid = !!nh_num;
- if (orig != si->nh_valid)
- reinstall = true;
-
- if (reinstall) {
- static_zebra_route_add(rn, si, vrf->vrf_id,
- safi, true);
- reinstall = false;
- }
+ static_zebra_route_add(rn, si, vrf->vrf_id, safi, true);
}
}
}
else {
struct interface *ifp;
- ifp = if_lookup_by_name(ifname, nh_svrf->vrf);
+ ifp = if_lookup_by_name(ifname, nh_svrf->vrf->vrf_id);
if (ifp && ifp->ifindex != IFINDEX_INTERNAL) {
si->ifindex = ifp->ifindex;
static_install_route(rn, si, safi);
si->nh_vrf_id = svrf->vrf->vrf_id;
si->nh_registered = false;
if (si->ifindex) {
- ifp = if_lookup_by_name(si->ifname, svrf->vrf);
+ ifp = if_lookup_by_name(si->ifname,
+ si->nh_vrf_id);
if (ifp)
si->ifindex = ifp->ifindex;
else
si->vrf_id = vrf->vrf_id;
if (si->ifindex) {
ifp = if_lookup_by_name(si->ifname,
- vrf_lookup_by_id(
- si->nh_vrf_id));
+ si->nh_vrf_id);
if (ifp)
si->ifindex = ifp->ifindex;
else
for (rn = route_top(stable); rn; rn = route_next(rn)) {
for (si = rn->info; si; si = si->next) {
- if (si->nh_vrf_id != vrf_to_id(ifp->vrf))
+ if (si->nh_vrf_id != ifp->vrf_id)
continue;
if (si->ifindex != ifp->ifindex)
struct static_vrf *svrf = vrf->info;
/* Not needed if same vrf since happens naturally */
- if (vrf == ifp->vrf)
+ if (vrf->vrf_id == ifp->vrf_id)
continue;
/* Install any static routes configured for this interface. */
struct zclient *zclient;
static struct hash *static_nht_hash;
-static struct interface *zebra_interface_if_lookup(struct stream *s, vrf_id_t vrf_id)
+static struct interface *zebra_interface_if_lookup(struct stream *s)
{
char ifname_tmp[INTERFACE_NAMSIZ];
stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
/* And look it up. */
- return if_lookup_by_name(ifname_tmp,
- vrf_lookup_by_id(vrf_id));
+ return if_lookup_by_name(ifname_tmp, VRF_DEFAULT);
}
/* Inteface addition message from zebra. */
{
struct interface *ifp;
- ifp = zebra_interface_if_lookup(zclient->ibuf, vrf_id);
+ ifp = zebra_interface_if_lookup(zclient->ibuf);
if (ifp) {
if (if_is_vrf(ifp)) {
--- /dev/null
+../bgp_l3vpn_to_bgp_vrf/ce1
\ No newline at end of file
--- /dev/null
+../bgp_l3vpn_to_bgp_vrf/ce2
\ No newline at end of file
--- /dev/null
+../bgp_l3vpn_to_bgp_vrf/ce3
\ No newline at end of file
--- /dev/null
+../bgp_l3vpn_to_bgp_vrf/ce4
\ No newline at end of file
--- /dev/null
+../bgp_l3vpn_to_bgp_vrf/customize.py
\ No newline at end of file
--- /dev/null
+../bgp_l3vpn_to_bgp_vrf/r1
\ No newline at end of file
--- /dev/null
+../bgp_l3vpn_to_bgp_vrf/r2
\ No newline at end of file
--- /dev/null
+../bgp_l3vpn_to_bgp_vrf/r3
\ No newline at end of file
--- /dev/null
+../bgp_l3vpn_to_bgp_vrf/r4
\ No newline at end of file
--- /dev/null
+../bgp_l3vpn_to_bgp_vrf/scripts
\ No newline at end of file
--- /dev/null
+#!/usr/bin/env python
+
+#
+# Part of NetDEF Topology Tests
+#
+# Copyright (c) 2018, LabN Consulting, L.L.C.
+# Authored by Lou Berger <lberger@labn.net>
+#
+# Permission to use, copy, modify, and/or distribute this software
+# for any purpose with or without fee is hereby granted, provided
+# that the above copyright notice and this permission notice appear
+# in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+#
+
+import os
+import sys
+import pytest
+
+sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../'))
+
+from lib.ltemplate import *
+
+def test_check_linux_vrf():
+ CliOnFail = None
+ # For debugging, uncomment the next line
+ #CliOnFail = 'tgen.mininet_cli'
+ CheckFunc = 'ltemplateVersionCheck(\'4.1\', iproute2=\'4.9\')'
+ #uncomment next line to start cli *before* script is run
+ #CheckFunc = 'ltemplateVersionCheck(\'4.1\', cli=True, iproute2=\'4.9\')'
+ ltemplateTest('scripts/check_linux_vrf.py', False, CliOnFail, CheckFunc)
+
+def test_adjacencies():
+ CliOnFail = None
+ # For debugging, uncomment the next line
+ #CliOnFail = 'tgen.mininet_cli'
+ CheckFunc = 'ltemplateVersionCheck(\'4.1\')'
+ #uncomment next line to start cli *before* script is run
+ #CheckFunc = 'ltemplateVersionCheck(\'4.1\', cli=True)'
+ ltemplateTest('scripts/adjacencies.py', False, CliOnFail, CheckFunc)
+
+def SKIP_test_add_routes():
+ CliOnFail = None
+ # For debugging, uncomment the next line
+ #CliOnFail = 'tgen.mininet_cli'
+ CheckFunc = 'ltemplateVersionCheck(\'4.1\')'
+ #uncomment next line to start cli *before* script is run
+ #CheckFunc = 'ltemplateVersionCheck(\'4.1\', cli=True)'
+ ltemplateTest('scripts/add_routes.py', False, CliOnFail, CheckFunc)
+
+def test_check_routes():
+ CliOnFail = None
+ # For debugging, uncomment the next line
+ #CliOnFail = 'tgen.mininet_cli'
+ CheckFunc = 'ltemplateVersionCheck(\'4.1\')'
+ #uncomment next line to start cli *before* script is run
+ #CheckFunc = 'ltemplateVersionCheck(\'4.1\', cli=True)'
+ ltemplateTest('scripts/check_routes.py', False, CliOnFail, CheckFunc)
+
+#manual data path setup test - remove once have bgp/zebra vrf path working
+def test_check_linux_mpls():
+ CliOnFail = None
+ # For debugging, uncomment the next line
+ #CliOnFail = 'tgen.mininet_cli'
+ CheckFunc = 'ltemplateVersionCheck(\'4.1\', iproute2=\'4.9\')'
+ #uncomment next line to start cli *before* script is run
+ #CheckFunc = 'ltemplateVersionCheck(\'4.1\', cli=True, iproute2=\'4.9\')'
+ ltemplateTest('scripts/check_linux_mpls.py', False, CliOnFail, CheckFunc)
+
+def test_del_bgp_instances():
+ CliOnFail = None
+ # For debugging, uncomment the next line
+ #CliOnFail = 'tgen.mininet_cli'
+ CheckFunc = 'ltemplateVersionCheck(\'4.1\')'
+ #uncomment next line to start cli *before* script is run
+ #CheckFunc = 'ltemplateVersionCheck(\'4.1\', cli=True)'
+ ltemplateTest('scripts/del_bgp_instances.py', False, CliOnFail, CheckFunc)
+
+if __name__ == '__main__':
+ retval = pytest.main(["-s"])
+ sys.exit(retval)
--- /dev/null
+from lutil import luCommand
+
+luCommand('r1','/usr/lib/frr/vtysh -c "conf ter" -c "no router bgp 5227 vrf r1-cust1" -c "no router bgp 5226"','.','none','Cleared bgp instances')
+luCommand('r2','/usr/lib/frr/vtysh -c "conf ter" -c "no router bgp 5226"','.','none','Cleared bgp instances')
+luCommand('r3','/usr/lib/frr/vtysh -c "conf ter" -c "no router bgp 5227 vrf r3-cust1" -c "no router bgp 5226"','.','none','Cleared bgp instances')
+luCommand('r4','/usr/lib/frr/vtysh -c "conf ter" -c "no router bgp 5228 vrf r4-cust2" -c "no router bgp 5227 vrf r4-cust1" -c "no router bgp 5226"','.','none','Cleared bgp instances')
+
luCommand('ce3', 'vtysh -c "show bgp sum"',
'.', 'pass', 'See %s sharp routes' % num)
if num > 0:
+ rtrs = ['ce1', 'ce2', 'ce3']
+ for rtr in rtrs:
+ luCommand(rtr, 'vtysh -c "show bgp ipv4 uni" | grep Display','.', 'none', 'BGP routes pre remove')
+ luCommand(rtr, 'ip route show | cat -n | tail','.', 'none', 'Linux routes pre remove')
wait = 2*num/500
luCommand('ce1', 'vtysh -c "sharp remove routes 10.0.0.0 {}"'.format(num),'.','none','Removing {} routes'.format(num))
luCommand('ce2', 'vtysh -c "sharp remove routes 10.0.0.0 {}"'.format(num),'.','none','Removing {} routes'.format(num))
- rtrs = ['ce1', 'ce2', 'ce3']
for rtr in rtrs:
- luCommand(rtr, 'vtysh -c "show bgp ipv4 uni" | grep -c 10\\.\\*/32','^0$', 'wait', 'BGP routes removed', wait)
+ luCommand(rtr, 'vtysh -c "show bgp ipv4 uni" | grep Display',' 10 route', 'wait', 'BGP routes removed', wait)
+ luCommand(rtr, 'vtysh -c "show bgp ipv4 uni"','.', 'none', 'BGP routes post remove')
for rtr in rtrs:
luCommand(rtr, 'ip route show | grep -c \\^10\\.','^0$', 'wait', 'Linux routes removed', wait)
+ luCommand(rtr, 'ip route show','.', 'none', 'Linux routes post remove')
rtrs = ['r1', 'r3', 'r4']
for rtr in rtrs:
luCommand(rtr, 'ip route show vrf {}-cust1 | grep -c \\^10\\.'.format(rtr),'^0$','wait','VRF route removed',wait)
else:
d = r
wait = 2*num/1000
-mem = {}
+mem_z = {}
+mem_b = {}
rtrs = ['ce1', 'ce2', 'ce3', 'r1', 'r2', 'r3', 'r4']
for rtr in rtrs:
- mem[rtr] = {'value': 0, 'units': 'unknown'}
- ret = luCommand(rtr, 'vtysh -c "show memory"', 'bgpd: System allocator statistics: Total heap allocated: *(\d*) ([A-Za-z]*)', 'none', 'collect bgpd memory stats')
+ mem_z[rtr] = {'value': 0, 'units': 'unknown'}
+ mem_b[rtr] = {'value': 0, 'units': 'unknown'}
+ ret = luCommand(rtr, 'vtysh -c "show memory"', 'zebra: System allocator statistics: Total heap allocated: *(\d*) ([A-Za-z]*) .*bgpd: System allocator statistics: Total heap allocated: *(\d*) ([A-Za-z]*)', 'none', 'collect bgpd memory stats')
found = luLast()
if ret != False and found != None:
- mem[rtr] = {'value': int(found.group(1)), 'units': found.group(2)}
+ mem_z[rtr] = {'value': int(found.group(1)), 'units': found.group(2)}
+ mem_b[rtr] = {'value': int(found.group(3)), 'units': found.group(4)}
luCommand('ce1', 'vtysh -c "sharp data nexthop"', 'sharpd is not running', 'none','check if sharpd running')
doSharp = True
luCommand(rtr, 'ip route show vrf {}-cust1 | grep -c \\^10\\.'.format(rtr), str(num), 'wait','See {} linux routes'.format(num), wait)
rtrs = ['ce1', 'ce2', 'ce3', 'r1', 'r2', 'r3', 'r4']
for rtr in rtrs:
- ret = luCommand(rtr, 'vtysh -c "show memory"', 'bgpd: System allocator statistics: Total heap allocated: *(\d*) ([A-Za-z]*)', 'none', 'collect bgpd memory stats')
+ ret = luCommand(rtr, 'vtysh -c "show memory"', 'zebra: System allocator statistics: Total heap allocated: *(\d*) ([A-Za-z]*) .*bgpd: System allocator statistics: Total heap allocated: *(\d*) ([A-Za-z]*)', 'none', 'collect bgpd memory stats')
found = luLast()
if ret != False and found != None:
- val = int(found.group(1))
- if mem[rtr]['units'] != found.group(2):
- val *= 1000
- delta = val - int(mem[rtr]['value'])
- ave = float(delta)/float(num)
- luCommand(rtr, 'vtysh -c "show thread cpu"', '.', 'pass', 'BGPd heap: {0} {1} --> {2} {3} ({4} {1}/route)'.format(mem[rtr]['value'], mem[rtr]['units'], found.group(1), found.group(2), round(ave,4)))
+ val_z = int(found.group(1))
+ if mem_z[rtr]['units'] != found.group(2):
+ val_z *= 1000
+ delta_z = val_z - int(mem_z[rtr]['value'])
+ ave_z = float(delta_z)/float(num)
+
+ val_b = int(found.group(3))
+ if mem_b[rtr]['units'] != found.group(4):
+ val_b *= 1000
+ delta_b = val_b - int(mem_b[rtr]['value'])
+ ave_b = float(delta_b)/float(num)
+ luCommand(rtr, 'vtysh -c "show thread cpu"', '.', 'pass', 'BGPd heap: {0} {1} --> {2} {3} ({4} {1}/vpn route)'.format(mem_b[rtr]['value'], mem_b[rtr]['units'], found.group(3), found.group(4), round(ave_b,4)))
+ luCommand(rtr, 'vtysh -c "show thread cpu"', '.', 'pass', 'Zebra heap: {0} {1} --> {2} {3} ({4} {1}/vpn route)'.format(mem_z[rtr]['value'], mem_z[rtr]['units'], found.group(1), found.group(2), round(ave_z,4)))
#done
base_log_dir = '.'
fout_name = 'output.log'
fsum_name = 'summary.txt'
- l_level = 9
+ l_level = 6
CallOnFail = False
l_total = 0
fsum = ''
net = ''
- def log(self, str):
+ def log(self, str, level=6):
if self.l_level > 0:
if self.fout == '':
self.fout = open(self.fout_name, 'w', 0)
self.fout.write(str+'\n')
- if self.l_level > 5:
+ if level <= self.l_level:
print(str)
def summary(self, str):
ret = success
else:
ret = search.group()
- self.log('found:%s:' % ret)
if op != 'fail':
success = True
+ level = 7
else:
success = False
+ level = 5
+ self.log('found:%s:' % ret, level)
# Experiment: compare matched strings obtained each way
if self.l_dotall_experiment and (group_nl_converted != ret):
- self.log('DOTALL experiment: strings differ dotall=[%s] orig=[%s]' % (group_nl_converted, ret))
+ self.log('DOTALL experiment: strings differ dotall=[%s] orig=[%s]' % (group_nl_converted, ret), 9)
if op == 'pass' or op == 'fail':
self.result(target, success, result)
if js != None:
#entry calls
def luStart(baseScriptDir='.', baseLogDir='.', net='',
- fout='output.log', fsum='summary.txt', level=9):
+ fout='output.log', fsum='summary.txt', level=None):
global LUtil
#init class
LUtil=lUtil()
LUtil.fout_name = baseLogDir + '/' + fout
if fsum != None:
LUtil.fsum_name = baseLogDir + '/' + fsum
- LUtil.l_level = level
+ if level != None:
+ LUtil.l_level = level
LUtil.l_dotall_experiment = False
LUtil.l_dotall_experiment = True
def luLast(usenl=False):
if usenl:
if LUtil.l_last_nl != None:
- LUtil.log('luLast:%s:' % LUtil.l_last_nl.group())
+ LUtil.log('luLast:%s:' % LUtil.l_last_nl.group(), 7)
return LUtil.l_last_nl
else:
if LUtil.l_last != None:
- LUtil.log('luLast:%s:' % LUtil.l_last.group())
+ LUtil.log('luLast:%s:' % LUtil.l_last.group(), 7)
return LUtil.l_last
def luInclude(filename, CallOnFail=None):
master = frr_init();
+ access_list_init();
vrrp_debug_init();
vrrp_zebra_init();
vrrp_vty_init();
/* Start PAM. */
ret = pam_start(FRR_PAM_NAME, user, &conv, &pamh);
- /* printf ("ret %d\n", ret); */
/* Is user really user? */
if (ret == PAM_SUCCESS)
ret = pam_authenticate(pamh, 0);
-/* printf ("ret %d\n", ret); */
-#if 0
- /* Permitted access? */
- if (ret == PAM_SUCCESS)
- ret = pam_acct_mgmt (pamh, 0);
- printf ("ret %d\n", ret);
-
- if (ret == PAM_AUTHINFO_UNAVAIL)
- ret = PAM_SUCCESS;
-#endif /* 0 */
-
-/* This is where we have been authorized or not. */
-#ifdef DEBUG
- if (ret == PAM_SUCCESS)
- printf("Authenticated\n");
- else
- printf("Not Authenticated\n");
-#endif /* DEBUG */
+ if (ret != PAM_SUCCESS)
+ fprintf(stderr, "vtysh_pam: Failure to initialize pam: %s(%d)",
+ pam_strerror(pamh, ret), ret);
/* close Linux-PAM */
if (pam_end(pamh, ret) != PAM_SUCCESS) {
pamh = NULL;
- fprintf(stderr, "vtysh_pam: failed to release authenticator\n");
+ fprintf(stderr, "vtysh_pam: failed to release authenticator: %s(%d)\n",
+ pam_strerror(pamh, ret), ret);
exit(1);
}
struct nexthop nh = {
.type = NEXTHOP_TYPE_IFINDEX,
.ifindex = ifp->ifindex,
- .vrf_id = vrf_to_id(ifp->vrf),
+ .vrf_id = ifp->vrf_id,
};
struct zebra_vrf *zvrf;
uint32_t metric;
- zvrf = zebra_vrf_lookup_by_id(ifp->vrf->vrf_id);
+ zvrf = zebra_vrf_lookup_by_id(ifp->vrf_id);
if (!zvrf) {
flog_err(EC_ZEBRA_VRF_NOT_FOUND,
"%s: Received Up for interface but no associated zvrf: %d",
- __PRETTY_FUNCTION__, ifp->vrf->vrf_id);
+ __PRETTY_FUNCTION__, ifp->vrf_id);
return;
}
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
zlog_debug(
"%u: IF %s address %s add/up, scheduling RIB processing",
- vrf_to_id(ifp->vrf), ifp->name,
+ ifp->vrf_id, ifp->name,
prefix2str(&p, buf, sizeof(buf)));
}
rib_update(zvrf->vrf->vrf_id, RIB_UPDATE_IF_CHANGE);
struct nexthop nh = {
.type = NEXTHOP_TYPE_IFINDEX,
.ifindex = ifp->ifindex,
- .vrf_id = vrf_to_id(ifp->vrf),
+ .vrf_id = ifp->vrf_id,
};
struct zebra_vrf *zvrf;
- zvrf = zebra_vrf_lookup_by_id(ifp->vrf->vrf_id);
+ zvrf = zebra_vrf_lookup_by_id(ifp->vrf_id);
if (!zvrf) {
flog_err(EC_ZEBRA_VRF_NOT_FOUND,
"%s: Received Up for interface but no associated zvrf: %d",
- __PRETTY_FUNCTION__, ifp->vrf->vrf_id);
+ __PRETTY_FUNCTION__, ifp->vrf_id);
return;
}
zlog_debug(
"%u: IF %s IP %s address del, scheduling RIB processing",
- vrf_to_id(ifp->vrf), ifp->name,
+ ifp->vrf_id, ifp->name,
prefix2str(p, buf, sizeof(buf)));
}
- rib_update(vrf_to_id(ifp->vrf), RIB_UPDATE_IF_CHANGE);
+ rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
/* Schedule LSP forwarding entries for processing, if appropriate. */
- if (vrf_to_id(ifp->vrf) == VRF_DEFAULT) {
+ if (ifp->vrf_id == VRF_DEFAULT) {
if (IS_ZEBRA_DEBUG_MPLS) {
char buf[PREFIX_STRLEN];
zlog_debug(
"%u: IF %s IP %s address delete, scheduling MPLS processing",
- vrf_to_id(ifp->vrf), ifp->name,
+ ifp->vrf_id, ifp->name,
prefix2str(p, buf, sizeof(buf)));
}
- mpls_mark_lsps_for_processing(zvrf_info_lookup(ifp->vrf), p);
+ mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id), p);
}
}
struct interface *ifp;
int n;
int lastlen;
- struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
/* Normally SIOCGIFCONF works with AF_INET socket. */
sock = socket(AF_INET, SOCK_DGRAM, 0);
unsigned int size;
ifreq = (struct ifreq *)((caddr_t)ifconf.ifc_req + n);
- ifp = if_get_by_name(ifreq->ifr_name, vrf);
+ ifp = if_get_by_name(ifreq->ifr_name, VRF_DEFAULT);
if_add_update(ifp);
size = ifreq->ifr_addr.sa_len;
if (size < sizeof(ifreq->ifr_addr))
}
#else
for (n = 0; n < ifconf.ifc_len; n += sizeof(struct ifreq)) {
- ifp = if_get_by_name(ifreq->ifr_name, vrf);
+ ifp = if_get_by_name(ifreq->ifr_name, VRF_DEFAULT);
if_add_update(ifp);
ifreq++;
}
ifreq.ifr_addr.sa_family = AF_INET;
/* Fetch Hardware address if available. */
- ret = vrf_if_ioctl(SIOCGIFHWADDR, (caddr_t)&ifreq,
- vrf_to_id(ifp->vrf));
+ ret = vrf_if_ioctl(SIOCGIFHWADDR, (caddr_t)&ifreq, ifp->vrf_id);
if (ret < 0)
ifp->hw_addr_len = 0;
else {
continue;
}
- ifp = if_lookup_by_name(ifap->ifa_name,
- vrf_lookup_by_id(VRF_DEFAULT));
+ ifp = if_lookup_by_name(ifap->ifa_name, VRF_DEFAULT);
if (ifp == NULL) {
flog_err(EC_LIB_INTERFACE,
"if_getaddrs(): Can't lookup interface %s\n",
int n;
size_t needed, lastneeded = 0;
char *buf = NULL;
- struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
frr_elevate_privs(&zserv_privs) {
sock = socket(af, SOCK_DGRAM, 0);
&& (*(lifreq->lifr_name + normallen) != ':'))
normallen++;
- ifp = if_get_by_name(lifreq->lifr_name, vrf);
+ ifp = if_get_by_name(lifreq->lifr_name, VRF_DEFAULT);
if (lifreq->lifr_addr.ss_family == AF_INET)
ifp->flags |= IFF_IPV4;
/* use ioctl to get IP address of an interface */
frr_elevate_privs(&zserv_privs) {
sd = vrf_socket(PF_INET, SOCK_DGRAM, IPPROTO_IP,
- vrf_to_id(interface->vrf),
+ interface->vrf_id,
NULL);
if (sd < 0) {
if (IS_ZEBRA_DEBUG_KERNEL)
return 0;
}
/* Get the current link state for the interface */
- rc = vrf_ioctl(vrf_to_id(interface->vrf), sd, SIOCETHTOOL,
+ rc = vrf_ioctl(interface->vrf_id, sd, SIOCETHTOOL,
(char *)&ifdata);
}
if (rc < 0) {
ifindex_t link_ifindex = IFINDEX_INTERNAL;
ifindex_t bond_ifindex = IFINDEX_INTERNAL;
struct zebra_if *zif;
- struct vrf *vrf;
zns = zebra_ns_lookup(ns_id);
ifi = NLMSG_DATA(h);
&& !vrf_is_backend_netns()) {
zif_slave_type = ZEBRA_IF_SLAVE_VRF;
vrf_id = *(uint32_t *)RTA_DATA(tb[IFLA_MASTER]);
- /* vrf can be needed before vrf netlink discovery */
- vrf_get(vrf_id, NULL);
} else if (slave_kind && (strcmp(slave_kind, "bridge") == 0)) {
zif_slave_type = ZEBRA_IF_SLAVE_BRIDGE;
bridge_ifindex =
}
if (vrf_is_backend_netns())
vrf_id = (vrf_id_t)ns_id;
- vrf = vrf_lookup_by_id(vrf_id);
+
/* If linking to another interface, note it. */
if (tb[IFLA_LINK])
link_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_LINK]);
/* Add interface. */
- ifp = if_get_by_name(name, vrf);
+ ifp = if_get_by_name(name, vrf_id);
set_ifindex(ifp, ifi->ifi_index, zns);
ifp->flags = ifi->ifi_flags & 0x0000fffff;
ifp->mtu6 = ifp->mtu = *(uint32_t *)RTA_DATA(tb[IFLA_MTU]);
ifindex_t link_ifindex = IFINDEX_INTERNAL;
uint8_t old_hw_addr[INTERFACE_HWADDR_MAX];
struct zebra_if *zif;
- struct vrf *vrf;
zns = zebra_ns_lookup(ns_id);
ifi = NLMSG_DATA(h);
}
if (vrf_is_backend_netns())
vrf_id = (vrf_id_t)ns_id;
-
- vrf = vrf_lookup_by_id(vrf_id);
-
if (ifp == NULL
|| !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
/* Add interface notification from kernel */
if (ifp == NULL) {
/* unknown interface */
- ifp = if_get_by_name(name, vrf);
+ ifp = if_get_by_name(name, vrf_id);
} else {
/* pre-configured interface, learnt now */
- if (ifp->vrf != vrf)
- if_update_to_new_vrf(ifp, vrf);
+ if (ifp->vrf_id != vrf_id)
+ if_update_to_new_vrf(ifp, vrf_id);
}
/* Update interface information. */
bridge_ifindex);
else if (IS_ZEBRA_IF_BOND_SLAVE(ifp))
zebra_l2if_update_bond_slave(ifp, bond_ifindex);
- } else if (ifp->vrf != vrf) {
+ } else if (ifp->vrf_id != vrf_id) {
/* VRF change for an interface. */
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug(
"RTM_NEWLINK vrf-change for %s(%u) "
"vrf_id %u -> %u flags 0x%x",
- name, ifp->ifindex, vrf_to_id(ifp->vrf),
- vrf_id, ifi->ifi_flags);
+ name, ifp->ifindex, ifp->vrf_id, vrf_id,
+ ifi->ifi_flags);
- if_handle_vrf_change(ifp, vrf->vrf_id);
+ if_handle_vrf_change(ifp, vrf_id);
} else {
bool was_bridge_slave, was_bond_slave;
{
struct zebra_if *if_data;
struct zebra_ns *zns;
- struct zebra_vrf *zvrf = zvrf_info_lookup(ifp->vrf);
+ struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id);
/* case interface populate before vrf enabled */
if (zvrf->zns)
zlog_debug(
"interface %s vrf %u index %d is shutdown. "
"Won't wake it up.",
- ifp->name, vrf_to_id(ifp->vrf),
- ifp->ifindex);
+ ifp->name, ifp->vrf_id, ifp->ifindex);
return;
}
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug(
"interface %s vrf %u index %d becomes active.",
- ifp->name, vrf_to_id(ifp->vrf), ifp->ifindex);
+ ifp->name, ifp->vrf_id, ifp->ifindex);
} else {
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug("interface %s vrf %u index %d is added.",
- ifp->name, vrf_to_id(ifp->vrf),
- ifp->ifindex);
+ ifp->name, ifp->vrf_id, ifp->ifindex);
}
}
flog_err(
EC_LIB_INTERFACE,
"interface %s vrf %u index %d is still up while being deleted.",
- ifp->name, vrf_to_id(ifp->vrf), ifp->ifindex);
+ ifp->name, ifp->vrf_id, ifp->ifindex);
return;
}
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug("interface %s vrf %u index %d is now inactive.",
- ifp->name, vrf_to_id(ifp->vrf), ifp->ifindex);
+ ifp->name, ifp->vrf_id, ifp->ifindex);
/* Delete connected routes from the kernel. */
if_delete_connected(ifp);
* occur with this implementation whereas it is not possible with
* vrf-lite).
*/
- if (ifp->vrf->vrf_id && !vrf_is_backend_netns())
+ if (ifp->vrf_id && !vrf_is_backend_netns())
if_handle_vrf_change(ifp, VRF_DEFAULT);
/* Reset some zebra interface params to default values. */
void if_handle_vrf_change(struct interface *ifp, vrf_id_t vrf_id)
{
vrf_id_t old_vrf_id;
- struct vrf *vrf = vrf_lookup_by_id(vrf_id);
- old_vrf_id = vrf_to_id(ifp->vrf);
+ old_vrf_id = ifp->vrf_id;
/* Uninstall connected routes. */
if_uninstall_connected(ifp);
zebra_interface_vrf_update_del(ifp, vrf_id);
/* update VRF */
- if_update_to_new_vrf(ifp, vrf);
+ if_update_to_new_vrf(ifp, vrf_id);
/* Send out notification on interface VRF change. */
/* This is to issue an ADD, if needed. */
*/
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
zlog_debug("%u: IF %s VRF change, scheduling RIB processing",
- vrf_to_id(ifp->vrf), ifp->name);
+ ifp->vrf_id, ifp->name);
rib_update(old_vrf_id, RIB_UPDATE_IF_CHANGE);
- rib_update(vrf_to_id(ifp->vrf), RIB_UPDATE_IF_CHANGE);
+ rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
}
static void ipv6_ll_address_to_mac(struct in6_addr *address, uint8_t *mac)
struct in6_addr *address,
int add)
{
- struct zebra_vrf *zvrf = zvrf_info_lookup(ifp->vrf);
+ struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id);
struct zebra_if *zif = ifp->info;
char buf[16] = "169.254.0.1";
struct in_addr ipv4_ll;
{
struct zebra_if *zif;
struct interface *link_if;
- struct zebra_vrf *zvrf = zvrf_info_lookup(ifp->vrf);
+ struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id);
zif = ifp->info;
zif->up_count++;
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
zlog_debug("%u: IF %s up, scheduling RIB processing",
- vrf_to_id(ifp->vrf), ifp->name);
- rib_update(vrf_to_id(ifp->vrf), RIB_UPDATE_IF_CHANGE);
+ ifp->vrf_id, ifp->name);
+ rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
/* Handle interface up for specific types for EVPN. Non-VxLAN interfaces
* are checked to see if (remote) neighbor entries need to be installed
{
struct zebra_if *zif;
struct interface *link_if;
- struct zebra_vrf *zvrf = zvrf_info_lookup(ifp->vrf);
+ struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id);
zif = ifp->info;
zif->down_count++;
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
zlog_debug("%u: IF %s down, scheduling RIB processing",
- vrf_to_id(ifp->vrf), ifp->name);
- rib_update(vrf_to_id(ifp->vrf), RIB_UPDATE_IF_CHANGE);
+ ifp->vrf_id, ifp->name);
+ rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp);
zebra_ptm_show_status(vty, ifp);
- vrf = ifp->vrf;
+ vrf = vrf_lookup_by_id(ifp->vrf_id);
vty_out(vty, " vrf: %s\n", vrf->name);
if (ifp->desc)
VRF_CMD_HELP_STR
"Interface status and configuration summary\n")
{
- struct vrf *vrf = NULL;
+ struct vrf *vrf;
struct interface *ifp;
+ vrf_id_t vrf_id = VRF_DEFAULT;
interface_update_stats();
if (name)
- VRF_GET_INSTANCE(vrf, name, false, false);
+ VRF_GET_ID(vrf_id, name, false);
/* All interface print. */
+ vrf = vrf_lookup_by_id(vrf_id);
if (brief) {
ifs_dump_brief_vty(vty, vrf);
} else {
int idx_ifname = 2;
int idx_name = 4;
struct interface *ifp;
- struct vrf *vrf;
+ vrf_id_t vrf_id;
interface_update_stats();
- VRF_GET_INSTANCE(vrf, argv[idx_name]->arg, false, false);
+ VRF_GET_ID(vrf_id, argv[idx_name]->arg, false);
/* Specified interface print. */
- ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf);
+ ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id);
if (ifp == NULL) {
vty_out(vty, "%% Can't find interface %s\n",
argv[idx_ifname]->arg);
/* All interface print. */
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
/* Specified interface print. */
- ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf);
+ ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf->vrf_id);
if (ifp) {
if_dump_vty(vty, ifp);
found++;
}
-static void if_show_description(struct vty *vty, struct vrf *vrf)
+static void if_show_description(struct vty *vty, vrf_id_t vrf_id)
{
+ struct vrf *vrf = vrf_lookup_by_id(vrf_id);
struct interface *ifp;
vty_out(vty, "Interface Status Protocol Description\n");
"Interface description\n"
VRF_CMD_HELP_STR)
{
- struct vrf *vrf;
+ vrf_id_t vrf_id = VRF_DEFAULT;
if (argc > 3)
- VRF_GET_INSTANCE(vrf, argv[4]->arg, false, false);
- else
- vrf = vrf_lookup_by_id(VRF_DEFAULT);
+ VRF_GET_ID(vrf_id, argv[4]->arg, false);
- if_show_description(vty, vrf);
+ if_show_description(vty, vrf_id);
return CMD_SUCCESS;
}
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
if (!RB_EMPTY(if_name_head, &vrf->ifaces_by_name)) {
vty_out(vty, "\n\tVRF %u\n\n", vrf->vrf_id);
- if_show_description(vty, vrf);
+ if_show_description(vty, vrf->vrf_id);
}
return CMD_SUCCESS;
struct vrf *vrf;
if_data = ifp->info;
- vrf = ifp->vrf;
+ vrf = vrf_lookup_by_id(ifp->vrf_id);
- if (vrf->vrf_id == VRF_DEFAULT)
+ if (ifp->vrf_id == VRF_DEFAULT)
vty_frame(vty, "interface %s\n", ifp->name);
else
vty_frame(vty, "interface %s vrf %s\n",
ifreq_set_name(&ifreq, ifp);
- if (vrf_if_ioctl(SIOCGIFMETRIC, (caddr_t)&ifreq,
- vrf_to_id(ifp->vrf)) < 0)
+ if (vrf_if_ioctl(SIOCGIFMETRIC, (caddr_t)&ifreq, ifp->vrf_id) < 0)
return;
ifp->metric = ifreq.ifr_metric;
if (ifp->metric == 0)
ifreq_set_name(&ifreq, ifp);
#if defined(SIOCGIFMTU)
- if (vrf_if_ioctl(SIOCGIFMTU, (caddr_t)&ifreq,
- vrf_to_id(ifp->vrf)) < 0) {
+ if (vrf_if_ioctl(SIOCGIFMTU, (caddr_t)&ifreq, ifp->vrf_id) < 0) {
zlog_info("Can't lookup mtu by ioctl(SIOCGIFMTU)");
ifp->mtu6 = ifp->mtu = -1;
return;
ifreq_set_name(&ifreq, ifp);
- ret = vrf_if_ioctl(SIOCGIFFLAGS, (caddr_t)&ifreq, vrf_to_id(ifp->vrf));
+ ret = vrf_if_ioctl(SIOCGIFFLAGS, (caddr_t)&ifreq, ifp->vrf_id);
if (ret < 0) {
flog_err_sys(EC_LIB_SYSTEM_CALL,
"vrf_if_ioctl(SIOCGIFFLAGS) failed: %s",
ifreq.ifr_flags = ifp->flags;
ifreq.ifr_flags |= flags;
- ret = vrf_if_ioctl(SIOCSIFFLAGS, (caddr_t)&ifreq, vrf_to_id(ifp->vrf));
+ ret = vrf_if_ioctl(SIOCSIFFLAGS, (caddr_t)&ifreq, ifp->vrf_id);
if (ret < 0) {
zlog_info("can't set interface flags");
ifreq.ifr_flags = ifp->flags;
ifreq.ifr_flags &= ~flags;
- ret = vrf_if_ioctl(SIOCSIFFLAGS, (caddr_t)&ifreq, vrf_to_id(ifp->vrf));
+ ret = vrf_if_ioctl(SIOCSIFFLAGS, (caddr_t)&ifreq, ifp->vrf_id);
if (ret < 0) {
zlog_info("can't unset interface flags");
static int ifan_read(struct if_announcemsghdr *ifan)
{
struct interface *ifp;
- struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
ifp = if_lookup_by_index(ifan->ifan_index, VRF_DEFAULT);
__func__, ifan->ifan_index, ifan->ifan_name);
/* Create Interface */
- ifp = if_get_by_name(ifan->ifan_name, vrf);
+ ifp = if_get_by_name(ifan->ifan_name, VRF_DEFAULT);
if_set_index(ifp, ifan->ifan_index);
if_get_metric(ifp);
int maskbit;
caddr_t cp;
char fbuf[64];
- struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
/* terminate ifname at head (for strnlen) and tail (for safety) */
ifname[IFNAMSIZ - 1] = '\0';
* be filled in.
*/
if ((ifp == NULL) && ifnlen)
- ifp = if_lookup_by_name(ifname, vrf);
+ ifp = if_lookup_by_name(ifname, VRF_DEFAULT);
/*
* If ifp still does not exist or has an invalid index
if (ifp == NULL) {
/* Interface that zebra was not previously aware of, so
* create. */
- ifp = if_create(ifname, vrf);
+ ifp = if_create(ifname, VRF_DEFAULT);
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug("%s: creating ifp for ifindex %d",
__func__, ifm->ifm_index);
#include "zebra/zebra_netns_notify.h"
#include "zebra/zebra_rnh.h"
#include "zebra/zebra_pbr.h"
+#include "zebra/zebra_vxlan.h"
#if defined(HANDLE_NETLINK_FUZZING)
#include "zebra/kernel_netlink.h"
/* RNH init */
zebra_rnh_init();
+ /* Config handler Init */
+ zebra_evpn_init();
+
/* Error init */
zebra_error_init();
if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug("MESSAGE: ZEBRA_INTERFACE_UP %s(%u)",
- ifp->name, vrf_to_id(ifp->vrf));
+ ifp->name, ifp->vrf_id);
if (ifp->ptm_status || !ifp->ptm_enable) {
for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode,
if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug("MESSAGE: ZEBRA_INTERFACE_DOWN %s(%u)",
- ifp->name, vrf_to_id(ifp->vrf));
+ ifp->name, ifp->vrf_id);
for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADD %s(%u)", ifp->name,
- vrf_to_id(ifp->vrf));
+ ifp->vrf_id);
for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
client->ifadd_cnt++;
if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug("MESSAGE: ZEBRA_INTERFACE_DELETE %s(%u)",
- ifp->name, vrf_to_id(ifp->vrf));
+ ifp->name, ifp->vrf_id);
for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
client->ifdel_cnt++;
p = ifc->address;
zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s on %s(%u)",
prefix2str(p, buf, sizeof(buf)), ifp->name,
- vrf_to_id(ifp->vrf));
+ ifp->vrf_id);
}
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
p = ifc->address;
zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s on %s(%u)",
prefix2str(p, buf, sizeof(buf)),
- ifp->name, vrf_to_id(ifp->vrf));
+ ifp->name, ifp->vrf_id);
}
zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 0);
if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug(
"MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/DEL %s VRF Id %u -> %u",
- ifp->name, vrf_to_id(ifp->vrf), new_vrf_id);
+ ifp->name, ifp->vrf_id, new_vrf_id);
for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
/* Need to delete if the client is not interested in the new
if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug(
"MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/ADD %s VRF Id %u -> %u",
- ifp->name, old_vrf_id, vrf_to_id(ifp->vrf));
+ ifp->name, old_vrf_id, ifp->vrf_id);
for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
/* Need to add if the client is interested in the new VRF. */
if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s(%u)",
- ifp->name, vrf_to_id(ifp->vrf));
+ ifp->name, ifp->vrf_id);
for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client))
zsend_interface_link_params(client, ifp);
struct prefix before;
struct prefix after;
struct zserv *client;
- struct zebra_vrf *zvrf = vrf_info_get(vrf_to_id(ifc->ifp->vrf));
+ struct zebra_vrf *zvrf = vrf_info_get(ifc->ifp->vrf_id);
if (router_id_bad_address(ifc))
return;
struct prefix before;
struct listnode *node;
struct zserv *client;
- struct zebra_vrf *zvrf = vrf_info_get(vrf_to_id(ifc->ifp->vrf));
+ struct zebra_vrf *zvrf = vrf_info_get(ifc->ifp->vrf_id);
if (router_id_bad_address(ifc))
return;
zebra_ns_lookup(ns_id),
index);
if (ifp)
- nh_vrf_id = vrf_to_id(ifp->vrf);
+ nh_vrf_id = ifp->vrf_id;
}
nh.vrf_id = nh_vrf_id;
zebra_ns_lookup(ns_id),
index);
if (ifp)
- nh_vrf_id = vrf_to_id(ifp->vrf);
+ nh_vrf_id = ifp->vrf_id;
else {
flog_warn(
EC_ZEBRA_UNKNOWN_INTERFACE,
char buf[256];
} req;
uint8_t dst_mac[6] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
- struct zebra_vrf *zvrf = zvrf_info_lookup(ifp->vrf);
+ struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(ifp->vrf_id);
zns = zvrf->zns;
memset(&req, 0, sizeof(req));
int vid_present = 0;
char vid_buf[20];
char dst_buf[30];
- struct zebra_vrf *zvrf = zvrf_info_lookup(ifp->vrf);
+ struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(ifp->vrf_id);
zns = zvrf->zns;
zif = ifp->info;
* 5549 support, re-install them.
*/
static void netlink_handle_5549(struct ndmsg *ndm, struct zebra_if *zif,
- struct interface *ifp, struct ipaddr *ip)
+ struct interface *ifp, struct ipaddr *ip,
+ bool handle_failed)
{
if (ndm->ndm_family != AF_INET)
return;
if (ipv4_ll.s_addr != ip->ip._v4_addr.s_addr)
return;
+ if (handle_failed && ndm->ndm_state & NUD_FAILED) {
+ zlog_info("Neighbor Entry for %s has entered a failed state, not reinstalling",
+ ifp->name);
+ return;
+ }
+
if_nbr_ipv6ll_to_ipv4ll_neigh_update(ifp, &zif->v6_2_v4_ll_addr6, true);
}
/* if kernel deletes our rfc5549 neighbor entry, re-install it */
if (h->nlmsg_type == RTM_DELNEIGH && (ndm->ndm_state & NUD_PERMANENT)) {
- netlink_handle_5549(ndm, zif, ifp, &ip);
+ netlink_handle_5549(ndm, zif, ifp, &ip, false);
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug(
"\tNeighbor Entry Received is a 5549 entry, finished");
}
/* if kernel marks our rfc5549 neighbor entry invalid, re-install it */
- if (h->nlmsg_type == RTM_NEWNEIGH && !(ndm->ndm_state & NUD_VALID)) {
- if (!(ndm->ndm_state & NUD_FAILED))
- netlink_handle_5549(ndm, zif, ifp, &ip);
- else
- zlog_info("Neighbor Entry for %s has entered a failed state, not reinstalling",
- ifp->name);
- }
+ if (h->nlmsg_type == RTM_NEWNEIGH && !(ndm->ndm_state & NUD_VALID))
+ netlink_handle_5549(ndm, zif, ifp, &ip, true);
/* The neighbor is present on an SVI. From this, we locate the
* underlying
{
int ret = 0;
struct zebra_ns *zns;
- struct zebra_vrf *zvrf = zvrf_info_lookup(vlan_if->vrf);
+ struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(vlan_if->vrf_id);
char buf[INET6_ADDRSTRLEN];
struct zebra_dplane_info dp_info;
__PRETTY_FUNCTION__, vlan_if->name,
vlan_if->ifindex,
ipaddr2str(ip, buf, sizeof(buf)),
- vrf_to_id(vlan_if->vrf));
+ vlan_if->vrf_id);
ret = netlink_request_specific_neigh_in_vlan(zns, RTM_GETNEIGH, ip,
vlan_if->ifindex);
struct zebra_ns *zns;
char buf[INET6_ADDRSTRLEN];
char buf2[ETHER_ADDR_STRLEN];
- struct zebra_vrf *zvrf = zvrf_info_lookup(ifp->vrf);
+ struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(ifp->vrf_id);
zns = zvrf->zns;
memset(&req, 0, sizeof(req));
static void rtadv_process_solicit(struct interface *ifp)
{
- struct zebra_vrf *zvrf = zvrf_info_lookup(ifp->vrf);
+ struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id);
assert(zvrf);
rtadv_send_packet(rtadv_get_socket(zvrf), ifp);
struct zebra_vrf *zvrf;
zif = ifp->info;
- zvrf = zvrf_info_lookup(ifp->vrf);
+ zvrf = vrf_info_lookup(ifp->vrf_id);
if (status == RA_SUPPRESS) {
/* RA is currently enabled */
zebra_route_string(client->proto));
return;
}
- if (ifp->vrf != zvrf->vrf) {
+ if (ifp->vrf_id != zvrf_id(zvrf)) {
zlog_debug(
"%u: IF %u RA %s client %s - VRF mismatch, IF VRF %u",
zvrf_id(zvrf), ifindex, enable ? "enable" : "disable",
- zebra_route_string(client->proto), vrf_to_id(ifp->vrf));
+ zebra_route_string(client->proto), ifp->vrf_id);
return;
}
struct zebra_if *zif = ifp->info;
struct zebra_vrf *zvrf;
- zvrf = zvrf_info_lookup(ifp->vrf);
+ zvrf = vrf_info_lookup(ifp->vrf_id);
interval = strtoul(argv[idx_number]->arg, NULL, 10);
if ((zif->rtadv.AdvDefaultLifetime != -1
struct zebra_if *zif = ifp->info;
struct zebra_vrf *zvrf;
- zvrf = zvrf_info_lookup(ifp->vrf);
+ zvrf = vrf_info_lookup(ifp->vrf_id);
interval = strtoul(argv[idx_number]->arg, NULL, 10);
if ((zif->rtadv.AdvDefaultLifetime != -1
struct zebra_if *zif = ifp->info;
struct zebra_vrf *zvrf = NULL;
- zvrf = zvrf_info_lookup(ifp->vrf);
+ zvrf = vrf_info_lookup(ifp->vrf_id);
if (zif->rtadv.MaxRtrAdvInterval % 1000)
zvrf->rtadv.adv_msec_if_count--;
{
struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
- zclient_create_header(s, ZEBRA_INTERFACE_ADD, vrf_to_id(ifp->vrf));
+ zclient_create_header(s, ZEBRA_INTERFACE_ADD, ifp->vrf_id);
zserv_encode_interface(s, ifp);
client->ifadd_cnt++;
{
struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
- zclient_create_header(s, ZEBRA_INTERFACE_DELETE, vrf_to_id(ifp->vrf));
+ zclient_create_header(s, ZEBRA_INTERFACE_DELETE, ifp->vrf_id);
zserv_encode_interface(s, ifp);
client->ifdel_cnt++;
return 0;
}
- zclient_create_header(s, ZEBRA_INTERFACE_LINK_PARAMS,
- vrf_to_id(ifp->vrf));
+ zclient_create_header(s, ZEBRA_INTERFACE_LINK_PARAMS, ifp->vrf_id);
/* Add Interface Index */
stream_putl(s, ifp->ifindex);
struct prefix *p;
struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
- zclient_create_header(s, cmd, vrf_to_id(ifp->vrf));
+ zclient_create_header(s, cmd, ifp->vrf_id);
stream_putl(s, ifp->ifindex);
/* Interface address flag. */
struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
struct prefix *p;
- zclient_create_header(s, cmd, vrf_to_id(ifp->vrf));
+ zclient_create_header(s, cmd, ifp->vrf_id);
stream_putl(s, ifp->ifindex);
/* Prefix information. */
{
struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
- zclient_create_header(s, ZEBRA_INTERFACE_VRF_UPDATE,
- vrf_to_id(ifp->vrf));
+ zclient_create_header(s, ZEBRA_INTERFACE_VRF_UPDATE, ifp->vrf_id);
/* Fill in the name of the interface and its new VRF (id) */
stream_put(s, ifp->name, INTERFACE_NAMSIZ);
{
struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
- zclient_create_header(s, cmd, vrf_to_id(ifp->vrf));
+ zclient_create_header(s, cmd, ifp->vrf_id);
zserv_encode_interface(s, ifp);
if (cmd == ZEBRA_INTERFACE_UP)
STREAM_GETC(s, ltype);
if (zvrf->vrf->vrf_id != VRF_DEFAULT)
- ifp = if_lookup_by_name(zvrf->vrf->name, zvrf->vrf);
+ ifp = if_lookup_by_name(zvrf->vrf->name, zvrf->vrf->vrf_id);
else
- ifp = if_lookup_by_name("lo", vrf_lookup_by_id(VRF_DEFAULT));
+ ifp = if_lookup_by_name("lo", VRF_DEFAULT);
if (!ifp) {
zlog_debug("Unable to find specified Interface for %s",
struct prefix_ipv4 *p;
p = (struct prefix_ipv4 *)ifc->address;
- rib_lookup_and_pushup(p, ifp->vrf->vrf_id);
+ rib_lookup_and_pushup(p, ifp->vrf_id);
}
#endif
prefix2str(ifc->address, addr_str, sizeof(addr_str));
zlog_debug("init intf ctx %s: idx %d, addr %u:%s",
- dplane_op2str(op), ifp->ifindex, ifp->vrf->vrf_id,
+ dplane_op2str(op), ifp->ifindex, ifp->vrf_id,
addr_str);
}
ctx->zd_op = op;
ctx->zd_status = ZEBRA_DPLANE_REQUEST_SUCCESS;
- ctx->zd_vrf_id = ifp->vrf->vrf_id;
+ ctx->zd_vrf_id = ifp->vrf_id;
- zns = zebra_ns_lookup(ifp->vrf->vrf_id);
+ zns = zebra_ns_lookup(ifp->vrf_id);
dplane_ctx_ns_init(ctx, zns, false);
/* Init the interface-addr-specific area */
}
if (!strcmp(ZEBRA_PTM_INVALID_VRF, vrf_str) && ifp) {
- vrf_id = vrf_to_id(ifp->vrf);
+ vrf_id = ifp->vrf_id;
} else {
vrf_id = vrf_name_to_id(vrf_str);
}
bool is_srcdst = src_p && src_p->prefixlen;
char straddr[PREFIX_STRLEN];
char srcaddr[PREFIX_STRLEN];
+ char nhname[PREFIX_STRLEN];
struct nexthop *nexthop;
zlog_debug("%s: dumping RE entry %p for %s%s%s vrf %u", func,
: "",
re->vrf_id);
zlog_debug("%s: uptime == %lu, type == %u, instance == %d, table == %d",
- func, (unsigned long)re->uptime, re->type, re->instance,
+ straddr, (unsigned long)re->uptime, re->type, re->instance,
re->table);
zlog_debug(
"%s: metric == %u, mtu == %u, distance == %u, flags == %u, status == %u",
- func, re->metric, re->mtu, re->distance, re->flags, re->status);
- zlog_debug("%s: nexthop_num == %u, nexthop_active_num == %u", func,
+ straddr, re->metric, re->mtu, re->distance, re->flags, re->status);
+ zlog_debug("%s: nexthop_num == %u, nexthop_active_num == %u", straddr,
re->nexthop_num, re->nexthop_active_num);
for (ALL_NEXTHOPS(re->ng, nexthop)) {
switch (nexthop->type) {
case NEXTHOP_TYPE_BLACKHOLE:
- sprintf(straddr, "Blackhole");
+ sprintf(nhname, "Blackhole");
break;
case NEXTHOP_TYPE_IFINDEX:
ifp = if_lookup_by_index(nexthop->ifindex,
nexthop->vrf_id);
- sprintf(straddr, "%s", ifp ? ifp->name : "Unknown");
+ sprintf(nhname, "%s", ifp ? ifp->name : "Unknown");
break;
case NEXTHOP_TYPE_IPV4:
/* fallthrough */
case NEXTHOP_TYPE_IPV4_IFINDEX:
- inet_ntop(AF_INET, &nexthop->gate, straddr,
+ inet_ntop(AF_INET, &nexthop->gate, nhname,
INET6_ADDRSTRLEN);
break;
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
- inet_ntop(AF_INET6, &nexthop->gate, straddr,
+ inet_ntop(AF_INET6, &nexthop->gate, nhname,
INET6_ADDRSTRLEN);
break;
}
zlog_debug("%s: %s %s[%u] vrf %s(%u) with flags %s%s%s%s%s%s",
- func, (nexthop->rparent ? " NH" : "NH"), straddr,
+ straddr, (nexthop->rparent ? " NH" : "NH"), nhname,
nexthop->ifindex, vrf ? vrf->name : "Unknown",
nexthop->vrf_id,
(CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)
? "DUPLICATE "
: ""));
}
- zlog_debug("%s: dump complete", func);
+ zlog_debug("%s: dump complete", straddr);
}
/* This is an exported helper to rtm_read() to dump the strange
* change.
*/
zebra_rnh_remove_from_routing_table(rnh);
- if (!prefix_same(&rnh->resolved_route, prn ? NULL : &prn->p)) {
+ if (!prefix_same(&rnh->resolved_route, prn ? &prn->p : NULL)) {
if (prn)
prefix_copy(&rnh->resolved_route, &prn->p);
else {
static int compare_state(struct route_entry *r1, struct route_entry *r2)
{
-
if (!r1 && !r2)
return 0;
if (r1->nexthop_num != r2->nexthop_num)
return 1;
- if (CHECK_FLAG(r1->status, ROUTE_ENTRY_NEXTHOPS_CHANGED)
- || CHECK_FLAG(r1->status, ROUTE_ENTRY_LABELS_CHANGED))
+ if (nexthop_group_hash(&r1->ng) != nexthop_group_hash(&r2->ng))
return 1;
return 0;
return zvrf->vrf->vrf_id;
}
-static inline struct zebra_vrf *zvrf_info_lookup(struct vrf *vrf)
-{
- struct zebra_vrf *zvrf = NULL;
-
- if (vrf)
- zvrf = (struct zebra_vrf *)vrf->info;
- return zvrf;
-}
-
static inline const char *zvrf_ns_name(struct zebra_vrf *zvrf)
{
if (!zvrf->vrf || !zvrf->vrf->ns_ctxt)
afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
struct zebra_vrf *zvrf;
struct route_table *t;
- vrf_id_t vrf_id;
+ vrf_id_t vrf_id = VRF_DEFAULT;
- VRF_GET_ID(vrf_id, vrf_name, !!json);
+ if (vrf_name)
+ VRF_GET_ID(vrf_id, vrf_name, !!json);
zvrf = zebra_vrf_lookup_by_id(vrf_id);
t = zebra_router_find_table(zvrf, table, afi, SAFI_UNICAST);
struct in_addr mcast_grp);
static void zebra_vxlan_sg_cleanup(struct hash_backet *backet, void *arg);
+static void zvni_send_mac_to_client(zebra_vni_t *zvn);
+static void zvni_send_neigh_to_client(zebra_vni_t *zvni);
+
/* Private functions */
static int host_rb_entry_compare(const struct host_rb_entry *hle1,
const struct host_rb_entry *hle2)
if (json_vni == NULL) {
if ((wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP) &&
(wctx->count == 0))
- vty_out(vty,
- "%*s %-6s %-8s %-17s %-21s\n",
+ vty_out(vty, "%*s %-6s %-8s %-17s %-21s %s\n",
-wctx->addr_width, "Neighbor", "Type",
- "State", "MAC", "Remote VTEP");
+ "State", "MAC", "Remote VTEP",
+ "Seq #'s");
vty_out(vty, "%*s %-6s %-8s %-17s %-21s %u/%u\n",
-wctx->addr_width, buf2, "remote", state_str,
buf1, inet_ntoa(n->r_vtep_ip), n->loc_seq, n->rem_seq);
else
json_object_int_add(json_mac, "vlan", vid);
} else /* No vid? fill out the space */
- vty_out(vty, " %-5s", "");
- vty_out(vty, " %u/%u", mac->loc_seq, mac->rem_seq);
+ if (json_mac_hdr == NULL)
+ vty_out(vty, " %-5s", "");
if (json_mac_hdr == NULL) {
+ vty_out(vty, " %u/%u", mac->loc_seq, mac->rem_seq);
vty_out(vty, "\n");
} else {
json_object_int_add(json_mac, "localSequence",
struct zebra_vrf *zvrf = NULL;
char buf[ETHER_ADDR_STRLEN];
- zvrf = zvrf_info_lookup(zvni->vxlan_if->vrf);
+ zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug("Processing neighbors on local MAC %s %s, VNI %u",
struct interface *tmp_if = NULL;
struct zebra_if *zif = NULL;
- zvrf = zvrf_info_lookup(ifp->vrf);
+ zvrf = vrf_info_lookup(ifp->vrf_id);
assert(zvrf);
FOR_ALL_INTERFACES (zvrf->vrf, tmp_if) {
apply_mask(&p);
if (advertise)
- ip_prefix_send_to_client(vrf_to_id(ifp->vrf), &p,
+ ip_prefix_send_to_client(ifp->vrf_id, &p,
ZEBRA_IP_PREFIX_ROUTE_ADD);
else
- ip_prefix_send_to_client(vrf_to_id(ifp->vrf), &p,
+ ip_prefix_send_to_client(ifp->vrf_id, &p,
ZEBRA_IP_PREFIX_ROUTE_DEL);
}
return 0;
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
"%u:SVI %s(%u) VNI %u, sending GW MAC %s IP %s del to BGP",
- vrf_to_id(ifp->vrf), ifp->name, ifp->ifindex, zvni->vni,
+ ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni,
prefix_mac2str(&(n->emac), buf1, sizeof(buf1)),
ipaddr2str(ip, buf2, sizeof(buf2)));
/* Add primary SVI MAC*/
zvni = (zebra_vni_t *)bucket->data;
+ /* Global (Zvrf) advertise-default-gw is disabled,
+ * but zvni advertise-default-gw is enabled
+ */
+ if (zvni->advertise_gw_macip) {
+ if (IS_ZEBRA_DEBUG_VXLAN)
+ zlog_debug("VNI: %u GW-MACIP enabled, retain gw-macip",
+ zvni->vni);
+ return;
+ }
+
ifp = zvni->vxlan_if;
if (!ifp)
return;
if (!zvni)
return;
+ /* Global(vrf) advertise-svi-ip disabled, but zvni advertise-svi-ip
+ * enabled
+ */
+ if (zvni->advertise_svi_macip) {
+ if (IS_ZEBRA_DEBUG_VXLAN)
+ zlog_debug("VNI: %u SVI-MACIP enabled, retain svi-macip",
+ zvni->vni);
+ return;
+ }
+
ifp = zvni->vxlan_if;
if (!ifp)
return;
}
}
- zvrf = zvrf_info_lookup(zvni->vxlan_if->vrf);
+ zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
if (!zvrf) {
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug("\tUnable to find vrf for: %s",
- zvni->vxlan_if->vrf->name);
+ zlog_debug("\tUnable to find vrf for: %d",
+ zvni->vxlan_if->vrf_id);
return -1;
}
ifp->name, ifp->ifindex, vni,
inet_ntoa(vxl->vtep_ip));
- /* VNI hash entry is not expected to exist. */
+ /* VNI hash entry is expected to exist, if the BGP process is killed */
zvni = zvni_lookup(vni);
if (zvni) {
zlog_debug(
"VNI hash already present for IF %s(%u) L2-VNI %u",
ifp->name, ifp->ifindex, vni);
- continue;
- }
- zvni = zvni_add(vni);
- if (!zvni) {
- zlog_debug(
- "Failed to add VNI hash, IF %s(%u) L2-VNI %u",
- ifp->name, ifp->ifindex, vni);
- return;
- }
+ /*
+ * Inform BGP if intf is up and mapped to
+ * bridge.
+ */
+ if (if_is_operative(ifp) &&
+ zif->brslave_info.br_if)
+ zvni_send_add_to_client(zvni);
- if (zvni->local_vtep_ip.s_addr != vxl->vtep_ip.s_addr ||
- zvni->mcast_grp.s_addr != vxl->mcast_grp.s_addr) {
- zebra_vxlan_sg_deref(zvni->local_vtep_ip,
- zvni->mcast_grp);
- zebra_vxlan_sg_ref(vxl->vtep_ip,
- vxl->mcast_grp);
- zvni->local_vtep_ip = vxl->vtep_ip;
- zvni->mcast_grp = vxl->mcast_grp;
- }
- zvni->vxlan_if = ifp;
- vlan_if = zvni_map_to_svi(vxl->access_vlan,
- zif->brslave_info.br_if);
- if (vlan_if) {
- zvni->vrf_id = vrf_to_id(vlan_if->vrf);
- zl3vni = zl3vni_from_vrf(
- vrf_to_id(vlan_if->vrf));
- if (zl3vni)
- listnode_add_sort(zl3vni->l2vnis, zvni);
- }
+ /* Send Local MAC-entries to client */
+ zvni_send_mac_to_client(zvni);
+ /* Send Loval Neighbor entries to client */
+ zvni_send_neigh_to_client(zvni);
+ } else {
+ zvni = zvni_add(vni);
+ if (!zvni) {
+ zlog_debug(
+ "Failed to add VNI hash, IF %s(%u) L2-VNI %u",
+ ifp->name, ifp->ifindex, vni);
+ return;
+ }
+
+ if (zvni->local_vtep_ip.s_addr !=
+ vxl->vtep_ip.s_addr ||
+ zvni->mcast_grp.s_addr !=
+ vxl->mcast_grp.s_addr) {
+ zebra_vxlan_sg_deref(
+ zvni->local_vtep_ip,
+ zvni->mcast_grp);
+ zebra_vxlan_sg_ref(vxl->vtep_ip,
+ vxl->mcast_grp);
+ zvni->local_vtep_ip = vxl->vtep_ip;
+ zvni->mcast_grp = vxl->mcast_grp;
+ }
+ zvni->vxlan_if = ifp;
+ vlan_if = zvni_map_to_svi(vxl->access_vlan,
+ zif->brslave_info.br_if);
+ if (vlan_if) {
+ zvni->vrf_id = vlan_if->vrf_id;
+ zl3vni = zl3vni_from_vrf(
+ vlan_if->vrf_id);
+ if (zl3vni)
+ listnode_add_sort(
+ zl3vni->l2vnis, zvni);
+ }
- /* Inform BGP if intf is up and mapped to bridge. */
- if (if_is_operative(ifp) && zif->brslave_info.br_if)
- zvni_send_add_to_client(zvni);
+ /*
+ * Inform BGP if intf is up and mapped to
+ * bridge.
+ */
+ if (if_is_operative(ifp) &&
+ zif->brslave_info.br_if)
+ zvni_send_add_to_client(zvni);
+ }
}
}
}
return;
}
- zvrf = zvrf_info_lookup(zvni->vxlan_if->vrf);
+ zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
if (!zvrf)
return;
if (!mac && !n)
return;
- zvrf = zvrf_info_lookup(zvni->vxlan_if->vrf);
+ zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
/* Ignore the delete if this mac is a gateway mac-ip */
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)
vty_out(vty,
"Number of ARPs (local and remote) known for this VNI: %u\n",
num_neigh);
- vty_out(vty, "%*s %-6s %-8s %-17s %-21s\n",
- -wctx.addr_width, "IP", "Type",
- "State", "MAC", "Remote VTEP");
+ vty_out(vty, "%*s %-6s %-8s %-17s %-21s %s\n", -wctx.addr_width,
+ "IP", "Type", "State", "MAC", "Remote VTEP", "Seq #'s");
} else
json_object_int_add(json, "numArpNd", num_neigh);
vty_out(vty,
"Number of MACs (local and remote) known for this VNI: %u\n",
num_macs);
- vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
- "Intf/Remote VTEP", "VLAN");
+ vty_out(vty, "%-17s %-6s %-21s %-5s %s\n", "MAC", "Type",
+ "Intf/Remote VTEP", "VLAN", "Seq #'s");
} else
json_object_int_add(json, "numMacs", num_macs);
return 0;
}
- zvrf = zvrf_info_lookup(zvni->vxlan_if->vrf);
+ zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
if (!zvrf) {
zlog_debug("%s: VNI %u vrf lookup failed.",
__PRETTY_FUNCTION__, zvni->vni);
return -1;
}
- zvrf = zvrf_info_lookup(zvni->vxlan_if->vrf);
+ zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
if (!zvrf) {
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug("\tNo Vrf found for vrf_id: %s",
- zvni->vxlan_if->vrf->name);
+ zlog_debug("\tNo Vrf found for vrf_id: %d",
+ zvni->vxlan_if->vrf_id);
return -1;
}
zlog_debug(
"SVI %s(%u) VNI %u VRF %s is UP, installing neighbors",
ifp->name, ifp->ifindex, zvni->vni,
- vrf_to_name(ifp->vrf));
+ vrf_id_to_name(ifp->vrf_id));
/* update the vrf information for l2-vni and inform bgp */
- zvni->vrf_id = vrf_to_id(ifp->vrf);
+ zvni->vrf_id = ifp->vrf_id;
zvni_send_add_to_client(zvni);
/* Install any remote neighbors for this VNI. */
vlan_if = zvni_map_to_svi(vxl->access_vlan,
zif->brslave_info.br_if);
if (vlan_if) {
- zvni->vrf_id = vrf_to_id(vlan_if->vrf);
- zl3vni = zl3vni_from_vrf(vrf_to_id(vlan_if->vrf));
+ zvni->vrf_id = vlan_if->vrf_id;
+ zl3vni = zl3vni_from_vrf(vlan_if->vrf_id);
if (zl3vni)
listnode_add_sort(zl3vni->l2vnis, zvni);
}
vlan_if = zvni_map_to_svi(vxl->access_vlan,
zif->brslave_info.br_if);
if (vlan_if) {
- zvni->vrf_id = vrf_to_id(vlan_if->vrf);
- zl3vni = zl3vni_from_vrf(vrf_to_id(vlan_if->vrf));
+ zvni->vrf_id = vlan_if->vrf_id;
+ zl3vni = zl3vni_from_vrf(vlan_if->vrf_id);
if (zl3vni)
listnode_add_sort(zl3vni->l2vnis, zvni);
}
zlog_debug(
"Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %s mcast_grp %s master %u",
vni,
- vlan_if ? vrf_to_name(vlan_if->vrf)
+ vlan_if ? vrf_id_to_name(vlan_if->vrf_id)
: VRF_DEFAULT_NAME,
ifp->name, ifp->ifindex, vxl->access_vlan,
addr_buf1, addr_buf2,
struct interface *ifp = NULL;
if (!EVPN_ENABLED(zvrf)) {
- zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u",
+ zlog_debug("EVPN SVI-MACIP Adv for non-EVPN VRF %u",
zvrf_id(zvrf));
return;
}
if (!vni) {
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug("EVPN gateway macip Adv %s, currently %s",
+ zlog_debug("EVPN SVI-MACIP Adv %s, currently %s",
advertise ? "enabled" : "disabled",
advertise_gw_macip_enabled(NULL)
? "enabled"
zebra_vxlan_sg_del(vxlan_sg);
}
+
+/************************** EVPN BGP config management ************************/
+/* Notify Local MACs to the clienti, skips GW MAC */
+static void zvni_send_mac_hash_entry_to_client(struct hash_bucket *bucket,
+ void *arg)
+{
+ struct mac_walk_ctx *wctx = arg;
+ zebra_mac_t *zmac = bucket->data;
+
+ if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_DEF_GW))
+ return;
+
+ if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_LOCAL))
+ zvni_mac_send_add_to_client(wctx->zvni->vni, &zmac->macaddr,
+ zmac->flags, zmac->loc_seq);
+}
+
+/* Iterator to Notify Local MACs of a L2VNI */
+static void zvni_send_mac_to_client(zebra_vni_t *zvni)
+{
+ struct mac_walk_ctx wctx;
+
+ if (!zvni->mac_table)
+ return;
+
+ memset(&wctx, 0, sizeof(struct mac_walk_ctx));
+ wctx.zvni = zvni;
+
+ hash_iterate(zvni->mac_table, zvni_send_mac_hash_entry_to_client,
+ &wctx);
+}
+
+/* Notify Neighbor entries to the Client, skips the GW entry */
+static void zvni_send_neigh_hash_entry_to_client(struct hash_bucket *bucket,
+ void *arg)
+{
+ struct mac_walk_ctx *wctx = arg;
+ zebra_neigh_t *zn = bucket->data;
+ zebra_mac_t *zmac = NULL;
+
+ if (CHECK_FLAG(zn->flags, ZEBRA_NEIGH_DEF_GW))
+ return;
+
+ if (CHECK_FLAG(zn->flags, ZEBRA_NEIGH_LOCAL) &&
+ IS_ZEBRA_NEIGH_ACTIVE(zn)) {
+ zmac = zvni_mac_lookup(wctx->zvni, &zn->emac);
+ if (!zmac)
+ return;
+
+ zvni_neigh_send_add_to_client(wctx->zvni->vni, &zn->ip,
+ &zn->emac, zn->flags,
+ zn->loc_seq);
+ }
+}
+
+/* Iterator of a specific L2VNI */
+static void zvni_send_neigh_to_client(zebra_vni_t *zvni)
+{
+ struct neigh_walk_ctx wctx;
+
+ memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
+ wctx.zvni = zvni;
+
+ hash_iterate(zvni->neigh_table, zvni_send_neigh_hash_entry_to_client,
+ &wctx);
+}
+
+static void zvni_evpn_cfg_cleanup(struct hash_bucket *bucket, void *ctxt)
+{
+ zebra_vni_t *zvni = NULL;
+
+ zvni = (zebra_vni_t *)bucket->data;
+ zvni->advertise_gw_macip = 0;
+ zvni->advertise_svi_macip = 0;
+ zvni->advertise_subnet = 0;
+
+ zvni_neigh_del_all(zvni, 0, 0,
+ DEL_REMOTE_NEIGH | DEL_REMOTE_NEIGH_FROM_VTEP);
+ zvni_mac_del_all(zvni, 0, 0,
+ DEL_REMOTE_MAC | DEL_REMOTE_MAC_FROM_VTEP);
+ zvni_vtep_del_all(zvni, 0);
+}
+
+/* Cleanup EVPN configuration of a specific VRF */
+static void zebra_evpn_vrf_cfg_cleanup(struct zebra_vrf *zvrf)
+{
+ zvrf->advertise_all_vni = 0;
+ zvrf->advertise_gw_macip = 0;
+ zvrf->advertise_svi_macip = 0;
+ zvrf->vxlan_flood_ctrl = VXLAN_FLOOD_HEAD_END_REPL;
+
+ hash_iterate(zvrf->vni_table, zvni_evpn_cfg_cleanup, NULL);
+}
+
+/* Cleanup BGP EVPN configuration upon client disconnect */
+static int zebra_evpn_cfg_clean_up(struct zserv *client)
+{
+ struct vrf *vrf;
+ struct zebra_vrf *zvrf;
+
+ if (client->proto != ZEBRA_ROUTE_BGP)
+ return 0;
+
+ RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
+ zvrf = vrf->info;
+ if (zvrf)
+ zebra_evpn_vrf_cfg_cleanup(zvrf);
+ }
+
+ return 0;
+}
+
+/* Cleanup BGP EVPN configuration upon client disconnect */
+extern void zebra_evpn_init(void)
+{
+ hook_register(zserv_client_close, zebra_evpn_cfg_clean_up);
+}
extern int zebra_vxlan_clear_dup_detect_vni(struct vty *vty,
struct zebra_vrf *zvrf,
vni_t vni);
+extern void zebra_evpn_init(void);
#ifdef __cplusplus
}