]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zebra_dplane.c
zebra: Add interface sysctl ignore on linkdown status
[mirror_frr.git] / zebra / zebra_dplane.c
index abafa6f8feff06dbffe480b85c09423fbf19e8e3..3a3bac6c74db9cbaa36032dc08f5d766ee335780 100644 (file)
@@ -192,9 +192,9 @@ struct dplane_intf_info {
 
        uint32_t metric;
        uint32_t flags;
-       uint32_t r_bitfield;
 
        bool protodown;
+       bool pd_reason_val;
 
 #define DPLANE_INTF_CONNECTED   (1 << 0) /* Connected peer, p2p */
 #define DPLANE_INTF_SECONDARY   (1 << 1)
@@ -301,10 +301,9 @@ struct dplane_gre_ctx {
  * info. The flags values are public, in the dplane.h file...
  */
 struct dplane_netconf_info {
-       ns_id_t ns_id;
-       ifindex_t ifindex;
        enum dplane_netconf_status_e mpls_val;
        enum dplane_netconf_status_e mcast_val;
+       enum dplane_netconf_status_e linkdown_val;
 };
 
 /*
@@ -1790,19 +1789,18 @@ void dplane_ctx_set_intf_metric(struct zebra_dplane_ctx *ctx, uint32_t metric)
        ctx->u.intf.metric = metric;
 }
 
-uint32_t dplane_ctx_get_intf_r_bitfield(const struct zebra_dplane_ctx *ctx)
+uint32_t dplane_ctx_get_intf_pd_reason_val(const struct zebra_dplane_ctx *ctx)
 {
        DPLANE_CTX_VALID(ctx);
 
-       return ctx->u.intf.r_bitfield;
+       return ctx->u.intf.pd_reason_val;
 }
 
-void dplane_ctx_set_intf_r_bitfield(struct zebra_dplane_ctx *ctx,
-                                   uint32_t r_bitfield)
+void dplane_ctx_set_intf_pd_reason_val(struct zebra_dplane_ctx *ctx, bool val)
 {
        DPLANE_CTX_VALID(ctx);
 
-       ctx->u.intf.r_bitfield = r_bitfield;
+       ctx->u.intf.pd_reason_val = val;
 }
 
 bool dplane_ctx_intf_is_protodown(const struct zebra_dplane_ctx *ctx)
@@ -2335,49 +2333,28 @@ dplane_ctx_neightable_get_mcast_probes(const struct zebra_dplane_ctx *ctx)
        return ctx->u.neightable.mcast_probes;
 }
 
-ifindex_t dplane_ctx_get_netconf_ifindex(const struct zebra_dplane_ctx *ctx)
-{
-       DPLANE_CTX_VALID(ctx);
-
-       return ctx->u.netconf.ifindex;
-}
-
-ns_id_t dplane_ctx_get_netconf_ns_id(const struct zebra_dplane_ctx *ctx)
-{
-       DPLANE_CTX_VALID(ctx);
-
-       return ctx->u.netconf.ns_id;
-}
-
-void dplane_ctx_set_netconf_ifindex(struct zebra_dplane_ctx *ctx,
-                                   ifindex_t ifindex)
-{
-       DPLANE_CTX_VALID(ctx);
-
-       ctx->u.netconf.ifindex = ifindex;
-}
-
-void dplane_ctx_set_netconf_ns_id(struct zebra_dplane_ctx *ctx, ns_id_t ns_id)
+enum dplane_netconf_status_e
+dplane_ctx_get_netconf_mpls(const struct zebra_dplane_ctx *ctx)
 {
        DPLANE_CTX_VALID(ctx);
 
-       ctx->u.netconf.ns_id = ns_id;
+       return ctx->u.netconf.mpls_val;
 }
 
 enum dplane_netconf_status_e
-dplane_ctx_get_netconf_mpls(const struct zebra_dplane_ctx *ctx)
+dplane_ctx_get_netconf_mcast(const struct zebra_dplane_ctx *ctx)
 {
        DPLANE_CTX_VALID(ctx);
 
-       return ctx->u.netconf.mpls_val;
+       return ctx->u.netconf.mcast_val;
 }
 
 enum dplane_netconf_status_e
-dplane_ctx_get_netconf_mcast(const struct zebra_dplane_ctx *ctx)
+dplane_ctx_get_netconf_linkdown(const struct zebra_dplane_ctx *ctx)
 {
        DPLANE_CTX_VALID(ctx);
 
-       return ctx->u.netconf.mcast_val;
+       return ctx->u.netconf.linkdown_val;
 }
 
 void dplane_ctx_set_netconf_mpls(struct zebra_dplane_ctx *ctx,
@@ -2396,6 +2373,15 @@ void dplane_ctx_set_netconf_mcast(struct zebra_dplane_ctx *ctx,
        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.
  */
@@ -2563,7 +2549,7 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op,
                }
 
                /* Check for available evpn encapsulations. */
-               if (!CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE))
+               if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_EVPN))
                        continue;
 
                zl3vni = zl3vni_from_vrf(nexthop->vrf_id);
