Hi, On Tue, Apr 28, 2020 at 9:41 AM Pau Espin Pedrol <[email protected]> wrote:
> From: Pau Espin Pedrol <[email protected]> > > It allows setting mappings for instance this way: > """ > config device > option name 'vlan41' > option type '8021q' > option vid '41' > option ifname 'eth1' > list ingress_qos_mapping '1:2' > list ingress_qos_mapping '2:5' > list egress_qos_mapping '0:3' > """ > > Size of mapping arrays (ingress=8, egress=16) taken from linux kernel > "struct vlan_dev_priv". > > Signed-off-by: Pau Espin Pedrol <[email protected]> > Tested-by: Pedro <[email protected]> > --- > system-linux.c | 19 ++++++++++++++++- > system.h | 5 +++++ > vlandev.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 80 insertions(+), 1 deletion(-) > > diff --git a/system-linux.c b/system-linux.c > index 62636c4..fa236ad 100644 > --- a/system-linux.c > +++ b/system-linux.c > @@ -1401,9 +1401,10 @@ int system_vlan_del(struct device *dev) > int system_vlandev_add(struct device *vlandev, struct device *dev, struct > vlandev_config *cfg) > { > struct nl_msg *msg; > - struct nlattr *linkinfo, *data; > + struct nlattr *linkinfo, *data, *qos; > struct ifinfomsg iim = { .ifi_family = AF_UNSPEC }; > int rv; > + int i; > > msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE > | NLM_F_EXCL); > > @@ -1431,6 +1432,22 @@ int system_vlandev_add(struct device *vlandev, > struct device *dev, struct vlande > 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); > #endif > > + if (!(qos = nla_nest_start(msg, IFLA_VLAN_INGRESS_QOS))) > + goto nla_put_failure; > + for (i = 0; i < cfg->ingress_qos_mappings_len; i++) > + nla_put(msg, IFLA_VLAN_QOS_MAPPING, > + sizeof(cfg->ingress_qos_mappings[i]), > + &cfg->ingress_qos_mappings[i]); > + nla_nest_end(msg, qos); > + > + if (!(qos = nla_nest_start(msg, IFLA_VLAN_EGRESS_QOS))) > + goto nla_put_failure; > + for (i = 0; i < cfg->egress_qos_mappings_len; i++) > + nla_put(msg, IFLA_VLAN_QOS_MAPPING, > + sizeof(cfg->egress_qos_mappings[i]), > + &cfg->egress_qos_mappings[i]); > + nla_nest_end(msg, qos); > + > nla_nest_end(msg, data); > nla_nest_end(msg, linkinfo); > > diff --git a/system.h b/system.h > index b377416..d8fc0c4 100644 > --- a/system.h > +++ b/system.h > @@ -18,6 +18,7 @@ > #include <sys/time.h> > #include <sys/socket.h> > #include <arpa/inet.h> > +#include <linux/if_link.h> > #include "device.h" > #include "interface-ip.h" > #include "iprule.h" > @@ -161,6 +162,10 @@ enum vlan_proto { > struct vlandev_config { > enum vlan_proto proto; > uint16_t vid; > + struct ifla_vlan_qos_mapping ingress_qos_mappings[8]; > + size_t ingress_qos_mappings_len; > + struct ifla_vlan_qos_mapping egress_qos_mappings[16]; > 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. 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 > + size_t egress_qos_mappings_len; > }; > > static inline int system_get_addr_family(unsigned int flags) > diff --git a/vlandev.c b/vlandev.c > index ceaeb3e..2cc9a19 100644 > --- a/vlandev.c > +++ b/vlandev.c > @@ -13,6 +13,7 @@ > */ > > #include <string.h> > +#include <inttypes.h> > > #include "netifd.h" > #include "device.h" > @@ -22,12 +23,16 @@ > enum { > VLANDEV_ATTR_IFNAME, > VLANDEV_ATTR_VID, > + VLANDEV_ATTR_INGRESS_QOS_MAPPING, > + VLANDEV_ATTR_EGRESS_QOS_MAPPING, > __VLANDEV_ATTR_MAX > }; > > static const struct blobmsg_policy vlandev_attrs[__VLANDEV_ATTR_MAX] = { > [VLANDEV_ATTR_IFNAME] = { "ifname", BLOBMSG_TYPE_STRING }, > [VLANDEV_ATTR_VID] = { "vid", BLOBMSG_TYPE_INT32 }, > + [VLANDEV_ATTR_INGRESS_QOS_MAPPING] = { "ingress_qos_mapping", > BLOBMSG_TYPE_ARRAY }, > + [VLANDEV_ATTR_EGRESS_QOS_MAPPING] = { "egress_qos_mapping", > BLOBMSG_TYPE_ARRAY }, > }; > > static const struct uci_blob_param_list vlandev_attr_list = { > @@ -152,6 +157,42 @@ vlandev_config_init(struct device *dev) > device_add_user(&mvdev->parent, basedev); > } > > +static size_t vlandev_qos_mappings_list_apply(struct > ifla_vlan_qos_mapping *qos_mapping, size_t len, struct blob_attr *list) > +{ > + struct blob_attr *cur; > + int rem, rc; > + int i = 0; > + > + blobmsg_for_each_attr(cur, list, rem) { > + if (i == len) { > + netifd_log_message(L_WARNING, "parsing failed: too > many (>%d) qos mappings\n", len); > Check is not necessary anymore if lists are used > + return 0; > + } > + > + if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING) { > + netifd_log_message(L_WARNING, "parsing failed: qos > mapping attr type != string\n"); > + return 0; > Just ignore this entry and don't bail out > + } > + > + if (!blobmsg_check_attr(cur, false)) { > + netifd_log_message(L_WARNING, "parsing failed: qos > mapping attr blobmsg_check_attr() failed\n"); > + return 0; > Same here; just ignore the entry and don'tt bail out > + } > + > + rc = sscanf(blobmsg_data(cur), "%" PRIu32 ":%" PRIu32, > &qos_mapping[i].from, &qos_mapping[i].to); > + if (rc != 2) { > + netifd_log_message(L_WARNING, "parsing failed: qos > mapping not in form <from_nr>:<to_nr>\n"); > Same here; just ignore and don't bail out > + return 0; > + } > + > + i++; > + } > + > + return i; > +} > + > + > + > static void > vlandev_apply_settings(struct vlandev_device *mvdev, struct blob_attr > **tb) > { > @@ -161,9 +202,25 @@ vlandev_apply_settings(struct vlandev_device *mvdev, > struct blob_attr **tb) > cfg->proto = (mvdev->dev.type == &vlan8021q_device_type) ? > VLAN_PROTO_8021Q : VLAN_PROTO_8021AD; > cfg->vid = 1; > + cfg->ingress_qos_mappings_len = 0; > + cfg->egress_qos_mappings_len = 0; > > if ((cur = tb[VLANDEV_ATTR_VID])) > cfg->vid = (uint16_t) blobmsg_get_u32(cur); > + > + if ((cur = tb[VLANDEV_ATTR_INGRESS_QOS_MAPPING])) { > + cfg->ingress_qos_mappings_len = > + > vlandev_qos_mappings_list_apply(cfg->ingress_qos_mappings, > + > ARRAY_SIZE(cfg->ingress_qos_mappings), > + cur); > + } > + > + if ((cur = tb[VLANDEV_ATTR_EGRESS_QOS_MAPPING])) { > + cfg->egress_qos_mappings_len = > + > vlandev_qos_mappings_list_apply(cfg->egress_qos_mappings, > + > ARRAY_SIZE(cfg->egress_qos_mappings), > + cur); > + } > } > > Extend vlandev_dump_info to display the ingress and egress qos mappings Hans > static enum dev_change_type > -- > 2.26.2 > > > _______________________________________________ > openwrt-devel mailing list > [email protected] > https://lists.openwrt.org/mailman/listinfo/openwrt-devel >
_______________________________________________ openwrt-devel mailing list [email protected] https://lists.openwrt.org/mailman/listinfo/openwrt-devel
