[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200818085134.3228896-1-alsi@bang-olufsen.dk>
Date: Tue, 18 Aug 2020 10:51:34 +0200
From: Alvin Šipraga <alsi@...g-olufsen.dk>
To: netdev@...r.kernel.org
Cc: Alvin Šipraga <alsi@...g-olufsen.dk>
Subject: [PATCH v2 net-next] macvlan: validate setting of multiple remote source MAC addresses
Remote source MAC addresses can be set on a 'source mode' macvlan
interface via the IFLA_MACVLAN_MACADDR_DATA attribute. This commit
tightens the validation of these MAC addresses to match the validation
already performed when setting or adding a single MAC address via the
IFLA_MACVLAN_MACADDR attribute.
iproute2 uses IFLA_MACVLAN_MACADDR_DATA for its 'macvlan macaddr set'
command, and IFLA_MACVLAN_MACADDR for its 'macvlan macaddr add' command,
which demonstrates the inconsistent behaviour that this commit
addresses:
# ip link add link eth0 name macvlan0 type macvlan mode source
# ip link set link dev macvlan0 type macvlan macaddr add 01:00:00:00:00:00
RTNETLINK answers: Cannot assign requested address
# ip link set link dev macvlan0 type macvlan macaddr set 01:00:00:00:00:00
# ip -d link show macvlan0
5: macvlan0@...0: <BROADCAST,MULTICAST,DYNAMIC,UP,LOWER_UP> mtu 1500 ...
link/ether 2e:ac:fd:2d:69:f8 brd ff:ff:ff:ff:ff:ff promiscuity 0
macvlan mode source remotes (1) 01:00:00:00:00:00 numtxqueues 1 ...
With this change, the 'set' command will (rightly) fail in the same way
as the 'add' command.
Signed-off-by: Alvin Šipraga <alsi@...g-olufsen.dk>
---
v1 -> v2: reverse christmas tree ordering of local variables
drivers/net/macvlan.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 4942f6112e51..5da04e997989 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -1269,6 +1269,9 @@ static void macvlan_port_destroy(struct net_device *dev)
static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
{
+ struct nlattr *nla, *head;
+ int rem, len;
+
if (tb[IFLA_ADDRESS]) {
if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
return -EINVAL;
@@ -1316,6 +1319,20 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[],
return -EADDRNOTAVAIL;
}
+ if (data[IFLA_MACVLAN_MACADDR_DATA]) {
+ head = nla_data(data[IFLA_MACVLAN_MACADDR_DATA]);
+ len = nla_len(data[IFLA_MACVLAN_MACADDR_DATA]);
+
+ nla_for_each_attr(nla, head, len, rem) {
+ if (nla_type(nla) != IFLA_MACVLAN_MACADDR ||
+ nla_len(nla) != ETH_ALEN)
+ return -EINVAL;
+
+ if (!is_valid_ether_addr(nla_data(nla)))
+ return -EADDRNOTAVAIL;
+ }
+ }
+
if (data[IFLA_MACVLAN_MACADDR_COUNT])
return -EINVAL;
@@ -1372,10 +1389,6 @@ static int macvlan_changelink_sources(struct macvlan_dev *vlan, u32 mode,
len = nla_len(data[IFLA_MACVLAN_MACADDR_DATA]);
nla_for_each_attr(nla, head, len, rem) {
- if (nla_type(nla) != IFLA_MACVLAN_MACADDR ||
- nla_len(nla) != ETH_ALEN)
- continue;
-
addr = nla_data(nla);
ret = macvlan_hash_add_source(vlan, addr);
if (ret)
--
2.28.0
Powered by blists - more mailing lists