aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-04-02 14:05:02 -0400
committerDavid S. Miller <davem@davemloft.net>2015-04-02 14:05:02 -0400
commite4a924f5768c55002c02ceba9b9f86824c35f956 (patch)
treeae8db8c41d5950644db9d4f5e609f228df958e57
parent033f46b3c13d4072d8ee6b26dd1e90fdd06895d0 (diff)
parenta45253bf32bf49cdb2807bad212b84f5ab51ac26 (diff)
Merge branch 'netdev_iflink_remove'
Nicolas Dichtel says: ==================== Remove iflink field from the net_device structure The first goal of this series was to advertise the veth peer via the IFLA_LINK attribute, but iflink was not ready for network namespaces. The iflink of an interface should be set to its ifindex for a physical interface and to another value (0 if not relevant) for a virtual interface. This was not the case for some interfaces, like vxlan, bond, or bridge for example. There is also a risk, if the targeted interface moves to another netns, that the ifindex changes without updating corresponding iflink fields (eg. vlan). Moving the management of this property into virtual interface drivers allows to better handle this last case because most of virtual interface drivers have a pointer to the link netdevice. Anyway, dev->iflink value was always a copy of some internal data of the virtual interface driver, thus let's use these internal data directly. So, this series removes the iflink field and let the drivers manage it. Only the last patch was present in the v1, but I fully rework it. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c8
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_vlan.c1
-rw-r--r--drivers/net/ipvlan/ipvlan_core.c2
-rw-r--r--drivers/net/ipvlan/ipvlan_main.c9
-rw-r--r--drivers/net/macvlan.c9
-rw-r--r--drivers/net/veth.c15
-rw-r--r--include/linux/netdevice.h7
-rw-r--r--include/net/ip6_tunnel.h1
-rw-r--r--include/net/ip_tunnels.h1
-rw-r--r--net/8021q/vlan_dev.c9
-rw-r--r--net/batman-adv/hard-interface.c5
-rw-r--r--net/bridge/br_netlink.c4
-rw-r--r--net/core/dev.c32
-rw-r--r--net/core/link_watch.c4
-rw-r--r--net/core/net-sysfs.c10
-rw-r--r--net/core/rtnetlink.c8
-rw-r--r--net/dsa/slave.c8
-rw-r--r--net/ipv4/ip_gre.c2
-rw-r--r--net/ipv4/ip_tunnel.c9
-rw-r--r--net/ipv4/ip_vti.c2
-rw-r--r--net/ipv4/ipip.c2
-rw-r--r--net/ipv4/ipmr.c9
-rw-r--r--net/ipv6/addrconf.c4
-rw-r--r--net/ipv6/ip6_gre.c8
-rw-r--r--net/ipv6/ip6_tunnel.c10
-rw-r--r--net/ipv6/ip6_vti.c3
-rw-r--r--net/ipv6/ip6mr.c9
-rw-r--r--net/ipv6/sit.c3
28 files changed, 140 insertions, 54 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 58b5aa3b6f2d..657b89b1d291 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -842,6 +842,13 @@ static void ipoib_set_mcast_list(struct net_device *dev)
842 queue_work(ipoib_workqueue, &priv->restart_task); 842 queue_work(ipoib_workqueue, &priv->restart_task);
843} 843}
844 844
845static int ipoib_get_iflink(const struct net_device *dev)
846{
847 struct ipoib_dev_priv *priv = netdev_priv(dev);
848
849 return priv->parent->ifindex;
850}
851
845static u32 ipoib_addr_hash(struct ipoib_neigh_hash *htbl, u8 *daddr) 852static u32 ipoib_addr_hash(struct ipoib_neigh_hash *htbl, u8 *daddr)
846{ 853{
847 /* 854 /*
@@ -1341,6 +1348,7 @@ static const struct net_device_ops ipoib_netdev_ops = {
1341 .ndo_start_xmit = ipoib_start_xmit, 1348 .ndo_start_xmit = ipoib_start_xmit,
1342 .ndo_tx_timeout = ipoib_timeout, 1349 .ndo_tx_timeout = ipoib_timeout,
1343 .ndo_set_rx_mode = ipoib_set_mcast_list, 1350 .ndo_set_rx_mode = ipoib_set_mcast_list,
1351 .ndo_get_iflink = ipoib_get_iflink,
1344}; 1352};
1345 1353
1346void ipoib_setup(struct net_device *dev) 1354void ipoib_setup(struct net_device *dev)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
index 9fad7b5ac8b9..4dd1313056a4 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -102,7 +102,6 @@ int __ipoib_vlan_add(struct ipoib_dev_priv *ppriv, struct ipoib_dev_priv *priv,
102 } 102 }
103 103
104 priv->child_type = type; 104 priv->child_type = type;
105 priv->dev->iflink = ppriv->dev->ifindex;
106 list_add_tail(&priv->list, &ppriv->child_intfs); 105 list_add_tail(&priv->list, &ppriv->child_intfs);
107 106
108 return 0; 107 return 0;
diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c
index 2a175006028b..131bde98188d 100644
--- a/drivers/net/ipvlan/ipvlan_core.c
+++ b/drivers/net/ipvlan/ipvlan_core.c
@@ -330,7 +330,7 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb)
330 struct rtable *rt; 330 struct rtable *rt;
331 int err, ret = NET_XMIT_DROP; 331 int err, ret = NET_XMIT_DROP;
332 struct flowi4 fl4 = { 332 struct flowi4 fl4 = {
333 .flowi4_oif = dev->iflink, 333 .flowi4_oif = dev_get_iflink(dev),
334 .flowi4_tos = RT_TOS(ip4h->tos), 334 .flowi4_tos = RT_TOS(ip4h->tos),
335 .flowi4_flags = FLOWI_FLAG_ANYSRC, 335 .flowi4_flags = FLOWI_FLAG_ANYSRC,
336 .daddr = ip4h->daddr, 336 .daddr = ip4h->daddr,
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
index 2950c3780230..1701ede2df89 100644
--- a/drivers/net/ipvlan/ipvlan_main.c
+++ b/drivers/net/ipvlan/ipvlan_main.c
@@ -114,7 +114,6 @@ static int ipvlan_init(struct net_device *dev)
114 dev->features = phy_dev->features & IPVLAN_FEATURES; 114 dev->features = phy_dev->features & IPVLAN_FEATURES;
115 dev->features |= NETIF_F_LLTX; 115 dev->features |= NETIF_F_LLTX;
116 dev->gso_max_size = phy_dev->gso_max_size; 116 dev->gso_max_size = phy_dev->gso_max_size;
117 dev->iflink = phy_dev->ifindex;
118 dev->hard_header_len = phy_dev->hard_header_len; 117 dev->hard_header_len = phy_dev->hard_header_len;
119 118
120 ipvlan_set_lockdep_class(dev); 119 ipvlan_set_lockdep_class(dev);
@@ -305,6 +304,13 @@ static int ipvlan_vlan_rx_kill_vid(struct net_device *dev, __be16 proto,
305 return 0; 304 return 0;
306} 305}
307 306
307static int ipvlan_get_iflink(const struct net_device *dev)
308{
309 struct ipvl_dev *ipvlan = netdev_priv(dev);
310
311 return ipvlan->phy_dev->ifindex;
312}
313
308static const struct net_device_ops ipvlan_netdev_ops = { 314static const struct net_device_ops ipvlan_netdev_ops = {
309 .ndo_init = ipvlan_init, 315 .ndo_init = ipvlan_init,
310 .ndo_uninit = ipvlan_uninit, 316 .ndo_uninit = ipvlan_uninit,
@@ -317,6 +323,7 @@ static const struct net_device_ops ipvlan_netdev_ops = {
317 .ndo_get_stats64 = ipvlan_get_stats64, 323 .ndo_get_stats64 = ipvlan_get_stats64,
318 .ndo_vlan_rx_add_vid = ipvlan_vlan_rx_add_vid, 324 .ndo_vlan_rx_add_vid = ipvlan_vlan_rx_add_vid,
319 .ndo_vlan_rx_kill_vid = ipvlan_vlan_rx_kill_vid, 325 .ndo_vlan_rx_kill_vid = ipvlan_vlan_rx_kill_vid,
326 .ndo_get_iflink = ipvlan_get_iflink,
320}; 327};
321 328
322static int ipvlan_hard_header(struct sk_buff *skb, struct net_device *dev, 329static int ipvlan_hard_header(struct sk_buff *skb, struct net_device *dev,
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index b5e3320ca506..b227a13f6473 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -786,7 +786,6 @@ static int macvlan_init(struct net_device *dev)
786 dev->hw_features |= NETIF_F_LRO; 786 dev->hw_features |= NETIF_F_LRO;
787 dev->vlan_features = lowerdev->vlan_features & MACVLAN_FEATURES; 787 dev->vlan_features = lowerdev->vlan_features & MACVLAN_FEATURES;
788 dev->gso_max_size = lowerdev->gso_max_size; 788 dev->gso_max_size = lowerdev->gso_max_size;
789 dev->iflink = lowerdev->ifindex;
790 dev->hard_header_len = lowerdev->hard_header_len; 789 dev->hard_header_len = lowerdev->hard_header_len;
791 790
792 macvlan_set_lockdep_class(dev); 791 macvlan_set_lockdep_class(dev);
@@ -995,6 +994,13 @@ static void macvlan_dev_netpoll_cleanup(struct net_device *dev)
995} 994}
996#endif /* CONFIG_NET_POLL_CONTROLLER */ 995#endif /* CONFIG_NET_POLL_CONTROLLER */
997 996
997static int macvlan_dev_get_iflink(const struct net_device *dev)
998{
999 struct macvlan_dev *vlan = netdev_priv(dev);
1000
1001 return vlan->lowerdev->ifindex;
1002}
1003
998static const struct ethtool_ops macvlan_ethtool_ops = { 1004static const struct ethtool_ops macvlan_ethtool_ops = {
999 .get_link = ethtool_op_get_link, 1005 .get_link = ethtool_op_get_link,
1000 .get_settings = macvlan_ethtool_get_settings, 1006 .get_settings = macvlan_ethtool_get_settings,
@@ -1025,6 +1031,7 @@ static const struct net_device_ops macvlan_netdev_ops = {
1025 .ndo_netpoll_setup = macvlan_dev_netpoll_setup, 1031 .ndo_netpoll_setup = macvlan_dev_netpoll_setup,
1026 .ndo_netpoll_cleanup = macvlan_dev_netpoll_cleanup, 1032 .ndo_netpoll_cleanup = macvlan_dev_netpoll_cleanup,
1027#endif 1033#endif
1034 .ndo_get_iflink = macvlan_dev_get_iflink,
1028}; 1035};
1029 1036
1030void macvlan_common_setup(struct net_device *dev) 1037void macvlan_common_setup(struct net_device *dev)
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 4cca36ebc4fb..c8186ffda1a3 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -263,6 +263,20 @@ static void veth_poll_controller(struct net_device *dev)
263} 263}
264#endif /* CONFIG_NET_POLL_CONTROLLER */ 264#endif /* CONFIG_NET_POLL_CONTROLLER */
265 265
266static int veth_get_iflink(const struct net_device *dev)
267{
268 struct veth_priv *priv = netdev_priv(dev);
269 struct net_device *peer;
270 int iflink;
271
272 rcu_read_lock();
273 peer = rcu_dereference(priv->peer);
274 iflink = peer ? peer->ifindex : 0;
275 rcu_read_unlock();
276
277 return iflink;
278}
279
266static const struct net_device_ops veth_netdev_ops = { 280static const struct net_device_ops veth_netdev_ops = {
267 .ndo_init = veth_dev_init, 281 .ndo_init = veth_dev_init,
268 .ndo_open = veth_open, 282 .ndo_open = veth_open,
@@ -275,6 +289,7 @@ static const struct net_device_ops veth_netdev_ops = {
275#ifdef CONFIG_NET_POLL_CONTROLLER 289#ifdef CONFIG_NET_POLL_CONTROLLER
276 .ndo_poll_controller = veth_poll_controller, 290 .ndo_poll_controller = veth_poll_controller,
277#endif 291#endif
292 .ndo_get_iflink = veth_get_iflink,
278}; 293};
279 294
280#define VETH_FEATURES (NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \ 295#define VETH_FEATURES (NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 967bb4c8caf1..846a1f5bc9db 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1030,6 +1030,8 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
1030 * int queue_index, u32 maxrate); 1030 * int queue_index, u32 maxrate);
1031 * Called when a user wants to set a max-rate limitation of specific 1031 * Called when a user wants to set a max-rate limitation of specific
1032 * TX queue. 1032 * TX queue.
1033 * int (*ndo_get_iflink)(const struct net_device *dev);
1034 * Called to get the iflink value of this device.
1033 */ 1035 */
1034struct net_device_ops { 1036struct net_device_ops {
1035 int (*ndo_init)(struct net_device *dev); 1037 int (*ndo_init)(struct net_device *dev);
@@ -1191,6 +1193,7 @@ struct net_device_ops {
1191 int (*ndo_set_tx_maxrate)(struct net_device *dev, 1193 int (*ndo_set_tx_maxrate)(struct net_device *dev,
1192 int queue_index, 1194 int queue_index,
1193 u32 maxrate); 1195 u32 maxrate);
1196 int (*ndo_get_iflink)(const struct net_device *dev);
1194}; 1197};
1195 1198
1196/** 1199/**
@@ -1535,7 +1538,7 @@ struct net_device {
1535 netdev_features_t mpls_features; 1538 netdev_features_t mpls_features;
1536 1539
1537 int ifindex; 1540 int ifindex;
1538 int iflink; 1541 int group;
1539 1542
1540 struct net_device_stats stats; 1543 struct net_device_stats stats;
1541 1544
@@ -1738,7 +1741,6 @@ struct net_device {
1738#endif 1741#endif
1739 struct phy_device *phydev; 1742 struct phy_device *phydev;
1740 struct lock_class_key *qdisc_tx_busylock; 1743 struct lock_class_key *qdisc_tx_busylock;
1741 int group;
1742 struct pm_qos_request pm_qos_req; 1744 struct pm_qos_request pm_qos_req;
1743}; 1745};
1744#define to_net_dev(d) container_of(d, struct net_device, dev) 1746#define to_net_dev(d) container_of(d, struct net_device, dev)
@@ -2149,6 +2151,7 @@ void __dev_remove_pack(struct packet_type *pt);
2149void dev_add_offload(struct packet_offload *po); 2151void dev_add_offload(struct packet_offload *po);
2150void dev_remove_offload(struct packet_offload *po); 2152void dev_remove_offload(struct packet_offload *po);
2151 2153
2154int dev_get_iflink(const struct net_device *dev);
2152struct net_device *__dev_get_by_flags(struct net *net, unsigned short flags, 2155struct net_device *__dev_get_by_flags(struct net *net, unsigned short flags,
2153 unsigned short mask); 2156 unsigned short mask);
2154struct net_device *dev_get_by_name(struct net *net, const char *name); 2157struct net_device *dev_get_by_name(struct net *net, const char *name);
diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h
index 76c091b53dae..1668be5937e6 100644
--- a/include/net/ip6_tunnel.h
+++ b/include/net/ip6_tunnel.h
@@ -71,6 +71,7 @@ __u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw);
71__u32 ip6_tnl_get_cap(struct ip6_tnl *t, const struct in6_addr *laddr, 71__u32 ip6_tnl_get_cap(struct ip6_tnl *t, const struct in6_addr *laddr,
72 const struct in6_addr *raddr); 72 const struct in6_addr *raddr);
73struct net *ip6_tnl_get_link_net(const struct net_device *dev); 73struct net *ip6_tnl_get_link_net(const struct net_device *dev);
74int ip6_tnl_get_iflink(const struct net_device *dev);
74 75
75static inline void ip6tunnel_xmit(struct sk_buff *skb, struct net_device *dev) 76static inline void ip6tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
76{ 77{
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index 2c47061a6954..d8214cb88bbc 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -142,6 +142,7 @@ int ip_tunnel_init(struct net_device *dev);
142void ip_tunnel_uninit(struct net_device *dev); 142void ip_tunnel_uninit(struct net_device *dev);
143void ip_tunnel_dellink(struct net_device *dev, struct list_head *head); 143void ip_tunnel_dellink(struct net_device *dev, struct list_head *head);
144struct net *ip_tunnel_get_link_net(const struct net_device *dev); 144struct net *ip_tunnel_get_link_net(const struct net_device *dev);
145int ip_tunnel_get_iflink(const struct net_device *dev);
145int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id, 146int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
146 struct rtnl_link_ops *ops, char *devname); 147 struct rtnl_link_ops *ops, char *devname);
147 148
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 8b5ab9033b41..01d7ba840df8 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -538,7 +538,6 @@ static int vlan_dev_init(struct net_device *dev)
538 /* IFF_BROADCAST|IFF_MULTICAST; ??? */ 538 /* IFF_BROADCAST|IFF_MULTICAST; ??? */
539 dev->flags = real_dev->flags & ~(IFF_UP | IFF_PROMISC | IFF_ALLMULTI | 539 dev->flags = real_dev->flags & ~(IFF_UP | IFF_PROMISC | IFF_ALLMULTI |
540 IFF_MASTER | IFF_SLAVE); 540 IFF_MASTER | IFF_SLAVE);
541 dev->iflink = real_dev->ifindex;
542 dev->state = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) | 541 dev->state = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) |
543 (1<<__LINK_STATE_DORMANT))) | 542 (1<<__LINK_STATE_DORMANT))) |
544 (1<<__LINK_STATE_PRESENT); 543 (1<<__LINK_STATE_PRESENT);
@@ -733,6 +732,13 @@ static void vlan_dev_netpoll_cleanup(struct net_device *dev)
733} 732}
734#endif /* CONFIG_NET_POLL_CONTROLLER */ 733#endif /* CONFIG_NET_POLL_CONTROLLER */
735 734
735static int vlan_dev_get_iflink(const struct net_device *dev)
736{
737 struct net_device *real_dev = vlan_dev_priv(dev)->real_dev;
738
739 return real_dev->ifindex;
740}
741
736static const struct ethtool_ops vlan_ethtool_ops = { 742static const struct ethtool_ops vlan_ethtool_ops = {
737 .get_settings = vlan_ethtool_get_settings, 743 .get_settings = vlan_ethtool_get_settings,
738 .get_drvinfo = vlan_ethtool_get_drvinfo, 744 .get_drvinfo = vlan_ethtool_get_drvinfo,
@@ -769,6 +775,7 @@ static const struct net_device_ops vlan_netdev_ops = {
769#endif 775#endif
770 .ndo_fix_features = vlan_dev_fix_features, 776 .ndo_fix_features = vlan_dev_fix_features,
771 .ndo_get_lock_subclass = vlan_dev_get_lock_subclass, 777 .ndo_get_lock_subclass = vlan_dev_get_lock_subclass,
778 .ndo_get_iflink = vlan_dev_get_iflink,
772}; 779};
773 780
774static void vlan_dev_free(struct net_device *dev) 781static void vlan_dev_free(struct net_device *dev)
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index fbda6b54baff..baf1f9843f2c 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -83,11 +83,12 @@ static bool batadv_is_on_batman_iface(const struct net_device *net_dev)
83 return true; 83 return true;
84 84
85 /* no more parents..stop recursion */ 85 /* no more parents..stop recursion */
86 if (net_dev->iflink == 0 || net_dev->iflink == net_dev->ifindex) 86 if (dev_get_iflink(net_dev) == 0 ||
87 dev_get_iflink(net_dev) == net_dev->ifindex)
87 return false; 88 return false;
88 89
89 /* recurse over the parent device */ 90 /* recurse over the parent device */
90 parent_dev = __dev_get_by_index(&init_net, net_dev->iflink); 91 parent_dev = __dev_get_by_index(&init_net, dev_get_iflink(net_dev));
91 /* if we got a NULL parent_dev there is something broken.. */ 92 /* if we got a NULL parent_dev there is something broken.. */
92 if (WARN(!parent_dev, "Cannot find parent device")) 93 if (WARN(!parent_dev, "Cannot find parent device"))
93 return false; 94 return false;
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index e1115a224a95..0e4ddb81610d 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -305,8 +305,8 @@ static int br_fill_ifinfo(struct sk_buff *skb,
305 nla_put_u8(skb, IFLA_OPERSTATE, operstate) || 305 nla_put_u8(skb, IFLA_OPERSTATE, operstate) ||
306 (dev->addr_len && 306 (dev->addr_len &&
307 nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) || 307 nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) ||
308 (dev->ifindex != dev->iflink && 308 (dev->ifindex != dev_get_iflink(dev) &&
309 nla_put_u32(skb, IFLA_LINK, dev->iflink))) 309 nla_put_u32(skb, IFLA_LINK, dev_get_iflink(dev))))
310 goto nla_put_failure; 310 goto nla_put_failure;
311 311
312 if (event == RTM_NEWLINK && port) { 312 if (event == RTM_NEWLINK && port) {
diff --git a/net/core/dev.c b/net/core/dev.c
index 65492b0354c0..26622d614f81 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -660,6 +660,27 @@ __setup("netdev=", netdev_boot_setup);
660*******************************************************************************/ 660*******************************************************************************/
661 661
662/** 662/**
663 * dev_get_iflink - get 'iflink' value of a interface
664 * @dev: targeted interface
665 *
666 * Indicates the ifindex the interface is linked to.
667 * Physical interfaces have the same 'ifindex' and 'iflink' values.
668 */
669
670int dev_get_iflink(const struct net_device *dev)
671{
672 if (dev->netdev_ops && dev->netdev_ops->ndo_get_iflink)
673 return dev->netdev_ops->ndo_get_iflink(dev);
674
675 /* If dev->rtnl_link_ops is set, it's a virtual interface. */
676 if (dev->rtnl_link_ops)
677 return 0;
678
679 return dev->ifindex;
680}
681EXPORT_SYMBOL(dev_get_iflink);
682
683/**
663 * __dev_get_by_name - find a device by its name 684 * __dev_get_by_name - find a device by its name
664 * @net: the applicable net namespace 685 * @net: the applicable net namespace
665 * @name: name to find 686 * @name: name to find
@@ -6314,8 +6335,6 @@ int register_netdevice(struct net_device *dev)
6314 spin_lock_init(&dev->addr_list_lock); 6335 spin_lock_init(&dev->addr_list_lock);
6315 netdev_set_addr_lockdep_class(dev); 6336 netdev_set_addr_lockdep_class(dev);
6316 6337
6317 dev->iflink = -1;
6318
6319 ret = dev_get_valid_name(net, dev, dev->name); 6338 ret = dev_get_valid_name(net, dev, dev->name);
6320 if (ret < 0) 6339 if (ret < 0)
6321 goto out; 6340 goto out;
@@ -6345,9 +6364,6 @@ int register_netdevice(struct net_device *dev)
6345 else if (__dev_get_by_index(net, dev->ifindex)) 6364 else if (__dev_get_by_index(net, dev->ifindex))
6346 goto err_uninit; 6365 goto err_uninit;
6347 6366
6348 if (dev->iflink == -1)
6349 dev->iflink = dev->ifindex;
6350
6351 /* Transfer changeable features to wanted_features and enable 6367 /* Transfer changeable features to wanted_features and enable
6352 * software offloads (GSO and GRO). 6368 * software offloads (GSO and GRO).
6353 */ 6369 */
@@ -7060,12 +7076,8 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
7060 dev_net_set(dev, net); 7076 dev_net_set(dev, net);
7061 7077
7062 /* If there is an ifindex conflict assign a new one */ 7078 /* If there is an ifindex conflict assign a new one */
7063 if (__dev_get_by_index(net, dev->ifindex)) { 7079 if (__dev_get_by_index(net, dev->ifindex))
7064 int iflink = (dev->iflink == dev->ifindex);
7065 dev->ifindex = dev_new_index(net); 7080 dev->ifindex = dev_new_index(net);
7066 if (iflink)
7067 dev->iflink = dev->ifindex;
7068 }
7069 7081
7070 /* Send a netdev-add uevent to the new namespace */ 7082 /* Send a netdev-add uevent to the new namespace */
7071 kobject_uevent(&dev->dev.kobj, KOBJ_ADD); 7083 kobject_uevent(&dev->dev.kobj, KOBJ_ADD);
diff --git a/net/core/link_watch.c b/net/core/link_watch.c
index 49a9e3e06c08..982861607f88 100644
--- a/net/core/link_watch.c
+++ b/net/core/link_watch.c
@@ -40,7 +40,7 @@ static DEFINE_SPINLOCK(lweventlist_lock);
40static unsigned char default_operstate(const struct net_device *dev) 40static unsigned char default_operstate(const struct net_device *dev)
41{ 41{
42 if (!netif_carrier_ok(dev)) 42 if (!netif_carrier_ok(dev))
43 return (dev->ifindex != dev->iflink ? 43 return (dev->ifindex != dev_get_iflink(dev) ?
44 IF_OPER_LOWERLAYERDOWN : IF_OPER_DOWN); 44 IF_OPER_LOWERLAYERDOWN : IF_OPER_DOWN);
45 45
46 if (netif_dormant(dev)) 46 if (netif_dormant(dev))
@@ -89,7 +89,7 @@ static bool linkwatch_urgent_event(struct net_device *dev)
89 if (!netif_running(dev)) 89 if (!netif_running(dev))
90 return false; 90 return false;
91 91
92 if (dev->ifindex != dev->iflink) 92 if (dev->ifindex != dev_get_iflink(dev))
93 return true; 93 return true;
94 94
95 if (dev->priv_flags & IFF_TEAM_PORT) 95 if (dev->priv_flags & IFF_TEAM_PORT)
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index cc5cf689809c..4238d6da5c60 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -109,11 +109,19 @@ NETDEVICE_SHOW_RO(dev_id, fmt_hex);
109NETDEVICE_SHOW_RO(dev_port, fmt_dec); 109NETDEVICE_SHOW_RO(dev_port, fmt_dec);
110NETDEVICE_SHOW_RO(addr_assign_type, fmt_dec); 110NETDEVICE_SHOW_RO(addr_assign_type, fmt_dec);
111NETDEVICE_SHOW_RO(addr_len, fmt_dec); 111NETDEVICE_SHOW_RO(addr_len, fmt_dec);
112NETDEVICE_SHOW_RO(iflink, fmt_dec);
113NETDEVICE_SHOW_RO(ifindex, fmt_dec); 112NETDEVICE_SHOW_RO(ifindex, fmt_dec);
114NETDEVICE_SHOW_RO(type, fmt_dec); 113NETDEVICE_SHOW_RO(type, fmt_dec);
115NETDEVICE_SHOW_RO(link_mode, fmt_dec); 114NETDEVICE_SHOW_RO(link_mode, fmt_dec);
116 115
116static ssize_t iflink_show(struct device *dev, struct device_attribute *attr,
117 char *buf)
118{
119 struct net_device *ndev = to_net_dev(dev);
120
121 return sprintf(buf, fmt_dec, dev_get_iflink(ndev));
122}
123static DEVICE_ATTR_RO(iflink);
124
117static ssize_t format_name_assign_type(const struct net_device *dev, char *buf) 125static ssize_t format_name_assign_type(const struct net_device *dev, char *buf)
118{ 126{
119 return sprintf(buf, fmt_dec, dev->name_assign_type); 127 return sprintf(buf, fmt_dec, dev->name_assign_type);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index b96ac2109c82..ee0186cdd5cf 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1055,8 +1055,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
1055#ifdef CONFIG_RPS 1055#ifdef CONFIG_RPS
1056 nla_put_u32(skb, IFLA_NUM_RX_QUEUES, dev->num_rx_queues) || 1056 nla_put_u32(skb, IFLA_NUM_RX_QUEUES, dev->num_rx_queues) ||
1057#endif 1057#endif
1058 (dev->ifindex != dev->iflink && 1058 (dev->ifindex != dev_get_iflink(dev) &&
1059 nla_put_u32(skb, IFLA_LINK, dev->iflink)) || 1059 nla_put_u32(skb, IFLA_LINK, dev_get_iflink(dev))) ||
1060 (upper_dev && 1060 (upper_dev &&
1061 nla_put_u32(skb, IFLA_MASTER, upper_dev->ifindex)) || 1061 nla_put_u32(skb, IFLA_MASTER, upper_dev->ifindex)) ||
1062 nla_put_u8(skb, IFLA_CARRIER, netif_carrier_ok(dev)) || 1062 nla_put_u8(skb, IFLA_CARRIER, netif_carrier_ok(dev)) ||
@@ -2863,8 +2863,8 @@ int ndo_dflt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
2863 nla_put_u32(skb, IFLA_MASTER, br_dev->ifindex)) || 2863 nla_put_u32(skb, IFLA_MASTER, br_dev->ifindex)) ||
2864 (dev->addr_len && 2864 (dev->addr_len &&
2865 nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) || 2865 nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) ||
2866 (dev->ifindex != dev->iflink && 2866 (dev->ifindex != dev_get_iflink(dev) &&
2867 nla_put_u32(skb, IFLA_LINK, dev->iflink))) 2867 nla_put_u32(skb, IFLA_LINK, dev_get_iflink(dev))))
2868 goto nla_put_failure; 2868 goto nla_put_failure;
2869 2869
2870 br_afspec = nla_nest_start(skb, IFLA_AF_SPEC); 2870 br_afspec = nla_nest_start(skb, IFLA_AF_SPEC);
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 3597724ec3d8..827cda560a55 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -55,13 +55,11 @@ void dsa_slave_mii_bus_init(struct dsa_switch *ds)
55 55
56 56
57/* slave device handling ****************************************************/ 57/* slave device handling ****************************************************/
58static int dsa_slave_init(struct net_device *dev) 58static int dsa_slave_get_iflink(const struct net_device *dev)
59{ 59{
60 struct dsa_slave_priv *p = netdev_priv(dev); 60 struct dsa_slave_priv *p = netdev_priv(dev);
61 61
62 dev->iflink = p->parent->dst->master_netdev->ifindex; 62 return p->parent->dst->master_netdev->ifindex;
63
64 return 0;
65} 63}
66 64
67static inline bool dsa_port_is_bridged(struct dsa_slave_priv *p) 65static inline bool dsa_port_is_bridged(struct dsa_slave_priv *p)
@@ -664,7 +662,6 @@ static const struct ethtool_ops dsa_slave_ethtool_ops = {
664}; 662};
665 663
666static const struct net_device_ops dsa_slave_netdev_ops = { 664static const struct net_device_ops dsa_slave_netdev_ops = {
667 .ndo_init = dsa_slave_init,
668 .ndo_open = dsa_slave_open, 665 .ndo_open = dsa_slave_open,
669 .ndo_stop = dsa_slave_close, 666 .ndo_stop = dsa_slave_close,
670 .ndo_start_xmit = dsa_slave_xmit, 667 .ndo_start_xmit = dsa_slave_xmit,
@@ -675,6 +672,7 @@ static const struct net_device_ops dsa_slave_netdev_ops = {
675 .ndo_fdb_del = dsa_slave_fdb_del, 672 .ndo_fdb_del = dsa_slave_fdb_del,
676 .ndo_fdb_dump = dsa_slave_fdb_dump, 673 .ndo_fdb_dump = dsa_slave_fdb_dump,
677 .ndo_do_ioctl = dsa_slave_ioctl, 674 .ndo_do_ioctl = dsa_slave_ioctl,
675 .ndo_get_iflink = dsa_slave_get_iflink,
678}; 676};
679 677
680static const struct swdev_ops dsa_slave_swdev_ops = { 678static const struct swdev_ops dsa_slave_swdev_ops = {
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 0eb2a040a830..1060ca0bc23a 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -456,6 +456,7 @@ static const struct net_device_ops ipgre_netdev_ops = {
456 .ndo_do_ioctl = ipgre_tunnel_ioctl, 456 .ndo_do_ioctl = ipgre_tunnel_ioctl,
457 .ndo_change_mtu = ip_tunnel_change_mtu, 457 .ndo_change_mtu = ip_tunnel_change_mtu,
458 .ndo_get_stats64 = ip_tunnel_get_stats64, 458 .ndo_get_stats64 = ip_tunnel_get_stats64,
459 .ndo_get_iflink = ip_tunnel_get_iflink,
459}; 460};
460 461
461#define GRE_FEATURES (NETIF_F_SG | \ 462#define GRE_FEATURES (NETIF_F_SG | \
@@ -686,6 +687,7 @@ static const struct net_device_ops gre_tap_netdev_ops = {
686 .ndo_validate_addr = eth_validate_addr, 687 .ndo_validate_addr = eth_validate_addr,
687 .ndo_change_mtu = ip_tunnel_change_mtu, 688 .ndo_change_mtu = ip_tunnel_change_mtu,
688 .ndo_get_stats64 = ip_tunnel_get_stats64, 689 .ndo_get_stats64 = ip_tunnel_get_stats64,
690 .ndo_get_iflink = ip_tunnel_get_iflink,
689}; 691};
690 692
691static void ipgre_tap_setup(struct net_device *dev) 693static void ipgre_tap_setup(struct net_device *dev)
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index 2cd08280c77b..4bb7252110a6 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -389,7 +389,6 @@ static int ip_tunnel_bind_dev(struct net_device *dev)
389 hlen = tdev->hard_header_len + tdev->needed_headroom; 389 hlen = tdev->hard_header_len + tdev->needed_headroom;
390 mtu = tdev->mtu; 390 mtu = tdev->mtu;
391 } 391 }
392 dev->iflink = tunnel->parms.link;
393 392
394 dev->needed_headroom = t_hlen + hlen; 393 dev->needed_headroom = t_hlen + hlen;
395 mtu -= (dev->hard_header_len + t_hlen); 394 mtu -= (dev->hard_header_len + t_hlen);
@@ -980,6 +979,14 @@ struct net *ip_tunnel_get_link_net(const struct net_device *dev)
980} 979}
981EXPORT_SYMBOL(ip_tunnel_get_link_net); 980EXPORT_SYMBOL(ip_tunnel_get_link_net);
982 981
982int ip_tunnel_get_iflink(const struct net_device *dev)
983{
984 struct ip_tunnel *tunnel = netdev_priv(dev);
985
986 return tunnel->parms.link;
987}
988EXPORT_SYMBOL(ip_tunnel_get_iflink);
989
983int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id, 990int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
984 struct rtnl_link_ops *ops, char *devname) 991 struct rtnl_link_ops *ops, char *devname)
985{ 992{
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
index 5a6e27054f0a..c4f93c0d1104 100644
--- a/net/ipv4/ip_vti.c
+++ b/net/ipv4/ip_vti.c
@@ -341,6 +341,7 @@ static const struct net_device_ops vti_netdev_ops = {
341 .ndo_do_ioctl = vti_tunnel_ioctl, 341 .ndo_do_ioctl = vti_tunnel_ioctl,
342 .ndo_change_mtu = ip_tunnel_change_mtu, 342 .ndo_change_mtu = ip_tunnel_change_mtu,
343 .ndo_get_stats64 = ip_tunnel_get_stats64, 343 .ndo_get_stats64 = ip_tunnel_get_stats64,
344 .ndo_get_iflink = ip_tunnel_get_iflink,
344}; 345};
345 346
346static void vti_tunnel_setup(struct net_device *dev) 347static void vti_tunnel_setup(struct net_device *dev)
@@ -361,7 +362,6 @@ static int vti_tunnel_init(struct net_device *dev)
361 dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr); 362 dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr);
362 dev->mtu = ETH_DATA_LEN; 363 dev->mtu = ETH_DATA_LEN;
363 dev->flags = IFF_NOARP; 364 dev->flags = IFF_NOARP;
364 dev->iflink = 0;
365 dev->addr_len = 4; 365 dev->addr_len = 4;
366 dev->features |= NETIF_F_LLTX; 366 dev->features |= NETIF_F_LLTX;
367 netif_keep_dst(dev); 367 netif_keep_dst(dev);
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index bfbcc85c02ee..5c81f6e40842 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -272,6 +272,7 @@ static const struct net_device_ops ipip_netdev_ops = {
272 .ndo_do_ioctl = ipip_tunnel_ioctl, 272 .ndo_do_ioctl = ipip_tunnel_ioctl,
273 .ndo_change_mtu = ip_tunnel_change_mtu, 273 .ndo_change_mtu = ip_tunnel_change_mtu,
274 .ndo_get_stats64 = ip_tunnel_get_stats64, 274 .ndo_get_stats64 = ip_tunnel_get_stats64,
275 .ndo_get_iflink = ip_tunnel_get_iflink,
275}; 276};
276 277
277#define IPIP_FEATURES (NETIF_F_SG | \ 278#define IPIP_FEATURES (NETIF_F_SG | \
@@ -286,7 +287,6 @@ static void ipip_tunnel_setup(struct net_device *dev)
286 287
287 dev->type = ARPHRD_TUNNEL; 288 dev->type = ARPHRD_TUNNEL;
288 dev->flags = IFF_NOARP; 289 dev->flags = IFF_NOARP;
289 dev->iflink = 0;
290 dev->addr_len = 4; 290 dev->addr_len = 4;
291 dev->features |= NETIF_F_LLTX; 291 dev->features |= NETIF_F_LLTX;
292 netif_keep_dst(dev); 292 netif_keep_dst(dev);
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index b4a545d24adb..d2e3b3ef039e 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -473,8 +473,14 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, struct net_device *dev)
473 return NETDEV_TX_OK; 473 return NETDEV_TX_OK;
474} 474}
475 475
476static int reg_vif_get_iflink(const struct net_device *dev)
477{
478 return 0;
479}
480
476static const struct net_device_ops reg_vif_netdev_ops = { 481static const struct net_device_ops reg_vif_netdev_ops = {
477 .ndo_start_xmit = reg_vif_xmit, 482 .ndo_start_xmit = reg_vif_xmit,
483 .ndo_get_iflink = reg_vif_get_iflink,
478}; 484};
479 485
480static void reg_vif_setup(struct net_device *dev) 486static void reg_vif_setup(struct net_device *dev)
@@ -509,7 +515,6 @@ static struct net_device *ipmr_reg_vif(struct net *net, struct mr_table *mrt)
509 free_netdev(dev); 515 free_netdev(dev);
510 return NULL; 516 return NULL;
511 } 517 }
512 dev->iflink = 0;
513 518
514 rcu_read_lock(); 519 rcu_read_lock();
515 in_dev = __in_dev_get_rcu(dev); 520 in_dev = __in_dev_get_rcu(dev);
@@ -801,7 +806,7 @@ static int vif_add(struct net *net, struct mr_table *mrt,
801 v->pkt_out = 0; 806 v->pkt_out = 0;
802 v->link = dev->ifindex; 807 v->link = dev->ifindex;
803 if (v->flags & (VIFF_TUNNEL | VIFF_REGISTER)) 808 if (v->flags & (VIFF_TUNNEL | VIFF_REGISTER))
804 v->link = dev->iflink; 809 v->link = dev_get_iflink(dev);
805 810
806 /* And finish update writing critical data */ 811 /* And finish update writing critical data */
807 write_lock_bh(&mrt_lock); 812 write_lock_bh(&mrt_lock);
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 5c9e94cb1b2c..37b70e82bff8 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -4858,8 +4858,8 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
4858 (dev->addr_len && 4858 (dev->addr_len &&
4859 nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) || 4859 nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) ||
4860 nla_put_u32(skb, IFLA_MTU, dev->mtu) || 4860 nla_put_u32(skb, IFLA_MTU, dev->mtu) ||
4861 (dev->ifindex != dev->iflink && 4861 (dev->ifindex != dev_get_iflink(dev) &&
4862 nla_put_u32(skb, IFLA_LINK, dev->iflink))) 4862 nla_put_u32(skb, IFLA_LINK, dev_get_iflink(dev))))
4863 goto nla_put_failure; 4863 goto nla_put_failure;
4864 protoinfo = nla_nest_start(skb, IFLA_PROTINFO); 4864 protoinfo = nla_nest_start(skb, IFLA_PROTINFO);
4865 if (!protoinfo) 4865 if (!protoinfo)
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 0f4e73da14e4..f724329d7436 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -1216,6 +1216,7 @@ static const struct net_device_ops ip6gre_netdev_ops = {
1216 .ndo_do_ioctl = ip6gre_tunnel_ioctl, 1216 .ndo_do_ioctl = ip6gre_tunnel_ioctl,
1217 .ndo_change_mtu = ip6gre_tunnel_change_mtu, 1217 .ndo_change_mtu = ip6gre_tunnel_change_mtu,
1218 .ndo_get_stats64 = ip_tunnel_get_stats64, 1218 .ndo_get_stats64 = ip_tunnel_get_stats64,
1219 .ndo_get_iflink = ip6_tnl_get_iflink,
1219}; 1220};
1220 1221
1221static void ip6gre_dev_free(struct net_device *dev) 1222static void ip6gre_dev_free(struct net_device *dev)
@@ -1238,7 +1239,6 @@ static void ip6gre_tunnel_setup(struct net_device *dev)
1238 if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) 1239 if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
1239 dev->mtu -= 8; 1240 dev->mtu -= 8;
1240 dev->flags |= IFF_NOARP; 1241 dev->flags |= IFF_NOARP;
1241 dev->iflink = 0;
1242 dev->addr_len = sizeof(struct in6_addr); 1242 dev->addr_len = sizeof(struct in6_addr);
1243 netif_keep_dst(dev); 1243 netif_keep_dst(dev);
1244} 1244}
@@ -1270,8 +1270,6 @@ static int ip6gre_tunnel_init(struct net_device *dev)
1270 u64_stats_init(&ip6gre_tunnel_stats->syncp); 1270 u64_stats_init(&ip6gre_tunnel_stats->syncp);
1271 } 1271 }
1272 1272
1273 dev->iflink = tunnel->parms.link;
1274
1275 return 0; 1273 return 0;
1276} 1274}
1277 1275
@@ -1480,8 +1478,6 @@ static int ip6gre_tap_init(struct net_device *dev)
1480 if (!dev->tstats) 1478 if (!dev->tstats)
1481 return -ENOMEM; 1479 return -ENOMEM;
1482 1480
1483 dev->iflink = tunnel->parms.link;
1484
1485 return 0; 1481 return 0;
1486} 1482}
1487 1483
@@ -1493,6 +1489,7 @@ static const struct net_device_ops ip6gre_tap_netdev_ops = {
1493 .ndo_validate_addr = eth_validate_addr, 1489 .ndo_validate_addr = eth_validate_addr,
1494 .ndo_change_mtu = ip6gre_tunnel_change_mtu, 1490 .ndo_change_mtu = ip6gre_tunnel_change_mtu,
1495 .ndo_get_stats64 = ip_tunnel_get_stats64, 1491 .ndo_get_stats64 = ip_tunnel_get_stats64,
1492 .ndo_get_iflink = ip6_tnl_get_iflink,
1496}; 1493};
1497 1494
1498static void ip6gre_tap_setup(struct net_device *dev) 1495static void ip6gre_tap_setup(struct net_device *dev)
@@ -1503,7 +1500,6 @@ static void ip6gre_tap_setup(struct net_device *dev)
1503 dev->netdev_ops = &ip6gre_tap_netdev_ops; 1500 dev->netdev_ops = &ip6gre_tap_netdev_ops;
1504 dev->destructor = ip6gre_dev_free; 1501 dev->destructor = ip6gre_dev_free;
1505 1502
1506 dev->iflink = 0;
1507 dev->features |= NETIF_F_NETNS_LOCAL; 1503 dev->features |= NETIF_F_NETNS_LOCAL;
1508} 1504}
1509 1505
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 9bd85f0dff69..b6a211a150b2 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1264,8 +1264,6 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
1264 else 1264 else
1265 dev->flags &= ~IFF_POINTOPOINT; 1265 dev->flags &= ~IFF_POINTOPOINT;
1266 1266
1267 dev->iflink = p->link;
1268
1269 if (p->flags & IP6_TNL_F_CAP_XMIT) { 1267 if (p->flags & IP6_TNL_F_CAP_XMIT) {
1270 int strict = (ipv6_addr_type(&p->raddr) & 1268 int strict = (ipv6_addr_type(&p->raddr) &
1271 (IPV6_ADDR_MULTICAST|IPV6_ADDR_LINKLOCAL)); 1269 (IPV6_ADDR_MULTICAST|IPV6_ADDR_LINKLOCAL));
@@ -1517,6 +1515,13 @@ ip6_tnl_change_mtu(struct net_device *dev, int new_mtu)
1517 return 0; 1515 return 0;
1518} 1516}
1519 1517
1518int ip6_tnl_get_iflink(const struct net_device *dev)
1519{
1520 struct ip6_tnl *t = netdev_priv(dev);
1521
1522 return t->parms.link;
1523}
1524EXPORT_SYMBOL(ip6_tnl_get_iflink);
1520 1525
1521static const struct net_device_ops ip6_tnl_netdev_ops = { 1526static const struct net_device_ops ip6_tnl_netdev_ops = {
1522 .ndo_init = ip6_tnl_dev_init, 1527 .ndo_init = ip6_tnl_dev_init,
@@ -1525,6 +1530,7 @@ static const struct net_device_ops ip6_tnl_netdev_ops = {
1525 .ndo_do_ioctl = ip6_tnl_ioctl, 1530 .ndo_do_ioctl = ip6_tnl_ioctl,
1526 .ndo_change_mtu = ip6_tnl_change_mtu, 1531 .ndo_change_mtu = ip6_tnl_change_mtu,
1527 .ndo_get_stats = ip6_get_stats, 1532 .ndo_get_stats = ip6_get_stats,
1533 .ndo_get_iflink = ip6_tnl_get_iflink,
1528}; 1534};
1529 1535
1530 1536
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
index 53d90ed68905..b53148444e15 100644
--- a/net/ipv6/ip6_vti.c
+++ b/net/ipv6/ip6_vti.c
@@ -601,8 +601,6 @@ static void vti6_link_config(struct ip6_tnl *t)
601 dev->flags |= IFF_POINTOPOINT; 601 dev->flags |= IFF_POINTOPOINT;
602 else 602 else
603 dev->flags &= ~IFF_POINTOPOINT; 603 dev->flags &= ~IFF_POINTOPOINT;
604
605 dev->iflink = p->link;
606} 604}
607 605
608/** 606/**
@@ -808,6 +806,7 @@ static const struct net_device_ops vti6_netdev_ops = {
808 .ndo_do_ioctl = vti6_ioctl, 806 .ndo_do_ioctl = vti6_ioctl,
809 .ndo_change_mtu = vti6_change_mtu, 807 .ndo_change_mtu = vti6_change_mtu,
810 .ndo_get_stats64 = ip_tunnel_get_stats64, 808 .ndo_get_stats64 = ip_tunnel_get_stats64,
809 .ndo_get_iflink = ip6_tnl_get_iflink,
811}; 810};
812 811
813/** 812/**
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index caf6b99374e6..003431f5b4b6 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -718,8 +718,14 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb,
718 return NETDEV_TX_OK; 718 return NETDEV_TX_OK;
719} 719}
720 720
721static int reg_vif_get_iflink(const struct net_device *dev)
722{
723 return 0;
724}
725
721static const struct net_device_ops reg_vif_netdev_ops = { 726static const struct net_device_ops reg_vif_netdev_ops = {
722 .ndo_start_xmit = reg_vif_xmit, 727 .ndo_start_xmit = reg_vif_xmit,
728 .ndo_get_iflink = reg_vif_get_iflink,
723}; 729};
724 730
725static void reg_vif_setup(struct net_device *dev) 731static void reg_vif_setup(struct net_device *dev)
@@ -752,7 +758,6 @@ static struct net_device *ip6mr_reg_vif(struct net *net, struct mr6_table *mrt)
752 free_netdev(dev); 758 free_netdev(dev);
753 return NULL; 759 return NULL;
754 } 760 }
755 dev->iflink = 0;
756 761
757 if (dev_open(dev)) 762 if (dev_open(dev))
758 goto failure; 763 goto failure;
@@ -992,7 +997,7 @@ static int mif6_add(struct net *net, struct mr6_table *mrt,
992 v->pkt_out = 0; 997 v->pkt_out = 0;
993 v->link = dev->ifindex; 998 v->link = dev->ifindex;
994 if (v->flags & MIFF_REGISTER) 999 if (v->flags & MIFF_REGISTER)
995 v->link = dev->iflink; 1000 v->link = dev_get_iflink(dev);
996 1001
997 /* And finish update writing critical data */ 1002 /* And finish update writing critical data */
998 write_lock_bh(&mrt_lock); 1003 write_lock_bh(&mrt_lock);
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index e6b9f51b15e8..6cf2026a9cea 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -1076,7 +1076,6 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev)
1076 if (dev->mtu < IPV6_MIN_MTU) 1076 if (dev->mtu < IPV6_MIN_MTU)
1077 dev->mtu = IPV6_MIN_MTU; 1077 dev->mtu = IPV6_MIN_MTU;
1078 } 1078 }
1079 dev->iflink = tunnel->parms.link;
1080} 1079}
1081 1080
1082static void ipip6_tunnel_update(struct ip_tunnel *t, struct ip_tunnel_parm *p) 1081static void ipip6_tunnel_update(struct ip_tunnel *t, struct ip_tunnel_parm *p)
@@ -1336,6 +1335,7 @@ static const struct net_device_ops ipip6_netdev_ops = {
1336 .ndo_do_ioctl = ipip6_tunnel_ioctl, 1335 .ndo_do_ioctl = ipip6_tunnel_ioctl,
1337 .ndo_change_mtu = ipip6_tunnel_change_mtu, 1336 .ndo_change_mtu = ipip6_tunnel_change_mtu,
1338 .ndo_get_stats64 = ip_tunnel_get_stats64, 1337 .ndo_get_stats64 = ip_tunnel_get_stats64,
1338 .ndo_get_iflink = ip_tunnel_get_iflink,
1339}; 1339};
1340 1340
1341static void ipip6_dev_free(struct net_device *dev) 1341static void ipip6_dev_free(struct net_device *dev)
@@ -1366,7 +1366,6 @@ static void ipip6_tunnel_setup(struct net_device *dev)
1366 dev->mtu = ETH_DATA_LEN - t_hlen; 1366 dev->mtu = ETH_DATA_LEN - t_hlen;
1367 dev->flags = IFF_NOARP; 1367 dev->flags = IFF_NOARP;
1368 netif_keep_dst(dev); 1368 netif_keep_dst(dev);
1369 dev->iflink = 0;
1370 dev->addr_len = 4; 1369 dev->addr_len = 4;
1371 dev->features |= NETIF_F_LLTX; 1370 dev->features |= NETIF_F_LLTX;
1372 dev->features |= SIT_FEATURES; 1371 dev->features |= SIT_FEATURES;