@@ -2680,7 +2666,7 @@ done:
 }
 
 /**
- * dplane_ctx_intf_init() - Initialize a context block for a inteface update
+ * dplane_ctx_intf_init() - Initialize a context block for a interface update
  *
  * @ctx:       Dataplane context to init
  * @op:                Operation being performed
@@ -2691,9 +2677,10 @@ done:
 int dplane_ctx_intf_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op,
                         const struct interface *ifp)
 {
-       struct zebra_ns *zns = NULL;
-       struct zebra_if *zif = NULL;
+       struct zebra_ns *zns;
+       struct zebra_if *zif;
        int ret = EINVAL;
+       bool set_pdown, unset_pdown;
 
        if (!ctx || !ifp)
                goto done;
@@ -2717,8 +2704,23 @@ int dplane_ctx_intf_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op,
        zif = (struct zebra_if *)ifp->info;
 
        if (zif) {
-               ctx->u.intf.r_bitfield = zif->protodown_rc;
-               ctx->u.intf.protodown = !!(zif->flags & ZIF_FLAG_PROTODOWN);
+               set_pdown = !!(zif->flags & ZIF_FLAG_SET_PROTODOWN);
+               unset_pdown = !!(zif->flags & ZIF_FLAG_UNSET_PROTODOWN);
+
+               if (zif->protodown_rc &&
+                   ZEBRA_IF_IS_PROTODOWN_ONLY_EXTERNAL(zif) == false)
+                       ctx->u.intf.pd_reason_val = true;
+
+               /*
+                * See if we have new protodown state to set, otherwise keep
+                * current state
+                */
+               if (set_pdown)
+                       ctx->u.intf.protodown = true;
+               else if (unset_pdown)
+                       ctx->u.intf.protodown = false;
+               else
+                       ctx->u.intf.protodown = !!ZEBRA_IF_IS_PROTODOWN(zif);
        }
 
        dplane_ctx_ns_init(ctx, zns, (op == DPLANE_OP_INTF_UPDATE));
@@ -4535,6 +4537,17 @@ iptable_update_internal(enum dplane_op_e op, struct zebra_pbr_iptable *iptable)
        struct zebra_dplane_ctx *ctx;
        int ret;
 
+       if ((op == DPLANE_OP_IPTABLE_ADD &&
+            CHECK_FLAG(iptable->internal_flags, IPTABLE_INSTALL_QUEUED)) ||
+           (op == DPLANE_OP_IPTABLE_DELETE &&
+            CHECK_FLAG(iptable->internal_flags, IPTABLE_UNINSTALL_QUEUED))) {
+               if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
+                       zlog_debug(
+                               "update dplane ctx %s: iptable %s already in progress",
+                               dplane_op2str(op), iptable->ipset_name);
+               return result;
+       }
+
        ctx = dplane_ctx_alloc();
 
        ret = dplane_ctx_iptable_init(ctx, op, iptable);
@@ -4547,14 +4560,19 @@ done:
        atomic_fetch_add_explicit(&zdplane_info.dg_iptable_in, 1,
                                  memory_order_relaxed);
 
-       if (ret == AOK)
+       if (ret == AOK) {
                result = ZEBRA_DPLANE_REQUEST_QUEUED;
-       else {
+               if (op == DPLANE_OP_IPTABLE_ADD)
+                       SET_FLAG(iptable->internal_flags,
+                                IPTABLE_INSTALL_QUEUED);
+               else
+                       SET_FLAG(iptable->internal_flags,
+                                IPTABLE_UNINSTALL_QUEUED);
+       } else {
                atomic_fetch_add_explicit(&zdplane_info.dg_iptable_errors, 1,
                                          memory_order_relaxed);
                dplane_ctx_free(&ctx);
        }
-
        return result;
 }
 
@@ -5408,7 +5426,7 @@ static void kernel_dplane_log_detail(struct zebra_dplane_ctx *ctx)
        case DPLANE_OP_INTF_NETCONFIG:
                zlog_debug("%s: ifindex %d, mpls %d, mcast %d",
                           dplane_op2str(dplane_ctx_get_op(ctx)),
-                          dplane_ctx_get_netconf_ifindex(ctx),
+                          dplane_ctx_get_ifindex(ctx),
                           dplane_ctx_get_netconf_mpls(ctx),
                           dplane_ctx_get_netconf_mcast(ctx));
                break;