<div dir="ltr"><div>Hi,<br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Apr 28, 2020 at 9:41 AM Pau Espin Pedrol <<a href="mailto:pespin@espeweb.net">pespin@espeweb.net</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">From: Pau Espin Pedrol <<a href="mailto:pespin.shar@gmail.com" target="_blank">pespin.shar@gmail.com</a>><br>
<br>
It allows setting mappings for instance this way:<br>
"""<br>
config device<br>
  option name 'vlan41'<br>
  option type '8021q'<br>
  option vid '41'<br>
  option ifname 'eth1'<br>
  list   ingress_qos_mapping '1:2'<br>
  list   ingress_qos_mapping '2:5'<br>
  list   egress_qos_mapping '0:3'<br>
"""<br>
<br>
Size of mapping arrays (ingress=8, egress=16) taken from linux kernel<br>
"struct vlan_dev_priv".<br>
<br>
Signed-off-by: Pau Espin Pedrol <<a href="mailto:pespin.shar@gmail.com" target="_blank">pespin.shar@gmail.com</a>><br>
Tested-by: Pedro <<a href="mailto:pedrowrt@cas.cat" target="_blank">pedrowrt@cas.cat</a>><br>
---<br>
 system-linux.c | 19 ++++++++++++++++-<br>
 system.h       |  5 +++++<br>
 vlandev.c      | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++<br>
 3 files changed, 80 insertions(+), 1 deletion(-)<br>
<br>
diff --git a/system-linux.c b/system-linux.c<br>
index 62636c4..fa236ad 100644<br>
--- a/system-linux.c<br>
+++ b/system-linux.c<br>
@@ -1401,9 +1401,10 @@ int system_vlan_del(struct device *dev)<br>
 int system_vlandev_add(struct device *vlandev, struct device *dev, struct vlandev_config *cfg)<br>
 {<br>
        struct nl_msg *msg;<br>
-       struct nlattr *linkinfo, *data;<br>
+       struct nlattr *linkinfo, *data, *qos;<br>
        struct ifinfomsg iim = { .ifi_family = AF_UNSPEC };<br>
        int rv;<br>
+       int i;<br>
<br>
        msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);<br>
