Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0e06877c authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller
Browse files

[RTNETLINK]: rtnl_link: allow specifying initial device address



Drivers need to validate the initial addresses in their netlink attribute
validation function or manually reject them if they can't support this.

Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2d85cba2
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -84,9 +84,21 @@ static int dummy_xmit(struct sk_buff *skb, struct net_device *dev)
	return 0;
}

static int dummy_validate(struct nlattr *tb[], struct nlattr *data[])
{
	if (tb[IFLA_ADDRESS]) {
		if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
			return -EINVAL;
		if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
			return -EADDRNOTAVAIL;
	}
	return 0;
}

static struct rtnl_link_ops dummy_link_ops __read_mostly = {
	.kind		= "dummy",
	.setup		= dummy_setup,
	.validate	= dummy_validate,
};

/* Number of dummy devices to be set up by this module. */
+12 −0
Original line number Diff line number Diff line
@@ -221,10 +221,22 @@ static int ifb_open(struct net_device *dev)
	return 0;
}

static int ifb_validate(struct nlattr *tb[], struct nlattr *data[])
{
	if (tb[IFLA_ADDRESS]) {
		if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
			return -EINVAL;
		if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
			return -EADDRNOTAVAIL;
	}
	return 0;
}

static struct rtnl_link_ops ifb_link_ops __read_mostly = {
	.kind		= "ifb",
	.priv_size	= sizeof(struct ifb_private),
	.setup		= ifb_setup,
	.validate	= ifb_validate,
};

/* Number of ifb devices to be set up by this module. */
+6 −2
Original line number Diff line number Diff line
@@ -324,8 +324,10 @@ static int vlan_dev_init(struct net_device *dev)
					  (1<<__LINK_STATE_DORMANT))) |
		      (1<<__LINK_STATE_PRESENT);

	memcpy(dev->broadcast, real_dev->broadcast, real_dev->addr_len);
	memcpy(dev->dev_addr, real_dev->dev_addr, real_dev->addr_len);
	if (is_zero_ether_addr(dev->dev_addr))
		memcpy(dev->dev_addr, real_dev->dev_addr, dev->addr_len);
	if (is_zero_ether_addr(dev->broadcast))
		memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len);

	if (real_dev->features & NETIF_F_HW_VLAN_TX) {
		dev->hard_header     = real_dev->hard_header;
@@ -373,6 +375,8 @@ void vlan_setup(struct net_device *new_dev)
	new_dev->set_multicast_list = vlan_dev_set_multicast_list;
	new_dev->destructor = free_netdev;
	new_dev->do_ioctl = vlan_dev_ioctl;

	memset(new_dev->broadcast, 0, sizeof(ETH_ALEN));
}

static void vlan_transfer_operstate(const struct net_device *dev, struct net_device *vlandev)
+7 −0
Original line number Diff line number Diff line
@@ -41,6 +41,13 @@ static int vlan_validate(struct nlattr *tb[], struct nlattr *data[])
	u16 id;
	int err;

	if (tb[IFLA_ADDRESS]) {
		if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
			return -EINVAL;
		if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
			return -EADDRNOTAVAIL;
	}

	if (!data)
		return -EINVAL;

+7 −2
Original line number Diff line number Diff line
@@ -1032,8 +1032,7 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)

		if (ifm->ifi_index || ifm->ifi_flags || ifm->ifi_change)
			return -EOPNOTSUPP;
		if (tb[IFLA_ADDRESS] || tb[IFLA_BROADCAST] || tb[IFLA_MAP] ||
		    tb[IFLA_MASTER] || tb[IFLA_PROTINFO])
		if (tb[IFLA_MAP] || tb[IFLA_MASTER] || tb[IFLA_PROTINFO])
			return -EOPNOTSUPP;

		if (!ops) {
@@ -1065,6 +1064,12 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)

		if (tb[IFLA_MTU])
			dev->mtu = nla_get_u32(tb[IFLA_MTU]);
		if (tb[IFLA_ADDRESS])
			memcpy(dev->dev_addr, nla_data(tb[IFLA_ADDRESS]),
			       nla_len(tb[IFLA_ADDRESS]));
		if (tb[IFLA_BROADCAST])
			memcpy(dev->broadcast, nla_data(tb[IFLA_BROADCAST]),
			       nla_len(tb[IFLA_BROADCAST]));
		if (tb[IFLA_TXQLEN])
			dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]);
		if (tb[IFLA_WEIGHT])