struct interface *ifp)
{
struct zebra_if *zif;
- enum dplane_netconf_status_e mpls;
+ enum dplane_netconf_status_e mpls, linkdown;
zif = ifp->info;
if (!zif) {
else if (mpls == DPLANE_NETCONF_STATUS_DISABLED)
zif->mpls = false;
+ linkdown = dplane_ctx_get_netconf_linkdown(ctx);
+ if (linkdown == DPLANE_NETCONF_STATUS_ENABLED)
+ zif->linkdown = true;
+ else if (linkdown == DPLANE_NETCONF_STATUS_DISABLED)
+ zif->linkdown = false;
+
if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug("%s: if %s, ifindex %d, mpls %s",
+ zlog_debug("%s: if %s, ifindex %d, mpls %s linkdown %s",
__func__, ifp->name, ifp->ifindex,
- (zif->mpls ? "ON" : "OFF"));
+ (zif->mpls ? "ON" : "OFF"),
+ (zif->linkdown ? "ON" : "OFF"));
}
void zebra_if_dplane_result(struct zebra_dplane_ctx *ctx)
if (zebra_if->mpls)
vty_out(vty, " MPLS enabled\n");
+ if (zebra_if->linkdown)
+ vty_out(vty, " Ignore all routes with linkdown\n");
+
/* Hardware address. */
vty_out(vty, " Type: %s\n", if_link_type_str(ifp->ll_type));
if (ifp->hw_addr_len != 0) {
zebra_if->desc);
json_object_boolean_add(json_if, "mplsEnabled", zebra_if->mpls);
+ json_object_boolean_add(json_if, "linkDown", zebra_if->linkdown);
if (ifp->ifindex == IFINDEX_INTERNAL) {
json_object_boolean_add(json_if, "pseudoInterface", true);
/* MPLS status. */
bool mpls;
+ /* Linkdown status */
+ bool linkdown;
+
/* Router advertise configuration. */
uint8_t rtadv_enable;
* Handle netconf update about a single interface: create dplane
* context, and enqueue for processing in the main zebra pthread.
*/
-static int netlink_netconf_dplane_update(ns_id_t ns_id, ifindex_t ifindex,
- enum dplane_netconf_status_e mpls_on,
- enum dplane_netconf_status_e mcast_on)
+static int
+netlink_netconf_dplane_update(ns_id_t ns_id, ifindex_t ifindex,
+ enum dplane_netconf_status_e mpls_on,
+ enum dplane_netconf_status_e mcast_on,
+ enum dplane_netconf_status_e linkdown_on)
{
struct zebra_dplane_ctx *ctx;
dplane_ctx_set_netconf_mpls(ctx, mpls_on);
dplane_ctx_set_netconf_mcast(ctx, mcast_on);
+ dplane_ctx_set_netconf_linkdown(ctx, linkdown_on);
/* Enqueue ctx for main pthread to process */
dplane_provider_enqueue_to_zebra(ctx);
uint32_t ival;
enum dplane_netconf_status_e mpls_on = DPLANE_NETCONF_STATUS_UNKNOWN;
enum dplane_netconf_status_e mcast_on = DPLANE_NETCONF_STATUS_UNKNOWN;
+ enum dplane_netconf_status_e linkdown_on =
+ DPLANE_NETCONF_STATUS_UNKNOWN;
if (h->nlmsg_type != RTM_NEWNETCONF && h->nlmsg_type != RTM_DELNETCONF)
return 0;
mcast_on = DPLANE_NETCONF_STATUS_DISABLED;
}
+ if (tb[NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN]) {
+ ival = *(uint32_t *)RTA_DATA(
+ tb[NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN]);
+ if (ival != 0)
+ linkdown_on = DPLANE_NETCONF_STATUS_ENABLED;
+ else
+ linkdown_on = DPLANE_NETCONF_STATUS_DISABLED;
+ }
+
if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug("%s: interface %u is mpls on: %d multicast on: %d",
- __func__, ifindex, mpls_on, mcast_on);
+ zlog_debug(
+ "%s: interface %u is mpls on: %d multicast on: %d linkdown: %d",
+ __func__, ifindex, mpls_on, mcast_on, linkdown_on);
/* Create a dplane context and pass it along for processing */
- netlink_netconf_dplane_update(ns_id, ifindex, mpls_on, mcast_on);
+ netlink_netconf_dplane_update(ns_id, ifindex, mpls_on, mcast_on,
+ linkdown_on);
return 0;
}
struct dplane_netconf_info {
enum dplane_netconf_status_e mpls_val;
enum dplane_netconf_status_e mcast_val;
+ enum dplane_netconf_status_e linkdown_val;
};
/*
return ctx->u.netconf.mcast_val;
}
+enum dplane_netconf_status_e
+dplane_ctx_get_netconf_linkdown(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.netconf.linkdown_val;
+}
+
void dplane_ctx_set_netconf_mpls(struct zebra_dplane_ctx *ctx,
enum dplane_netconf_status_e val)
{
ctx->u.netconf.mcast_val = val;
}
+void dplane_ctx_set_netconf_linkdown(struct zebra_dplane_ctx *ctx,
+ enum dplane_netconf_status_e val)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ ctx->u.netconf.linkdown_val = val;
+}
+
+
/*
* Retrieve the limit on the number of pending, unprocessed updates.
*/
dplane_ctx_get_netconf_mpls(const struct zebra_dplane_ctx *ctx);
enum dplane_netconf_status_e
dplane_ctx_get_netconf_mcast(const struct zebra_dplane_ctx *ctx);
+enum dplane_netconf_status_e
+dplane_ctx_get_netconf_linkdown(const struct zebra_dplane_ctx *ctx);
+
void dplane_ctx_set_netconf_mpls(struct zebra_dplane_ctx *ctx,
enum dplane_netconf_status_e val);
void dplane_ctx_set_netconf_mcast(struct zebra_dplane_ctx *ctx,
enum dplane_netconf_status_e val);
+void dplane_ctx_set_netconf_linkdown(struct zebra_dplane_ctx *ctx,
+ enum dplane_netconf_status_e val);
/* Namespace fd info - esp. for netlink communication */
const struct zebra_dplane_info *dplane_ctx_get_ns(