]> git.itanic.dy.fi Git - linux-stable/commitdiff
devlink: Validate port function request
authorShay Drory <shayd@nvidia.com>
Tue, 6 Dec 2022 18:51:13 +0000 (20:51 +0200)
committerJakub Kicinski <kuba@kernel.org>
Thu, 8 Dec 2022 04:09:18 +0000 (20:09 -0800)
In order to avoid partial request processing, validate the request
before processing it.

Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/core/devlink.c

index 907df71241570245bb6322762fe775dd89bcabb8..035249c5dd17ae2d8184bbe119096b2e3eb983b3 100644 (file)
@@ -1632,11 +1632,6 @@ static int devlink_port_function_hw_addr_set(struct devlink_port *port,
                }
        }
 
-       if (!ops->port_function_hw_addr_set) {
-               NL_SET_ERR_MSG_MOD(extack, "Port doesn't support function attributes");
-               return -EOPNOTSUPP;
-       }
-
        return ops->port_function_hw_addr_set(port, hw_addr, hw_addr_len,
                                              extack);
 }
@@ -1650,12 +1645,27 @@ static int devlink_port_fn_state_set(struct devlink_port *port,
 
        state = nla_get_u8(attr);
        ops = port->devlink->ops;
-       if (!ops->port_fn_state_set) {
-               NL_SET_ERR_MSG_MOD(extack,
-                                  "Function does not support state setting");
+       return ops->port_fn_state_set(port, state, extack);
+}
+
+static int devlink_port_function_validate(struct devlink_port *devlink_port,
+                                         struct nlattr **tb,
+                                         struct netlink_ext_ack *extack)
+{
+       const struct devlink_ops *ops = devlink_port->devlink->ops;
+
+       if (tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] &&
+           !ops->port_function_hw_addr_set) {
+               NL_SET_ERR_MSG_ATTR(extack, tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR],
+                                   "Port doesn't support function attributes");
                return -EOPNOTSUPP;
        }
-       return ops->port_fn_state_set(port, state, extack);
+       if (tb[DEVLINK_PORT_FN_ATTR_STATE] && !ops->port_fn_state_set) {
+               NL_SET_ERR_MSG_ATTR(extack, tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR],
+                                   "Function does not support state setting");
+               return -EOPNOTSUPP;
+       }
+       return 0;
 }
 
 static int devlink_port_function_set(struct devlink_port *port,
@@ -1672,6 +1682,10 @@ static int devlink_port_function_set(struct devlink_port *port,
                return err;
        }
 
+       err = devlink_port_function_validate(port, tb, extack);
+       if (err)
+               return err;
+
        attr = tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR];
        if (attr) {
                err = devlink_port_function_hw_addr_set(port, attr, extack);