swconfig: parse "switch_vlan" before "switch_port"
authorRafał Miłecki <rafal@milecki.pl>
Tue, 5 Apr 2022 06:49:58 +0000 (08:49 +0200)
committerRafał Miłecki <rafal@milecki.pl>
Wed, 15 Jun 2022 08:44:32 +0000 (10:44 +0200)
Before this change UCI sections of both types were parsed in order as
specified in UCI. That didn't work well with all drivers (e.g. b53).

It seems that VLAN setup can reset / overwrite previously set ports
parameters. It resulted in "switch_port" options defined above
"switch_vlan"s being silently ignored.

Ideally swconfig & all drivers should be improved to handle that
properly but it'd be a waste of time at this point as DSA replaces
swconfig. Use this minor parsing change as a quick fix.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
package/network/config/swconfig/src/uci.c

index f99583b483a7842e003323bf0f949a43d8178cf9..200069f94f3eea5fd6fbf922de201cf5506893c5 100644 (file)
@@ -164,32 +164,7 @@ found:
                struct uci_element *os;
                s = uci_to_section(e);
 
-               if (!strcmp(s->type, "switch_port")) {
-                       char *devn = NULL, *port = NULL, *port_err = NULL;
-                       int port_n;
-
-                       uci_foreach_element(&s->options, os) {
-                               o = uci_to_option(os);
-                               if (o->type != UCI_TYPE_STRING)
-                                       continue;
-
-                               if (!strcmp(os->name, "device")) {
-                                       devn = o->v.string;
-                                       if (!swlib_match_name(dev, devn))
-                                               devn = NULL;
-                               } else if (!strcmp(os->name, "port")) {
-                                       port = o->v.string;
-                               }
-                       }
-                       if (!devn || !port || !port[0])
-                               continue;
-
-                       port_n = strtoul(port, &port_err, 0);
-                       if (port_err && port_err[0])
-                               continue;
-
-                       swlib_map_settings(dev, SWLIB_ATTR_GROUP_PORT, port_n, s);
-               } else if (!strcmp(s->type, "switch_vlan")) {
+               if (!strcmp(s->type, "switch_vlan")) {
                        char *devn = NULL, *vlan = NULL, *vlan_err = NULL;
                        int vlan_n;
 
@@ -216,6 +191,38 @@ found:
                        swlib_map_settings(dev, SWLIB_ATTR_GROUP_VLAN, vlan_n, s);
                }
        }
+       uci_foreach_element(&p->sections, e) {
+               struct uci_element *os;
+               char *devn = NULL, *port = NULL, *port_err = NULL;
+               int port_n;
+
+               s = uci_to_section(e);
+
+               if (strcmp(s->type, "switch_port"))
+                       continue;
+
+               uci_foreach_element(&s->options, os) {
+                       o = uci_to_option(os);
+                       if (o->type != UCI_TYPE_STRING)
+                               continue;
+
+                       if (!strcmp(os->name, "device")) {
+                               devn = o->v.string;
+                               if (!swlib_match_name(dev, devn))
+                                       devn = NULL;
+                       } else if (!strcmp(os->name, "port")) {
+                               port = o->v.string;
+                       }
+               }
+               if (!devn || !port || !port[0])
+                       continue;
+
+               port_n = strtoul(port, &port_err, 0);
+               if (port_err && port_err[0])
+                       continue;
+
+               swlib_map_settings(dev, SWLIB_ATTR_GROUP_PORT, port_n, s);
+       }
 
        for (i = 0; i < ARRAY_SIZE(early_settings); i++) {
                struct swlib_setting *st = &early_settings[i];