OSDN Git Service

devlink: Prepare code to fill multiple port function attributes
authorParav Pandit <parav@nvidia.com>
Sat, 12 Dec 2020 06:12:12 +0000 (22:12 -0800)
committerSaeed Mahameed <saeedm@nvidia.com>
Fri, 22 Jan 2021 19:32:06 +0000 (11:32 -0800)
Prepare code to fill zero or more port function optional attributes.
Subsequent patch makes use of this to fill more port function
attributes.

Signed-off-by: Parav Pandit <parav@nvidia.com>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Reviewed-by: Vu Pham <vuhuong@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
net/core/devlink.c

index ee828e4..c394963 100644 (file)
@@ -713,42 +713,48 @@ static int devlink_nl_port_attrs_put(struct sk_buff *msg,
 }
 
 static int
+devlink_port_fn_hw_addr_fill(struct devlink *devlink, const struct devlink_ops *ops,
+                            struct devlink_port *port, struct sk_buff *msg,
+                            struct netlink_ext_ack *extack, bool *msg_updated)
+{
+       u8 hw_addr[MAX_ADDR_LEN];
+       int hw_addr_len;
+       int err;
+
+       if (!ops->port_function_hw_addr_get)
+               return 0;
+
+       err = ops->port_function_hw_addr_get(devlink, port, hw_addr, &hw_addr_len, extack);
+       if (err) {
+               if (err == -EOPNOTSUPP)
+                       return 0;
+               return err;
+       }
+       err = nla_put(msg, DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR, hw_addr_len, hw_addr);
+       if (err)
+               return err;
+       *msg_updated = true;
+       return 0;
+}
+
+static int
 devlink_nl_port_function_attrs_put(struct sk_buff *msg, struct devlink_port *port,
                                   struct netlink_ext_ack *extack)
 {
        struct devlink *devlink = port->devlink;
        const struct devlink_ops *ops;
        struct nlattr *function_attr;
-       bool empty_nest = true;
-       int err = 0;
+       bool msg_updated = false;
+       int err;
 
        function_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PORT_FUNCTION);
        if (!function_attr)
                return -EMSGSIZE;
 
        ops = devlink->ops;
-       if (ops->port_function_hw_addr_get) {
-               int hw_addr_len;
-               u8 hw_addr[MAX_ADDR_LEN];
-
-               err = ops->port_function_hw_addr_get(devlink, port, hw_addr, &hw_addr_len, extack);
-               if (err == -EOPNOTSUPP) {
-                       /* Port function attributes are optional for a port. If port doesn't
-                        * support function attribute, returning -EOPNOTSUPP is not an error.
-                        */
-                       err = 0;
-                       goto out;
-               } else if (err) {
-                       goto out;
-               }
-               err = nla_put(msg, DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR, hw_addr_len, hw_addr);
-               if (err)
-                       goto out;
-               empty_nest = false;
-       }
-
-out:
-       if (err || empty_nest)
+       err = devlink_port_fn_hw_addr_fill(devlink, ops, port, msg,
+                                          extack, &msg_updated);
+       if (err || !msg_updated)
                nla_nest_cancel(msg, function_attr);
        else
                nla_nest_end(msg, function_attr);
@@ -986,7 +992,6 @@ devlink_port_function_hw_addr_set(struct devlink *devlink, struct devlink_port *
        const struct devlink_ops *ops;
        const u8 *hw_addr;
        int hw_addr_len;
-       int err;
 
        hw_addr = nla_data(attr);
        hw_addr_len = nla_len(attr);
@@ -1011,12 +1016,7 @@ devlink_port_function_hw_addr_set(struct devlink *devlink, struct devlink_port *
                return -EOPNOTSUPP;
        }
 
-       err = ops->port_function_hw_addr_set(devlink, port, hw_addr, hw_addr_len, extack);
-       if (err)
-               return err;
-
-       devlink_port_notify(port, DEVLINK_CMD_PORT_NEW);
-       return 0;
+       return ops->port_function_hw_addr_set(devlink, port, hw_addr, hw_addr_len, extack);
 }
 
 static int
@@ -1037,6 +1037,8 @@ devlink_port_function_set(struct devlink *devlink, struct devlink_port *port,
        if (attr)
                err = devlink_port_function_hw_addr_set(devlink, port, attr, extack);
 
+       if (!err)
+               devlink_port_notify(port, DEVLINK_CMD_PORT_NEW);
        return err;
 }