diff options
Diffstat (limited to 'net/core/dev.c')
-rw-r--r-- | net/core/dev.c | 109 |
1 files changed, 69 insertions, 40 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 45109b70664e..3b3965288f52 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 | |||
670 | int 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 | } | ||
681 | EXPORT_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 |
@@ -1385,7 +1406,7 @@ static int __dev_close(struct net_device *dev) | |||
1385 | return retval; | 1406 | return retval; |
1386 | } | 1407 | } |
1387 | 1408 | ||
1388 | static int dev_close_many(struct list_head *head) | 1409 | int dev_close_many(struct list_head *head, bool unlink) |
1389 | { | 1410 | { |
1390 | struct net_device *dev, *tmp; | 1411 | struct net_device *dev, *tmp; |
1391 | 1412 | ||
@@ -1399,11 +1420,13 @@ static int dev_close_many(struct list_head *head) | |||
1399 | list_for_each_entry_safe(dev, tmp, head, close_list) { | 1420 | list_for_each_entry_safe(dev, tmp, head, close_list) { |
1400 | rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING, GFP_KERNEL); | 1421 | rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING, GFP_KERNEL); |
1401 | call_netdevice_notifiers(NETDEV_DOWN, dev); | 1422 | call_netdevice_notifiers(NETDEV_DOWN, dev); |
1402 | list_del_init(&dev->close_list); | 1423 | if (unlink) |
1424 | list_del_init(&dev->close_list); | ||
1403 | } | 1425 | } |
1404 | 1426 | ||
1405 | return 0; | 1427 | return 0; |
1406 | } | 1428 | } |
1429 | EXPORT_SYMBOL(dev_close_many); | ||
1407 | 1430 | ||
1408 | /** | 1431 | /** |
1409 | * dev_close - shutdown an interface. | 1432 | * dev_close - shutdown an interface. |
@@ -1420,7 +1443,7 @@ int dev_close(struct net_device *dev) | |||
1420 | LIST_HEAD(single); | 1443 | LIST_HEAD(single); |
1421 | 1444 | ||
1422 | list_add(&dev->close_list, &single); | 1445 | list_add(&dev->close_list, &single); |
1423 | dev_close_many(&single); | 1446 | dev_close_many(&single, true); |
1424 | list_del(&single); | 1447 | list_del(&single); |
1425 | } | 1448 | } |
1426 | return 0; | 1449 | return 0; |
@@ -1694,6 +1717,7 @@ int __dev_forward_skb(struct net_device *dev, struct sk_buff *skb) | |||
1694 | } | 1717 | } |
1695 | 1718 | ||
1696 | skb_scrub_packet(skb, true); | 1719 | skb_scrub_packet(skb, true); |
1720 | skb->priority = 0; | ||
1697 | skb->protocol = eth_type_trans(skb, dev); | 1721 | skb->protocol = eth_type_trans(skb, dev); |
1698 | skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); | 1722 | skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); |
1699 | 1723 | ||
@@ -1737,7 +1761,8 @@ static inline int deliver_skb(struct sk_buff *skb, | |||
1737 | 1761 | ||
1738 | static inline void deliver_ptype_list_skb(struct sk_buff *skb, | 1762 | static inline void deliver_ptype_list_skb(struct sk_buff *skb, |
1739 | struct packet_type **pt, | 1763 | struct packet_type **pt, |
1740 | struct net_device *dev, __be16 type, | 1764 | struct net_device *orig_dev, |
1765 | __be16 type, | ||
1741 | struct list_head *ptype_list) | 1766 | struct list_head *ptype_list) |
1742 | { | 1767 | { |
1743 | struct packet_type *ptype, *pt_prev = *pt; | 1768 | struct packet_type *ptype, *pt_prev = *pt; |
@@ -1746,7 +1771,7 @@ static inline void deliver_ptype_list_skb(struct sk_buff *skb, | |||
1746 | if (ptype->type != type) | 1771 | if (ptype->type != type) |
1747 | continue; | 1772 | continue; |
1748 | if (pt_prev) | 1773 | if (pt_prev) |
1749 | deliver_skb(skb, pt_prev, dev); | 1774 | deliver_skb(skb, pt_prev, orig_dev); |
1750 | pt_prev = ptype; | 1775 | pt_prev = ptype; |
1751 | } | 1776 | } |
1752 | *pt = pt_prev; | 1777 | *pt = pt_prev; |
@@ -2559,12 +2584,26 @@ static netdev_features_t harmonize_features(struct sk_buff *skb, | |||
2559 | return features; | 2584 | return features; |
2560 | } | 2585 | } |
2561 | 2586 | ||
2587 | netdev_features_t passthru_features_check(struct sk_buff *skb, | ||
2588 | struct net_device *dev, | ||
2589 | netdev_features_t features) | ||
2590 | { | ||
2591 | return features; | ||
2592 | } | ||
2593 | EXPORT_SYMBOL(passthru_features_check); | ||
2594 | |||
2595 | static netdev_features_t dflt_features_check(const struct sk_buff *skb, | ||
2596 | struct net_device *dev, | ||
2597 | netdev_features_t features) | ||
2598 | { | ||
2599 | return vlan_features_check(skb, features); | ||
2600 | } | ||
2601 | |||
2562 | netdev_features_t netif_skb_features(struct sk_buff *skb) | 2602 | netdev_features_t netif_skb_features(struct sk_buff *skb) |
2563 | { | 2603 | { |
2564 | struct net_device *dev = skb->dev; | 2604 | struct net_device *dev = skb->dev; |
2565 | netdev_features_t features = dev->features; | 2605 | netdev_features_t features = dev->features; |
2566 | u16 gso_segs = skb_shinfo(skb)->gso_segs; | 2606 | u16 gso_segs = skb_shinfo(skb)->gso_segs; |
2567 | __be16 protocol = skb->protocol; | ||
2568 | 2607 | ||
2569 | if (gso_segs > dev->gso_max_segs || gso_segs < dev->gso_min_segs) | 2608 | if (gso_segs > dev->gso_max_segs || gso_segs < dev->gso_min_segs) |
2570 | features &= ~NETIF_F_GSO_MASK; | 2609 | features &= ~NETIF_F_GSO_MASK; |
@@ -2576,34 +2615,17 @@ netdev_features_t netif_skb_features(struct sk_buff *skb) | |||
2576 | if (skb->encapsulation) | 2615 | if (skb->encapsulation) |
2577 | features &= dev->hw_enc_features; | 2616 | features &= dev->hw_enc_features; |
2578 | 2617 | ||
2579 | if (!skb_vlan_tag_present(skb)) { | 2618 | if (skb_vlan_tagged(skb)) |
2580 | if (unlikely(protocol == htons(ETH_P_8021Q) || | ||
2581 | protocol == htons(ETH_P_8021AD))) { | ||
2582 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; | ||
2583 | protocol = veh->h_vlan_encapsulated_proto; | ||
2584 | } else { | ||
2585 | goto finalize; | ||
2586 | } | ||
2587 | } | ||
2588 | |||
2589 | features = netdev_intersect_features(features, | ||
2590 | dev->vlan_features | | ||
2591 | NETIF_F_HW_VLAN_CTAG_TX | | ||
2592 | NETIF_F_HW_VLAN_STAG_TX); | ||
2593 | |||
2594 | if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD)) | ||
2595 | features = netdev_intersect_features(features, | 2619 | features = netdev_intersect_features(features, |
2596 | NETIF_F_SG | | 2620 | dev->vlan_features | |
2597 | NETIF_F_HIGHDMA | | ||
2598 | NETIF_F_FRAGLIST | | ||
2599 | NETIF_F_GEN_CSUM | | ||
2600 | NETIF_F_HW_VLAN_CTAG_TX | | 2621 | NETIF_F_HW_VLAN_CTAG_TX | |
2601 | NETIF_F_HW_VLAN_STAG_TX); | 2622 | NETIF_F_HW_VLAN_STAG_TX); |
2602 | 2623 | ||
2603 | finalize: | ||
2604 | if (dev->netdev_ops->ndo_features_check) | 2624 | if (dev->netdev_ops->ndo_features_check) |
2605 | features &= dev->netdev_ops->ndo_features_check(skb, dev, | 2625 | features &= dev->netdev_ops->ndo_features_check(skb, dev, |
2606 | features); | 2626 | features); |
2627 | else | ||
2628 | features &= dflt_features_check(skb, dev, features); | ||
2607 | 2629 | ||
2608 | return harmonize_features(skb, features); | 2630 | return harmonize_features(skb, features); |
2609 | } | 2631 | } |
@@ -5914,6 +5936,24 @@ int dev_get_phys_port_id(struct net_device *dev, | |||
5914 | EXPORT_SYMBOL(dev_get_phys_port_id); | 5936 | EXPORT_SYMBOL(dev_get_phys_port_id); |
5915 | 5937 | ||
5916 | /** | 5938 | /** |
5939 | * dev_get_phys_port_name - Get device physical port name | ||
5940 | * @dev: device | ||
5941 | * @name: port name | ||
5942 | * | ||
5943 | * Get device physical port name | ||
5944 | */ | ||
5945 | int dev_get_phys_port_name(struct net_device *dev, | ||
5946 | char *name, size_t len) | ||
5947 | { | ||
5948 | const struct net_device_ops *ops = dev->netdev_ops; | ||
5949 | |||
5950 | if (!ops->ndo_get_phys_port_name) | ||
5951 | return -EOPNOTSUPP; | ||
5952 | return ops->ndo_get_phys_port_name(dev, name, len); | ||
5953 | } | ||
5954 | EXPORT_SYMBOL(dev_get_phys_port_name); | ||
5955 | |||
5956 | /** | ||
5917 | * dev_new_index - allocate an ifindex | 5957 | * dev_new_index - allocate an ifindex |
5918 | * @net: the applicable net namespace | 5958 | * @net: the applicable net namespace |
5919 | * | 5959 | * |
@@ -5970,7 +6010,7 @@ static void rollback_registered_many(struct list_head *head) | |||
5970 | /* If device is running, close it first. */ | 6010 | /* If device is running, close it first. */ |
5971 | list_for_each_entry(dev, head, unreg_list) | 6011 | list_for_each_entry(dev, head, unreg_list) |
5972 | list_add_tail(&dev->close_list, &close_head); | 6012 | list_add_tail(&dev->close_list, &close_head); |
5973 | dev_close_many(&close_head); | 6013 | dev_close_many(&close_head, true); |
5974 | 6014 | ||
5975 | list_for_each_entry(dev, head, unreg_list) { | 6015 | list_for_each_entry(dev, head, unreg_list) { |
5976 | /* And unlink it from device chain. */ | 6016 | /* And unlink it from device chain. */ |
@@ -6297,8 +6337,6 @@ int register_netdevice(struct net_device *dev) | |||
6297 | spin_lock_init(&dev->addr_list_lock); | 6337 | spin_lock_init(&dev->addr_list_lock); |
6298 | netdev_set_addr_lockdep_class(dev); | 6338 | netdev_set_addr_lockdep_class(dev); |
6299 | 6339 | ||
6300 | dev->iflink = -1; | ||
6301 | |||
6302 | ret = dev_get_valid_name(net, dev, dev->name); | 6340 | ret = dev_get_valid_name(net, dev, dev->name); |
6303 | if (ret < 0) | 6341 | if (ret < 0) |
6304 | goto out; | 6342 | goto out; |
@@ -6328,9 +6366,6 @@ int register_netdevice(struct net_device *dev) | |||
6328 | else if (__dev_get_by_index(net, dev->ifindex)) | 6366 | else if (__dev_get_by_index(net, dev->ifindex)) |
6329 | goto err_uninit; | 6367 | goto err_uninit; |
6330 | 6368 | ||
6331 | if (dev->iflink == -1) | ||
6332 | dev->iflink = dev->ifindex; | ||
6333 | |||
6334 | /* Transfer changeable features to wanted_features and enable | 6369 | /* Transfer changeable features to wanted_features and enable |
6335 | * software offloads (GSO and GRO). | 6370 | * software offloads (GSO and GRO). |
6336 | */ | 6371 | */ |
@@ -6843,8 +6878,6 @@ void free_netdev(struct net_device *dev) | |||
6843 | { | 6878 | { |
6844 | struct napi_struct *p, *n; | 6879 | struct napi_struct *p, *n; |
6845 | 6880 | ||
6846 | release_net(dev_net(dev)); | ||
6847 | |||
6848 | netif_free_tx_queues(dev); | 6881 | netif_free_tx_queues(dev); |
6849 | #ifdef CONFIG_SYSFS | 6882 | #ifdef CONFIG_SYSFS |
6850 | kvfree(dev->_rx); | 6883 | kvfree(dev->_rx); |
@@ -7045,12 +7078,8 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char | |||
7045 | dev_net_set(dev, net); | 7078 | dev_net_set(dev, net); |
7046 | 7079 | ||
7047 | /* If there is an ifindex conflict assign a new one */ | 7080 | /* If there is an ifindex conflict assign a new one */ |
7048 | if (__dev_get_by_index(net, dev->ifindex)) { | 7081 | if (__dev_get_by_index(net, dev->ifindex)) |
7049 | int iflink = (dev->iflink == dev->ifindex); | ||
7050 | dev->ifindex = dev_new_index(net); | 7082 | dev->ifindex = dev_new_index(net); |
7051 | if (iflink) | ||
7052 | dev->iflink = dev->ifindex; | ||
7053 | } | ||
7054 | 7083 | ||
7055 | /* Send a netdev-add uevent to the new namespace */ | 7084 | /* Send a netdev-add uevent to the new namespace */ |
7056 | kobject_uevent(&dev->dev.kobj, KOBJ_ADD); | 7085 | kobject_uevent(&dev->dev.kobj, KOBJ_ADD); |