<br>
@@ -1431,6 +1432,22 @@ int system_vlandev_add(struct device *vlandev, struct device *dev, struct vlande<br>
                netifd_log_message(L_WARNING, "%s Your kernel is older than linux 3.10.0, 802.1ad is not supported defaulting to 802.1q", vlandev->type->name);<br>
 #endif<br>
<br>
+       if (!(qos = nla_nest_start(msg, IFLA_VLAN_INGRESS_QOS)))<br>
+               goto nla_put_failure;<br>
+       for (i = 0; i < cfg->ingress_qos_mappings_len; i++)<br>
+               nla_put(msg, IFLA_VLAN_QOS_MAPPING,<br>
+                       sizeof(cfg->ingress_qos_mappings[i]),<br>
+                       &cfg->ingress_qos_mappings[i]);<br>
+       nla_nest_end(msg, qos);<br>
+<br>
+       if (!(qos = nla_nest_start(msg, IFLA_VLAN_EGRESS_QOS)))<br>
+               goto nla_put_failure;<br>
+       for (i = 0; i < cfg->egress_qos_mappings_len; i++)<br>
+               nla_put(msg, IFLA_VLAN_QOS_MAPPING,<br>
+                       sizeof(cfg->egress_qos_mappings[i]),<br>
+                       &cfg->egress_qos_mappings[i]);<br>
+       nla_nest_end(msg, qos);<br>
+<br>
        nla_nest_end(msg, data);<br>
        nla_nest_end(msg, linkinfo);<br>
<br>
diff --git a/system.h b/system.h<br>
index b377416..d8fc0c4 100644<br>
--- a/system.h<br>
+++ b/system.h<br>
@@ -18,6 +18,7 @@<br>
 #include <sys/time.h><br>
 #include <sys/socket.h><br>
 #include <arpa/inet.h><br>
+#include <linux/if_link.h><br>
 #include "device.h"<br>
 #include "interface-ip.h"<br>
 #include "iprule.h"<br>
@@ -161,6 +162,10 @@ enum vlan_proto {<br>
 struct vlandev_config {<br>
        enum vlan_proto proto;<br>
        uint16_t vid;<br>
+       struct ifla_vlan_qos_mapping ingress_qos_mappings[8]; <br></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+       size_t ingress_qos_mappings_len;<br>
+       struct ifla_vlan_qos_mapping egress_qos_mappings[16];<br></blockquote><div>Use a netifd defined struct as struct ifla_vlan_qos_mapping is a Linux specific struct ; the usage of struct ifla_vlan_qos should be confined to system-linux.c.</div><div>Also use lists here iso fixed arrays as at least for egress qos settings you can define more than 16 entries after checking the Linux kernel code <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+       size_t egress_qos_mappings_len;<br>
 };<br>
<br>
 static inline int system_get_addr_family(unsigned int flags)<br>
diff --git a/vlandev.c b/vlandev.c<br>
index ceaeb3e..2cc9a19 100644<br>
--- a/vlandev.c<br>
+++ b/vlandev.c<br>
@@ -13,6 +13,7 @@<br>
  */<br>
<br>
 #include <string.h><br>
+#include <inttypes.h><br>
<br>
 #include "netifd.h"<br>
 #include "device.h"<br>
@@ -22,12 +23,16 @@<br>
 enum {<br>
        VLANDEV_ATTR_IFNAME,<br>
        VLANDEV_ATTR_VID,<br>
+       VLANDEV_ATTR_INGRESS_QOS_MAPPING,<br>
+       VLANDEV_ATTR_EGRESS_QOS_MAPPING,<br>
        __VLANDEV_ATTR_MAX<br>
 };<br>
<br>
 static const struct blobmsg_policy vlandev_attrs[__VLANDEV_ATTR_MAX] = {<br>
        [VLANDEV_ATTR_IFNAME] = { "ifname", BLOBMSG_TYPE_STRING },<br>
        [VLANDEV_ATTR_VID] = { "vid", BLOBMSG_TYPE_INT32 },<br>
+       [VLANDEV_ATTR_INGRESS_QOS_MAPPING] = { "ingress_qos_mapping", BLOBMSG_TYPE_ARRAY },<br>
+       [VLANDEV_ATTR_EGRESS_QOS_MAPPING] = { "egress_qos_mapping", BLOBMSG_TYPE_ARRAY },<br>
 };<br>
<br>
 static const struct uci_blob_param_list vlandev_attr_list = {<br>
@@ -152,6 +157,42 @@ vlandev_config_init(struct device *dev)<br>
        device_add_user(&mvdev->parent, basedev);<br>
 }<br>
<br>
+static size_t vlandev_qos_mappings_list_apply(struct ifla_vlan_qos_mapping *qos_mapping, size_t len, struct blob_attr *list)<br>
+{<br>
+       struct blob_attr *cur;<br>
+       int rem, rc;<br>
+       int i = 0;<br>
+<br>
+       blobmsg_for_each_attr(cur, list, rem) {<br>
+               if (i == len) {<br>
+                       netifd_log_message(L_WARNING, "parsing failed: too many (>%d) qos mappings\n", len);<br>
</blockquote><div>Check is not necessary anymore if lists are used <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">+                       return 0;<br>
+               }<br>
+<br>
+               if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING) {<br>
+                       netifd_log_message(L_WARNING, "parsing failed: qos mapping attr type != string\n");<br>
+                       return 0;<br></blockquote><div>Just ignore this entry and don't bail out <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+               }<br>
+<br>
+               if (!blobmsg_check_attr(cur, false)) {<br>
+                       netifd_log_message(L_WARNING, "parsing failed: qos mapping attr blobmsg_check_attr() failed\n");<br>
+                       return 0;<br></blockquote><div>Same here; just ignore the entry and don'tt bail out <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+               }<br>
+<br>
+               rc = sscanf(blobmsg_data(cur), "%" PRIu32 ":%" PRIu32, &qos_mapping[i].from, &qos_mapping[i].to);<br>
+               if (rc != 2) {<br>
+                       netifd_log_message(L_WARNING, "parsing failed: qos mapping not in form <from_nr>:<to_nr>\n");<br></blockquote><div>Same here; just ignore and don't bail out <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+                       return 0;<br>
+               }<br>
+<br>
+               i++;<br>
+       }<br>
+<br>
+       return i;<br>
+}<br>
+<br>
+<br>
+<br>
 static void<br>
 vlandev_apply_settings(struct vlandev_device *mvdev, struct blob_attr **tb)<br>
 {<br>
@@ -161,9 +202,25 @@ vlandev_apply_settings(struct vlandev_device *mvdev, struct blob_attr **tb)<br>
        cfg->proto = (mvdev->dev.type == &vlan8021q_device_type) ?<br>
                VLAN_PROTO_8021Q : VLAN_PROTO_8021AD;<br>
        cfg->vid = 1;<br>
+       cfg->ingress_qos_mappings_len = 0;<br>
+       cfg->egress_qos_mappings_len = 0;<br>
<br>
        if ((cur = tb[VLANDEV_ATTR_VID]))<br>
                cfg->vid = (uint16_t) blobmsg_get_u32(cur);<br>
+<br>
+       if ((cur = tb[VLANDEV_ATTR_INGRESS_QOS_MAPPING])) {<br>
+               cfg->ingress_qos_mappings_len =<br>
+                       vlandev_qos_mappings_list_apply(cfg->ingress_qos_mappings,<br>
+                                                       ARRAY_SIZE(cfg->ingress_qos_mappings),<br>
+                                                       cur);<br>
+       }<br>
+<br>
+       if ((cur = tb[VLANDEV_ATTR_EGRESS_QOS_MAPPING])) {<br>
+               cfg->egress_qos_mappings_len =<br>
+                       vlandev_qos_mappings_list_apply(cfg->egress_qos_mappings,<br>
+                                                       ARRAY_SIZE(cfg->egress_qos_mappings),<br>
+                                                       cur);<br>
+       }<br>
 }<br>
<br></blockquote><div>Extend vlandev_dump_info to display the ingress and egress qos mappings</div><div><br></div><div>Hans<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
 static enum dev_change_type<br>
-- <br>
2.26.2<br>
<br>
<br>
_______________________________________________<br>
openwrt-devel mailing list<br>
<a href="mailto:openwrt-devel@lists.openwrt.org" target="_blank">openwrt-devel@lists.openwrt.org</a><br>
<a href="https://lists.openwrt.org/mailman/listinfo/openwrt-devel" rel="noreferrer" target="_blank">https://lists.openwrt.org/mailman/listinfo/openwrt-devel</a><br>
</blockquote></div></div>