There are cases where you need a different MAC on a VLAN interface, i.e. if if have move than one connection to a switch. A later change of the MAC is not possible on VLAN interfaces, so it has to be done on creation. The new macaddr option allows to set a unique MAC for a VLAN interface. Example: config device 'testvl' option type '8021ad' option name 'testvl' option ifname 'eth0' option vid '106' option macaddr 'f2:48:00:89:45:4c'
config interface 'testif' option ifname 'testvl' option proto 'none' option auto '1' Signed-off-by: André Valentin <avalen...@marcant.net> --- system-linux.c | 2 ++ system.h | 7 +++++++ vlandev.c | 17 +++++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/system-linux.c b/system-linux.c index 909ba0f..ac657c2 100644 --- a/system-linux.c +++ b/system-linux.c @@ -1014,6 +1014,8 @@ int system_vlandev_add(struct device *vlandev, struct device *dev, struct vlande return -1; nlmsg_append(msg, &iim, sizeof(iim), 0); + if (cfg->flags & VLANDEV_OPT_MACADDR) + nla_put(msg, IFLA_ADDRESS, sizeof(cfg->macaddr), cfg->macaddr); nla_put_string(msg, IFLA_IFNAME, vlandev->ifname); nla_put_u32(msg, IFLA_LINK, dev->ifindex); diff --git a/system.h b/system.h index 97fbc8b..a053072 100644 --- a/system.h +++ b/system.h @@ -77,9 +77,16 @@ enum vlan_proto { VLAN_PROTO_8021AD = 0x88A8 }; +enum vlandev_opt { + VLANDEV_OPT_MACADDR = (1 << 0), +}; + struct vlandev_config { enum vlan_proto proto; uint16_t vid; + + enum vlandev_opt flags; + unsigned char macaddr[6]; }; static inline int system_get_addr_family(unsigned int flags) diff --git a/vlandev.c b/vlandev.c index b93527c..7f1eda7 100644 --- a/vlandev.c +++ b/vlandev.c @@ -13,15 +13,22 @@ */ #include <string.h> +#include <net/ethernet.h> + +#ifdef linux +#include <netinet/ether.h> +#endif #include "netifd.h" #include "device.h" #include "interface.h" #include "system.h" + enum { VLANDEV_ATTR_TYPE, VLANDEV_ATTR_IFNAME, + VLANDEV_ATTR_MACADDR, VLANDEV_ATTR_VID, __VLANDEV_ATTR_MAX }; @@ -29,6 +36,7 @@ enum { static const struct blobmsg_policy vlandev_attrs[__VLANDEV_ATTR_MAX] = { [VLANDEV_ATTR_TYPE] = { "type", BLOBMSG_TYPE_STRING }, [VLANDEV_ATTR_IFNAME] = { "ifname", BLOBMSG_TYPE_STRING }, + [VLANDEV_ATTR_MACADDR] = { "macaddr", BLOBMSG_TYPE_STRING }, [VLANDEV_ATTR_VID] = { "vid", BLOBMSG_TYPE_INT32 }, }; @@ -157,6 +165,7 @@ vlandev_apply_settings(struct vlandev_device *mvdev, struct blob_attr **tb) { struct vlandev_config *cfg = &mvdev->config; struct blob_attr *cur; + struct ether_addr *ea; cfg->proto = VLAN_PROTO_8021Q; cfg->vid = 1; @@ -169,6 +178,14 @@ vlandev_apply_settings(struct vlandev_device *mvdev, struct blob_attr **tb) if ((cur = tb[VLANDEV_ATTR_VID])) cfg->vid = (uint16_t) blobmsg_get_u32(cur); + + if ((cur = tb[VLANDEV_ATTR_MACADDR])) { + ea = ether_aton(blobmsg_data(cur)); + if (ea) { + memcpy(cfg->macaddr, ea, 6); + cfg->flags |= VLANDEV_OPT_MACADDR; + } + } } static enum dev_change_type -- 2.1.4 _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel