devlink: Force enclosing array on binary fmsg data
authorAya Levin <ayal@mellanox.com>
Tue, 11 Feb 2020 22:32:42 +0000 (14:32 -0800)
committerSaeed Mahameed <saeedm@mellanox.com>
Wed, 19 Feb 2020 03:17:28 +0000 (19:17 -0800)
Add a new API for start/end binary array brackets [] to force array
around binary data as required from JSON. With this restriction, re-open
API to set binary fmsg data.

Signed-off-by: Aya Levin <ayal@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
include/net/devlink.h
net/core/devlink.c

index ce5cea4..149c108 100644 (file)
@@ -981,12 +981,17 @@ int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg);
 int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg,
                                     const char *name);
 int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg);
+int devlink_fmsg_binary_pair_nest_start(struct devlink_fmsg *fmsg,
+                                       const char *name);
+int devlink_fmsg_binary_pair_nest_end(struct devlink_fmsg *fmsg);
 
 int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value);
 int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value);
 int devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value);
 int devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value);
 int devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value);
+int devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value,
+                           u16 value_len);
 
 int devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name,
                               bool value);
index 549ee56..216bdd2 100644 (file)
@@ -4237,6 +4237,12 @@ struct devlink_fmsg_item {
 
 struct devlink_fmsg {
        struct list_head item_list;
+       bool putting_binary; /* This flag forces enclosing of binary data
+                             * in an array brackets. It forces using
+                             * of designated API:
+                             * devlink_fmsg_binary_pair_nest_start()
+                             * devlink_fmsg_binary_pair_nest_end()
+                             */
 };
 
 static struct devlink_fmsg *devlink_fmsg_alloc(void)
@@ -4280,17 +4286,26 @@ static int devlink_fmsg_nest_common(struct devlink_fmsg *fmsg,
 
 int devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg)
 {
+       if (fmsg->putting_binary)
+               return -EINVAL;
+
        return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_OBJ_NEST_START);
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start);
 
 static int devlink_fmsg_nest_end(struct devlink_fmsg *fmsg)
 {
+       if (fmsg->putting_binary)
+               return -EINVAL;
+
        return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_NEST_END);
 }
 
 int devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg)
 {
+       if (fmsg->putting_binary)
+               return -EINVAL;
+
        return devlink_fmsg_nest_end(fmsg);
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end);
@@ -4301,6 +4316,9 @@ static int devlink_fmsg_put_name(struct devlink_fmsg *fmsg, const char *name)
 {
        struct devlink_fmsg_item *item;
 
+       if (fmsg->putting_binary)
+               return -EINVAL;
+
        if (strlen(name) + 1 > DEVLINK_FMSG_MAX_SIZE)
                return -EMSGSIZE;
 
@@ -4321,6 +4339,9 @@ int devlink_fmsg_pair_nest_start(struct devlink_fmsg *fmsg, const char *name)
 {
        int err;
 
+       if (fmsg->putting_binary)
+               return -EINVAL;
+
        err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_PAIR_NEST_START);
        if (err)
                return err;
@@ -4335,6 +4356,9 @@ EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start);
 
 int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg)
 {
+       if (fmsg->putting_binary)
+               return -EINVAL;
+
        return devlink_fmsg_nest_end(fmsg);
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end);
@@ -4344,6 +4368,9 @@ int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg,
 {
        int err;
 
+       if (fmsg->putting_binary)
+               return -EINVAL;
+
        err = devlink_fmsg_pair_nest_start(fmsg, name);
        if (err)
                return err;
@@ -4360,6 +4387,9 @@ int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg)
 {
        int err;
 
+       if (fmsg->putting_binary)
+               return -EINVAL;
+
        err = devlink_fmsg_nest_end(fmsg);
        if (err)
                return err;
@@ -4372,6 +4402,30 @@ int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg)
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end);
 
+int devlink_fmsg_binary_pair_nest_start(struct devlink_fmsg *fmsg,
+                                       const char *name)
+{
+       int err;
+
+       err = devlink_fmsg_arr_pair_nest_start(fmsg, name);
+       if (err)
+               return err;
+
+       fmsg->putting_binary = true;
+       return err;
+}
+EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_start);
+
+int devlink_fmsg_binary_pair_nest_end(struct devlink_fmsg *fmsg)
+{
+       if (!fmsg->putting_binary)
+               return -EINVAL;
+
+       fmsg->putting_binary = false;
+       return devlink_fmsg_arr_pair_nest_end(fmsg);
+}
+EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_end);
+
 static int devlink_fmsg_put_value(struct devlink_fmsg *fmsg,
                                  const void *value, u16 value_len,
                                  u8 value_nla_type)
@@ -4396,40 +4450,59 @@ static int devlink_fmsg_put_value(struct devlink_fmsg *fmsg,
 
 int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value)
 {
+       if (fmsg->putting_binary)
+               return -EINVAL;
+
        return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_FLAG);
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_put);
 
 int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value)
 {
+       if (fmsg->putting_binary)
+               return -EINVAL;
+
        return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U8);
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_put);
 
 int devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value)
 {
+       if (fmsg->putting_binary)
+               return -EINVAL;
+
        return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U32);
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put);
 
 int devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value)
 {
+       if (fmsg->putting_binary)
+               return -EINVAL;
+
        return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U64);
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_put);
 
 int devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value)
 {
+       if (fmsg->putting_binary)
+               return -EINVAL;
+
        return devlink_fmsg_put_value(fmsg, value, strlen(value) + 1,
                                      NLA_NUL_STRING);
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_string_put);
 
-static int devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value,
-                                  u16 value_len)
+int devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value,
+                           u16 value_len)
 {
+       if (!fmsg->putting_binary)
+               return -EINVAL;
+
        return devlink_fmsg_put_value(fmsg, value, value_len, NLA_BINARY);
 }
+EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put);
 
 int devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name,
                               bool value)
@@ -4540,10 +4613,11 @@ int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name,
                                 const void *value, u32 value_len)
 {
        u32 data_size;
+       int end_err;
        u32 offset;
        int err;
 
-       err = devlink_fmsg_arr_pair_nest_start(fmsg, name);
+       err = devlink_fmsg_binary_pair_nest_start(fmsg, name);
        if (err)
                return err;
 
@@ -4553,14 +4627,18 @@ int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name,
                        data_size = DEVLINK_FMSG_MAX_SIZE;
                err = devlink_fmsg_binary_put(fmsg, value + offset, data_size);
                if (err)
-                       return err;
+                       break;
+               /* Exit from loop with a break (instead of
+                * return) to make sure putting_binary is turned off in
+                * devlink_fmsg_binary_pair_nest_end
+                */
        }
 
-       err = devlink_fmsg_arr_pair_nest_end(fmsg);
-       if (err)
-               return err;
+       end_err = devlink_fmsg_binary_pair_nest_end(fmsg);
+       if (end_err)
+               err = end_err;
 
-       return 0;
+       return err;
 }
 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put);