diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 408d420be6..9a30c2b78f 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -876,9 +876,24 @@ void zsend_iptable_notify_owner(const struct zebra_dplane_ctx *ctx, struct stream *s; struct zebra_pbr_iptable ipt; uint16_t cmd = ZEBRA_IPTABLE_NOTIFY_OWNER; + struct zebra_pbr_iptable *ipt_hash; + enum dplane_op_e op = dplane_ctx_get_op(ctx); dplane_ctx_get_pbr_iptable(ctx, &ipt); + ipt_hash = hash_lookup(zrouter.iptable_hash, &ipt); + if (ipt_hash) { + if (op == DPLANE_OP_IPTABLE_ADD && + CHECK_FLAG(ipt_hash->internal_flags, + IPTABLE_INSTALL_QUEUED)) + UNSET_FLAG(ipt_hash->internal_flags, + IPTABLE_INSTALL_QUEUED); + else if (op == DPLANE_OP_IPTABLE_DELETE && + CHECK_FLAG(ipt_hash->internal_flags, + IPTABLE_UNINSTALL_QUEUED)) + UNSET_FLAG(ipt_hash->internal_flags, + IPTABLE_UNINSTALL_QUEUED); + } if (IS_ZEBRA_DEBUG_PACKET) zlog_debug("%s: Notifying %s id %u note %u", __func__, zserv_command_string(cmd), ipt.unique, note); diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 4e753c9d1a..0da44e3c4e 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -4550,6 +4550,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); @@ -4562,14 +4573,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; } diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c index e66d7aaf5c..bb963bcc23 100644 --- a/zebra/zebra_pbr.c +++ b/zebra/zebra_pbr.c @@ -812,8 +812,11 @@ static void *pbr_iptable_alloc_intern(void *arg) void zebra_pbr_add_iptable(struct zebra_pbr_iptable *iptable) { - (void)hash_get(zrouter.iptable_hash, iptable, pbr_iptable_alloc_intern); - (void)dplane_pbr_iptable_add(iptable); + struct zebra_pbr_iptable *ipt_hash; + + ipt_hash = hash_get(zrouter.iptable_hash, iptable, + pbr_iptable_alloc_intern); + (void)dplane_pbr_iptable_add(ipt_hash); } void zebra_pbr_del_iptable(struct zebra_pbr_iptable *iptable) diff --git a/zebra/zebra_pbr.h b/zebra/zebra_pbr.h index c5102df4fa..33b8162a88 100644 --- a/zebra/zebra_pbr.h +++ b/zebra/zebra_pbr.h @@ -171,6 +171,9 @@ struct zebra_pbr_iptable { struct list *interface_name_list; +#define IPTABLE_INSTALL_QUEUED 1 << 1 +#define IPTABLE_UNINSTALL_QUEUED 1 << 2 + uint8_t internal_flags; char ipset_name[ZEBRA_IPSET_NAME_SIZE]; };