[OpenWrt-Devel] [PATCH] vlandev: Add support for setting a unique MAC on a VLAN interface

André Valentin avalentin at marcant.net
Sun Jan 24 14:47:26 EST 2016


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 <avalentin at 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 at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel


More information about the openwrt-devel mailing list