Merge tag 'net-next-5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev...
[linux-2.6-microblaze.git] / kernel / sysctl.c
index 0151c8c..f91d327 100644 (file)
@@ -1026,6 +1026,65 @@ int proc_douintvec_minmax(struct ctl_table *table, int write,
                                 do_proc_douintvec_minmax_conv, &param);
 }
 
+/**
+ * proc_dou8vec_minmax - read a vector of unsigned chars with min/max values
+ * @table: the sysctl table
+ * @write: %TRUE if this is a write to the sysctl file
+ * @buffer: the user buffer
+ * @lenp: the size of the user buffer
+ * @ppos: file position
+ *
+ * Reads/writes up to table->maxlen/sizeof(u8) unsigned chars
+ * values from/to the user buffer, treated as an ASCII string. Negative
+ * strings are not allowed.
+ *
+ * This routine will ensure the values are within the range specified by
+ * table->extra1 (min) and table->extra2 (max).
+ *
+ * Returns 0 on success or an error on write when the range check fails.
+ */
+int proc_dou8vec_minmax(struct ctl_table *table, int write,
+                       void *buffer, size_t *lenp, loff_t *ppos)
+{
+       struct ctl_table tmp;
+       unsigned int min = 0, max = 255U, val;
+       u8 *data = table->data;
+       struct do_proc_douintvec_minmax_conv_param param = {
+               .min = &min,
+               .max = &max,
+       };
+       int res;
+
+       /* Do not support arrays yet. */
+       if (table->maxlen != sizeof(u8))
+               return -EINVAL;
+
+       if (table->extra1) {
+               min = *(unsigned int *) table->extra1;
+               if (min > 255U)
+                       return -EINVAL;
+       }
+       if (table->extra2) {
+               max = *(unsigned int *) table->extra2;
+               if (max > 255U)
+                       return -EINVAL;
+       }
+
+       tmp = *table;
+
+       tmp.maxlen = sizeof(val);
+       tmp.data = &val;
+       val = *data;
+       res = do_proc_douintvec(&tmp, write, buffer, lenp, ppos,
+                               do_proc_douintvec_minmax_conv, &param);
+       if (res)
+               return res;
+       if (write)
+               *data = val;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(proc_dou8vec_minmax);
+
 static int do_proc_dopipe_max_size_conv(unsigned long *lvalp,
                                        unsigned int *valp,
                                        int write, void *data)
@@ -1574,6 +1633,12 @@ int proc_douintvec_minmax(struct ctl_table *table, int write,
        return -ENOSYS;
 }
 
+int proc_dou8vec_minmax(struct ctl_table *table, int write,
+                       void *buffer, size_t *lenp, loff_t *ppos)
+{
+       return -ENOSYS;
+}
+
 int proc_dointvec_jiffies(struct ctl_table *table, int write,
                    void *buffer, size_t *lenp, loff_t *ppos)
 {