diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
index 97460f47e537..cb9567a6a90d 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
@@ -1178,6 +1178,7 @@ static void mlxsw_devlink_trap_fini(struct devlink *devlink,
 static int mlxsw_devlink_trap_action_set(struct devlink *devlink,
 					 const struct devlink_trap *trap,
 					 enum devlink_trap_action action,
+					 void *trap_ctx,
 					 struct netlink_ext_ack *extack)
 {
 	struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
diff --git a/include/net/devlink.h b/include/net/devlink.h
index d387ea5518c3..b4897ee38209 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -110,6 +110,7 @@ struct devlink_port {
 	struct delayed_work type_warn_dw;
 	struct list_head reporter_list;
 	struct mutex reporters_lock; /* Protects reporter_list */
+	struct devlink_trap_mngr trap_mngr;
 };
 
 struct devlink_sb_pool_info {
@@ -1108,6 +1109,7 @@ struct devlink_trap_ops {
 	int (*trap_action_set)(struct devlink *devlink,
 			       const struct devlink_trap *trap,
 			       enum devlink_trap_action action,
+			       void *trap_ctx,
 			       struct netlink_ext_ack *extack);
 	/**
 	 * @trap_group_init: Trap group initialization function.
@@ -1414,6 +1416,29 @@ devlink_trap_policers_unregister(struct devlink *devlink,
 				 const struct devlink_trap_policer *policers,
 				 size_t policers_count);
 
+void devlink_port_traps_ops(struct devlink_port *devlink_port,
+			    const struct devlink_trap_ops *ops);
+int devlink_port_traps_register(struct devlink_port *devlink_port,
+				const struct devlink_trap *traps,
+				size_t traps_count, void *priv);
+void devlink_port_traps_unregister(struct devlink_port *devlink_port,
+				   const struct devlink_trap *traps,
+				   size_t traps_count);
+void devlink_port_trap_report(struct devlink_port *devlink_port, struct sk_buff *skb,
+			      void *trap_ctx, const struct flow_action_cookie *fa_cookie);
+int devlink_port_trap_groups_register(struct devlink_port *devlink_port,
+				      const struct devlink_trap_group *groups,
+				      size_t groups_count);
+void devlink_port_trap_groups_unregister(struct devlink_port *devlink_port,
+					 const struct devlink_trap_group *groups,
+					 size_t groups_count);
+int devlink_port_trap_policers_register(struct devlink_port *devlink_port,
+					const struct devlink_trap_policer *policers,
+					size_t policers_count);
+void devlink_port_trap_policers_unregister(struct devlink_port *devlink_port,
+					   const struct devlink_trap_policer *policers,
+					   size_t policers_count);
+
 #if IS_ENABLED(CONFIG_NET_DEVLINK)
 
 void devlink_compat_running_version(struct net_device *dev,
diff --git a/net/core/devlink.c b/net/core/devlink.c
index a30b5444289b..b13e1b40bf1c 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -6155,7 +6155,13 @@ struct devlink_trap_item {
 static struct devlink_trap_mngr *
 devlink_trap_get_trap_mngr_from_info(struct devlink *devlink, struct genl_info *info)
 {
-		return &devlink->trap_mngr;
+	struct devlink_port *devlink_port;
+
+	devlink_port = devlink_port_get_from_attrs(devlink, info->attrs);
+	if (IS_ERR(devlink_port))
+		return  &devlink->trap_mngr;
+	else
+		return &devlink_port->trap_mngr;
 }
 
 static struct devlink_trap_policer_item *
@@ -6382,6 +6388,7 @@ static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff *msg,
 {
 	struct devlink_trap_mngr *trap_mngr;
 	struct devlink_trap_item *trap_item;
+	struct devlink_port *port;
 	struct devlink *devlink;
 	int start = cb->args[0];
 	int idx = 0;
@@ -6411,6 +6418,30 @@ static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff *msg,
 		}
 		mutex_unlock(&devlink->lock);
 	}
+	list_for_each_entry(devlink, &devlink_list, list) {
+		if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
+			continue;
+		list_for_each_entry(port, &devlink->port_list, list) {
+			trap_mngr = &port->trap_mngr;
+			mutex_lock(&devlink->lock);
+			list_for_each_entry(trap_item, &trap_mngr->trap_list, list) {
+				if (idx < start) {
+					idx++;
+					continue;
+				}
+				err = devlink_nl_trap_fill(msg, devlink, trap_item,
+							   DEVLINK_CMD_TRAP_NEW,
+							   NETLINK_CB(cb->skb).portid,
+							   cb->nlh->nlmsg_seq,
+							   NLM_F_MULTI);
+				if (err)
+					goto out;
+				idx++;
+			}
+			mutex_unlock(&devlink->lock);
+		}
+	}
+
 out:
 	mutex_unlock(&devlink_mutex);
 
@@ -6433,7 +6464,7 @@ static int __devlink_trap_action_set(struct devlink *devlink,
 	}
 
 	err = trap_mngr->trap_ops->trap_action_set(devlink, trap_item->trap,
-						   trap_action, extack);
+						   trap_action, trap_item, extack);
 	if (err)
 		return err;
 
@@ -6481,6 +6512,7 @@ static int devlink_nl_cmd_trap_set_doit(struct sk_buff *skb,
 		NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
 		return -ENOENT;
 	}
+	return devlink_trap_action_set(devlink, trap_mngr, trap_item, info);
 
 	err = devlink_trap_action_set(devlink, trap_mngr, trap_item, info);
 	if (err)
@@ -6614,6 +6646,7 @@ static int devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff *msg,
 	struct devlink_trap_group_item *group_item;
 	u32 portid = NETLINK_CB(cb->skb).portid;
 	struct devlink_trap_mngr *trap_mngr;
+	struct devlink_port *port;
 	struct devlink *devlink;
 	int start = cb->args[0];
 	int idx = 0;
@@ -6644,6 +6677,30 @@ static int devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff *msg,
 		}
 		mutex_unlock(&devlink->lock);
 	}
+	list_for_each_entry(devlink, &devlink_list, list) {
+		if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
+			continue;
+		list_for_each_entry(port, &devlink->port_list, list) {
+			trap_mngr = &port->trap_mngr;
+			mutex_lock(&devlink->lock);
+			list_for_each_entry(group_item, &trap_mngr->trap_group_list, list) {
+				if (idx < start) {
+					idx++;
+					continue;
+				}
+				err = devlink_nl_trap_group_fill(msg, devlink,
+								 group_item, cmd,
+								 portid,
+								 cb->nlh->nlmsg_seq,
+								 NLM_F_MULTI);
+				if (err)
+					goto out;
+				idx++;
+			}
+			mutex_unlock(&devlink->lock);
+		}
+	}
+
 out:
 	mutex_unlock(&devlink_mutex);
 
@@ -6912,6 +6969,7 @@ static int devlink_nl_cmd_trap_policer_get_dumpit(struct sk_buff *msg,
 	struct devlink_trap_policer_item *policer_item;
 	u32 portid = NETLINK_CB(cb->skb).portid;
 	struct devlink_trap_mngr *trap_mngr;
+	struct devlink_port *port;
 	struct devlink *devlink;
 	int start = cb->args[0];
 	int idx = 0;
@@ -6943,6 +7001,32 @@ static int devlink_nl_cmd_trap_policer_get_dumpit(struct sk_buff *msg,
 		}
 		mutex_unlock(&devlink->lock);
 	}
+	list_for_each_entry(devlink, &devlink_list, list) {
+		if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
+			continue;
+		list_for_each_entry(port, &devlink->port_list, list) {
+			trap_mngr = &port->trap_mngr;
+			mutex_lock(&devlink->lock);
+			list_for_each_entry(policer_item, &trap_mngr->trap_policer_list,
+					    list) {
+				if (idx < start) {
+					idx++;
+					continue;
+				}
+				err = devlink_nl_trap_policer_fill(msg, devlink,
+								   policer_item, cmd,
+								   portid,
+								   cb->nlh->nlmsg_seq,
+								   trap_mngr,
+								   NLM_F_MULTI);
+				if (err)
+					goto out;
+				idx++;
+			}
+			mutex_unlock(&devlink->lock);
+		}
+	}
+
 out:
 	mutex_unlock(&devlink_mutex);
 
@@ -7348,34 +7432,40 @@ static const struct genl_ops devlink_nl_ops[] = {
 		.cmd = DEVLINK_CMD_TRAP_GET,
 		.doit = devlink_nl_cmd_trap_get_doit,
 		.dumpit = devlink_nl_cmd_trap_get_dumpit,
+		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
 		/* can be retrieved by unprivileged users */
 	},
 	{
 		.cmd = DEVLINK_CMD_TRAP_SET,
 		.doit = devlink_nl_cmd_trap_set_doit,
 		.flags = GENL_ADMIN_PERM,
+		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
 	},
 	{
 		.cmd = DEVLINK_CMD_TRAP_GROUP_GET,
 		.doit = devlink_nl_cmd_trap_group_get_doit,
 		.dumpit = devlink_nl_cmd_trap_group_get_dumpit,
+		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
 		/* can be retrieved by unprivileged users */
 	},
 	{
 		.cmd = DEVLINK_CMD_TRAP_GROUP_SET,
 		.doit = devlink_nl_cmd_trap_group_set_doit,
 		.flags = GENL_ADMIN_PERM,
+		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
 	},
 	{
 		.cmd = DEVLINK_CMD_TRAP_POLICER_GET,
 		.doit = devlink_nl_cmd_trap_policer_get_doit,
 		.dumpit = devlink_nl_cmd_trap_policer_get_dumpit,
 		/* can be retrieved by unprivileged users */
+		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
 	},
 	{
 		.cmd = DEVLINK_CMD_TRAP_POLICER_SET,
 		.doit = devlink_nl_cmd_trap_policer_set_doit,
 		.flags = GENL_ADMIN_PERM,
+		.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
 	},
 };
 
@@ -7593,6 +7683,10 @@ int devlink_port_register(struct devlink *devlink,
 	INIT_DELAYED_WORK(&devlink_port->type_warn_dw, &devlink_port_type_warn);
 	devlink_port_type_warn_schedule(devlink_port);
 	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
+	INIT_LIST_HEAD(&devlink_port->trap_mngr.trap_list);
+	INIT_LIST_HEAD(&devlink_port->trap_mngr.trap_group_list);
+	INIT_LIST_HEAD(&devlink_port->trap_mngr.trap_policer_list);
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(devlink_port_register);
