diff options
Diffstat (limited to 'net/core/dev.c')
-rw-r--r-- | net/core/dev.c | 152 |
1 files changed, 120 insertions, 32 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 722d50dbf8a4..1b5a4410be0e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -145,6 +145,7 @@ | |||
145 | #include <linux/sctp.h> | 145 | #include <linux/sctp.h> |
146 | #include <net/udp_tunnel.h> | 146 | #include <net/udp_tunnel.h> |
147 | #include <linux/net_namespace.h> | 147 | #include <linux/net_namespace.h> |
148 | #include <linux/indirect_call_wrapper.h> | ||
148 | 149 | ||
149 | #include "net-sysfs.h" | 150 | #include "net-sysfs.h" |
150 | 151 | ||
@@ -162,6 +163,9 @@ static struct list_head offload_base __read_mostly; | |||
162 | static int netif_rx_internal(struct sk_buff *skb); | 163 | static int netif_rx_internal(struct sk_buff *skb); |
163 | static int call_netdevice_notifiers_info(unsigned long val, | 164 | static int call_netdevice_notifiers_info(unsigned long val, |
164 | struct netdev_notifier_info *info); | 165 | struct netdev_notifier_info *info); |
166 | static int call_netdevice_notifiers_extack(unsigned long val, | ||
167 | struct net_device *dev, | ||
168 | struct netlink_ext_ack *extack); | ||
165 | static struct napi_struct *napi_by_id(unsigned int napi_id); | 169 | static struct napi_struct *napi_by_id(unsigned int napi_id); |
166 | 170 | ||
167 | /* | 171 | /* |
@@ -1361,7 +1365,7 @@ void netdev_notify_peers(struct net_device *dev) | |||
1361 | } | 1365 | } |
1362 | EXPORT_SYMBOL(netdev_notify_peers); | 1366 | EXPORT_SYMBOL(netdev_notify_peers); |
1363 | 1367 | ||
1364 | static int __dev_open(struct net_device *dev) | 1368 | static int __dev_open(struct net_device *dev, struct netlink_ext_ack *extack) |
1365 | { | 1369 | { |
1366 | const struct net_device_ops *ops = dev->netdev_ops; | 1370 | const struct net_device_ops *ops = dev->netdev_ops; |
1367 | int ret; | 1371 | int ret; |
@@ -1377,7 +1381,7 @@ static int __dev_open(struct net_device *dev) | |||
1377 | */ | 1381 | */ |
1378 | netpoll_poll_disable(dev); | 1382 | netpoll_poll_disable(dev); |
1379 | 1383 | ||
1380 | ret = call_netdevice_notifiers(NETDEV_PRE_UP, dev); | 1384 | ret = call_netdevice_notifiers_extack(NETDEV_PRE_UP, dev, extack); |
1381 | ret = notifier_to_errno(ret); | 1385 | ret = notifier_to_errno(ret); |
1382 | if (ret) | 1386 | if (ret) |
1383 | return ret; | 1387 | return ret; |
@@ -1406,7 +1410,8 @@ static int __dev_open(struct net_device *dev) | |||
1406 | 1410 | ||
1407 | /** | 1411 | /** |
1408 | * dev_open - prepare an interface for use. | 1412 | * dev_open - prepare an interface for use. |
1409 | * @dev: device to open | 1413 | * @dev: device to open |
1414 | * @extack: netlink extended ack | ||
1410 | * | 1415 | * |
1411 | * Takes a device from down to up state. The device's private open | 1416 | * Takes a device from down to up state. The device's private open |
1412 | * function is invoked and then the multicast lists are loaded. Finally | 1417 | * function is invoked and then the multicast lists are loaded. Finally |
@@ -1416,14 +1421,14 @@ static int __dev_open(struct net_device *dev) | |||
1416 | * Calling this function on an active interface is a nop. On a failure | 1421 | * Calling this function on an active interface is a nop. On a failure |
1417 | * a negative errno code is returned. | 1422 | * a negative errno code is returned. |
1418 | */ | 1423 | */ |
1419 | int dev_open(struct net_device *dev) | 1424 | int dev_open(struct net_device *dev, struct netlink_ext_ack *extack) |
1420 | { | 1425 | { |
1421 | int ret; | 1426 | int ret; |
1422 | 1427 | ||
1423 | if (dev->flags & IFF_UP) | 1428 | if (dev->flags & IFF_UP) |
1424 | return 0; | 1429 | return 0; |
1425 | 1430 | ||
1426 | ret = __dev_open(dev); | 1431 | ret = __dev_open(dev, extack); |
1427 | if (ret < 0) | 1432 | if (ret < 0) |
1428 | return ret; | 1433 | return ret; |
1429 | 1434 | ||
@@ -1585,6 +1590,7 @@ const char *netdev_cmd_to_name(enum netdev_cmd cmd) | |||
1585 | N(UDP_TUNNEL_DROP_INFO) N(CHANGE_TX_QUEUE_LEN) | 1590 | N(UDP_TUNNEL_DROP_INFO) N(CHANGE_TX_QUEUE_LEN) |
1586 | N(CVLAN_FILTER_PUSH_INFO) N(CVLAN_FILTER_DROP_INFO) | 1591 | N(CVLAN_FILTER_PUSH_INFO) N(CVLAN_FILTER_DROP_INFO) |
1587 | N(SVLAN_FILTER_PUSH_INFO) N(SVLAN_FILTER_DROP_INFO) | 1592 | N(SVLAN_FILTER_PUSH_INFO) N(SVLAN_FILTER_DROP_INFO) |
1593 | N(PRE_CHANGEADDR) | ||
1588 | } | 1594 | } |
1589 | #undef N | 1595 | #undef N |
1590 | return "UNKNOWN_NETDEV_EVENT"; | 1596 | return "UNKNOWN_NETDEV_EVENT"; |
@@ -1733,6 +1739,18 @@ static int call_netdevice_notifiers_info(unsigned long val, | |||
1733 | return raw_notifier_call_chain(&netdev_chain, val, info); | 1739 | return raw_notifier_call_chain(&netdev_chain, val, info); |
1734 | } | 1740 | } |
1735 | 1741 | ||
1742 | static int call_netdevice_notifiers_extack(unsigned long val, | ||
1743 | struct net_device *dev, | ||
1744 | struct netlink_ext_ack *extack) | ||
1745 | { | ||
1746 | struct netdev_notifier_info info = { | ||
1747 | .dev = dev, | ||
1748 | .extack = extack, | ||
1749 | }; | ||
1750 | |||
1751 | return call_netdevice_notifiers_info(val, &info); | ||
1752 | } | ||
1753 | |||
1736 | /** | 1754 | /** |
1737 | * call_netdevice_notifiers - call all network notifier blocks | 1755 | * call_netdevice_notifiers - call all network notifier blocks |
1738 | * @val: value passed unmodified to notifier function | 1756 | * @val: value passed unmodified to notifier function |
@@ -1744,11 +1762,7 @@ static int call_netdevice_notifiers_info(unsigned long val, | |||
1744 | 1762 | ||
1745 | int call_netdevice_notifiers(unsigned long val, struct net_device *dev) | 1763 | int call_netdevice_notifiers(unsigned long val, struct net_device *dev) |
1746 | { | 1764 | { |
1747 | struct netdev_notifier_info info = { | 1765 | return call_netdevice_notifiers_extack(val, dev, NULL); |
1748 | .dev = dev, | ||
1749 | }; | ||
1750 | |||
1751 | return call_netdevice_notifiers_info(val, &info); | ||
1752 | } | 1766 | } |
1753 | EXPORT_SYMBOL(call_netdevice_notifiers); | 1767 | EXPORT_SYMBOL(call_netdevice_notifiers); |
1754 | 1768 | ||
@@ -3096,10 +3110,17 @@ EXPORT_SYMBOL(__skb_gso_segment); | |||
3096 | 3110 | ||
3097 | /* Take action when hardware reception checksum errors are detected. */ | 3111 | /* Take action when hardware reception checksum errors are detected. */ |
3098 | #ifdef CONFIG_BUG | 3112 | #ifdef CONFIG_BUG |
3099 | void netdev_rx_csum_fault(struct net_device *dev) | 3113 | void netdev_rx_csum_fault(struct net_device *dev, struct sk_buff *skb) |
3100 | { | 3114 | { |
3101 | if (net_ratelimit()) { | 3115 | if (net_ratelimit()) { |
3102 | pr_err("%s: hw csum failure\n", dev ? dev->name : "<unknown>"); | 3116 | pr_err("%s: hw csum failure\n", dev ? dev->name : "<unknown>"); |
3117 | if (dev) | ||
3118 | pr_err("dev features: %pNF\n", &dev->features); | ||
3119 | pr_err("skb len=%u data_len=%u pkt_type=%u gso_size=%u gso_type=%u nr_frags=%u ip_summed=%u csum=%x csum_complete_sw=%d csum_valid=%d csum_level=%u\n", | ||
3120 | skb->len, skb->data_len, skb->pkt_type, | ||
3121 | skb_shinfo(skb)->gso_size, skb_shinfo(skb)->gso_type, | ||
3122 | skb_shinfo(skb)->nr_frags, skb->ip_summed, skb->csum, | ||
3123 | skb->csum_complete_sw, skb->csum_valid, skb->csum_level); | ||
3103 | dump_stack(); | 3124 | dump_stack(); |
3104 | } | 3125 | } |
3105 | } | 3126 | } |
@@ -4525,9 +4546,14 @@ static int netif_rx_internal(struct sk_buff *skb) | |||
4525 | 4546 | ||
4526 | int netif_rx(struct sk_buff *skb) | 4547 | int netif_rx(struct sk_buff *skb) |
4527 | { | 4548 | { |
4549 | int ret; | ||
4550 | |||
4528 | trace_netif_rx_entry(skb); | 4551 | trace_netif_rx_entry(skb); |
4529 | 4552 | ||
4530 | return netif_rx_internal(skb); | 4553 | ret = netif_rx_internal(skb); |
4554 | trace_netif_rx_exit(ret); | ||
4555 | |||
4556 | return ret; | ||
4531 | } | 4557 | } |
4532 | EXPORT_SYMBOL(netif_rx); | 4558 | EXPORT_SYMBOL(netif_rx); |
4533 | 4559 | ||
@@ -4542,6 +4568,7 @@ int netif_rx_ni(struct sk_buff *skb) | |||
4542 | if (local_softirq_pending()) | 4568 | if (local_softirq_pending()) |
4543 | do_softirq(); | 4569 | do_softirq(); |
4544 | preempt_enable(); | 4570 | preempt_enable(); |
4571 | trace_netif_rx_ni_exit(err); | ||
4545 | 4572 | ||
4546 | return err; | 4573 | return err; |
4547 | } | 4574 | } |
@@ -4894,7 +4921,7 @@ skip_classify: | |||
4894 | * and set skb->priority like in vlan_do_receive() | 4921 | * and set skb->priority like in vlan_do_receive() |
4895 | * For the time being, just ignore Priority Code Point | 4922 | * For the time being, just ignore Priority Code Point |
4896 | */ | 4923 | */ |
4897 | skb->vlan_tci = 0; | 4924 | __vlan_hwaccel_clear_tag(skb); |
4898 | } | 4925 | } |
4899 | 4926 | ||
4900 | type = skb->protocol; | 4927 | type = skb->protocol; |
@@ -5227,9 +5254,14 @@ static void netif_receive_skb_list_internal(struct list_head *head) | |||
5227 | */ | 5254 | */ |
5228 | int netif_receive_skb(struct sk_buff *skb) | 5255 | int netif_receive_skb(struct sk_buff *skb) |
5229 | { | 5256 | { |
5257 | int ret; | ||
5258 | |||
5230 | trace_netif_receive_skb_entry(skb); | 5259 | trace_netif_receive_skb_entry(skb); |
5231 | 5260 | ||
5232 | return netif_receive_skb_internal(skb); | 5261 | ret = netif_receive_skb_internal(skb); |
5262 | trace_netif_receive_skb_exit(ret); | ||
5263 | |||
5264 | return ret; | ||
5233 | } | 5265 | } |
5234 | EXPORT_SYMBOL(netif_receive_skb); | 5266 | EXPORT_SYMBOL(netif_receive_skb); |
5235 | 5267 | ||
@@ -5249,9 +5281,12 @@ void netif_receive_skb_list(struct list_head *head) | |||
5249 | 5281 | ||
5250 | if (list_empty(head)) | 5282 | if (list_empty(head)) |
5251 | return; | 5283 | return; |
5252 | list_for_each_entry(skb, head, list) | 5284 | if (trace_netif_receive_skb_list_entry_enabled()) { |
5253 | trace_netif_receive_skb_list_entry(skb); | 5285 | list_for_each_entry(skb, head, list) |
5286 | trace_netif_receive_skb_list_entry(skb); | ||
5287 | } | ||
5254 | netif_receive_skb_list_internal(head); | 5288 | netif_receive_skb_list_internal(head); |
5289 | trace_netif_receive_skb_list_exit(0); | ||
5255 | } | 5290 | } |
5256 | EXPORT_SYMBOL(netif_receive_skb_list); | 5291 | EXPORT_SYMBOL(netif_receive_skb_list); |
5257 | 5292 | ||
@@ -5304,6 +5339,8 @@ static void flush_all_backlogs(void) | |||
5304 | put_online_cpus(); | 5339 | put_online_cpus(); |
5305 | } | 5340 | } |
5306 | 5341 | ||
5342 | INDIRECT_CALLABLE_DECLARE(int inet_gro_complete(struct sk_buff *, int)); | ||
5343 | INDIRECT_CALLABLE_DECLARE(int ipv6_gro_complete(struct sk_buff *, int)); | ||
5307 | static int napi_gro_complete(struct sk_buff *skb) | 5344 | static int napi_gro_complete(struct sk_buff *skb) |
5308 | { | 5345 | { |
5309 | struct packet_offload *ptype; | 5346 | struct packet_offload *ptype; |
@@ -5323,7 +5360,9 @@ static int napi_gro_complete(struct sk_buff *skb) | |||
5323 | if (ptype->type != type || !ptype->callbacks.gro_complete) | 5360 | if (ptype->type != type || !ptype->callbacks.gro_complete) |
5324 | continue; | 5361 | continue; |
5325 | 5362 | ||
5326 | err = ptype->callbacks.gro_complete(skb, 0); | 5363 | err = INDIRECT_CALL_INET(ptype->callbacks.gro_complete, |
5364 | ipv6_gro_complete, inet_gro_complete, | ||
5365 | skb, 0); | ||
5327 | break; | 5366 | break; |
5328 | } | 5367 | } |
5329 | rcu_read_unlock(); | 5368 | rcu_read_unlock(); |
@@ -5362,11 +5401,13 @@ static void __napi_gro_flush_chain(struct napi_struct *napi, u32 index, | |||
5362 | */ | 5401 | */ |
5363 | void napi_gro_flush(struct napi_struct *napi, bool flush_old) | 5402 | void napi_gro_flush(struct napi_struct *napi, bool flush_old) |
5364 | { | 5403 | { |
5365 | u32 i; | 5404 | unsigned long bitmask = napi->gro_bitmask; |
5405 | unsigned int i, base = ~0U; | ||
5366 | 5406 | ||
5367 | for (i = 0; i < GRO_HASH_BUCKETS; i++) { | 5407 | while ((i = ffs(bitmask)) != 0) { |
5368 | if (test_bit(i, &napi->gro_bitmask)) | 5408 | bitmask >>= i; |
5369 | __napi_gro_flush_chain(napi, i, flush_old); | 5409 | base += i; |
5410 | __napi_gro_flush_chain(napi, base, flush_old); | ||
5370 | } | 5411 | } |
5371 | } | 5412 | } |
5372 | EXPORT_SYMBOL(napi_gro_flush); | 5413 | EXPORT_SYMBOL(napi_gro_flush); |
@@ -5391,7 +5432,9 @@ static struct list_head *gro_list_prepare(struct napi_struct *napi, | |||
5391 | } | 5432 | } |
5392 | 5433 | ||
5393 | diffs = (unsigned long)p->dev ^ (unsigned long)skb->dev; | 5434 | diffs = (unsigned long)p->dev ^ (unsigned long)skb->dev; |
5394 | diffs |= p->vlan_tci ^ skb->vlan_tci; | 5435 | diffs |= skb_vlan_tag_present(p) ^ skb_vlan_tag_present(skb); |
5436 | if (skb_vlan_tag_present(p)) | ||
5437 | diffs |= p->vlan_tci ^ skb->vlan_tci; | ||
5395 | diffs |= skb_metadata_dst_cmp(p, skb); | 5438 | diffs |= skb_metadata_dst_cmp(p, skb); |
5396 | diffs |= skb_metadata_differs(p, skb); | 5439 | diffs |= skb_metadata_differs(p, skb); |
5397 | if (maclen == ETH_HLEN) | 5440 | if (maclen == ETH_HLEN) |
@@ -5466,6 +5509,10 @@ static void gro_flush_oldest(struct list_head *head) | |||
5466 | napi_gro_complete(oldest); | 5509 | napi_gro_complete(oldest); |
5467 | } | 5510 | } |
5468 | 5511 | ||
5512 | INDIRECT_CALLABLE_DECLARE(struct sk_buff *inet_gro_receive(struct list_head *, | ||
5513 | struct sk_buff *)); | ||
5514 | INDIRECT_CALLABLE_DECLARE(struct sk_buff *ipv6_gro_receive(struct list_head *, | ||
5515 | struct sk_buff *)); | ||
5469 | static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) | 5516 | static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) |
5470 | { | 5517 | { |
5471 | u32 hash = skb_get_hash_raw(skb) & (GRO_HASH_BUCKETS - 1); | 5518 | u32 hash = skb_get_hash_raw(skb) & (GRO_HASH_BUCKETS - 1); |
@@ -5515,7 +5562,9 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff | |||
5515 | NAPI_GRO_CB(skb)->csum_valid = 0; | 5562 | NAPI_GRO_CB(skb)->csum_valid = 0; |
5516 | } | 5563 | } |
5517 | 5564 | ||
5518 | pp = ptype->callbacks.gro_receive(gro_head, skb); | 5565 | pp = INDIRECT_CALL_INET(ptype->callbacks.gro_receive, |
5566 | ipv6_gro_receive, inet_gro_receive, | ||
5567 | gro_head, skb); | ||
5519 | break; | 5568 | break; |
5520 | } | 5569 | } |
5521 | rcu_read_unlock(); | 5570 | rcu_read_unlock(); |
@@ -5639,12 +5688,17 @@ static gro_result_t napi_skb_finish(gro_result_t ret, struct sk_buff *skb) | |||
5639 | 5688 | ||
5640 | gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) | 5689 | gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) |
5641 | { | 5690 | { |
5691 | gro_result_t ret; | ||
5692 | |||
5642 | skb_mark_napi_id(skb, napi); | 5693 | skb_mark_napi_id(skb, napi); |
5643 | trace_napi_gro_receive_entry(skb); | 5694 | trace_napi_gro_receive_entry(skb); |
5644 | 5695 | ||
5645 | skb_gro_reset_offset(skb); | 5696 | skb_gro_reset_offset(skb); |
5646 | 5697 | ||
5647 | return napi_skb_finish(dev_gro_receive(napi, skb), skb); | 5698 | ret = napi_skb_finish(dev_gro_receive(napi, skb), skb); |
5699 | trace_napi_gro_receive_exit(ret); | ||
5700 | |||
5701 | return ret; | ||
5648 | } | 5702 | } |
5649 | EXPORT_SYMBOL(napi_gro_receive); | 5703 | EXPORT_SYMBOL(napi_gro_receive); |
5650 | 5704 | ||
@@ -5657,7 +5711,7 @@ static void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) | |||
5657 | __skb_pull(skb, skb_headlen(skb)); | 5711 | __skb_pull(skb, skb_headlen(skb)); |
5658 | /* restore the reserve we had after netdev_alloc_skb_ip_align() */ | 5712 | /* restore the reserve we had after netdev_alloc_skb_ip_align() */ |
5659 | skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN - skb_headroom(skb)); | 5713 | skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN - skb_headroom(skb)); |
5660 | skb->vlan_tci = 0; | 5714 | __vlan_hwaccel_clear_tag(skb); |
5661 | skb->dev = napi->dev; | 5715 | skb->dev = napi->dev; |
5662 | skb->skb_iif = 0; | 5716 | skb->skb_iif = 0; |
5663 | 5717 | ||
@@ -5762,6 +5816,7 @@ static struct sk_buff *napi_frags_skb(struct napi_struct *napi) | |||
5762 | 5816 | ||
5763 | gro_result_t napi_gro_frags(struct napi_struct *napi) | 5817 | gro_result_t napi_gro_frags(struct napi_struct *napi) |
5764 | { | 5818 | { |
5819 | gro_result_t ret; | ||
5765 | struct sk_buff *skb = napi_frags_skb(napi); | 5820 | struct sk_buff *skb = napi_frags_skb(napi); |
5766 | 5821 | ||
5767 | if (!skb) | 5822 | if (!skb) |
@@ -5769,7 +5824,10 @@ gro_result_t napi_gro_frags(struct napi_struct *napi) | |||
5769 | 5824 | ||
5770 | trace_napi_gro_frags_entry(skb); | 5825 | trace_napi_gro_frags_entry(skb); |
5771 | 5826 | ||
5772 | return napi_frags_finish(napi, skb, dev_gro_receive(napi, skb)); | 5827 | ret = napi_frags_finish(napi, skb, dev_gro_receive(napi, skb)); |
5828 | trace_napi_gro_frags_exit(ret); | ||
5829 | |||
5830 | return ret; | ||
5773 | } | 5831 | } |
5774 | EXPORT_SYMBOL(napi_gro_frags); | 5832 | EXPORT_SYMBOL(napi_gro_frags); |
5775 | 5833 | ||
@@ -5785,10 +5843,11 @@ __sum16 __skb_gro_checksum_complete(struct sk_buff *skb) | |||
5785 | 5843 | ||
5786 | /* NAPI_GRO_CB(skb)->csum holds pseudo checksum */ | 5844 | /* NAPI_GRO_CB(skb)->csum holds pseudo checksum */ |
5787 | sum = csum_fold(csum_add(NAPI_GRO_CB(skb)->csum, wsum)); | 5845 | sum = csum_fold(csum_add(NAPI_GRO_CB(skb)->csum, wsum)); |
5846 | /* See comments in __skb_checksum_complete(). */ | ||
5788 | if (likely(!sum)) { | 5847 | if (likely(!sum)) { |
5789 | if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE) && | 5848 | if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE) && |
5790 | !skb->csum_complete_sw) | 5849 | !skb->csum_complete_sw) |
5791 | netdev_rx_csum_fault(skb->dev); | 5850 | netdev_rx_csum_fault(skb->dev, skb); |
5792 | } | 5851 | } |
5793 | 5852 | ||
5794 | NAPI_GRO_CB(skb)->csum = wsum; | 5853 | NAPI_GRO_CB(skb)->csum = wsum; |
@@ -7467,7 +7526,8 @@ unsigned int dev_get_flags(const struct net_device *dev) | |||
7467 | } | 7526 | } |
7468 | EXPORT_SYMBOL(dev_get_flags); | 7527 | EXPORT_SYMBOL(dev_get_flags); |
7469 | 7528 | ||
7470 | int __dev_change_flags(struct net_device *dev, unsigned int flags) | 7529 | int __dev_change_flags(struct net_device *dev, unsigned int flags, |
7530 | struct netlink_ext_ack *extack) | ||
7471 | { | 7531 | { |
7472 | unsigned int old_flags = dev->flags; | 7532 | unsigned int old_flags = dev->flags; |
7473 | int ret; | 7533 | int ret; |
@@ -7504,7 +7564,7 @@ int __dev_change_flags(struct net_device *dev, unsigned int flags) | |||
7504 | if (old_flags & IFF_UP) | 7564 | if (old_flags & IFF_UP) |
7505 | __dev_close(dev); | 7565 | __dev_close(dev); |
7506 | else | 7566 | else |
7507 | ret = __dev_open(dev); | 7567 | ret = __dev_open(dev, extack); |
7508 | } | 7568 | } |
7509 | 7569 | ||
7510 | if ((flags ^ dev->gflags) & IFF_PROMISC) { | 7570 | if ((flags ^ dev->gflags) & IFF_PROMISC) { |
@@ -7564,16 +7624,18 @@ void __dev_notify_flags(struct net_device *dev, unsigned int old_flags, | |||
7564 | * dev_change_flags - change device settings | 7624 | * dev_change_flags - change device settings |
7565 | * @dev: device | 7625 | * @dev: device |
7566 | * @flags: device state flags | 7626 | * @flags: device state flags |
7627 | * @extack: netlink extended ack | ||
7567 | * | 7628 | * |
7568 | * Change settings on device based state flags. The flags are | 7629 | * Change settings on device based state flags. The flags are |
7569 | * in the userspace exported format. | 7630 | * in the userspace exported format. |
7570 | */ | 7631 | */ |
7571 | int dev_change_flags(struct net_device *dev, unsigned int flags) | 7632 | int dev_change_flags(struct net_device *dev, unsigned int flags, |
7633 | struct netlink_ext_ack *extack) | ||
7572 | { | 7634 | { |
7573 | int ret; | 7635 | int ret; |
7574 | unsigned int changes, old_flags = dev->flags, old_gflags = dev->gflags; | 7636 | unsigned int changes, old_flags = dev->flags, old_gflags = dev->gflags; |
7575 | 7637 | ||
7576 | ret = __dev_change_flags(dev, flags); | 7638 | ret = __dev_change_flags(dev, flags, extack); |
7577 | if (ret < 0) | 7639 | if (ret < 0) |
7578 | return ret; | 7640 | return ret; |
7579 | 7641 | ||
@@ -7706,13 +7768,36 @@ void dev_set_group(struct net_device *dev, int new_group) | |||
7706 | EXPORT_SYMBOL(dev_set_group); | 7768 | EXPORT_SYMBOL(dev_set_group); |
7707 | 7769 | ||
7708 | /** | 7770 | /** |
7771 | * dev_pre_changeaddr_notify - Call NETDEV_PRE_CHANGEADDR. | ||
7772 | * @dev: device | ||
7773 | * @addr: new address | ||
7774 | * @extack: netlink extended ack | ||
7775 | */ | ||
7776 | int dev_pre_changeaddr_notify(struct net_device *dev, const char *addr, | ||
7777 | struct netlink_ext_ack *extack) | ||
7778 | { | ||
7779 | struct netdev_notifier_pre_changeaddr_info info = { | ||
7780 | .info.dev = dev, | ||
7781 | .info.extack = extack, | ||
7782 | .dev_addr = addr, | ||
7783 | }; | ||
7784 | int rc; | ||
7785 | |||
7786 | rc = call_netdevice_notifiers_info(NETDEV_PRE_CHANGEADDR, &info.info); | ||
7787 | return notifier_to_errno(rc); | ||
7788 | } | ||
7789 | EXPORT_SYMBOL(dev_pre_changeaddr_notify); | ||
7790 | |||
7791 | /** | ||
7709 | * dev_set_mac_address - Change Media Access Control Address | 7792 | * dev_set_mac_address - Change Media Access Control Address |
7710 | * @dev: device | 7793 | * @dev: device |
7711 | * @sa: new address | 7794 | * @sa: new address |
7795 | * @extack: netlink extended ack | ||
7712 | * | 7796 | * |
7713 | * Change the hardware (MAC) address of the device | 7797 | * Change the hardware (MAC) address of the device |
7714 | */ | 7798 | */ |
7715 | int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa) | 7799 | int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa, |
7800 | struct netlink_ext_ack *extack) | ||
7716 | { | 7801 | { |
7717 | const struct net_device_ops *ops = dev->netdev_ops; | 7802 | const struct net_device_ops *ops = dev->netdev_ops; |
7718 | int err; | 7803 | int err; |
@@ -7723,6 +7808,9 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa) | |||
7723 | return -EINVAL; | 7808 | return -EINVAL; |
7724 | if (!netif_device_present(dev)) | 7809 | if (!netif_device_present(dev)) |
7725 | return -ENODEV; | 7810 | return -ENODEV; |
7811 | err = dev_pre_changeaddr_notify(dev, sa->sa_data, extack); | ||
7812 | if (err) | ||
7813 | return err; | ||
7726 | err = ops->ndo_set_mac_address(dev, sa); | 7814 | err = ops->ndo_set_mac_address(dev, sa); |
7727 | if (err) | 7815 | if (err) |
7728 | return err; | 7816 | return err; |