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

Commit 009146d1 authored by Mahesh Bandewar's avatar Mahesh Bandewar Committed by David S. Miller
Browse files

ipvlan: assign unique dev-id for each slave device.



IPvlan setup uses one mac-address (of master). The IPv6 link-local
addresses are derived using the mac-address on the link. Lack of
dev-ids makes these link-local addresses same for all slaves including
that of master device. dev-ids are necessary to add differentiation
when L2 address is shared.

Signed-off-by: default avatarMahesh Bandewar <maheshb@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a896eee3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ struct ipvl_port {
	struct work_struct	wq;
	struct sk_buff_head	backlog;
	int			count;
	struct ida		ida;
};

struct ipvl_skb_cb {
+16 −1
Original line number Diff line number Diff line
@@ -119,6 +119,7 @@ static int ipvlan_port_create(struct net_device *dev)

	skb_queue_head_init(&port->backlog);
	INIT_WORK(&port->wq, ipvlan_process_multicast);
	ida_init(&port->ida);

	err = netdev_rx_handler_register(dev, ipvlan_handle_frame, port);
	if (err)
@@ -150,6 +151,7 @@ static void ipvlan_port_destroy(struct net_device *dev)
			dev_put(skb->dev);
		kfree_skb(skb);
	}
	ida_destroy(&port->ida);
	kfree(port);
}

@@ -533,6 +535,16 @@ static int ipvlan_link_new(struct net *src_net, struct net_device *dev,
	ipvlan_adjust_mtu(ipvlan, phy_dev);
	INIT_LIST_HEAD(&ipvlan->addrs);

	/* Since L2 address is shared among all IPvlan slaves including
	 * master, use unique 16 bit dev-ids to diffentiate among them.
	 * Assign IDs between 0x1 and 0xFFFE (used by the master) to each
	 * slave link [see addrconf_ifid_eui48()].
	 */
	err = ida_simple_get(&port->ida, 1, 0xFFFE, GFP_KERNEL);
	if (err < 0)
		goto destroy_ipvlan_port;
	dev->dev_id = err;

	/* TODO Probably put random address here to be presented to the
	 * world but keep using the physical-dev address for the outgoing
	 * packets.
@@ -543,7 +555,7 @@ static int ipvlan_link_new(struct net *src_net, struct net_device *dev,

	err = register_netdevice(dev);
	if (err < 0)
		goto destroy_ipvlan_port;
		goto remove_ida;

	err = netdev_upper_dev_link(phy_dev, dev);
	if (err) {
@@ -562,6 +574,8 @@ static int ipvlan_link_new(struct net *src_net, struct net_device *dev,
	netdev_upper_dev_unlink(phy_dev, dev);
unregister_netdev:
	unregister_netdevice(dev);
remove_ida:
	ida_simple_remove(&port->ida, dev->dev_id);
destroy_ipvlan_port:
	if (create)
		ipvlan_port_destroy(phy_dev);
@@ -579,6 +593,7 @@ static void ipvlan_link_delete(struct net_device *dev, struct list_head *head)
		kfree_rcu(addr, rcu);
	}

	ida_simple_remove(&ipvlan->port->ida, dev->dev_id);
	list_del_rcu(&ipvlan->pnode);
	unregister_netdevice_queue(dev, head);
	netdev_upper_dev_unlink(ipvlan->phy_dev, dev);