summaryrefslogtreecommitdiff
path: root/zebra/interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/interface.c')
-rw-r--r--zebra/interface.c2918
1 files changed, 958 insertions, 1960 deletions
diff --git a/zebra/interface.c b/zebra/interface.c
index 496a85e676..b824977f9e 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -18,7 +18,6 @@
#include "log.h"
#include "zclient.h"
#include "vrf.h"
-#include "lib/northbound_cli.h"
#include "zebra/rtadv.h"
#include "zebra_ns.h"
@@ -44,8 +43,6 @@ DEFINE_MTYPE_STATIC(ZEBRA, ZINFO, "Zebra Interface Information");
DEFINE_HOOK(zebra_if_extra_info, (struct vty * vty, struct interface *ifp),
(vty, ifp));
-DEFINE_HOOK(zebra_if_config_wr, (struct vty * vty, struct interface *ifp),
- (vty, ifp));
DEFINE_MTYPE(ZEBRA, ZIF_DESC, "Intf desc");
@@ -65,7 +62,7 @@ static void if_zebra_speed_update(struct event *thread)
* interfaces not available.
* note that loopback & virtual interfaces can return 0 as speed
*/
- if (error < 0)
+ if (error == INTERFACE_SPEED_ERROR_READ)
return;
if (new_speed != ifp->speed) {
@@ -76,7 +73,7 @@ static void if_zebra_speed_update(struct event *thread)
changed = true;
}
- if (changed || new_speed == UINT32_MAX) {
+ if (changed || error == INTERFACE_SPEED_ERROR_UNKNOWN) {
#define SPEED_UPDATE_SLEEP_TIME 5
#define SPEED_UPDATE_COUNT_MAX (4 * 60 / SPEED_UPDATE_SLEEP_TIME)
/*
@@ -91,7 +88,7 @@ static void if_zebra_speed_update(struct event *thread)
* to not update the system to keep track of that. This
* is far simpler to just stop trying after 4 minutes
*/
- if (new_speed == UINT32_MAX &&
+ if (error == INTERFACE_SPEED_ERROR_UNKNOWN &&
zif->speed_update_count == SPEED_UPDATE_COUNT_MAX)
return;
@@ -111,17 +108,6 @@ static void zebra_if_node_destroy(route_table_delegate_t *delegate,
route_node_destroy(delegate, table, node);
}
-static void zebra_if_nhg_dependents_free(struct zebra_if *zebra_if)
-{
- nhg_connected_tree_free(&zebra_if->nhg_dependents);
-}
-
-static void zebra_if_nhg_dependents_init(struct zebra_if *zebra_if)
-{
- nhg_connected_tree_init(&zebra_if->nhg_dependents);
-}
-
-
route_table_delegate_t zebra_if_table_delegate = {
.create_node = route_node_create,
.destroy_node = zebra_if_node_destroy};
@@ -135,11 +121,12 @@ static int if_zebra_new_hook(struct interface *ifp)
zebra_if->ifp = ifp;
zebra_if->multicast = IF_ZEBRA_DATA_UNSPEC;
- zebra_if->shutdown = IF_ZEBRA_DATA_OFF;
+ zebra_if->mpls_config = IF_ZEBRA_DATA_UNSPEC;
+ zebra_if->shutdown = IF_ZEBRA_DATA_UNSPEC;
zebra_if->link_nsid = NS_UNKNOWN;
- zebra_if_nhg_dependents_init(zebra_if);
+ nhg_connected_tree_init(&zebra_if->nhg_dependents);
zebra_ptm_if_init(zebra_if);
@@ -147,6 +134,8 @@ static int if_zebra_new_hook(struct interface *ifp)
rtadv_if_init(zebra_if);
+ zebra_evpn_mh_if_init(zebra_if);
+
memset(&zebra_if->neigh_mac[0], 0, 6);
/* Initialize installed address chains tree. */
@@ -170,18 +159,13 @@ static int if_zebra_new_hook(struct interface *ifp)
return 0;
}
-static void if_nhg_dependents_check_valid(struct nhg_hash_entry *nhe)
-{
- zebra_nhg_check_valid(nhe);
-}
-
static void if_down_nhg_dependents(const struct interface *ifp)
{
struct nhg_connected *rb_node_dep = NULL;
struct zebra_if *zif = (struct zebra_if *)ifp->info;
frr_each(nhg_connected_tree, &zif->nhg_dependents, rb_node_dep)
- if_nhg_dependents_check_valid(rb_node_dep->nhe);
+ zebra_nhg_check_valid(rb_node_dep->nhe);
}
static void if_nhg_dependents_release(const struct interface *ifp)
@@ -191,7 +175,11 @@ static void if_nhg_dependents_release(const struct interface *ifp)
frr_each(nhg_connected_tree, &zif->nhg_dependents, rb_node_dep) {
rb_node_dep->nhe->ifp = NULL; /* Null it out */
- if_nhg_dependents_check_valid(rb_node_dep->nhe);
+ zebra_nhg_check_valid(rb_node_dep->nhe);
+ if (CHECK_FLAG(rb_node_dep->nhe->flags,
+ NEXTHOP_GROUP_KEEP_AROUND) &&
+ rb_node_dep->nhe->refcnt == 1)
+ zebra_nhg_decrement_ref(rb_node_dep->nhe);
}
}
@@ -199,6 +187,7 @@ static void if_nhg_dependents_release(const struct interface *ifp)
static int if_zebra_delete_hook(struct interface *ifp)
{
struct zebra_if *zebra_if;
+ struct zebra_l2info_bond *bond;
if (ifp->info) {
zebra_if = ifp->info;
@@ -216,12 +205,16 @@ static int if_zebra_delete_hook(struct interface *ifp)
rtadv_if_fini(zebra_if);
+ bond = &zebra_if->bond_info;
+ if (bond && bond->mbr_zifs)
+ list_delete(&bond->mbr_zifs);
+
zebra_l2_bridge_if_cleanup(ifp);
zebra_evpn_if_cleanup(zebra_if);
zebra_evpn_mac_ifp_del(ifp);
if_nhg_dependents_release(ifp);
- zebra_if_nhg_dependents_free(zebra_if);
+ nhg_connected_tree_free(&zebra_if->nhg_dependents);
XFREE(MTYPE_ZIF_DESC, zebra_if->desc);
@@ -267,6 +260,9 @@ struct interface *if_link_per_ns(struct zebra_ns *ns, struct interface *ifp)
/* Delete a VRF. This is called in vrf_terminate(). */
void if_unlink_per_ns(struct interface *ifp)
{
+ if (!ifp->node)
+ return;
+
ifp->node->info = NULL;
route_unlock_node(ifp->node);
ifp->node = NULL;
@@ -480,12 +476,11 @@ void if_flags_update(struct interface *ifp, uint64_t newflags)
address. */
void if_addr_wakeup(struct interface *ifp)
{
- struct listnode *node, *nnode;
struct connected *ifc;
struct prefix *p;
enum zebra_dplane_result dplane_res;
- for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, ifc)) {
+ frr_each_safe (if_connected, ifp->connected, ifc) {
p = ifc->address;
if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)
@@ -606,6 +601,11 @@ void if_add_update(struct interface *ifp)
if_addr_wakeup(ifp);
+ if (if_data->mpls_config == IF_ZEBRA_DATA_ON)
+ dplane_intf_mpls_modify_state(ifp, true);
+ else if (if_data->mpls_config == IF_ZEBRA_DATA_OFF)
+ dplane_intf_mpls_modify_state(ifp, false);
+
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug(
"interface %s vrf %s(%u) index %d becomes active.",
@@ -623,32 +623,24 @@ void if_add_update(struct interface *ifp)
/* Install connected routes corresponding to an interface. */
static void if_install_connected(struct interface *ifp)
{
- struct listnode *node;
- struct listnode *next;
struct connected *ifc;
- if (ifp->connected) {
- for (ALL_LIST_ELEMENTS(ifp->connected, node, next, ifc)) {
- if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
- zebra_interface_address_add_update(ifp, ifc);
+ frr_each (if_connected, ifp->connected, ifc) {
+ if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
+ zebra_interface_address_add_update(ifp, ifc);
- connected_up(ifp, ifc);
- }
+ connected_up(ifp, ifc);
}
}
/* Uninstall connected routes corresponding to an interface. */
static void if_uninstall_connected(struct interface *ifp)
{
- struct listnode *node;
- struct listnode *next;
struct connected *ifc;
- if (ifp->connected) {
- for (ALL_LIST_ELEMENTS(ifp->connected, node, next, ifc)) {
- zebra_interface_address_delete_update(ifp, ifc);
- connected_down(ifp, ifc);
- }
+ frr_each_safe (if_connected, ifp->connected, ifc) {
+ zebra_interface_address_delete_update(ifp, ifc);
+ connected_down(ifp, ifc);
}
}
@@ -656,20 +648,15 @@ static void if_uninstall_connected(struct interface *ifp)
/* TODO - Check why IPv4 handling here is different from install or if_down */
static void if_delete_connected(struct interface *ifp)
{
- struct connected *ifc;
+ struct connected *ifc, *ifc_next;
struct prefix cp;
struct route_node *rn;
struct zebra_if *zebra_if;
- struct listnode *node;
- struct listnode *last = NULL;
zebra_if = ifp->info;
- if (!ifp->connected)
- return;
-
- while ((node = (last ? last->next : listhead(ifp->connected)))) {
- ifc = listgetdata(node);
+ for (ifc = if_connected_first(ifp->connected); ifc; ifc = ifc_next) {
+ ifc_next = if_connected_next(ifp->connected, ifc);
cp = *CONNECTED_PREFIX(ifc);
apply_mask(&cp);
@@ -718,11 +705,15 @@ static void if_delete_connected(struct interface *ifp)
* (unconditionally). */
if (!CHECK_FLAG(ifc->conf,
ZEBRA_IFC_CONFIGURED)) {
- listnode_delete(ifp->connected,
+ if (ifc == ifc_next)
+ ifc_next = if_connected_next(
+ ifp->connected,
ifc);
+
+ if_connected_del(ifp->connected,
+ ifc);
connected_free(&ifc);
- } else
- last = node;
+ }
}
/* Free chain list and respective route node. */
@@ -737,14 +728,10 @@ static void if_delete_connected(struct interface *ifp)
UNSET_FLAG(ifc->conf, ZEBRA_IFC_REAL);
UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
- if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
- last = node;
- else {
- listnode_delete(ifp->connected, ifc);
+ if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)) {
+ if_connected_del(ifp->connected, ifc);
connected_free(&ifc);
}
- } else {
- last = node;
}
}
}
@@ -778,6 +765,15 @@ void if_delete_update(struct interface **pifp)
/* Delete connected routes from the kernel. */
if_delete_connected(ifp);
+ /* if the ifp is in a vrf, move it to default so vrf can be deleted if
+ * desired. This operation is not done for netns implementation to avoid
+ * collision with interface with the same name in the default vrf (can
+ * occur with this implementation whereas it is not possible with
+ * vrf-lite).
+ */
+ if (ifp->vrf->vrf_id && !vrf_is_backend_netns())
+ if_handle_vrf_change(ifp, VRF_DEFAULT);
+
/* Send out notification on interface delete. */
zebra_interface_delete_update(ifp);
@@ -791,14 +787,7 @@ void if_delete_update(struct interface **pifp)
if_set_index(ifp, IFINDEX_INTERNAL);
ifp->node = NULL;
- /* if the ifp is in a vrf, move it to default so vrf can be deleted if
- * desired. This operation is not done for netns implementation to avoid
- * collision with interface with the same name in the default vrf (can
- * occur with this implementation whereas it is not possible with
- * vrf-lite).
- */
- if (ifp->vrf->vrf_id && !vrf_is_backend_netns())
- if_handle_vrf_change(ifp, VRF_DEFAULT);
+ UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK);
/* Reset some zebra interface params to default values. */
zif = ifp->info;
@@ -837,9 +826,12 @@ void if_handle_vrf_change(struct interface *ifp, vrf_id_t vrf_id)
if_down_del_nbr_connected(ifp);
/* Send out notification on interface VRF change. */
- /* This is to issue an UPDATE or a DELETE, as appropriate. */
+ /* This is to issue a DELETE, as appropriate. */
zebra_interface_vrf_update_del(ifp, vrf_id);
+ if (if_is_vrf(ifp))
+ return;
+
/* update VRF */
if_update_to_new_vrf(ifp, vrf_id);
@@ -955,47 +947,6 @@ static void if_down_del_nbr_connected(struct interface *ifp)
}
}
-void if_nhg_dependents_add(struct interface *ifp, struct nhg_hash_entry *nhe)
-{
- if (ifp->info) {
- struct zebra_if *zif = (struct zebra_if *)ifp->info;
-
- nhg_connected_tree_add_nhe(&zif->nhg_dependents, nhe);
- }
-}
-
-void if_nhg_dependents_del(struct interface *ifp, struct nhg_hash_entry *nhe)
-{
- if (ifp->info) {
- struct zebra_if *zif = (struct zebra_if *)ifp->info;
-
- nhg_connected_tree_del_nhe(&zif->nhg_dependents, nhe);
- }
-}
-
-unsigned int if_nhg_dependents_count(const struct interface *ifp)
-{
- if (ifp->info) {
- struct zebra_if *zif = (struct zebra_if *)ifp->info;
-
- return nhg_connected_tree_count(&zif->nhg_dependents);
- }
-
- return 0;
-}
-
-
-bool if_nhg_dependents_is_empty(const struct interface *ifp)
-{
- if (ifp->info) {
- struct zebra_if *zif = (struct zebra_if *)ifp->info;
-
- return nhg_connected_tree_is_empty(&zif->nhg_dependents);
- }
-
- return false;
-}
-
/* Interface is up. */
void if_up(struct interface *ifp, bool install_connected)
{
@@ -1023,6 +974,14 @@ void if_up(struct interface *ifp, bool install_connected)
if (install_connected)
if_install_connected(ifp);
+ /*
+ * Interface associated NHG's have been deleted on
+ * interface down events, now that this interface
+ * is coming back up, let's resync the zebra -> dplane
+ * nhg's so that they can be continued to be used.
+ */
+ zebra_interface_nhg_reinstall(ifp);
+
/* Handle interface up for specific types for EVPN. Non-VxLAN interfaces
* are checked to see if (remote) neighbor entries need to be installed
* on them for ARP suppression.
@@ -1049,6 +1008,8 @@ void if_up(struct interface *ifp, bool install_connected)
event_add_timer(zrouter.master, if_zebra_speed_update, ifp, 0,
&zif->speed_update);
event_ignore_late_timer(zif->speed_update);
+
+ if_addr_wakeup(ifp);
}
/* Interface goes down. We have to manage different behavior of based
@@ -1112,8 +1073,6 @@ void zebra_if_update_link(struct interface *ifp, ifindex_t link_ifindex,
{
struct zebra_if *zif;
- if (IS_ZEBRA_IF_VETH(ifp))
- return;
zif = (struct zebra_if *)ifp->info;
zif->link_nsid = ns_id;
zif->link_ifindex = link_ifindex;
@@ -1176,6 +1135,12 @@ static bool if_ignore_set_protodown(const struct interface *ifp, bool new_down,
zif = ifp->info;
+ /*
+ * FRR does not have enough data to make this request
+ */
+ if (ifp->ifindex == IFINDEX_INTERNAL)
+ return true;
+
/* Current state as we know it */
old_down = !!(ZEBRA_IF_IS_PROTODOWN(zif));
old_set_down = !!CHECK_FLAG(zif->flags, ZIF_FLAG_SET_PROTODOWN);
@@ -1285,6 +1250,9 @@ static void zebra_if_addr_update_ctx(struct zebra_dplane_ctx *ctx,
const struct prefix *addr, *dest = NULL;
enum dplane_op_e op;
+ if (!ifp)
+ return;
+
op = dplane_ctx_get_op(ctx);
addr = dplane_ctx_get_intf_addr(ctx);
@@ -1305,6 +1273,9 @@ static void zebra_if_addr_update_ctx(struct zebra_dplane_ctx *ctx,
if (dplane_ctx_intf_is_secondary(ctx))
SET_FLAG(flags, ZEBRA_IFA_SECONDARY);
+ if (dplane_ctx_intf_is_noprefixroute(ctx))
+ SET_FLAG(flags, ZEBRA_IFA_NOPREFIXROUTE);
+
/* Label? */
if (dplane_ctx_intf_has_label(ctx))
label = dplane_ctx_get_intf_label(ctx);
@@ -1356,6 +1327,13 @@ static void zebra_if_update_ctx(struct zebra_dplane_ctx *ctx,
bool pd_reason_val;
bool down;
+ if (!ifp) {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug("%s: Can't find ifp", __func__);
+
+ return;
+ }
+
dp_res = dplane_ctx_get_status(ctx);
pd_reason_val = dplane_ctx_get_intf_pd_reason_val(ctx);
down = dplane_ctx_intf_is_protodown(ctx);
@@ -1403,6 +1381,13 @@ static void zebra_if_netconf_update_ctx(struct zebra_dplane_ctx *ctx,
enum dplane_netconf_status_e mpls, mcast_on, linkdown;
bool *mcast_set, *linkdown_set;
+ if (!ifp && ifindex != -1 && ifindex != -2) {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug("%s: Can't find ifp(%u)", __func__, ifindex);
+
+ return;
+ }
+
afi = dplane_ctx_get_afi(ctx);
mpls = dplane_ctx_get_netconf_mpls(ctx);
linkdown = dplane_ctx_get_netconf_linkdown(ctx);
@@ -1425,7 +1410,7 @@ static void zebra_if_netconf_update_ctx(struct zebra_dplane_ctx *ctx,
linkdown_set = &zrouter.default_linkdownv6;
}
} else {
- zif = ifp ? ifp->info : NULL;
+ zif = ifp->info;
if (!zif) {
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug(
@@ -1472,6 +1457,762 @@ static void zebra_if_netconf_update_ctx(struct zebra_dplane_ctx *ctx,
(*linkdown_set ? "ON" : "OFF"));
}
+static void interface_vrf_change(enum dplane_op_e op, ifindex_t ifindex,
+ const char *name, uint32_t tableid,
+ ns_id_t ns_id)
+{
+ struct vrf *vrf;
+ struct zebra_vrf *zvrf = NULL;
+
+ if (op == DPLANE_OP_INTF_DELETE) {
+ if (IS_ZEBRA_DEBUG_DPLANE)
+ zlog_debug("DPLANE_OP_INTF_DELETE for VRF %s(%u)", name,
+ ifindex);
+
+ vrf = vrf_lookup_by_id((vrf_id_t)ifindex);
+ if (!vrf) {
+ flog_warn(EC_ZEBRA_VRF_NOT_FOUND,
+ "%s(%u): vrf not found", name, ifindex);
+ return;
+ }
+
+ vrf_delete(vrf);
+ } else {
+ if (IS_ZEBRA_DEBUG_DPLANE)
+ zlog_debug(
+ "DPLANE_OP_INTF_UPDATE for VRF %s(%u) table %u",
+ name, ifindex, tableid);
+
+ if (!vrf_lookup_by_id((vrf_id_t)ifindex)) {
+ vrf_id_t exist_id;
+
+ exist_id = zebra_vrf_lookup_by_table(tableid, ns_id);
+ if (exist_id != VRF_DEFAULT) {
+ vrf = vrf_lookup_by_id(exist_id);
+
+ if (vrf)
+ flog_err(EC_ZEBRA_VRF_MISCONFIGURED,
+ "VRF %s id %u table id overlaps existing vrf %s(%d), misconfiguration exiting",
+ name, ifindex, vrf->name,
+ vrf->vrf_id);
+ else
+ flog_err(EC_ZEBRA_VRF_NOT_FOUND,
+ "VRF %s id %u does not exist",
+ name, ifindex);
+
+ exit(-1);
+ }
+ }
+
+ vrf = vrf_update((vrf_id_t)ifindex, name);
+ if (!vrf) {
+ flog_err(EC_LIB_INTERFACE, "VRF %s id %u not created",
+ name, ifindex);
+ return;
+ }
+
+ /*
+ * This is the only place that we get the actual kernel table_id
+ * being used. We need it to set the table_id of the routes
+ * we are passing to the kernel.... And to throw some totally
+ * awesome parties. that too.
+ *
+ * At this point we *must* have a zvrf because the vrf_create
+ * callback creates one. We *must* set the table id
+ * before the vrf_enable because of( at the very least )
+ * static routes being delayed for installation until
+ * during the vrf_enable callbacks.
+ */
+ zvrf = (struct zebra_vrf *)vrf->info;
+ zvrf->table_id = tableid;
+
+ /* Enable the created VRF. */
+ if (!vrf_enable(vrf)) {
+ flog_err(EC_LIB_INTERFACE,
+ "Failed to enable VRF %s id %u", name,
+ ifindex);
+ return;
+ }
+ }
+}
+
+/*
+ * Note: on netlink systems, there should be a 1-to-1 mapping
+ * between interface names and ifindex values.
+ */
+static void set_ifindex(struct interface *ifp, ifindex_t ifi_index,
+ struct zebra_ns *zns)
+{
+ struct interface *oifp;
+
+ oifp = if_lookup_by_index_per_ns(zns, ifi_index);
+ if ((oifp != NULL) && (oifp != ifp)) {
+ if (ifi_index == IFINDEX_INTERNAL)
+ flog_err(
+ EC_LIB_INTERFACE,
+ "Netlink is setting interface %s ifindex to reserved internal value %u",
+ ifp->name, ifi_index);
+ else {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "interface index %d was renamed from %s to %s",
+ ifi_index, oifp->name, ifp->name);
+ if (if_is_up(oifp))
+ flog_err(
+ EC_LIB_INTERFACE,
+ "interface rename detected on up interface: index %d was renamed from %s to %s, results are uncertain!",
+ ifi_index, oifp->name, ifp->name);
+ if_delete_update(&oifp);
+ }
+ }
+ if_set_index(ifp, ifi_index);
+}
+
+static inline void zebra_if_set_ziftype(struct interface *ifp,
+ enum zebra_iftype zif_type,
+ enum zebra_slave_iftype zif_slave_type)
+{
+ struct zebra_if *zif;
+
+ zif = (struct zebra_if *)ifp->info;
+ zif->zif_slave_type = zif_slave_type;
+
+ if (zif->zif_type != zif_type) {
+ zif->zif_type = zif_type;
+ /* If the if_type has been set to bond initialize ES info
+ * against it. XXX - note that we don't handle the case where
+ * a zif changes from bond to non-bond; it is really
+ * an unexpected/error condition.
+ */
+ zebra_evpn_if_init(zif);
+ }
+}
+
+static void interface_update_hw_addr(struct zebra_dplane_ctx *ctx,
+ struct interface *ifp)
+{
+ int i;
+
+ ifp->hw_addr_len = dplane_ctx_get_ifp_hw_addr_len(ctx);
+ memcpy(ifp->hw_addr, dplane_ctx_get_ifp_hw_addr(ctx), ifp->hw_addr_len);
+
+ for (i = 0; i < ifp->hw_addr_len; i++)
+ if (ifp->hw_addr[i] != 0)
+ break;
+
+ if (i == ifp->hw_addr_len)
+ ifp->hw_addr_len = 0;
+}
+
+static void interface_update_l2info(struct zebra_dplane_ctx *ctx,
+ struct interface *ifp,
+ enum zebra_iftype zif_type, int add,
+ ns_id_t link_nsid)
+{
+ const struct zebra_l2info_vxlan *vxlan_info;
+ const struct zebra_l2info_gre *gre_info;
+
+ switch (zif_type) {
+ case ZEBRA_IF_BRIDGE:
+ zebra_l2_bridge_add_update(ifp,
+ dplane_ctx_get_ifp_bridge_info(ctx));
+ break;
+ case ZEBRA_IF_VLAN:
+ zebra_l2_vlanif_update(ifp, dplane_ctx_get_ifp_vlan_info(ctx));
+ zebra_evpn_acc_bd_svi_set(ifp->info, NULL,
+ !!if_is_operative(ifp));
+ break;
+ case ZEBRA_IF_VXLAN:
+ vxlan_info = dplane_ctx_get_ifp_vxlan_info(ctx);
+ zebra_l2_vxlanif_add_update(ifp, vxlan_info, add);
+ if (link_nsid != NS_UNKNOWN && vxlan_info->ifindex_link)
+ zebra_if_update_link(ifp, vxlan_info->ifindex_link,
+ link_nsid);
+ break;
+ case ZEBRA_IF_GRE:
+ gre_info = dplane_ctx_get_ifp_gre_info(ctx);
+ zebra_l2_greif_add_update(ifp, gre_info, add);
+ if (link_nsid != NS_UNKNOWN && gre_info->ifindex_link)
+ zebra_if_update_link(ifp, gre_info->ifindex_link,
+ link_nsid);
+ break;
+ case ZEBRA_IF_OTHER:
+ case ZEBRA_IF_VRF:
+ case ZEBRA_IF_MACVLAN:
+ case ZEBRA_IF_VETH:
+ case ZEBRA_IF_BOND:
+ break;
+ }
+}
+
+static bool is_if_protodown_reason_only_frr(uint32_t rc_bitfield)
+{
+ uint8_t frr_protodown_r_bit = if_netlink_get_frr_protodown_r_bit();
+
+ return (rc_bitfield == (((uint32_t)1) << frr_protodown_r_bit));
+}
+
+static void interface_if_protodown(struct interface *ifp, bool protodown,
+ uint32_t rc_bitfield)
+{
+ struct zebra_if *zif = ifp->info;
+ bool old_protodown;
+
+ /*
+ * Set our reason code to note it wasn't us.
+ * If the reason we got from the kernel is ONLY frr though, don't
+ * set it.
+ */
+ COND_FLAG(zif->protodown_rc, ZEBRA_PROTODOWN_EXTERNAL,
+ protodown && rc_bitfield &&
+ !is_if_protodown_reason_only_frr(rc_bitfield));
+
+
+ old_protodown = !!ZEBRA_IF_IS_PROTODOWN(zif);
+ if (protodown == old_protodown)
+ return;
+
+ if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_DPLANE)
+ zlog_debug("interface %s dplane change, protodown %s",
+ ifp->name, protodown ? "on" : "off");
+
+ /* Set protodown, respectively */
+ COND_FLAG(zif->flags, ZIF_FLAG_PROTODOWN, protodown);
+
+ if (zebra_evpn_is_es_bond_member(ifp)) {
+ /* Check it's not already being sent to the dplane first */
+ if (protodown &&
+ CHECK_FLAG(zif->flags, ZIF_FLAG_SET_PROTODOWN)) {
+ if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "bond mbr %s protodown on recv'd but already sent protodown on to the dplane",
+ ifp->name);
+ return;
+ }
+
+ if (!protodown &&
+ CHECK_FLAG(zif->flags, ZIF_FLAG_UNSET_PROTODOWN)) {
+ if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "bond mbr %s protodown off recv'd but already sent protodown off to the dplane",
+ ifp->name);
+ return;
+ }
+
+ if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "bond mbr %s reinstate protodown %s in the dplane",
+ ifp->name, old_protodown ? "on" : "off");
+
+ if (old_protodown)
+ SET_FLAG(zif->flags, ZIF_FLAG_SET_PROTODOWN);
+ else
+ SET_FLAG(zif->flags, ZIF_FLAG_UNSET_PROTODOWN);
+
+ dplane_intf_update(zif->ifp);
+ }
+}
+
+static void if_sweep_protodown(struct zebra_if *zif)
+{
+ bool protodown;
+
+ protodown = !!ZEBRA_IF_IS_PROTODOWN(zif);
+
+ if (!protodown)
+ return;
+
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug("interface %s sweeping protodown %s reason 0x%x",
+ zif->ifp->name, protodown ? "on" : "off",
+ zif->protodown_rc);
+
+ /* Only clear our reason codes, leave external if it was set */
+ UNSET_FLAG(zif->protodown_rc, ZEBRA_PROTODOWN_ALL);
+ dplane_intf_update(zif->ifp);
+}
+
+static void
+interface_bridge_vxlan_vlan_vni_map_update(struct zebra_dplane_ctx *ctx,
+ struct interface *ifp)
+{
+ const struct zebra_vxlan_vni_array *vniarray =
+ dplane_ctx_get_ifp_vxlan_vni_array(ctx);
+ struct zebra_vxlan_vni vni_start, vni_end;
+ struct hash *vni_table = NULL;
+ struct zebra_vxlan_vni vni, *vnip;
+ vni_t vni_id;
+ vlanid_t vid;
+ int i;
+
+ if (vniarray == NULL)
+ return;
+
+ memset(&vni_start, 0, sizeof(vni_start));
+ memset(&vni_end, 0, sizeof(vni_end));
+
+ for (i = 0; i < vniarray->count; i++) {
+ uint16_t flags = vniarray->vnis[i].flags;
+
+ if (flags & DPLANE_BRIDGE_VLAN_INFO_RANGE_BEGIN) {
+ vni_start = vniarray->vnis[i];
+ continue;
+ }
+
+ if (flags & DPLANE_BRIDGE_VLAN_INFO_RANGE_END)
+ vni_end = vniarray->vnis[i];
+
+ if (!(flags & DPLANE_BRIDGE_VLAN_INFO_RANGE_END)) {
+ vni_start = vniarray->vnis[i];
+ vni_end = vniarray->vnis[i];
+ }
+
+ if (IS_ZEBRA_DEBUG_DPLANE)
+ zlog_debug(
+ "Vlan-Vni(%d:%d-%d:%d) update for VxLAN IF %s(%u)",
+ vni_start.access_vlan, vni_end.access_vlan,
+ vni_start.vni, vni_end.vni, ifp->name,
+ ifp->ifindex);
+
+ if (!vni_table) {
+ vni_table = zebra_vxlan_vni_table_create();
+ if (!vni_table)
+ return;
+ }
+
+ for (vid = vni_start.access_vlan, vni_id = vni_start.vni;
+ vid <= vni_end.access_vlan; vid++, vni_id++) {
+
+ memset(&vni, 0, sizeof(vni));
+ vni.vni = vni_id;
+ vni.access_vlan = vid;
+ vnip = hash_get(vni_table, &vni, zebra_vxlan_vni_alloc);
+ if (!vnip)
+ return;
+ }
+
+ memset(&vni_start, 0, sizeof(vni_start));
+ memset(&vni_end, 0, sizeof(vni_end));
+ }
+
+ if (vni_table)
+ zebra_vxlan_if_vni_table_add_update(ifp, vni_table);
+}
+
+static void interface_bridge_vxlan_update(struct zebra_dplane_ctx *ctx,
+ struct interface *ifp)
+{
+ struct zebra_if *zif = ifp->info;
+ const struct zebra_dplane_bridge_vlan_info *bvinfo;
+
+ if (dplane_ctx_get_ifp_no_afspec(ctx))
+ return;
+
+ if (IS_ZEBRA_VXLAN_IF_SVD(zif))
+ interface_bridge_vxlan_vlan_vni_map_update(ctx, ifp);
+
+ if (dplane_ctx_get_ifp_no_bridge_vlan_info(ctx))
+ return;
+
+ bvinfo = dplane_ctx_get_ifp_bridge_vlan_info(ctx);
+
+ if (!(bvinfo->flags & DPLANE_BRIDGE_VLAN_INFO_PVID))
+ return;
+
+ if (IS_ZEBRA_DEBUG_DPLANE)
+ zlog_debug("Access VLAN %u for VxLAN IF %s(%u)", bvinfo->vid,
+ ifp->name, ifp->ifindex);
+
+ zebra_l2_vxlanif_update_access_vlan(ifp, bvinfo->vid);
+}
+
+static void interface_bridge_vlan_update(struct zebra_dplane_ctx *ctx,
+ struct interface *ifp)
+{
+ struct zebra_if *zif = ifp->info;
+ const struct zebra_dplane_bridge_vlan_info_array *bvarray;
+ struct zebra_dplane_bridge_vlan_info bvinfo;
+ bitfield_t old_vlan_bitmap;
+ uint16_t vid_range_start = 0;
+ int32_t i;
+
+ /* cache the old bitmap addrs */
+ old_vlan_bitmap = zif->vlan_bitmap;
+ /* create a new bitmap space for re-eval */
+ bf_init(zif->vlan_bitmap, IF_VLAN_BITMAP_MAX);
+
+ /* Could we have multiple bridge vlan infos? */
+ bvarray = dplane_ctx_get_ifp_bridge_vlan_info_array(ctx);
+ if (!bvarray)
+ return;
+
+ for (i = 0; i < bvarray->count; i++) {
+ bvinfo = bvarray->array[i];
+
+ if (bvinfo.flags & DPLANE_BRIDGE_VLAN_INFO_RANGE_BEGIN) {
+ vid_range_start = bvinfo.vid;
+ continue;
+ }
+
+ if (!(bvinfo.flags & DPLANE_BRIDGE_VLAN_INFO_RANGE_END))
+ vid_range_start = bvinfo.vid;
+
+ zebra_vlan_bitmap_compute(ifp, vid_range_start, bvinfo.vid);
+ }
+
+ zebra_vlan_mbr_re_eval(ifp, old_vlan_bitmap);
+ bf_free(old_vlan_bitmap);
+}
+
+static void interface_bridge_handling(struct zebra_dplane_ctx *ctx,
+ struct interface *ifp,
+ enum zebra_iftype zif_type)
+{
+ struct zebra_if *zif;
+
+ if (!ifp) {
+ zlog_warn("Cannot find bridge if %s(%u)",
+ dplane_ctx_get_ifname(ctx),
+ dplane_ctx_get_ifindex(ctx));
+ return;
+ }
+
+ if (IS_ZEBRA_IF_VXLAN(ifp))
+ return interface_bridge_vxlan_update(ctx, ifp);
+
+ /*
+ * build vlan bitmap associated with this interface if that
+ * device type is interested in the vlans
+ */
+ zif = ifp->info;
+ if (bf_is_inited(zif->vlan_bitmap))
+ interface_bridge_vlan_update(ctx, ifp);
+}
+
+static void zebra_if_dplane_ifp_handling(struct zebra_dplane_ctx *ctx)
+{
+ enum dplane_op_e op = dplane_ctx_get_op(ctx);
+ const char *name = dplane_ctx_get_ifname(ctx);
+ ns_id_t ns_id = dplane_ctx_get_ns_id(ctx);
+ ifindex_t ifindex = dplane_ctx_get_ifindex(ctx);
+ ifindex_t bond_ifindex = dplane_ctx_get_ifp_bond_ifindex(ctx);
+ uint32_t tableid = dplane_ctx_get_ifp_table_id(ctx);
+ enum zebra_iftype zif_type = dplane_ctx_get_ifp_zif_type(ctx);
+ struct interface *ifp;
+ struct zebra_ns *zns;
+
+ zns = zebra_ns_lookup(ns_id);
+ if (!zns) {
+ zlog_err("Where is our namespace?");
+ return;
+ }
+
+ if (IS_ZEBRA_DEBUG_DPLANE)
+ zlog_debug("%s for %s(%u)", dplane_op2str(op), name, ifindex);
+
+ ifp = if_lookup_by_name_per_ns(zns, name);
+ if (op == DPLANE_OP_INTF_DELETE) {
+ /* Delete interface notification from kernel */
+ if (ifp == NULL) {
+ if (IS_ZEBRA_DEBUG_EVENT)
+ zlog_debug(
+ "Delete LINK received for unknown interface %s(%u)",
+ name, ifindex);
+ return;
+ }
+
+ if (IS_ZEBRA_IF_BOND(ifp))
+ zebra_l2if_update_bond(ifp, false);
+ if (IS_ZEBRA_IF_BOND_SLAVE(ifp))
+ zebra_l2if_update_bond_slave(ifp, bond_ifindex, false);
+ /* Special handling for bridge or VxLAN interfaces. */
+ if (IS_ZEBRA_IF_BRIDGE(ifp))
+ zebra_l2_bridge_del(ifp);
+ else if (IS_ZEBRA_IF_VXLAN(ifp))
+ zebra_l2_vxlanif_del(ifp);
+
+ if_delete_update(&ifp);
+
+ if (zif_type == ZEBRA_IF_VRF && !vrf_is_backend_netns())
+ interface_vrf_change(op, ifindex, name, tableid, ns_id);
+ } else {
+ ifindex_t master_ifindex, bridge_ifindex, bond_ifindex,
+ link_ifindex;
+ enum zebra_slave_iftype zif_slave_type;
+ uint8_t bypass;
+ uint64_t flags;
+ vrf_id_t vrf_id;
+ uint32_t mtu;
+ ns_id_t link_nsid;
+ struct zebra_if *zif;
+ bool protodown, protodown_set, startup;
+ uint32_t rc_bitfield;
+ uint8_t old_hw_addr[INTERFACE_HWADDR_MAX];
+ char *desc;
+ uint8_t family;
+
+ /* If VRF, create or update the VRF structure itself. */
+ if (zif_type == ZEBRA_IF_VRF && !vrf_is_backend_netns())
+ interface_vrf_change(op, ifindex, name, tableid, ns_id);
+
+ master_ifindex = dplane_ctx_get_ifp_master_ifindex(ctx);
+ zif_slave_type = dplane_ctx_get_ifp_zif_slave_type(ctx);
+ bridge_ifindex = dplane_ctx_get_ifp_bridge_ifindex(ctx);
+ bond_ifindex = dplane_ctx_get_ifp_bond_ifindex(ctx);
+ bypass = dplane_ctx_get_ifp_bypass(ctx);
+ flags = dplane_ctx_get_ifp_flags(ctx);
+ vrf_id = dplane_ctx_get_ifp_vrf_id(ctx);
+ mtu = dplane_ctx_get_ifp_mtu(ctx);
+ link_ifindex = dplane_ctx_get_ifp_link_ifindex(ctx);
+ link_nsid = dplane_ctx_get_ifp_link_nsid(ctx);
+ protodown_set = dplane_ctx_get_ifp_protodown_set(ctx);
+ protodown = dplane_ctx_get_ifp_protodown(ctx);
+ rc_bitfield = dplane_ctx_get_ifp_rc_bitfield(ctx);
+ startup = dplane_ctx_get_ifp_startup(ctx);
+ desc = dplane_ctx_get_ifp_desc(ctx);
+ family = dplane_ctx_get_ifp_family(ctx);
+
+#ifndef AF_BRIDGE
+ /*
+ * Work around to make free bsd happy at the moment
+ */
+#define AF_BRIDGE 7
+#endif
+ if (family == AF_BRIDGE)
+ return interface_bridge_handling(ctx, ifp, zif_type);
+
+ if (ifp == NULL ||
+ !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
+ /* Add interface notification from kernel */
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "RTM_NEWLINK ADD for %s(%u) vrf_id %u type %d sl_type %d master %u",
+ name, ifindex, vrf_id, zif_type,
+ zif_slave_type, master_ifindex);
+
+ if (ifp == NULL) {
+ /* unknown interface */
+ ifp = if_get_by_name(name, vrf_id, NULL);
+ } else {
+ /* pre-configured interface, learnt now */
+ if (ifp->vrf->vrf_id != vrf_id)
+ if_update_to_new_vrf(ifp, vrf_id);
+ }
+
+ zif = ifp->info;
+
+ /* Update interface information. */
+ set_ifindex(ifp, ifindex, zns);
+ ifp->flags = flags;
+ ifp->mtu6 = ifp->mtu = mtu;
+ ifp->metric = 0;
+ ifp->speed = kernel_get_speed(ifp, NULL);
+ ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN;
+ ifp->txqlen = dplane_ctx_get_intf_txqlen(ctx);
+
+ /* Set interface type */
+ zebra_if_set_ziftype(ifp, zif_type, zif_slave_type);
+ if (IS_ZEBRA_IF_VRF(ifp))
+ SET_FLAG(ifp->status,
+ ZEBRA_INTERFACE_VRF_LOOPBACK);
+
+ /* Update link. */
+ zebra_if_update_link(ifp, link_ifindex, link_nsid);
+
+ ifp->ll_type = dplane_ctx_get_ifp_zltype(ctx);
+ interface_update_hw_addr(ctx, ifp);
+
+ /* Inform clients, install any configured addresses. */
+ if_add_update(ifp);
+
+ /*
+ * Extract and save L2 interface information, take
+ * additional actions.
+ */
+ interface_update_l2info(ctx, ifp, zif_type, 1,
+ link_nsid);
+ if (IS_ZEBRA_IF_BOND(ifp))
+ zebra_l2if_update_bond(ifp, true);
+ if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp))
+ zebra_l2if_update_bridge_slave(
+ ifp, bridge_ifindex, ns_id,
+ ZEBRA_BRIDGE_NO_ACTION);
+ else if (IS_ZEBRA_IF_BOND_SLAVE(ifp))
+ zebra_l2if_update_bond_slave(ifp, bond_ifindex,
+ !!bypass);
+
+ if (protodown_set) {
+ interface_if_protodown(ifp, protodown,
+ rc_bitfield);
+ if (startup)
+ if_sweep_protodown(zif);
+ }
+
+ if (IS_ZEBRA_IF_BRIDGE(ifp)) {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "RTM_NEWLINK ADD for %s(%u), vlan-aware %d",
+ name, ifp->ifindex,
+ IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(
+ zif));
+ }
+ } else if (ifp->vrf->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",
+ name, ifp->ifindex, ifp->vrf->vrf_id,
+ vrf_id);
+
+ if_handle_vrf_change(ifp, vrf_id);
+ } else {
+ bool was_bridge_slave, was_bond_slave;
+ uint8_t chgflags = ZEBRA_BRIDGE_NO_ACTION;
+
+ zif = ifp->info;
+
+ /* Interface update. */
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "RTM_NEWLINK update for %s(%u) sl_type %d master %u",
+ name, ifp->ifindex, zif_slave_type,
+ master_ifindex);
+
+ set_ifindex(ifp, ifindex, zns);
+ ifp->mtu6 = ifp->mtu = mtu;
+ ifp->metric = 0;
+ ifp->txqlen = dplane_ctx_get_intf_txqlen(ctx);
+
+ /*
+ * Update interface type - NOTE: Only slave_type can
+ * change.
+ */
+ was_bridge_slave = IS_ZEBRA_IF_BRIDGE_SLAVE(ifp);
+ was_bond_slave = IS_ZEBRA_IF_BOND_SLAVE(ifp);
+ zebra_if_set_ziftype(ifp, zif_type, zif_slave_type);
+
+ memcpy(old_hw_addr, ifp->hw_addr, INTERFACE_HWADDR_MAX);
+
+ /* Update link. */
+ zebra_if_update_link(ifp, link_ifindex, link_nsid);
+
+ ifp->ll_type = dplane_ctx_get_ifp_zltype(ctx);
+ interface_update_hw_addr(ctx, ifp);
+
+ if (protodown_set)
+ interface_if_protodown(ifp, protodown,
+ rc_bitfield);
+
+ if (if_is_no_ptm_operative(ifp)) {
+ bool is_up = if_is_operative(ifp);
+
+ ifp->flags = flags;
+ if (!if_is_no_ptm_operative(ifp) ||
+ CHECK_FLAG(zif->flags,
+ ZIF_FLAG_PROTODOWN)) {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "Intf %s(%u) has gone DOWN",
+ name, ifp->ifindex);
+ if_down(ifp);
+ rib_update(RIB_UPDATE_KERNEL);
+ } else if (if_is_operative(ifp)) {
+ bool mac_updated = false;
+
+ /*
+ * Must notify client daemons of new
+ * interface status.
+ */
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "Intf %s(%u) PTM up, notifying clients",
+ name, ifp->ifindex);
+ if_up(ifp, !is_up);
+
+ /*
+ * Update EVPN VNI when SVI MAC change
+ */
+ if (memcmp(old_hw_addr, ifp->hw_addr,
+ INTERFACE_HWADDR_MAX))
+ mac_updated = true;
+ if (IS_ZEBRA_IF_VLAN(ifp) &&
+ mac_updated) {
+ struct interface *link_if;
+
+ link_if = if_lookup_by_index_per_ns(
+ zebra_ns_lookup(
+ NS_DEFAULT),
+ link_ifindex);
+ if (link_if)
+ zebra_vxlan_svi_up(
+ ifp, link_if);
+ } else if (mac_updated &&
+ IS_ZEBRA_IF_BRIDGE(ifp)) {
+ zlog_debug(
+ "Intf %s(%u) bridge changed MAC address",
+ name, ifp->ifindex);
+ chgflags =
+ ZEBRA_BRIDGE_MASTER_MAC_CHANGE;
+ }
+ }
+ } else {
+ ifp->flags = flags;
+ if (if_is_operative(ifp) &&
+ !CHECK_FLAG(zif->flags,
+ ZIF_FLAG_PROTODOWN)) {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "Intf %s(%u) has come UP",
+ name, ifp->ifindex);
+ if_up(ifp, true);
+ if (IS_ZEBRA_IF_BRIDGE(ifp))
+ chgflags =
+ ZEBRA_BRIDGE_MASTER_UP;
+ } else {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "Intf %s(%u) has gone DOWN",
+ name, ifp->ifindex);
+ if_down(ifp);
+ rib_update(RIB_UPDATE_KERNEL);
+ }
+ }
+
+ /*
+ * Extract and save L2 interface information, take
+ * additional actions.
+ */
+ interface_update_l2info(ctx, ifp, zif_type, 0,
+ link_nsid);
+ if (IS_ZEBRA_IF_BRIDGE(ifp))
+ zebra_l2if_update_bridge(ifp, chgflags);
+ if (IS_ZEBRA_IF_BOND(ifp))
+ zebra_l2if_update_bond(ifp, true);
+ if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) || was_bridge_slave)
+ zebra_l2if_update_bridge_slave(
+ ifp, bridge_ifindex, ns_id, chgflags);
+ else if (IS_ZEBRA_IF_BOND_SLAVE(ifp) || was_bond_slave)
+ zebra_l2if_update_bond_slave(ifp, bond_ifindex,
+ !!bypass);
+ if (IS_ZEBRA_IF_BRIDGE(ifp)) {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "RTM_NEWLINK update for %s(%u), vlan-aware %d",
+ name, ifp->ifindex,
+ IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(
+ zif));
+ }
+ }
+
+ zif = ifp->info;
+ if (zif) {
+ XFREE(MTYPE_ZIF_DESC, zif->desc);
+ if (desc[0])
+ zif->desc = XSTRDUP(MTYPE_ZIF_DESC, desc);
+ }
+ }
+}
+
void zebra_if_dplane_result(struct zebra_dplane_ctx *ctx)
{
struct zebra_ns *zns;
@@ -1501,83 +2242,22 @@ void zebra_if_dplane_result(struct zebra_dplane_ctx *ctx)
}
ifp = if_lookup_by_index_per_ns(zns, ifindex);
- if (ifp == NULL) {
- if (op != DPLANE_OP_INTF_NETCONFIG ||
- (ifindex != -1 && ifindex != -2)) {
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug(
- "%s: can't find ifp at nsid %u index %d",
- __func__, ns_id, ifindex);
-
- return;
- }
- }
- switch (op) {
- case DPLANE_OP_INTF_ADDR_ADD:
- case DPLANE_OP_INTF_ADDR_DEL:
+ if (op == DPLANE_OP_INTF_ADDR_ADD || op == DPLANE_OP_INTF_ADDR_DEL) {
zebra_if_addr_update_ctx(ctx, ifp);
- break;
-
- case DPLANE_OP_INTF_INSTALL:
- case DPLANE_OP_INTF_UPDATE:
- case DPLANE_OP_INTF_DELETE:
- zebra_if_update_ctx(ctx, ifp);
- break;
-
- case DPLANE_OP_INTF_NETCONFIG:
+ } else if (op == DPLANE_OP_INTF_INSTALL ||
+ op == DPLANE_OP_INTF_UPDATE || op == DPLANE_OP_INTF_DELETE) {
+ /*
+ * Queued from the dplane means it is something
+ * that we need to handle( create/delete the
+ * interface as needed )
+ */
+ if (dp_res == ZEBRA_DPLANE_REQUEST_QUEUED)
+ zebra_if_dplane_ifp_handling(ctx);
+ else
+ zebra_if_update_ctx(ctx, ifp);
+ } else if (op == DPLANE_OP_INTF_NETCONFIG) {
zebra_if_netconf_update_ctx(ctx, ifp, ifindex);
- break;
-
- case DPLANE_OP_ROUTE_INSTALL:
- case DPLANE_OP_ROUTE_UPDATE:
- case DPLANE_OP_ROUTE_DELETE:
- case DPLANE_OP_NH_DELETE:
- case DPLANE_OP_NH_INSTALL:
- case DPLANE_OP_NH_UPDATE:
- case DPLANE_OP_ROUTE_NOTIFY:
- case DPLANE_OP_LSP_INSTALL:
- case DPLANE_OP_LSP_UPDATE:
- case DPLANE_OP_LSP_DELETE:
- case DPLANE_OP_LSP_NOTIFY:
- case DPLANE_OP_PW_INSTALL:
- case DPLANE_OP_PW_UNINSTALL:
- case DPLANE_OP_SYS_ROUTE_ADD:
- case DPLANE_OP_SYS_ROUTE_DELETE:
- case DPLANE_OP_ADDR_INSTALL:
- case DPLANE_OP_ADDR_UNINSTALL:
- case DPLANE_OP_MAC_INSTALL:
- case DPLANE_OP_MAC_DELETE:
- case DPLANE_OP_NEIGH_INSTALL:
- case DPLANE_OP_NEIGH_UPDATE:
- case DPLANE_OP_NEIGH_DELETE:
- case DPLANE_OP_NEIGH_IP_INSTALL:
- case DPLANE_OP_NEIGH_IP_DELETE:
- case DPLANE_OP_VTEP_ADD:
- case DPLANE_OP_VTEP_DELETE:
- case DPLANE_OP_RULE_ADD:
- case DPLANE_OP_RULE_DELETE:
- case DPLANE_OP_RULE_UPDATE:
- case DPLANE_OP_NEIGH_DISCOVER:
- case DPLANE_OP_BR_PORT_UPDATE:
- case DPLANE_OP_NONE:
- case DPLANE_OP_IPTABLE_ADD:
- case DPLANE_OP_IPTABLE_DELETE:
- case DPLANE_OP_IPSET_ADD:
- case DPLANE_OP_IPSET_DELETE:
- case DPLANE_OP_IPSET_ENTRY_ADD:
- case DPLANE_OP_IPSET_ENTRY_DELETE:
- case DPLANE_OP_NEIGH_TABLE_UPDATE:
- case DPLANE_OP_GRE_SET:
- case DPLANE_OP_TC_QDISC_INSTALL:
- case DPLANE_OP_TC_QDISC_UNINSTALL:
- case DPLANE_OP_TC_CLASS_ADD:
- case DPLANE_OP_TC_CLASS_DELETE:
- case DPLANE_OP_TC_CLASS_UPDATE:
- case DPLANE_OP_TC_FILTER_ADD:
- case DPLANE_OP_TC_FILTER_DELETE:
- case DPLANE_OP_TC_FILTER_UPDATE:
- break; /* should never hit here */
}
}
@@ -1617,6 +2297,12 @@ static void connected_dump_vty(struct vty *vty, json_object *json,
vty_out(vty, " secondary");
if (json)
+ json_object_boolean_add(json_addr, "noPrefixRoute",
+ CHECK_FLAG(connected->flags, ZEBRA_IFA_NOPREFIXROUTE));
+ else if (CHECK_FLAG(connected->flags, ZEBRA_IFA_NOPREFIXROUTE))
+ vty_out(vty, " noprefixroute");
+
+ if (json)
json_object_boolean_add(
json_addr, "unnumbered",
CHECK_FLAG(connected->flags, ZEBRA_IFA_UNNUMBERED));
@@ -1692,9 +2378,6 @@ static const char *zebra_ziftype_2str(enum zebra_iftype zif_type)
case ZEBRA_IF_BOND:
return "bond";
- case ZEBRA_IF_BOND_SLAVE:
- return "bond_slave";
-
case ZEBRA_IF_MACVLAN:
return "macvlan";
@@ -1768,34 +2451,27 @@ static void ifs_dump_brief_vty(struct vty *vty, struct vrf *vrf)
}
uint32_t v6_list_size = 0;
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
+ frr_each (if_connected, ifp->connected, connected) {
if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
&& (connected->address->family == AF_INET6))
v6_list_size++;
}
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
- if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
- && !CHECK_FLAG(connected->flags,
- ZEBRA_IFA_SECONDARY)
- && (connected->address->family == AF_INET6)) {
+ frr_each (if_connected, ifp->connected, connected) {
+ if (!CHECK_FLAG(connected->flags, ZEBRA_IFA_SECONDARY) &&
+ (connected->address->family == AF_INET6)) {
p = connected->address;
- /* Don't print link local pfx */
- if (!IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6)) {
- if (first_pfx_printed) {
- /* padding to prepare row only
- * for ip addr */
- vty_out(vty, "%-40s", "");
- if (v6_list_size > 1)
- vty_out(vty, "+ ");
- vty_out(vty, "%pFX\n", p);
- } else {
- if (v6_list_size > 1)
- vty_out(vty, "+ ");
- vty_out(vty, "%pFX\n", p);
- }
- first_pfx_printed = true;
- break;
+ if (first_pfx_printed) {
+ vty_out(vty, "%-40s", "");
+ if (v6_list_size > 1)
+ vty_out(vty, "+ ");
+ vty_out(vty, "%pFX\n", p);
+ } else {
+ if (v6_list_size > 1)
+ vty_out(vty, "+ ");
+ vty_out(vty, "%pFX\n", p);
}
+ first_pfx_printed = true;
+ break;
}
}
if (!first_pfx_printed)
@@ -1807,7 +2483,6 @@ static void ifs_dump_brief_vty(struct vty *vty, struct vrf *vrf)
static void ifs_dump_brief_vty_json(json_object *json, struct vrf *vrf)
{
struct connected *connected;
- struct listnode *node;
struct interface *ifp;
FOR_ALL_INTERFACES (vrf, ifp) {
@@ -1823,13 +2498,8 @@ static void ifs_dump_brief_vty_json(json_object *json, struct vrf *vrf)
json_addrs = json_object_new_array();
json_object_object_add(json_if, "addresses", json_addrs);
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
- if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
- && !CHECK_FLAG(connected->flags,
- ZEBRA_IFA_SECONDARY)
- && !(connected->address->family == AF_INET6
- && IN6_IS_ADDR_LINKLOCAL(
- &connected->address->u.prefix6))) {
+ frr_each (if_connected, ifp->connected, connected) {
+ if (!CHECK_FLAG(connected->flags, ZEBRA_IFA_SECONDARY)) {
char buf[PREFIX2STR_BUFFER];
json_array_string_add(
@@ -1990,8 +2660,8 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp)
return;
}
- vty_out(vty, " index %d metric %d mtu %d speed %u ", ifp->ifindex,
- ifp->metric, ifp->mtu, ifp->speed);
+ vty_out(vty, " index %d metric %d mtu %d speed %u txqlen %u",
+ ifp->ifindex, ifp->metric, ifp->mtu, ifp->speed, ifp->txqlen);
if (ifp->mtu6 != ifp->mtu)
vty_out(vty, "mtu6 %d ", ifp->mtu6);
vty_out(vty, "\n flags: %s\n", if_flag_dump(ifp->flags));
@@ -2036,9 +2706,8 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp)
connected_dump_vty(vty, NULL, connected);
}
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
- if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
- && (connected->address->family == AF_INET6))
+ frr_each (if_connected, ifp->connected, connected) {
+ if (connected->address->family == AF_INET6)
connected_dump_vty(vty, NULL, connected);
}
@@ -2170,8 +2839,8 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp)
" Link Delay Variation %u (micro-sec.)\n",
iflp->delay_var);
if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
- vty_out(vty, " Link Packet Loss %g (in %%)\n",
- iflp->pkt_loss);
+ vty_out(vty, " Link Packet Loss %f (in %%)\n",
+ (double)iflp->pkt_loss * LOSS_PRECISION);
if (IS_PARAM_SET(iflp, LP_AVA_BW))
vty_out(vty, " Available Bandwidth %g (Byte/s)\n",
iflp->ava_bw);
@@ -2345,7 +3014,7 @@ static void if_dump_vty_json(struct vty *vty, struct interface *ifp,
json_object_string_add(json_if, "lastLinkDown",
zebra_if->down_last);
- zebra_ptm_show_status(vty, json, ifp);
+ zebra_ptm_show_status(vty, json_if, ifp);
json_object_string_add(json_if, "vrfName", ifp->vrf->name);
@@ -2378,6 +3047,7 @@ static void if_dump_vty_json(struct vty *vty, struct interface *ifp,
if (ifp->mtu6 != ifp->mtu)
json_object_int_add(json_if, "mtu6", ifp->mtu6);
json_object_int_add(json_if, "speed", ifp->speed);
+ json_object_int_add(json_if, "txqlen", ifp->txqlen);
json_object_string_add(json_if, "flags", if_flag_dump(ifp->flags));
/* Hardware address. */
@@ -2412,9 +3082,8 @@ static void if_dump_vty_json(struct vty *vty, struct interface *ifp,
connected_dump_vty(vty, json_addrs, connected);
}
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
- if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
- && (connected->address->family == AF_INET6))
+ frr_each (if_connected, ifp->connected, connected) {
+ if (connected->address->family == AF_INET6)
connected_dump_vty(vty, json_addrs, connected);
}
@@ -2571,7 +3240,8 @@ static void if_dump_vty_json(struct vty *vty, struct interface *ifp,
iflp->delay_var);
if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
json_object_double_add(json_te, "linkPacketLoss",
- iflp->pkt_loss);
+ (double)iflp->pkt_loss *
+ LOSS_PRECISION);
if (IS_PARAM_SET(iflp, LP_AVA_BW))
json_object_double_add(json_te, "availableBandwidth",
iflp->ava_bw);
@@ -2955,66 +3625,43 @@ DEFUN (show_interface_desc_vrf_all,
return CMD_SUCCESS;
}
-int if_multicast_set(struct interface *ifp)
+void if_arp(struct interface *ifp, bool enable)
{
- struct zebra_if *if_data;
+ int ret;
- if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
- if (if_set_flags(ifp, IFF_MULTICAST) < 0) {
- zlog_debug("Can't set multicast flag on interface %s",
- ifp->name);
- return -1;
- }
- if_refresh(ifp);
+ if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE))
+ return;
+
+ if (enable)
+ ret = if_unset_flags(ifp, IFF_NOARP);
+ else
+ ret = if_set_flags(ifp, IFF_NOARP);
+
+ if (ret < 0) {
+ zlog_debug("Can't %sset noarp flag on interface %s",
+ enable ? "" : "un", ifp->name);
+ return;
}
- if_data = ifp->info;
- if_data->multicast = IF_ZEBRA_DATA_ON;
- return 0;
+ if_refresh(ifp);
}
-DEFUN (multicast,
- multicast_cmd,
- "multicast",
- "Set multicast flag to interface\n")
+int if_multicast_set(struct interface *ifp)
{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- int ret;
struct zebra_if *if_data;
if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
- ret = if_set_flags(ifp, IFF_MULTICAST);
- if (ret < 0) {
- vty_out(vty, "Can't set multicast flag\n");
- return CMD_WARNING_CONFIG_FAILED;
+ if (if_set_flags(ifp, IFF_MULTICAST) < 0) {
+ zlog_debug("Can't set multicast flag on interface %s",
+ ifp->name);
+ return -1;
}
if_refresh(ifp);
}
if_data = ifp->info;
if_data->multicast = IF_ZEBRA_DATA_ON;
- return CMD_SUCCESS;
-}
-
-DEFPY (mpls,
- mpls_cmd,
- "[no] mpls enable",
- NO_STR
- MPLS_STR
- "Set mpls to be on for the interface\n")
-{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct zebra_if *if_data = ifp->info;
-
- if (no) {
- dplane_intf_mpls_modify_state(ifp, false);
- if_data->mpls = IF_ZEBRA_DATA_UNSPEC;
- } else {
- dplane_intf_mpls_modify_state(ifp, true);
- if_data->mpls = IF_ZEBRA_DATA_ON;
- }
-
- return CMD_SUCCESS;
+ return 0;
}
int if_multicast_unset(struct interface *ifp)
@@ -3035,30 +3682,6 @@ int if_multicast_unset(struct interface *ifp)
return 0;
}
-DEFUN (no_multicast,
- no_multicast_cmd,
- "no multicast",
- NO_STR
- "Unset multicast flag to interface\n")
-{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- int ret;
- struct zebra_if *if_data;
-
- if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
- ret = if_unset_flags(ifp, IFF_MULTICAST);
- if (ret < 0) {
- vty_out(vty, "Can't unset multicast flag\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- if_refresh(ifp);
- }
- if_data = ifp->info;
- if_data->multicast = IF_ZEBRA_DATA_OFF;
-
- return CMD_SUCCESS;
-}
-
int if_linkdetect(struct interface *ifp, bool detect)
{
int if_was_operative;
@@ -3082,30 +3705,6 @@ int if_linkdetect(struct interface *ifp, bool detect)
return 0;
}
-DEFUN(linkdetect, linkdetect_cmd, "link-detect",
- "Enable link detection on interface\n")
-{
- VTY_DECLVAR_CONTEXT(interface, ifp);
-
- if_linkdetect(ifp, true);
-
- return CMD_SUCCESS;
-}
-
-
-DEFUN (no_linkdetect,
- no_linkdetect_cmd,
- "no link-detect",
- NO_STR
- "Disable link detection on interface\n")
-{
- VTY_DECLVAR_CONTEXT(interface, ifp);
-
- if_linkdetect(ifp, false);
-
- return CMD_SUCCESS;
-}
-
int if_shutdown(struct interface *ifp)
{
struct zebra_if *if_data;
@@ -3125,31 +3724,6 @@ int if_shutdown(struct interface *ifp)
return 0;
}
-DEFUN (shutdown_if,
- shutdown_if_cmd,
- "shutdown",
- "Shutdown the selected interface\n")
-{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- int ret;
- struct zebra_if *if_data;
-
- if (ifp->ifindex != IFINDEX_INTERNAL) {
- /* send RA lifetime of 0 before stopping. rfc4861/6.2.5 */
- rtadv_stop_ra(ifp);
- ret = if_unset_flags(ifp, IFF_UP);
- if (ret < 0) {
- vty_out(vty, "Can't shutdown interface\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- if_refresh(ifp);
- }
- if_data = ifp->info;
- if_data->shutdown = IF_ZEBRA_DATA_ON;
-
- return CMD_SUCCESS;
-}
-
int if_no_shutdown(struct interface *ifp)
{
struct zebra_if *if_data;
@@ -3174,984 +3748,56 @@ int if_no_shutdown(struct interface *ifp)
return 0;
}
-DEFUN (no_shutdown_if,
- no_shutdown_if_cmd,
- "no shutdown",
- NO_STR
- "Shutdown the selected interface\n")
-{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- int ret;
- struct zebra_if *if_data;
-
- if (ifp->ifindex != IFINDEX_INTERNAL) {
- ret = if_set_flags(ifp, IFF_UP | IFF_RUNNING);
- if (ret < 0) {
- vty_out(vty, "Can't up interface\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- if_refresh(ifp);
-
- /* Some addresses (in particular, IPv6 addresses on Linux) get
- * removed when the interface goes down. They need to be
- * readded.
- */
- if_addr_wakeup(ifp);
- }
-
- if_data = ifp->info;
- if_data->shutdown = IF_ZEBRA_DATA_OFF;
-
- return CMD_SUCCESS;
-}
-
-DEFUN (bandwidth_if,
- bandwidth_if_cmd,
- "bandwidth (1-100000)",
- "Set bandwidth informational parameter\n"
- "Bandwidth in megabits\n")
-{
- int idx_number = 1;
- VTY_DECLVAR_CONTEXT(interface, ifp);
- unsigned int bandwidth;
-
- bandwidth = strtol(argv[idx_number]->arg, NULL, 10);
-
- /* bandwidth range is <1-100000> */
- if (bandwidth < 1 || bandwidth > 100000) {
- vty_out(vty, "Bandwidth is invalid\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- ifp->bandwidth = bandwidth;
-
- /* force protocols to recalculate routes due to cost change */
- if (if_is_operative(ifp))
- zebra_interface_up_update(ifp);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (no_bandwidth_if,
- no_bandwidth_if_cmd,
- "no bandwidth [(1-100000)]",
- NO_STR
- "Set bandwidth informational parameter\n"
- "Bandwidth in megabits\n")
-{
- VTY_DECLVAR_CONTEXT(interface, ifp);
-
- ifp->bandwidth = 0;
-
- /* force protocols to recalculate routes due to cost change */
- if (if_is_operative(ifp))
- zebra_interface_up_update(ifp);
-
- return CMD_SUCCESS;
-}
-
-
-struct cmd_node link_params_node = {
- .name = "link-params",
- .node = LINK_PARAMS_NODE,
- .parent_node = INTERFACE_NODE,
- .prompt = "%s(config-link-params)# ",
- .no_xpath = true,
-};
-
-static void link_param_cmd_set_uint32(struct interface *ifp, uint32_t *field,
- uint32_t type, uint32_t value)
+void link_param_cmd_set_uint32(struct interface *ifp, uint32_t *field,
+ uint32_t type, uint32_t value)
{
/* Update field as needed */
if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) {
*field = value;
SET_PARAM(ifp->link_params, type);
-
- /* force protocols to update LINK STATE due to parameters change
- */
- if (if_is_operative(ifp))
- zebra_interface_parameters_update(ifp);
}
}
-static void link_param_cmd_set_float(struct interface *ifp, float *field,
- uint32_t type, float value)
-{
+void link_param_cmd_set_float(struct interface *ifp, float *field,
+ uint32_t type, float value)
+{
/* Update field as needed */
if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) {
*field = value;
SET_PARAM(ifp->link_params, type);
-
- /* force protocols to update LINK STATE due to parameters change
- */
- if (if_is_operative(ifp))
- zebra_interface_parameters_update(ifp);
}
}
-static void link_param_cmd_unset(struct interface *ifp, uint32_t type)
+void link_param_cmd_unset(struct interface *ifp, uint32_t type)
{
if (ifp->link_params == NULL)
return;
/* Unset field */
UNSET_PARAM(ifp->link_params, type);
-
- /* force protocols to update LINK STATE due to parameters change */
- if (if_is_operative(ifp))
- zebra_interface_parameters_update(ifp);
-}
-
-DEFUN_NOSH (link_params,
- link_params_cmd,
- "link-params",
- LINK_PARAMS_STR)
-{
- /* vty->qobj_index stays the same @ interface pointer */
- vty->node = LINK_PARAMS_NODE;
-
- return CMD_SUCCESS;
-}
-
-DEFUN_NOSH (exit_link_params,
- exit_link_params_cmd,
- "exit-link-params",
- "Exit from Link Params configuration mode\n")
-{
- if (vty->node == LINK_PARAMS_NODE)
- vty->node = INTERFACE_NODE;
- return CMD_SUCCESS;
-}
-
-/* Specific Traffic Engineering parameters commands */
-DEFUN (link_params_enable,
- link_params_enable_cmd,
- "enable",
- "Activate link parameters on this interface\n")
-{
- VTY_DECLVAR_CONTEXT(interface, ifp);
-
- /* This command could be issue at startup, when activate MPLS TE */
- /* on a new interface or after a ON / OFF / ON toggle */
- /* In all case, TE parameters are reset to their default factory */
- if (IS_ZEBRA_DEBUG_EVENT || IS_ZEBRA_DEBUG_MPLS)
- zlog_debug(
- "Link-params: enable TE link parameters on interface %s",
- ifp->name);
-
- if (!if_link_params_get(ifp))
- if_link_params_enable(ifp);
-
- /* force protocols to update LINK STATE due to parameters change */
- if (if_is_operative(ifp))
- zebra_interface_parameters_update(ifp);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (no_link_params_enable,
- no_link_params_enable_cmd,
- "no enable",
- NO_STR
- "Disable link parameters on this interface\n")
-{
- char xpath[XPATH_MAXLEN];
- int ret;
- VTY_DECLVAR_CONTEXT(interface, ifp);
-
- if (IS_ZEBRA_DEBUG_EVENT || IS_ZEBRA_DEBUG_MPLS)
- zlog_debug("MPLS-TE: disable TE link parameters on interface %s",
- ifp->name);
-
- if_link_params_free(ifp);
-
- snprintf(
- xpath, sizeof(xpath),
- "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params/affinities",
- ifp->name);
- if (yang_dnode_exists(running_config->dnode, xpath))
- nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
-
- ret = nb_cli_apply_changes(vty, NULL);
-
- if (ret != CMD_SUCCESS)
- return ret;
-
- /* force protocols to update LINK STATE due to parameters change */
- if (if_is_operative(ifp))
- zebra_interface_parameters_update(ifp);
-
- return CMD_SUCCESS;
}
-/* STANDARD TE metrics */
-DEFUN (link_params_metric,
- link_params_metric_cmd,
- "metric (0-4294967295)",
- "Link metric for MPLS-TE purpose\n"
- "Metric value in decimal\n")
-{
- int idx_number = 1;
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct if_link_params *iflp = if_link_params_get(ifp);
- uint32_t metric;
-
- metric = strtoul(argv[idx_number]->arg, NULL, 10);
-
- if (!iflp)
- iflp = if_link_params_enable(ifp);
-
- /* Update TE metric if needed */
- link_param_cmd_set_uint32(ifp, &iflp->te_metric, LP_TE_METRIC, metric);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (no_link_params_metric,
- no_link_params_metric_cmd,
- "no metric",
- NO_STR
- "Disable Link Metric on this interface\n")
-{
- VTY_DECLVAR_CONTEXT(interface, ifp);
-
- /* Unset TE Metric */
- link_param_cmd_unset(ifp, LP_TE_METRIC);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (link_params_maxbw,
- link_params_maxbw_cmd,
- "max-bw BANDWIDTH",
- "Maximum bandwidth that can be used\n"
- "Bytes/second (IEEE floating point format)\n")
-{
- int idx_bandwidth = 1;
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct if_link_params *iflp = if_link_params_get(ifp);
-
- float bw;
-
- if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
- vty_out(vty, "link_params_maxbw: fscanf: %s\n",
- safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- /* Check that Maximum bandwidth is not lower than other bandwidth
- * parameters */
- if (iflp && ((bw <= iflp->max_rsv_bw) || (bw <= iflp->unrsv_bw[0]) ||
- (bw <= iflp->unrsv_bw[1]) || (bw <= iflp->unrsv_bw[2]) ||
- (bw <= iflp->unrsv_bw[3]) || (bw <= iflp->unrsv_bw[4]) ||
- (bw <= iflp->unrsv_bw[5]) || (bw <= iflp->unrsv_bw[6]) ||
- (bw <= iflp->unrsv_bw[7]) || (bw <= iflp->ava_bw) ||
- (bw <= iflp->res_bw) || (bw <= iflp->use_bw))) {
- vty_out(vty,
- "Maximum Bandwidth could not be lower than others bandwidth\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (!iflp)
- iflp = if_link_params_enable(ifp);
-
- /* Update Maximum Bandwidth if needed */
- link_param_cmd_set_float(ifp, &iflp->max_bw, LP_MAX_BW, bw);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (link_params_max_rsv_bw,
- link_params_max_rsv_bw_cmd,
- "max-rsv-bw BANDWIDTH",
- "Maximum bandwidth that may be reserved\n"
- "Bytes/second (IEEE floating point format)\n")
-{
- int idx_bandwidth = 1;
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct if_link_params *iflp = if_link_params_get(ifp);
- float bw;
-
- if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
- vty_out(vty, "link_params_max_rsv_bw: fscanf: %s\n",
- safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- /* Check that bandwidth is not greater than maximum bandwidth parameter
- */
- if (iflp && bw > iflp->max_bw) {
- vty_out(vty,
- "Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
- iflp->max_bw);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (!iflp)
- iflp = if_link_params_enable(ifp);
-
- /* Update Maximum Reservable Bandwidth if needed */
- link_param_cmd_set_float(ifp, &iflp->max_rsv_bw, LP_MAX_RSV_BW, bw);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (link_params_unrsv_bw,
- link_params_unrsv_bw_cmd,
- "unrsv-bw (0-7) BANDWIDTH",
- "Unreserved bandwidth at each priority level\n"
- "Priority\n"
- "Bytes/second (IEEE floating point format)\n")
-{
- int idx_number = 1;
- int idx_bandwidth = 2;
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct if_link_params *iflp = if_link_params_get(ifp);
- int priority;
- float bw;
-
- /* We don't have to consider about range check here. */
- if (sscanf(argv[idx_number]->arg, "%d", &priority) != 1) {
- vty_out(vty, "link_params_unrsv_bw: fscanf: %s\n",
- safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
- vty_out(vty, "link_params_unrsv_bw: fscanf: %s\n",
- safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- /* Check that bandwidth is not greater than maximum bandwidth parameter
- */
- if (iflp && bw > iflp->max_bw) {
- vty_out(vty,
- "UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
- iflp->max_bw);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (!iflp)
- iflp = if_link_params_enable(ifp);
-
- /* Update Unreserved Bandwidth if needed */
- link_param_cmd_set_float(ifp, &iflp->unrsv_bw[priority], LP_UNRSV_BW,
- bw);
-
- return CMD_SUCCESS;
-}
-
-DEFPY_YANG(link_params_admin_grp, link_params_admin_grp_cmd,
- "admin-grp BITPATTERN",
- "Administrative group membership\n"
- "32-bit Hexadecimal value (e.g. 0xa1)\n")
-{
- char xpath[XPATH_MAXLEN];
- int idx_bitpattern = 1;
- unsigned long value;
- char value_str[11];
-
- VTY_DECLVAR_CONTEXT(interface, ifp);
-
- snprintf(
- xpath, sizeof(xpath),
- "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params/affinities",
- ifp->name);
- if (yang_dnode_exists(running_config->dnode, xpath)) {
- vty_out(vty,
- "cannot use the admin-grp command when affinity is set\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (sscanf(argv[idx_bitpattern]->arg, "0x%lx", &value) != 1) {
- vty_out(vty, "link_params_admin_grp: fscanf: %s\n",
- safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (value > 0xFFFFFFFF) {
- vty_out(vty, "value must be not be superior to 0xFFFFFFFF\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- snprintf(value_str, sizeof(value_str), "%ld", value);
-
- nb_cli_enqueue_change(
- vty, "./frr-zebra:zebra/link-params/legacy-admin-group",
- NB_OP_MODIFY, value_str);
-
- return nb_cli_apply_changes(vty, NULL);
-}
-
-DEFPY_YANG(no_link_params_admin_grp, no_link_params_admin_grp_cmd,
- "no admin-grp",
- NO_STR "Disable Administrative group membership on this interface\n")
-{
- nb_cli_enqueue_change(
- vty, "./frr-zebra:zebra/link-params/legacy-admin-group",
- NB_OP_DESTROY, NULL);
-
- return nb_cli_apply_changes(vty, NULL);
-}
-
-/* RFC5392 & RFC5316: INTER-AS */
-DEFUN (link_params_inter_as,
- link_params_inter_as_cmd,
- "neighbor A.B.C.D as (1-4294967295)",
- "Configure remote ASBR information (Neighbor IP address and AS number)\n"
- "Remote IP address in dot decimal A.B.C.D\n"
- "Remote AS number\n"
- "AS number in the range <1-4294967295>\n")
-{
- int idx_ipv4 = 1;
- int idx_number = 3;
-
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct if_link_params *iflp = if_link_params_get(ifp);
- struct in_addr addr;
- uint32_t as;
-
- if (!inet_aton(argv[idx_ipv4]->arg, &addr)) {
- vty_out(vty, "Please specify Router-Addr by A.B.C.D\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (!iflp)
- iflp = if_link_params_enable(ifp);
-
- as = strtoul(argv[idx_number]->arg, NULL, 10);
-
- /* Update Remote IP and Remote AS fields if needed */
- if (IS_PARAM_UNSET(iflp, LP_RMT_AS) || iflp->rmt_as != as
- || iflp->rmt_ip.s_addr != addr.s_addr) {
-
- iflp->rmt_as = as;
- iflp->rmt_ip.s_addr = addr.s_addr;
- SET_PARAM(iflp, LP_RMT_AS);
-
- /* force protocols to update LINK STATE due to parameters change
- */
- if (if_is_operative(ifp))
- zebra_interface_parameters_update(ifp);
- }
- return CMD_SUCCESS;
-}
-
-DEFUN (no_link_params_inter_as,
- no_link_params_inter_as_cmd,
- "no neighbor",
- NO_STR
- "Remove Neighbor IP address and AS number for Inter-AS TE\n")
-{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct if_link_params *iflp = if_link_params_get(ifp);
-
- if (!iflp)
- return CMD_SUCCESS;
-
- /* Reset Remote IP and AS neighbor */
- iflp->rmt_as = 0;
- iflp->rmt_ip.s_addr = 0;
- UNSET_PARAM(iflp, LP_RMT_AS);
-
- /* force protocols to update LINK STATE due to parameters change */
- if (if_is_operative(ifp))
- zebra_interface_parameters_update(ifp);
-
- return CMD_SUCCESS;
-}
-
-/* RFC7471: OSPF Traffic Engineering (TE) Metric extensions &
- * draft-ietf-isis-metric-extensions-07.txt */
-DEFUN (link_params_delay,
- link_params_delay_cmd,
- "delay (0-16777215) [min (0-16777215) max (0-16777215)]",
- "Unidirectional Average Link Delay\n"
- "Average delay in micro-second as decimal (0...16777215)\n"
- "Minimum delay\n"
- "Minimum delay in micro-second as decimal (0...16777215)\n"
- "Maximum delay\n"
- "Maximum delay in micro-second as decimal (0...16777215)\n")
-{
- /* Get and Check new delay values */
- uint32_t delay = 0, low = 0, high = 0;
- delay = strtoul(argv[1]->arg, NULL, 10);
- if (argc == 6) {
- low = strtoul(argv[3]->arg, NULL, 10);
- high = strtoul(argv[5]->arg, NULL, 10);
- }
-
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct if_link_params *iflp = if_link_params_get(ifp);
- uint8_t update = 0;
-
- if (argc == 2) {
- /*
- * Check new delay value against old Min and Max delays if set
- *
- * RFC 7471 Section 4.2.7:
- * It is possible for min delay and max delay to be
- * the same value.
- *
- * Therefore, it is also allowed that the average
- * delay be equal to the min delay or max delay.
- */
- if (iflp && IS_PARAM_SET(iflp, LP_MM_DELAY) &&
- (delay < iflp->min_delay || delay > iflp->max_delay)) {
- vty_out(vty,
- "Average delay should be in range Min (%d) - Max (%d) delay\n",
- iflp->min_delay, iflp->max_delay);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (!iflp)
- iflp = if_link_params_enable(ifp);
-
- /* Update delay if value is not set or change */
- if (IS_PARAM_UNSET(iflp, LP_DELAY) || iflp->av_delay != delay) {
- iflp->av_delay = delay;
- SET_PARAM(iflp, LP_DELAY);
- update = 1;
- }
- /* Unset Min and Max delays if already set */
- if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
- iflp->min_delay = 0;
- iflp->max_delay = 0;
- UNSET_PARAM(iflp, LP_MM_DELAY);
- update = 1;
- }
- } else {
- /*
- * Check new delays value coherency. See above note
- * regarding average delay equal to min/max allowed
- */
- if (delay < low || delay > high) {
- vty_out(vty,
- "Average delay should be in range Min (%d) - Max (%d) delay\n",
- low, high);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (!iflp)
- iflp = if_link_params_enable(ifp);
-
- /* Update Delays if needed */
- if (IS_PARAM_UNSET(iflp, LP_DELAY)
- || IS_PARAM_UNSET(iflp, LP_MM_DELAY)
- || iflp->av_delay != delay || iflp->min_delay != low
- || iflp->max_delay != high) {
- iflp->av_delay = delay;
- SET_PARAM(iflp, LP_DELAY);
- iflp->min_delay = low;
- iflp->max_delay = high;
- SET_PARAM(iflp, LP_MM_DELAY);
- update = 1;
- }
- }
-
- /* force protocols to update LINK STATE due to parameters change */
- if (update == 1 && if_is_operative(ifp))
- zebra_interface_parameters_update(ifp);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (no_link_params_delay,
- no_link_params_delay_cmd,
- "no delay",
- NO_STR
- "Disable Unidirectional Average, Min & Max Link Delay on this interface\n")
-{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct if_link_params *iflp = if_link_params_get(ifp);
-
- if (!iflp)
- return CMD_SUCCESS;
-
- /* Unset Delays */
- iflp->av_delay = 0;
- UNSET_PARAM(iflp, LP_DELAY);
- iflp->min_delay = 0;
- iflp->max_delay = 0;
- UNSET_PARAM(iflp, LP_MM_DELAY);
-
- /* force protocols to update LINK STATE due to parameters change */
- if (if_is_operative(ifp))
- zebra_interface_parameters_update(ifp);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (link_params_delay_var,
- link_params_delay_var_cmd,
- "delay-variation (0-16777215)",
- "Unidirectional Link Delay Variation\n"
- "delay variation in micro-second as decimal (0...16777215)\n")
-{
- int idx_number = 1;
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct if_link_params *iflp = if_link_params_get(ifp);
- uint32_t value;
-
- value = strtoul(argv[idx_number]->arg, NULL, 10);
-
- if (!iflp)
- iflp = if_link_params_enable(ifp);
-
- /* Update Delay Variation if needed */
- link_param_cmd_set_uint32(ifp, &iflp->delay_var, LP_DELAY_VAR, value);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (no_link_params_delay_var,
- no_link_params_delay_var_cmd,
- "no delay-variation",
- NO_STR
- "Disable Unidirectional Delay Variation on this interface\n")
-{
- VTY_DECLVAR_CONTEXT(interface, ifp);
-
- /* Unset Delay Variation */
- link_param_cmd_unset(ifp, LP_DELAY_VAR);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (link_params_pkt_loss,
- link_params_pkt_loss_cmd,
- "packet-loss PERCENTAGE",
- "Unidirectional Link Packet Loss\n"
- "percentage of total traffic by 0.000003% step and less than 50.331642%\n")
-{
- int idx_percentage = 1;
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct if_link_params *iflp = if_link_params_get(ifp);
- float fval;
-
- if (sscanf(argv[idx_percentage]->arg, "%g", &fval) != 1) {
- vty_out(vty, "link_params_pkt_loss: fscanf: %s\n",
- safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (fval > MAX_PKT_LOSS)
- fval = MAX_PKT_LOSS;
-
- if (!iflp)
- iflp = if_link_params_enable(ifp);
-
- /* Update Packet Loss if needed */
- link_param_cmd_set_float(ifp, &iflp->pkt_loss, LP_PKT_LOSS, fval);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (no_link_params_pkt_loss,
- no_link_params_pkt_loss_cmd,
- "no packet-loss",
- NO_STR
- "Disable Unidirectional Link Packet Loss on this interface\n")
-{
- VTY_DECLVAR_CONTEXT(interface, ifp);
-
- /* Unset Packet Loss */
- link_param_cmd_unset(ifp, LP_PKT_LOSS);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (link_params_res_bw,
- link_params_res_bw_cmd,
- "res-bw BANDWIDTH",
- "Unidirectional Residual Bandwidth\n"
- "Bytes/second (IEEE floating point format)\n")
-{
- int idx_bandwidth = 1;
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct if_link_params *iflp = if_link_params_get(ifp);
- float bw;
-
- if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
- vty_out(vty, "link_params_res_bw: fscanf: %s\n",
- safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- /* Check that bandwidth is not greater than maximum bandwidth parameter
- */
- if (iflp && bw > iflp->max_bw) {
- vty_out(vty,
- "Residual Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
- iflp->max_bw);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (!iflp)
- iflp = if_link_params_enable(ifp);
-
- /* Update Residual Bandwidth if needed */
- link_param_cmd_set_float(ifp, &iflp->res_bw, LP_RES_BW, bw);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (no_link_params_res_bw,
- no_link_params_res_bw_cmd,
- "no res-bw",
- NO_STR
- "Disable Unidirectional Residual Bandwidth on this interface\n")
-{
- VTY_DECLVAR_CONTEXT(interface, ifp);
-
- /* Unset Residual Bandwidth */
- link_param_cmd_unset(ifp, LP_RES_BW);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (link_params_ava_bw,
- link_params_ava_bw_cmd,
- "ava-bw BANDWIDTH",
- "Unidirectional Available Bandwidth\n"
- "Bytes/second (IEEE floating point format)\n")
-{
- int idx_bandwidth = 1;
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct if_link_params *iflp = if_link_params_get(ifp);
- float bw;
-
- if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
- vty_out(vty, "link_params_ava_bw: fscanf: %s\n",
- safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- /* Check that bandwidth is not greater than maximum bandwidth parameter
- */
- if (iflp && bw > iflp->max_bw) {
- vty_out(vty,
- "Available Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
- iflp->max_bw);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (!iflp)
- iflp = if_link_params_enable(ifp);
-
- /* Update Residual Bandwidth if needed */
- link_param_cmd_set_float(ifp, &iflp->ava_bw, LP_AVA_BW, bw);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (no_link_params_ava_bw,
- no_link_params_ava_bw_cmd,
- "no ava-bw",
- NO_STR
- "Disable Unidirectional Available Bandwidth on this interface\n")
-{
- VTY_DECLVAR_CONTEXT(interface, ifp);
-
- /* Unset Available Bandwidth */
- link_param_cmd_unset(ifp, LP_AVA_BW);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (link_params_use_bw,
- link_params_use_bw_cmd,
- "use-bw BANDWIDTH",
- "Unidirectional Utilised Bandwidth\n"
- "Bytes/second (IEEE floating point format)\n")
-{
- int idx_bandwidth = 1;
- VTY_DECLVAR_CONTEXT(interface, ifp);
- struct if_link_params *iflp = if_link_params_get(ifp);
- float bw;
-
- if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
- vty_out(vty, "link_params_use_bw: fscanf: %s\n",
- safe_strerror(errno));
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- /* Check that bandwidth is not greater than maximum bandwidth parameter
- */
- if (iflp && bw > iflp->max_bw) {
- vty_out(vty,
- "Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
- iflp->max_bw);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (!iflp)
- iflp = if_link_params_enable(ifp);
-
- /* Update Utilized Bandwidth if needed */
- link_param_cmd_set_float(ifp, &iflp->use_bw, LP_USE_BW, bw);
-
- return CMD_SUCCESS;
-}
-
-DEFUN (no_link_params_use_bw,
- no_link_params_use_bw_cmd,
- "no use-bw",
- NO_STR
- "Disable Unidirectional Utilised Bandwidth on this interface\n")
-{
- VTY_DECLVAR_CONTEXT(interface, ifp);
-
- /* Unset Utilised Bandwidth */
- link_param_cmd_unset(ifp, LP_USE_BW);
-
- return CMD_SUCCESS;
-}
-
-static int ag_change(struct vty *vty, int argc, struct cmd_token **argv,
- const char *xpath, bool no, int start_idx)
-{
- for (int i = start_idx; i < argc; i++)
- nb_cli_enqueue_change(vty, xpath,
- no ? NB_OP_DESTROY : NB_OP_CREATE,
- argv[i]->arg);
- return nb_cli_apply_changes(vty, NULL);
-}
-
-/*
- * XPath:
- * /frr-interface:lib/interface/frr-zebra:zebra/link-params/affinities/affinity
- */
-DEFPY_YANG(link_params_affinity, link_params_affinity_cmd,
- "[no] affinity NAME...",
- NO_STR
- "Interface affinities\n"
- "Affinity names\n")
-{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- char xpath[XPATH_MAXLEN];
-
- snprintf(
- xpath, sizeof(xpath),
- "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params/legacy-admin-group",
- ifp->name);
- if (yang_dnode_exists(running_config->dnode, xpath)) {
- vty_out(vty,
- "cannot use the affinity command when admin-grp is set\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- return ag_change(vty, argc, argv,
- "./frr-zebra:zebra/link-params/affinities/affinity",
- no, no ? 2 : 1);
-}
-
-
-/*
- * XPath:
- * /frr-interface:lib/interface/frr-zebra:zebra/link-params/affinities/affinity-mode
- */
-DEFPY_YANG(link_params_affinity_mode, link_params_affinity_mode_cmd,
- "affinity-mode <standard|extended|both>$affmode",
- "Interface affinity mode\n"
- "Standard Admin-Group only RFC3630,5305,5329 (default)\n"
- "Extended Admin-Group only RFC7308\n"
- "Standard and extended Admin-Group format\n")
-{
- const char *xpath = "./frr-zebra:zebra/link-params/affinity-mode";
-
- nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, affmode);
-
- return nb_cli_apply_changes(vty, NULL);
-}
-
-DEFPY_YANG(no_link_params_affinity_mode, no_link_params_affinity_mode_cmd,
- "no affinity-mode [<standard|extended|both>]",
- NO_STR
- "Interface affinity mode\n"
- "Standard Admin-Group only RFC3630,5305,5329 (default)\n"
- "Extended Admin-Group only RFC7308\n"
- "Standard and extended Admin-Group format\n")
-{
- const char *xpath = "./frr-zebra:zebra/link-params/affinity-mode";
-
- nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, "standard");
-
- return nb_cli_apply_changes(vty, NULL);
-}
-
-static int ag_iter_cb(const struct lyd_node *dnode, void *arg)
-{
- struct vty *vty = (struct vty *)arg;
-
- vty_out(vty, " %s", yang_dnode_get_string(dnode, "."));
- return YANG_ITER_CONTINUE;
-}
-
-void cli_show_legacy_admin_group(struct vty *vty, const struct lyd_node *dnode,
- bool show_defaults)
-{
- if (!yang_dnode_exists(dnode, "./legacy-admin-group"))
- return;
-
- vty_out(vty, " admin-group 0x%x\n",
- yang_dnode_get_uint32(dnode, "./legacy-admin-group"));
-}
-
-void cli_show_affinity_mode(struct vty *vty, const struct lyd_node *dnode,
- bool show_defaults)
-{
- enum affinity_mode affinity_mode = yang_dnode_get_enum(dnode, ".");
-
- if (affinity_mode == AFFINITY_MODE_STANDARD)
- vty_out(vty, " affinity-mode standard\n");
- else if (affinity_mode == AFFINITY_MODE_BOTH)
- vty_out(vty, " affinity-mode both\n");
-}
-
-void cli_show_affinity(struct vty *vty, const struct lyd_node *dnode,
- bool show_defaults)
-{
- if (!yang_dnode_exists(dnode, "./affinity"))
- return;
-
- vty_out(vty, " affinity");
- yang_dnode_iterate(ag_iter_cb, vty, dnode, "./affinity");
- vty_out(vty, "\n");
-}
-
-int if_ip_address_install(struct interface *ifp, struct prefix *prefix,
- const char *label, struct prefix *pp)
+void if_ip_address_install(struct interface *ifp, struct prefix *prefix,
+ const char *label, struct prefix *pp)
{
struct zebra_if *if_data;
- struct prefix_ipv4 lp;
- struct prefix_ipv4 *p;
struct connected *ifc;
- enum zebra_dplane_result dplane_res;
if_data = ifp->info;
- lp.family = prefix->family;
- lp.prefix = prefix->u.prefix4;
- lp.prefixlen = prefix->prefixlen;
- apply_mask_ipv4(&lp);
-
- ifc = connected_check_ptp(ifp, &lp, pp ? pp : NULL);
+ ifc = connected_check_ptp(ifp, prefix, pp);
if (!ifc) {
ifc = connected_new();
ifc->ifp = ifp;
/* Address. */
- p = prefix_ipv4_new();
- *p = lp;
- ifc->address = (struct prefix *)p;
+ ifc->address = prefix_new();
+ prefix_copy(ifc->address, prefix);
if (pp) {
SET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
- p = prefix_ipv4_new();
- *p = *(struct prefix_ipv4 *)pp;
- ifc->destination = (struct prefix *)p;
+ ifc->destination = prefix_new();
+ prefix_copy(ifc->destination, pp);
}
/* Label. */
@@ -4159,7 +3805,7 @@ int if_ip_address_install(struct interface *ifp, struct prefix *prefix,
ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
/* Add to linked list. */
- listnode_add(ifp->connected, ifc);
+ if_connected_add_tail(ifp->connected, ifc);
}
/* This address is configured from zebra. */
@@ -4176,13 +3822,7 @@ int if_ip_address_install(struct interface *ifp, struct prefix *prefix,
if_refresh(ifp);
}
- dplane_res = dplane_intf_addr_set(ifp, ifc);
- if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
- zlog_debug(
- "dplane can't set interface IP address: %s.",
- dplane_res2str(dplane_res));
- return NB_ERR;
- }
+ dplane_intf_addr_set(ifp, ifc);
SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
/* The address will be advertised to zebra clients when the
@@ -4190,407 +3830,50 @@ int if_ip_address_install(struct interface *ifp, struct prefix *prefix,
* from the kernel has been received.
* It will also be added to the subnet chain list, then. */
}
-
- return 0;
}
-static int ip_address_install(struct vty *vty, struct interface *ifp,
- const char *addr_str, const char *peer_str,
- const char *label)
+void if_ip_address_uninstall(struct interface *ifp, struct prefix *prefix,
+ struct prefix *pp)
{
- struct zebra_if *if_data;
- struct prefix_ipv4 lp, pp;
struct connected *ifc;
- struct prefix_ipv4 *p;
- int ret;
- enum zebra_dplane_result dplane_res;
-
- if_data = ifp->info;
-
- ret = str2prefix_ipv4(addr_str, &lp);
- if (ret <= 0) {
- vty_out(vty, "%% Malformed address \n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (ipv4_martian(&lp.prefix)) {
- vty_out(vty, "%% Invalid address\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (peer_str) {
- if (lp.prefixlen != IPV4_MAX_BITLEN) {
- vty_out(vty,
- "%% Local prefix length for P-t-P address must be /32\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- ret = str2prefix_ipv4(peer_str, &pp);
- if (ret <= 0) {
- vty_out(vty, "%% Malformed peer address\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- }
-
- ifc = connected_check_ptp(ifp, &lp, peer_str ? &pp : NULL);
- if (!ifc) {
- ifc = connected_new();
- ifc->ifp = ifp;
-
- /* Address. */
- p = prefix_ipv4_new();
- *p = lp;
- ifc->address = (struct prefix *)p;
-
- if (peer_str) {
- SET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
- p = prefix_ipv4_new();
- *p = pp;
- ifc->destination = (struct prefix *)p;
- }
-
- /* Label. */
- if (label)
- ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
-
- /* Add to linked list. */
- listnode_add(ifp->connected, ifc);
- }
-
- /* This address is configured from zebra. */
- if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
- SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
-
- /* In case of this route need to install kernel. */
- if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) &&
- CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE) &&
- !(if_data && if_data->shutdown == IF_ZEBRA_DATA_ON)) {
- /* Some system need to up the interface to set IP address. */
- if (!if_is_up(ifp)) {
- if_set_flags(ifp, IFF_UP | IFF_RUNNING);
- if_refresh(ifp);
- }
-
- dplane_res = dplane_intf_addr_set(ifp, ifc);
- if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
- vty_out(vty, "%% Can't set interface IP address: %s.\n",
- dplane_res2str(dplane_res));
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
- /* The address will be advertised to zebra clients when the
- * notification
- * from the kernel has been received.
- * It will also be added to the subnet chain list, then. */
- }
-
- return CMD_SUCCESS;
-}
-
-int if_ip_address_uinstall(struct interface *ifp, struct prefix *prefix)
-{
- struct connected *ifc = NULL;
- enum zebra_dplane_result dplane_res;
-
- if (prefix->family == AF_INET) {
- /* Check current interface address. */
- ifc = connected_check_ptp(ifp, prefix, NULL);
- if (!ifc) {
- zlog_debug("interface %s Can't find address",
- ifp->name);
- return -1;
- }
- } else if (prefix->family == AF_INET6) {
- /* Check current interface address. */
- ifc = connected_check(ifp, prefix);
- }
+ ifc = connected_check_ptp(ifp, prefix, pp);
+ assert(ifc);
- if (!ifc) {
- zlog_debug("interface %s Can't find address", ifp->name);
- return -1;
- }
UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
/* This is not real address or interface is not active. */
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
|| !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
- listnode_delete(ifp->connected, ifc);
+ if_connected_del(ifp->connected, ifc);
connected_free(&ifc);
- return CMD_WARNING_CONFIG_FAILED;
+ return;
}
/* This is real route. */
- dplane_res = dplane_intf_addr_unset(ifp, ifc);
- if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
- zlog_debug("Can't unset interface IP address: %s.",
- dplane_res2str(dplane_res));
- return -1;
- }
- UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
-
- return 0;
-}
-
-static int ip_address_uninstall(struct vty *vty, struct interface *ifp,
- const char *addr_str, const char *peer_str,
- const char *label)
-{
- struct prefix_ipv4 lp, pp;
- struct connected *ifc;
- int ret;
- enum zebra_dplane_result dplane_res;
-
- /* Convert to prefix structure. */
- ret = str2prefix_ipv4(addr_str, &lp);
- if (ret <= 0) {
- vty_out(vty, "%% Malformed address \n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (peer_str) {
- if (lp.prefixlen != IPV4_MAX_BITLEN) {
- vty_out(vty,
- "%% Local prefix length for P-t-P address must be /32\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- ret = str2prefix_ipv4(peer_str, &pp);
- if (ret <= 0) {
- vty_out(vty, "%% Malformed peer address\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- }
-
- /* Check current interface address. */
- ifc = connected_check_ptp(ifp, &lp, peer_str ? &pp : NULL);
- if (!ifc) {
- vty_out(vty, "%% Can't find address\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ dplane_intf_addr_unset(ifp, ifc);
- /* This is not configured address. */
- if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
- return CMD_WARNING_CONFIG_FAILED;
-
- UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
-
- /* This is not real address or interface is not active. */
- if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
- || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
- listnode_delete(ifp->connected, ifc);
- connected_free(&ifc);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- /* This is real route. */
- dplane_res = dplane_intf_addr_unset(ifp, ifc);
- if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
- vty_out(vty, "%% Can't unset interface IP address: %s.\n",
- dplane_res2str(dplane_res));
- return CMD_WARNING_CONFIG_FAILED;
- }
UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
- /* we will receive a kernel notification about this route being removed.
- * this will trigger its removal from the connected list. */
- return CMD_SUCCESS;
-}
-
-DEFUN (ip_address,
- ip_address_cmd,
- "ip address A.B.C.D/M",
- "Interface Internet Protocol config commands\n"
- "Set the IP address of an interface\n"
- "IP address (e.g. 10.0.0.1/8)\n")
-{
- int idx_ipv4_prefixlen = 2;
- VTY_DECLVAR_CONTEXT(interface, ifp);
- return ip_address_install(vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL,
- NULL);
-}
-
-DEFUN (no_ip_address,
- no_ip_address_cmd,
- "no ip address A.B.C.D/M",
- NO_STR
- "Interface Internet Protocol config commands\n"
- "Set the IP address of an interface\n"
- "IP Address (e.g. 10.0.0.1/8)\n")
-{
- int idx_ipv4_prefixlen = 3;
- VTY_DECLVAR_CONTEXT(interface, ifp);
- return ip_address_uninstall(vty, ifp, argv[idx_ipv4_prefixlen]->arg,
- NULL, NULL);
-}
-
-DEFUN(ip_address_peer,
- ip_address_peer_cmd,
- "ip address A.B.C.D peer A.B.C.D/M",
- "Interface Internet Protocol config commands\n"
- "Set the IP address of an interface\n"
- "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
- "Specify P-t-P address\n"
- "Peer IP address (e.g. 10.0.0.1/8)\n")
-{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- return ip_address_install(vty, ifp, argv[2]->arg, argv[4]->arg, NULL);
-}
-
-DEFUN(no_ip_address_peer,
- no_ip_address_peer_cmd,
- "no ip address A.B.C.D peer A.B.C.D/M",
- NO_STR
- "Interface Internet Protocol config commands\n"
- "Set the IP address of an interface\n"
- "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
- "Specify P-t-P address\n"
- "Peer IP address (e.g. 10.0.0.1/8)\n")
-{
- VTY_DECLVAR_CONTEXT(interface, ifp);
- return ip_address_uninstall(vty, ifp, argv[3]->arg, argv[5]->arg, NULL);
-}
-
-#ifdef HAVE_NETLINK
-DEFUN (ip_address_label,
- ip_address_label_cmd,
- "ip address A.B.C.D/M label LINE",
- "Interface Internet Protocol config commands\n"
- "Set the IP address of an interface\n"
- "IP address (e.g. 10.0.0.1/8)\n"
- "Label of this address\n"
- "Label\n")
-{
- int idx_ipv4_prefixlen = 2;
- int idx_line = 4;
- VTY_DECLVAR_CONTEXT(interface, ifp);
- return ip_address_install(vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL,
- argv[idx_line]->arg);
-}
-
-DEFUN (no_ip_address_label,
- no_ip_address_label_cmd,
- "no ip address A.B.C.D/M label LINE",
- NO_STR
- "Interface Internet Protocol config commands\n"
- "Set the IP address of an interface\n"
- "IP address (e.g. 10.0.0.1/8)\n"
- "Label of this address\n"
- "Label\n")
-{
- int idx_ipv4_prefixlen = 3;
- int idx_line = 5;
- VTY_DECLVAR_CONTEXT(interface, ifp);
- return ip_address_uninstall(vty, ifp, argv[idx_ipv4_prefixlen]->arg,
- NULL, argv[idx_line]->arg);
}
-#endif /* HAVE_NETLINK */
-int if_ipv6_address_install(struct interface *ifp, struct prefix *prefix,
- const char *label)
+void if_ipv6_address_install(struct interface *ifp, struct prefix *prefix)
{
struct zebra_if *if_data;
- struct prefix_ipv6 cp;
struct connected *ifc;
- struct prefix_ipv6 *p;
- enum zebra_dplane_result dplane_res;
-
- if_data = ifp->info;
-
- cp.family = prefix->family;
- cp.prefixlen = prefix->prefixlen;
- cp.prefix = prefix->u.prefix6;
- apply_mask_ipv6(&cp);
-
- ifc = connected_check(ifp, (struct prefix *)&cp);
- if (!ifc) {
- ifc = connected_new();
- ifc->ifp = ifp;
-
- /* Address. */
- p = prefix_ipv6_new();
- *p = cp;
- ifc->address = (struct prefix *)p;
-
- /* Label. */
- if (label)
- ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
-
- /* Add to linked list. */
- listnode_add(ifp->connected, ifc);
- }
-
- /* This address is configured from zebra. */
- if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
- SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
-
- /* In case of this route need to install kernel. */
- if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) &&
- CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE) &&
- !(if_data && if_data->shutdown == IF_ZEBRA_DATA_ON)) {
- /* Some system need to up the interface to set IP address. */
- if (!if_is_up(ifp)) {
- if_set_flags(ifp, IFF_UP | IFF_RUNNING);
- if_refresh(ifp);
- }
-
- dplane_res = dplane_intf_addr_set(ifp, ifc);
- if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
- zlog_debug(
- "dplane can't set interface IP address: %s.",
- dplane_res2str(dplane_res));
- return NB_ERR;
- }
-
- SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
- /* The address will be advertised to zebra clients when the
- * notification
- * from the kernel has been received. */
- }
-
- return 0;
-}
-
-static int ipv6_address_install(struct vty *vty, struct interface *ifp,
- const char *addr_str, const char *peer_str,
- const char *label)
-{
- struct zebra_if *if_data;
- struct prefix_ipv6 cp;
- struct connected *ifc;
- struct prefix_ipv6 *p;
- int ret;
- enum zebra_dplane_result dplane_res;
if_data = ifp->info;
- ret = str2prefix_ipv6(addr_str, &cp);
- if (ret <= 0) {
- vty_out(vty, "%% Malformed address \n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (ipv6_martian(&cp.prefix)) {
- vty_out(vty, "%% Invalid address\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- ifc = connected_check(ifp, (struct prefix *)&cp);
+ ifc = connected_check(ifp, prefix);
if (!ifc) {
ifc = connected_new();
ifc->ifp = ifp;
/* Address. */
- p = prefix_ipv6_new();
- *p = cp;
- ifc->address = (struct prefix *)p;
-
- /* Label. */
- if (label)
- ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
+ ifc->address = prefix_new();
+ prefix_copy(ifc->address, prefix);
/* Add to linked list. */
- listnode_add(ifp->connected, ifc);
+ if_connected_add_tail(ifp->connected, ifc);
}
/* This address is configured from zebra. */
@@ -4607,261 +3890,36 @@ static int ipv6_address_install(struct vty *vty, struct interface *ifp,
if_refresh(ifp);
}
- dplane_res = dplane_intf_addr_set(ifp, ifc);
- if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
- vty_out(vty, "%% Can't set interface IP address: %s.\n",
- dplane_res2str(dplane_res));
- return CMD_WARNING_CONFIG_FAILED;
- }
+ dplane_intf_addr_set(ifp, ifc);
SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
/* The address will be advertised to zebra clients when the
* notification
* from the kernel has been received. */
}
-
- return CMD_SUCCESS;
-}
-
-/* Return true if an ipv6 address is configured on ifp */
-int ipv6_address_configured(struct interface *ifp)
-{
- struct connected *connected;
- struct listnode *node;
-
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected))
- if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
- && (connected->address->family == AF_INET6))
- return 1;
-
- return 0;
}
-static int ipv6_address_uninstall(struct vty *vty, struct interface *ifp,
- const char *addr_str, const char *peer_str,
- const char *label)
+void if_ipv6_address_uninstall(struct interface *ifp, struct prefix *prefix)
{
- struct prefix_ipv6 cp;
struct connected *ifc;
- int ret;
- enum zebra_dplane_result dplane_res;
-
- /* Convert to prefix structure. */
- ret = str2prefix_ipv6(addr_str, &cp);
- if (ret <= 0) {
- vty_out(vty, "%% Malformed address \n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- /* Check current interface address. */
- ifc = connected_check(ifp, (struct prefix *)&cp);
- if (!ifc) {
- vty_out(vty, "%% Can't find address\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- /* This is not configured address. */
- if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
- return CMD_WARNING_CONFIG_FAILED;
+ ifc = connected_check(ifp, prefix);
+ assert(ifc);
UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
/* This is not real address or interface is not active. */
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
|| !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
- listnode_delete(ifp->connected, ifc);
+ if_connected_del(ifp->connected, ifc);
connected_free(&ifc);
- return CMD_WARNING_CONFIG_FAILED;
+ return;
}
/* This is real route. */
- dplane_res = dplane_intf_addr_unset(ifp, ifc);
- if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
- vty_out(vty, "%% Can't unset interface IP address: %s.\n",
- dplane_res2str(dplane_res));
- return CMD_WARNING_CONFIG_FAILED;
- }
+ dplane_intf_addr_unset(ifp, ifc);
UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
- /* This information will be propagated to the zclients when the
- * kernel notification is received. */
- return CMD_SUCCESS;
-}
-
-DEFUN (ipv6_address,
- ipv6_address_cmd,
- "ipv6 address X:X::X:X/M",
- "Interface IPv6 config commands\n"
- "Set the IP address of an interface\n"
- "IPv6 address (e.g. 3ffe:506::1/48)\n")
-{
- int idx_ipv6_prefixlen = 2;
- VTY_DECLVAR_CONTEXT(interface, ifp);
- return ipv6_address_install(vty, ifp, argv[idx_ipv6_prefixlen]->arg,
- NULL, NULL);
-}
-
-DEFUN (no_ipv6_address,
- no_ipv6_address_cmd,
- "no ipv6 address X:X::X:X/M",
- NO_STR
- "Interface IPv6 config commands\n"
- "Set the IP address of an interface\n"
- "IPv6 address (e.g. 3ffe:506::1/48)\n")
-{
- int idx_ipv6_prefixlen = 3;
- VTY_DECLVAR_CONTEXT(interface, ifp);
- return ipv6_address_uninstall(vty, ifp, argv[idx_ipv6_prefixlen]->arg,
- NULL, NULL);
-}
-
-static int link_params_config_write(struct vty *vty, struct interface *ifp)
-{
- const struct lyd_node *dnode;
- char xpath[XPATH_MAXLEN];
- int i;
-
- if ((ifp == NULL) || !HAS_LINK_PARAMS(ifp))
- return -1;
-
- struct if_link_params *iflp = ifp->link_params;
-
- vty_out(vty, " link-params\n");
- vty_out(vty, " enable\n");
- if (IS_PARAM_SET(iflp, LP_TE_METRIC) && iflp->te_metric != ifp->metric)
- vty_out(vty, " metric %u\n", iflp->te_metric);
- if (IS_PARAM_SET(iflp, LP_MAX_BW) && iflp->max_bw != iflp->default_bw)
- vty_out(vty, " max-bw %g\n", iflp->max_bw);
- if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW)
- && iflp->max_rsv_bw != iflp->default_bw)
- vty_out(vty, " max-rsv-bw %g\n", iflp->max_rsv_bw);
- if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) {
- for (i = 0; i < 8; i++)
- if (iflp->unrsv_bw[i] != iflp->default_bw)
- vty_out(vty, " unrsv-bw %d %g\n", i,
- iflp->unrsv_bw[i]);
- }
-
- snprintf(
- xpath, sizeof(xpath),
- "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params",
- ifp->name);
- dnode = yang_dnode_get(running_config->dnode, xpath);
- if (dnode)
- nb_cli_show_dnode_cmds(vty, dnode, false);
-
- if (IS_PARAM_SET(iflp, LP_DELAY)) {
- vty_out(vty, " delay %u", iflp->av_delay);
- if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
- vty_out(vty, " min %u", iflp->min_delay);
- vty_out(vty, " max %u", iflp->max_delay);
- }
- vty_out(vty, "\n");
- }
- if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
- vty_out(vty, " delay-variation %u\n", iflp->delay_var);
- if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
- vty_out(vty, " packet-loss %g\n", iflp->pkt_loss);
- if (IS_PARAM_SET(iflp, LP_AVA_BW))
- vty_out(vty, " ava-bw %g\n", iflp->ava_bw);
- if (IS_PARAM_SET(iflp, LP_RES_BW))
- vty_out(vty, " res-bw %g\n", iflp->res_bw);
- if (IS_PARAM_SET(iflp, LP_USE_BW))
- vty_out(vty, " use-bw %g\n", iflp->use_bw);
- if (IS_PARAM_SET(iflp, LP_RMT_AS))
- vty_out(vty, " neighbor %pI4 as %u\n", &iflp->rmt_ip,
- iflp->rmt_as);
-
- vty_out(vty, " exit-link-params\n");
- return 0;
-}
-
-static int if_config_write(struct vty *vty)
-{
- struct vrf *vrf;
- struct interface *ifp;
-
- zebra_ptm_write(vty);
-
- RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
- FOR_ALL_INTERFACES (vrf, ifp) {
- struct zebra_if *if_data;
- struct listnode *addrnode;
- struct connected *ifc;
- struct prefix *p;
-
- if_data = ifp->info;
-
- if_vty_config_start(vty, ifp);
-
- if (if_data) {
- if (if_data->shutdown == IF_ZEBRA_DATA_ON)
- vty_out(vty, " shutdown\n");
-
- zebra_ptm_if_write(vty, if_data);
- }
-
- if (ifp->desc)
- vty_out(vty, " description %s\n", ifp->desc);
-
- /* Assign bandwidth here to avoid unnecessary interface
- flap
- while processing config script */
- if (ifp->bandwidth != 0)
- vty_out(vty, " bandwidth %u\n", ifp->bandwidth);
-
- if (!CHECK_FLAG(ifp->status,
- ZEBRA_INTERFACE_LINKDETECTION))
- vty_out(vty, " no link-detect\n");
-
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, addrnode,
- ifc)) {
- if (CHECK_FLAG(ifc->conf,
- ZEBRA_IFC_CONFIGURED)) {
- char buf[INET6_ADDRSTRLEN];
- p = ifc->address;
- vty_out(vty, " ip%s address %s",
- p->family == AF_INET ? ""
- : "v6",
- inet_ntop(p->family,
- &p->u.prefix, buf,
- sizeof(buf)));
- if (CONNECTED_PEER(ifc)) {
- p = ifc->destination;
- vty_out(vty, " peer %s",
- inet_ntop(p->family,
- &p->u.prefix,
- buf,
- sizeof(buf)));
- }
- vty_out(vty, "/%d", p->prefixlen);
-
- if (ifc->label)
- vty_out(vty, " label %s",
- ifc->label);
-
- vty_out(vty, "\n");
- }
- }
-
- if (if_data) {
- if (if_data->multicast != IF_ZEBRA_DATA_UNSPEC)
- vty_out(vty, " %smulticast\n",
- if_data->multicast ==
- IF_ZEBRA_DATA_ON
- ? ""
- : "no ");
- if (if_data->mpls == IF_ZEBRA_DATA_ON)
- vty_out(vty, " mpls enable\n");
- }
-
- hook_call(zebra_if_config_wr, vty, ifp);
- zebra_evpn_mh_if_write(vty, ifp);
- link_params_config_write(vty, ifp);
-
- if_vty_config_end(vty);
- }
- return 0;
}
/* Allocate and initialize interface vector. */
@@ -4871,15 +3929,6 @@ void zebra_if_init(void)
hook_register_prio(if_add, 0, if_zebra_new_hook);
hook_register_prio(if_del, 0, if_zebra_delete_hook);
- /* Install configuration write function. */
- if_cmd_init(if_config_write);
- install_node(&link_params_node);
- /*
- * This is *intentionally* setting this to NULL, signaling
- * that interface creation for zebra acts differently
- */
- if_zapi_callbacks(NULL, NULL, NULL, NULL);
-
install_element(VIEW_NODE, &show_interface_cmd);
install_element(VIEW_NODE, &show_interface_vrf_all_cmd);
install_element(VIEW_NODE, &show_interface_name_vrf_cmd);
@@ -4887,55 +3936,4 @@ void zebra_if_init(void)
install_element(ENABLE_NODE, &show_interface_desc_cmd);
install_element(ENABLE_NODE, &show_interface_desc_vrf_all_cmd);
- install_element(INTERFACE_NODE, &multicast_cmd);
- install_element(INTERFACE_NODE, &no_multicast_cmd);
- install_element(INTERFACE_NODE, &mpls_cmd);
- install_element(INTERFACE_NODE, &linkdetect_cmd);
- install_element(INTERFACE_NODE, &no_linkdetect_cmd);
- install_element(INTERFACE_NODE, &shutdown_if_cmd);
- install_element(INTERFACE_NODE, &no_shutdown_if_cmd);
- install_element(INTERFACE_NODE, &bandwidth_if_cmd);
- install_element(INTERFACE_NODE, &no_bandwidth_if_cmd);
- install_element(INTERFACE_NODE, &ip_address_cmd);
- install_element(INTERFACE_NODE, &no_ip_address_cmd);
- install_element(INTERFACE_NODE, &ip_address_peer_cmd);
- install_element(INTERFACE_NODE, &no_ip_address_peer_cmd);
- install_element(INTERFACE_NODE, &ipv6_address_cmd);
- install_element(INTERFACE_NODE, &no_ipv6_address_cmd);
-#ifdef HAVE_NETLINK
- install_element(INTERFACE_NODE, &ip_address_label_cmd);
- install_element(INTERFACE_NODE, &no_ip_address_label_cmd);
-#endif /* HAVE_NETLINK */
- install_element(INTERFACE_NODE, &link_params_cmd);
- install_default(LINK_PARAMS_NODE);
- install_element(LINK_PARAMS_NODE, &link_params_enable_cmd);
- install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd);
- install_element(LINK_PARAMS_NODE, &link_params_metric_cmd);
- install_element(LINK_PARAMS_NODE, &no_link_params_metric_cmd);
- install_element(LINK_PARAMS_NODE, &link_params_maxbw_cmd);
- install_element(LINK_PARAMS_NODE, &link_params_max_rsv_bw_cmd);
- install_element(LINK_PARAMS_NODE, &link_params_unrsv_bw_cmd);
- install_element(LINK_PARAMS_NODE, &link_params_admin_grp_cmd);
- install_element(LINK_PARAMS_NODE, &no_link_params_admin_grp_cmd);
- install_element(LINK_PARAMS_NODE, &link_params_inter_as_cmd);
- install_element(LINK_PARAMS_NODE, &no_link_params_inter_as_cmd);
- install_element(LINK_PARAMS_NODE, &link_params_delay_cmd);
- install_element(LINK_PARAMS_NODE, &no_link_params_delay_cmd);
- install_element(LINK_PARAMS_NODE, &link_params_delay_var_cmd);
- install_element(LINK_PARAMS_NODE, &no_link_params_delay_var_cmd);
- install_element(LINK_PARAMS_NODE, &link_params_pkt_loss_cmd);
- install_element(LINK_PARAMS_NODE, &no_link_params_pkt_loss_cmd);
- install_element(LINK_PARAMS_NODE, &link_params_ava_bw_cmd);
- install_element(LINK_PARAMS_NODE, &no_link_params_ava_bw_cmd);
- install_element(LINK_PARAMS_NODE, &link_params_res_bw_cmd);
- install_element(LINK_PARAMS_NODE, &no_link_params_res_bw_cmd);
- install_element(LINK_PARAMS_NODE, &link_params_use_bw_cmd);
- install_element(LINK_PARAMS_NODE, &no_link_params_use_bw_cmd);
- install_element(LINK_PARAMS_NODE, &link_params_affinity_cmd);
- install_element(LINK_PARAMS_NODE, &link_params_affinity_mode_cmd);
- install_element(LINK_PARAMS_NODE, &no_link_params_affinity_mode_cmd);
- install_element(LINK_PARAMS_NODE, &exit_link_params_cmd);
-
- /* setup EVPN MH elements */
- zebra_evpn_interface_init();
}