summaryrefslogtreecommitdiff
path: root/zebra/interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/interface.c')
-rw-r--r--zebra/interface.c87
1 files changed, 79 insertions, 8 deletions
diff --git a/zebra/interface.c b/zebra/interface.c
index 2e13cfd55c..fbd2aac005 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -64,7 +64,7 @@ DEFINE_HOOK(zebra_if_config_wr, (struct vty * vty, struct interface *ifp),
static void if_down_del_nbr_connected(struct interface *ifp);
-static int if_zebra_speed_update(struct thread *thread)
+static void if_zebra_speed_update(struct thread *thread)
{
struct interface *ifp = THREAD_ARG(thread);
struct zebra_if *zif = ifp->info;
@@ -72,8 +72,6 @@ static int if_zebra_speed_update(struct thread *thread)
bool changed = false;
int error = 0;
- zif->speed_update = NULL;
-
new_speed = kernel_get_speed(ifp, &error);
/* error may indicate vrf not available or
@@ -81,7 +79,7 @@ static int if_zebra_speed_update(struct thread *thread)
* note that loopback & virtual interfaces can return 0 as speed
*/
if (error < 0)
- return 1;
+ return;
if (new_speed != ifp->speed) {
zlog_info("%s: %s old speed: %u new speed: %u", __func__,
@@ -92,12 +90,29 @@ static int if_zebra_speed_update(struct thread *thread)
}
if (changed || new_speed == UINT32_MAX) {
- thread_add_timer(zrouter.master, if_zebra_speed_update, ifp, 5,
- &zif->speed_update);
+#define SPEED_UPDATE_SLEEP_TIME 5
+#define SPEED_UPDATE_COUNT_MAX (4 * 60 / SPEED_UPDATE_SLEEP_TIME)
+ /*
+ * Some interfaces never actually have an associated speed
+ * with them ( I am looking at you bridges ).
+ * So instead of iterating forever, let's give the
+ * system 4 minutes to try to figure out the speed
+ * if after that it it's probably never going to become
+ * useful.
+ * Since I don't know all the wonderful types of interfaces
+ * that may come into existence in the future I am going
+ * 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 &&
+ zif->speed_update_count == SPEED_UPDATE_COUNT_MAX)
+ return;
+
+ zif->speed_update_count++;
+ thread_add_timer(zrouter.master, if_zebra_speed_update, ifp,
+ SPEED_UPDATE_SLEEP_TIME, &zif->speed_update);
thread_ignore_late_timer(zif->speed_update);
}
-
- return 1;
}
static void zebra_if_node_destroy(route_table_delegate_t *delegate,
@@ -198,6 +213,7 @@ static int if_zebra_new_hook(struct interface *ifp)
* of seconds and ask again. Hopefully it's all settled
* down upon startup.
*/
+ zebra_if->speed_update_count = 0;
thread_add_timer(zrouter.master, if_zebra_speed_update, ifp, 15,
&zebra_if->speed_update);
thread_ignore_late_timer(zebra_if->speed_update);
@@ -1320,6 +1336,56 @@ done:
dplane_ctx_fini(&ctx);
}
+/*
+ * Handle netconf change from a dplane context object; runs in the main
+ * pthread so it can update zebra data structs.
+ */
+int zebra_if_netconf_update_ctx(struct zebra_dplane_ctx *ctx)
+{
+ struct zebra_ns *zns;
+ struct interface *ifp;
+ struct zebra_if *zif;
+ enum dplane_netconf_status_e mpls;
+ int ret = 0;
+
+ zns = zebra_ns_lookup(dplane_ctx_get_netconf_ns_id(ctx));
+ if (zns == NULL) {
+ ret = -1;
+ goto done;
+ }
+
+ ifp = if_lookup_by_index_per_ns(zns,
+ dplane_ctx_get_netconf_ifindex(ctx));
+ if (ifp == NULL) {
+ ret = -1;
+ goto done;
+ }
+
+ zif = ifp->info;
+ if (zif == NULL) {
+ ret = -1;
+ goto done;
+ }
+
+ mpls = dplane_ctx_get_netconf_mpls(ctx);
+
+ if (mpls == DPLANE_NETCONF_STATUS_ENABLED)
+ zif->mpls = true;
+ else if (mpls == DPLANE_NETCONF_STATUS_DISABLED)
+ zif->mpls = false;
+
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug("%s: if %s, ifindex %d, mpls %s",
+ __func__, ifp->name, ifp->ifindex,
+ (zif->mpls ? "ON" : "OFF"));
+
+done:
+ /* Free the context */
+ dplane_ctx_fini(&ctx);
+
+ return ret;
+}
+
/* Dump if address information to vty. */
static void connected_dump_vty(struct vty *vty, json_object *json,
struct connected *connected)
@@ -1672,6 +1738,9 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp)
vty_out(vty, "mtu6 %d ", ifp->mtu6);
vty_out(vty, "\n flags: %s\n", if_flag_dump(ifp->flags));
+ if (zebra_if->mpls)
+ vty_out(vty, " MPLS enabled\n");
+
/* Hardware address. */
vty_out(vty, " Type: %s\n", if_link_type_str(ifp->ll_type));
if (ifp->hw_addr_len != 0) {
@@ -1992,6 +2061,8 @@ static void if_dump_vty_json(struct vty *vty, struct interface *ifp,
json_object_string_add(json_if, "OsDescription",
zebra_if->desc);
+ json_object_boolean_add(json_if, "mplsEnabled", zebra_if->mpls);
+
if (ifp->ifindex == IFINDEX_INTERNAL) {
json_object_boolean_add(json_if, "pseudoInterface", true);
return;