kernel: swconfig: make compatible with kernel 5.2
authorMathias Kresin <dev@kresin.me>
Thu, 18 Jul 2019 08:29:08 +0000 (10:29 +0200)
committerMathias Kresin <dev@kresin.me>
Sat, 20 Jul 2019 21:49:53 +0000 (23:49 +0200)
Since kernel 5.2 within netlink messages the NLA_F_NESTED nested flag is
validated. But swconfig/swlib doesn't set the flag for
SWITCH_ATTR_OP_VALUE_PORTS related netlink messages and assigning ports
to vlans via

  swconfig dev switch0 vlan 1 set ports '0 1 2 3 4 6t'

Errors put with "Failed to set attribute: Invalid input data or
parameter".

Relax the validation rules and use the deprecated functions, to use the
same level of validation as it was till kernel 5.1. Depending on who has
swconfig related netlink messages implemented, there might be more
broken tools out there and we should keep backward compatibility if
possible.

Signed-off-by: Mathias Kresin <dev@kresin.me>
target/linux/generic/files/drivers/net/phy/swconfig.c

index de033d0..4b03999 100644 (file)
@@ -591,12 +591,15 @@ swconfig_parse_ports(struct sk_buff *msg, struct nlattr *head,
 
                port = &val->value.ports[val->len];
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4,12,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0)
+               if (nla_parse_nested_deprecated(tb, SWITCH_PORT_ATTR_MAX, nla,
+                               port_policy, NULL))
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0)
                if (nla_parse_nested(tb, SWITCH_PORT_ATTR_MAX, nla,
-                               port_policy))
+                               port_policy, NULL))
 #else
                if (nla_parse_nested(tb, SWITCH_PORT_ATTR_MAX, nla,
-                               port_policy, NULL))
+                               port_policy))
 #endif
                        return -EINVAL;
 
@@ -618,10 +621,12 @@ swconfig_parse_link(struct sk_buff *msg, struct nlattr *nla,
 {
        struct nlattr *tb[SWITCH_LINK_ATTR_MAX + 1];
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4,12,0)
-       if (nla_parse_nested(tb, SWITCH_LINK_ATTR_MAX, nla, link_policy))
-#else
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0)
+       if (nla_parse_nested_deprecated(tb, SWITCH_LINK_ATTR_MAX, nla, link_policy, NULL))
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0)
        if (nla_parse_nested(tb, SWITCH_LINK_ATTR_MAX, nla, link_policy, NULL))
+#else
+       if (nla_parse_nested(tb, SWITCH_LINK_ATTR_MAX, nla, link_policy))
 #endif
                return -EINVAL;
 
@@ -1000,6 +1005,9 @@ swconfig_done(struct netlink_callback *cb)
 static struct genl_ops swconfig_ops[] = {
        {
                .cmd = SWITCH_CMD_LIST_GLOBAL,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0)
+               .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
+#endif
                .doit = swconfig_list_attrs,
 #if LINUX_VERSION_CODE < KERNEL_VERSION(5,2,0)
                .policy = switch_policy,
@@ -1007,6 +1015,9 @@ static struct genl_ops swconfig_ops[] = {
        },
        {
                .cmd = SWITCH_CMD_LIST_VLAN,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0)
+               .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
+#endif
                .doit = swconfig_list_attrs,
 #if LINUX_VERSION_CODE < KERNEL_VERSION(5,2,0)
                .policy = switch_policy,
@@ -1014,6 +1025,9 @@ static struct genl_ops swconfig_ops[] = {
        },
        {
                .cmd = SWITCH_CMD_LIST_PORT,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0)
+               .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
+#endif
                .doit = swconfig_list_attrs,
 #if LINUX_VERSION_CODE < KERNEL_VERSION(5,2,0)
                .policy = switch_policy,
@@ -1021,6 +1035,9 @@ static struct genl_ops swconfig_ops[] = {
        },
        {
                .cmd = SWITCH_CMD_GET_GLOBAL,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0)
+               .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
+#endif
                .doit = swconfig_get_attr,
 #if LINUX_VERSION_CODE < KERNEL_VERSION(5,2,0)
                .policy = switch_policy,
@@ -1028,6 +1045,9 @@ static struct genl_ops swconfig_ops[] = {
        },
        {
                .cmd = SWITCH_CMD_GET_VLAN,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0)
+               .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
+#endif
                .doit = swconfig_get_attr,
 #if LINUX_VERSION_CODE < KERNEL_VERSION(5,2,0)
                .policy = switch_policy,
@@ -1035,6 +1055,9 @@ static struct genl_ops swconfig_ops[] = {
        },
        {
                .cmd = SWITCH_CMD_GET_PORT,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0)
+               .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
+#endif
                .doit = swconfig_get_attr,
 #if LINUX_VERSION_CODE < KERNEL_VERSION(5,2,0)
                .policy = switch_policy,
@@ -1042,6 +1065,9 @@ static struct genl_ops swconfig_ops[] = {
        },
        {
                .cmd = SWITCH_CMD_SET_GLOBAL,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0)
+               .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
+#endif
                .flags = GENL_ADMIN_PERM,
                .doit = swconfig_set_attr,
 #if LINUX_VERSION_CODE < KERNEL_VERSION(5,2,0)
@@ -1050,6 +1076,9 @@ static struct genl_ops swconfig_ops[] = {
        },
        {
                .cmd = SWITCH_CMD_SET_VLAN,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0)
+               .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
+#endif
                .flags = GENL_ADMIN_PERM,
                .doit = swconfig_set_attr,
 #if LINUX_VERSION_CODE < KERNEL_VERSION(5,2,0)
@@ -1058,6 +1087,9 @@ static struct genl_ops swconfig_ops[] = {
        },
        {
                .cmd = SWITCH_CMD_SET_PORT,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0)
+               .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
+#endif
                .flags = GENL_ADMIN_PERM,
                .doit = swconfig_set_attr,
 #if LINUX_VERSION_CODE < KERNEL_VERSION(5,2,0)
@@ -1066,6 +1098,9 @@ static struct genl_ops swconfig_ops[] = {
        },
        {
                .cmd = SWITCH_CMD_GET_SWITCH,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0)
+               .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
+#endif
                .dumpit = swconfig_dump_switches,
 #if LINUX_VERSION_CODE < KERNEL_VERSION(5,2,0)
                .policy = switch_policy,
@@ -1082,7 +1117,7 @@ static struct genl_family switch_fam = {
        .hdrsize = 0,
        .version = 1,
        .maxattr = SWITCH_ATTR_MAX,
-#if LINUX_VERSION_CODE > KERNEL_VERSION(5,1,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0)
        .policy = switch_policy,
 #endif
        .module = THIS_MODULE,