devlink: extend multicast filtering by port index
authorJiri Pirko <jiri@nvidia.com>
Sat, 16 Dec 2023 12:30:01 +0000 (13:30 +0100)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 19 Dec 2023 14:31:40 +0000 (15:31 +0100)
Expose the previously introduced notification multicast messages
filtering infrastructure and allow the user to select messages using
port index.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Documentation/netlink/specs/devlink.yaml
net/devlink/devl_internal.h
net/devlink/health.c
net/devlink/netlink.c
net/devlink/netlink_gen.c
net/devlink/port.c

index 88bfcb3c3346724abbe54f58723aaa972bc53a40..cf6eaa0da821b323d988b290dbcedc2cf615d738 100644 (file)
@@ -2264,3 +2264,4 @@ operations:
           attributes:
             - bus-name
             - dev-name
+            - port-index
index 82e0fb3bbebf29ca0dc54d056503553d492911b2..c7a8e13f917cfa70b4775f3abcb7bace0d853470 100644 (file)
@@ -195,6 +195,8 @@ struct devlink_obj_desc {
        struct rcu_head rcu;
        const char *bus_name;
        const char *dev_name;
+       unsigned int port_index;
+       bool port_index_valid;
        long data[];
 };
 
@@ -206,6 +208,13 @@ static inline void devlink_nl_obj_desc_init(struct devlink_obj_desc *desc,
        desc->dev_name = dev_name(devlink->dev);
 }
 
+static inline void devlink_nl_obj_desc_port_set(struct devlink_obj_desc *desc,
+                                               struct devlink_port *devlink_port)
+{
+       desc->port_index = devlink_port->index;
+       desc->port_index_valid = true;
+}
+
 int devlink_nl_notify_filter(struct sock *dsk, struct sk_buff *skb, void *data);
 
 static inline void devlink_nl_notify_send_desc(struct devlink *devlink,
index 1d59ec0202f6792e89a40b656f3c26ddfeb9e5b5..acb8c0e174bb818c9b7f798c553b2cde48f3795e 100644 (file)
@@ -490,6 +490,7 @@ static void devlink_recover_notify(struct devlink_health_reporter *reporter,
                                   enum devlink_command cmd)
 {
        struct devlink *devlink = reporter->devlink;
+       struct devlink_obj_desc desc;
        struct sk_buff *msg;
        int err;
 
@@ -509,7 +510,10 @@ static void devlink_recover_notify(struct devlink_health_reporter *reporter,
                return;
        }
 
-       devlink_nl_notify_send(devlink, msg);
+       devlink_nl_obj_desc_init(&desc, devlink);
+       if (reporter->devlink_port)
+               devlink_nl_obj_desc_port_set(&desc, reporter->devlink_port);
+       devlink_nl_notify_send_desc(devlink, msg, &desc);
 }
 
 void
index 3176be2585cb48ce5fe657f47c7502b9431e3976..499885c8b9cae21e846ca3e310dc6ec767b184eb 100644 (file)
@@ -73,8 +73,13 @@ int devlink_nl_notify_filter_set_doit(struct sk_buff *skb,
                flt->dev_name = pos;
        }
 
+       if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
+               flt->port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
+               flt->port_index_valid = true;
+       }
+
        /* Don't attach empty filter. */
-       if (!flt->bus_name && !flt->dev_name) {
+       if (!flt->bus_name && !flt->dev_name && !flt->port_index_valid) {
                kfree(flt);
                flt = NULL;
        }
@@ -101,6 +106,9 @@ static bool devlink_obj_desc_match(const struct devlink_obj_desc *desc,
        if (desc->dev_name && flt->dev_name &&
            strcmp(desc->dev_name, flt->dev_name))
                return false;
+       if (desc->port_index_valid && flt->port_index_valid &&
+           desc->port_index != flt->port_index)
+               return false;
        return true;
 }
 
index 1cb0e05305d29cbfe81f920feb12c0c999f2fee5..c81cf2dd154f3c2cffb1d2d28c3f25ddab7a477b 100644 (file)
@@ -561,9 +561,10 @@ static const struct nla_policy devlink_selftests_run_nl_policy[DEVLINK_ATTR_SELF
 };
 
 /* DEVLINK_CMD_NOTIFY_FILTER_SET - do */
-static const struct nla_policy devlink_notify_filter_set_nl_policy[DEVLINK_ATTR_DEV_NAME + 1] = {
+static const struct nla_policy devlink_notify_filter_set_nl_policy[DEVLINK_ATTR_PORT_INDEX + 1] = {
        [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
        [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+       [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
 };
 
 /* Ops table for devlink */
@@ -1243,7 +1244,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
                .cmd            = DEVLINK_CMD_NOTIFY_FILTER_SET,
                .doit           = devlink_nl_notify_filter_set_doit,
                .policy         = devlink_notify_filter_set_nl_policy,
-               .maxattr        = DEVLINK_ATTR_DEV_NAME,
+               .maxattr        = DEVLINK_ATTR_PORT_INDEX,
                .flags          = GENL_CMD_CAP_DO,
        },
 };
index 758df3000a1bd1c451b31cfc65000e2ab68cf9fd..62e54e152ecf1fa601cb2cd755988c9ff97670af 100644 (file)
@@ -507,6 +507,7 @@ static void devlink_port_notify(struct devlink_port *devlink_port,
                                enum devlink_command cmd)
 {
        struct devlink *devlink = devlink_port->devlink;
+       struct devlink_obj_desc desc;
        struct sk_buff *msg;
        int err;
 
@@ -525,7 +526,9 @@ static void devlink_port_notify(struct devlink_port *devlink_port,
                return;
        }
 
-       devlink_nl_notify_send(devlink, msg);
+       devlink_nl_obj_desc_init(&desc, devlink);
+       devlink_nl_obj_desc_port_set(&desc, devlink_port);
+       devlink_nl_notify_send_desc(devlink, msg, &desc);
 }
 
 static void devlink_ports_notify(struct devlink *devlink,