Typical usage of PVID is when it's set to the same VLAN ID as untagged
VLAN on that port so that ingress traffic would fall into the same VLAN
as egress traffic. Before PVID was set to VLAN group number which
could easily differ from VLAN ID.

Signed-off-by: Roman Yeryomin <[email protected]>
---
 package/network/config/swconfig/src/uci.c | 59 ++++++++++++++++++++++++++++++-
 1 file changed, 58 insertions(+), 1 deletion(-)

diff --git a/package/network/config/swconfig/src/uci.c 
b/package/network/config/swconfig/src/uci.c
index bbeeb03..804766e 100644
--- a/package/network/config/swconfig/src/uci.c
+++ b/package/network/config/swconfig/src/uci.c
@@ -105,6 +105,60 @@ skip:
        }
 }
 
+static int
+swlib_map_pvids(struct switch_dev *dev, char *pvid, struct uci_section *s)
+{
+       struct swlib_setting *setting;
+       struct switch_attr *attr;
+       struct uci_element *e;
+       struct uci_option *o;
+
+       attr = swlib_lookup_attr(dev, SWLIB_ATTR_GROUP_PORT, "pvid");
+       if (!attr)
+               return -1;
+
+       uci_foreach_element(&s->options, e) {
+               o = uci_to_option(e);
+
+               if (o->type != UCI_TYPE_STRING)
+                       continue;
+
+               if (strcmp(e->name, "ports"))
+                       continue;
+
+               char *ptr = o->v.string;
+               int port_n;
+               while(ptr && *ptr) {
+                       while(*ptr && isspace(*ptr))
+                               ptr++;
+
+                       if (!*ptr)
+                               break;
+
+                       if (!isdigit(*ptr))
+                               return -1;
+
+                       if (*(ptr + 1) && *(ptr + 1) == 't') {
+                               ptr += 2;
+                               continue;
+                       }
+
+                       if (sscanf(ptr, "%i", &port_n)) {
+                               setting = malloc(sizeof(struct swlib_setting));
+                               memset(setting, 0, sizeof(struct 
swlib_setting));
+                               setting->attr = attr;
+                               setting->port_vlan = port_n;
+                               setting->val = pvid;
+                               *head = setting;
+                               head = &setting->next;
+                       }
+
+                       if (*ptr)
+                               ptr++;
+               }
+       }
+}
+
 int swlib_apply_from_uci(struct switch_dev *dev, struct uci_package *p)
 {
        struct switch_attr *attr;
@@ -190,7 +244,7 @@ found:
 
                        swlib_map_settings(dev, SWLIB_ATTR_GROUP_PORT, port_n, 
s);
                } else if (!strcmp(s->type, "switch_vlan")) {
-                       char *devn, *vlan, *vlan_err = NULL;
+                       char *devn, *vlan, *pvid, *vlan_err = NULL;
                        int vlan_n;
 
                        uci_foreach_element(&s->options, os) {
@@ -204,6 +258,8 @@ found:
                                                devn = NULL;
                                } else if (!strcmp(os->name, "vlan")) {
                                        vlan = o->v.string;
+                               } else if (!strcmp(os->name, "vid")) {
+                                       pvid = o->v.string;
                                }
                        }
                        if (!devn || !vlan || !vlan[0])
@@ -214,6 +270,7 @@ found:
                                continue;
 
                        swlib_map_settings(dev, SWLIB_ATTR_GROUP_VLAN, vlan_n, 
s);
+                       swlib_map_pvids(dev, pvid, s);
                }
        }
 
-- 
2.1.0
_______________________________________________
openwrt-devel mailing list
[email protected]
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

Reply via email to