| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (c) 2007 Patrick McHardy <kaber@trash.net> |
|---|
| 3 | | - * |
|---|
| 4 | | - * This program is free software; you can redistribute it and/or |
|---|
| 5 | | - * modify it under the terms of the GNU General Public License as |
|---|
| 6 | | - * published by the Free Software Foundation; either version 2 of |
|---|
| 7 | | - * the License, or (at your option) any later version. |
|---|
| 8 | 4 | * |
|---|
| 9 | 5 | * The code this is based on carried the following copyright notice: |
|---|
| 10 | 6 | * --- |
|---|
| .. | .. |
|---|
| 24 | 20 | #include <linux/notifier.h> |
|---|
| 25 | 21 | #include <linux/netdevice.h> |
|---|
| 26 | 22 | #include <linux/etherdevice.h> |
|---|
| 23 | +#include <linux/net_tstamp.h> |
|---|
| 27 | 24 | #include <linux/ethtool.h> |
|---|
| 28 | 25 | #include <linux/if_arp.h> |
|---|
| 29 | 26 | #include <linux/if_vlan.h> |
|---|
| .. | .. |
|---|
| 34 | 31 | #include <net/rtnetlink.h> |
|---|
| 35 | 32 | #include <net/xfrm.h> |
|---|
| 36 | 33 | #include <linux/netpoll.h> |
|---|
| 34 | +#include <linux/phy.h> |
|---|
| 37 | 35 | |
|---|
| 38 | 36 | #define MACVLAN_HASH_BITS 8 |
|---|
| 39 | 37 | #define MACVLAN_HASH_SIZE (1<<MACVLAN_HASH_BITS) |
|---|
| .. | .. |
|---|
| 119 | 117 | return rtnl_dereference(dev->rx_handler_data); |
|---|
| 120 | 118 | } |
|---|
| 121 | 119 | |
|---|
| 122 | | -#define macvlan_port_exists(dev) (dev->priv_flags & IFF_MACVLAN_PORT) |
|---|
| 123 | | - |
|---|
| 124 | 120 | static struct macvlan_dev *macvlan_hash_lookup(const struct macvlan_port *port, |
|---|
| 125 | 121 | const unsigned char *addr) |
|---|
| 126 | 122 | { |
|---|
| 127 | 123 | struct macvlan_dev *vlan; |
|---|
| 128 | 124 | u32 idx = macvlan_eth_hash(addr); |
|---|
| 129 | 125 | |
|---|
| 130 | | - hlist_for_each_entry_rcu(vlan, &port->vlan_hash[idx], hlist) { |
|---|
| 126 | + hlist_for_each_entry_rcu(vlan, &port->vlan_hash[idx], hlist, |
|---|
| 127 | + lockdep_rtnl_is_held()) { |
|---|
| 131 | 128 | if (ether_addr_equal_64bits(vlan->dev->dev_addr, addr)) |
|---|
| 132 | 129 | return vlan; |
|---|
| 133 | 130 | } |
|---|
| .. | .. |
|---|
| 142 | 139 | u32 idx = macvlan_eth_hash(addr); |
|---|
| 143 | 140 | struct hlist_head *h = &vlan->port->vlan_source_hash[idx]; |
|---|
| 144 | 141 | |
|---|
| 145 | | - hlist_for_each_entry_rcu(entry, h, hlist) { |
|---|
| 142 | + hlist_for_each_entry_rcu(entry, h, hlist, lockdep_rtnl_is_held()) { |
|---|
| 146 | 143 | if (ether_addr_equal_64bits(entry->addr, addr) && |
|---|
| 147 | 144 | entry->vlan == vlan) |
|---|
| 148 | 145 | return entry; |
|---|
| .. | .. |
|---|
| 337 | 334 | |
|---|
| 338 | 335 | if (src) |
|---|
| 339 | 336 | dev_put(src->dev); |
|---|
| 340 | | - kfree_skb(skb); |
|---|
| 337 | + consume_skb(skb); |
|---|
| 341 | 338 | |
|---|
| 342 | 339 | cond_resched(); |
|---|
| 343 | 340 | } |
|---|
| .. | .. |
|---|
| 549 | 546 | static inline netdev_tx_t macvlan_netpoll_send_skb(struct macvlan_dev *vlan, struct sk_buff *skb) |
|---|
| 550 | 547 | { |
|---|
| 551 | 548 | #ifdef CONFIG_NET_POLL_CONTROLLER |
|---|
| 552 | | - if (vlan->netpoll) |
|---|
| 553 | | - netpoll_send_skb(vlan->netpoll, skb); |
|---|
| 549 | + return netpoll_send_skb(vlan->netpoll, skb); |
|---|
| 554 | 550 | #else |
|---|
| 555 | 551 | BUG(); |
|---|
| 556 | | -#endif |
|---|
| 557 | 552 | return NETDEV_TX_OK; |
|---|
| 553 | +#endif |
|---|
| 558 | 554 | } |
|---|
| 559 | 555 | |
|---|
| 560 | 556 | static netdev_tx_t macvlan_start_xmit(struct sk_buff *skb, |
|---|
| .. | .. |
|---|
| 752 | 748 | |
|---|
| 753 | 749 | if (vlan->mode == MACVLAN_MODE_PASSTHRU) { |
|---|
| 754 | 750 | macvlan_set_addr_change(vlan->port); |
|---|
| 755 | | - return dev_set_mac_address(vlan->lowerdev, addr); |
|---|
| 751 | + return dev_set_mac_address(vlan->lowerdev, addr, NULL); |
|---|
| 756 | 752 | } |
|---|
| 757 | 753 | |
|---|
| 758 | 754 | if (macvlan_addr_busy(vlan->port, addr->sa_data)) |
|---|
| .. | .. |
|---|
| 832 | 828 | return 0; |
|---|
| 833 | 829 | } |
|---|
| 834 | 830 | |
|---|
| 831 | +static int macvlan_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
|---|
| 832 | +{ |
|---|
| 833 | + struct net_device *real_dev = macvlan_dev_real_dev(dev); |
|---|
| 834 | + const struct net_device_ops *ops = real_dev->netdev_ops; |
|---|
| 835 | + struct ifreq ifrr; |
|---|
| 836 | + int err = -EOPNOTSUPP; |
|---|
| 837 | + |
|---|
| 838 | + strscpy(ifrr.ifr_name, real_dev->name, IFNAMSIZ); |
|---|
| 839 | + ifrr.ifr_ifru = ifr->ifr_ifru; |
|---|
| 840 | + |
|---|
| 841 | + switch (cmd) { |
|---|
| 842 | + case SIOCSHWTSTAMP: |
|---|
| 843 | + if (!net_eq(dev_net(dev), &init_net)) |
|---|
| 844 | + break; |
|---|
| 845 | + fallthrough; |
|---|
| 846 | + case SIOCGHWTSTAMP: |
|---|
| 847 | + if (netif_device_present(real_dev) && ops->ndo_do_ioctl) |
|---|
| 848 | + err = ops->ndo_do_ioctl(real_dev, &ifrr, cmd); |
|---|
| 849 | + break; |
|---|
| 850 | + } |
|---|
| 851 | + |
|---|
| 852 | + if (!err) |
|---|
| 853 | + ifr->ifr_ifru = ifrr.ifr_ifru; |
|---|
| 854 | + |
|---|
| 855 | + return err; |
|---|
| 856 | +} |
|---|
| 857 | + |
|---|
| 835 | 858 | /* |
|---|
| 836 | 859 | * macvlan network devices have devices nesting below it and are a special |
|---|
| 837 | 860 | * "super class" of normal network devices; split their locks off into a |
|---|
| .. | .. |
|---|
| 854 | 877 | #define MACVLAN_STATE_MASK \ |
|---|
| 855 | 878 | ((1<<__LINK_STATE_NOCARRIER) | (1<<__LINK_STATE_DORMANT)) |
|---|
| 856 | 879 | |
|---|
| 857 | | -static int macvlan_get_nest_level(struct net_device *dev) |
|---|
| 858 | | -{ |
|---|
| 859 | | - return ((struct macvlan_dev *)netdev_priv(dev))->nest_level; |
|---|
| 860 | | -} |
|---|
| 861 | | - |
|---|
| 862 | 880 | static void macvlan_set_lockdep_class(struct net_device *dev) |
|---|
| 863 | 881 | { |
|---|
| 864 | 882 | netdev_lockdep_set_classes(dev); |
|---|
| 865 | | - lockdep_set_class_and_subclass(&dev->addr_list_lock, |
|---|
| 866 | | - &macvlan_netdev_addr_lock_key, |
|---|
| 867 | | - macvlan_get_nest_level(dev)); |
|---|
| 883 | + lockdep_set_class(&dev->addr_list_lock, |
|---|
| 884 | + &macvlan_netdev_addr_lock_key); |
|---|
| 868 | 885 | } |
|---|
| 869 | 886 | |
|---|
| 870 | 887 | static int macvlan_init(struct net_device *dev) |
|---|
| .. | .. |
|---|
| 884 | 901 | dev->gso_max_size = lowerdev->gso_max_size; |
|---|
| 885 | 902 | dev->gso_max_segs = lowerdev->gso_max_segs; |
|---|
| 886 | 903 | dev->hard_header_len = lowerdev->hard_header_len; |
|---|
| 887 | | - |
|---|
| 888 | 904 | macvlan_set_lockdep_class(dev); |
|---|
| 889 | 905 | |
|---|
| 890 | 906 | vlan->pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats); |
|---|
| .. | .. |
|---|
| 971 | 987 | static int macvlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], |
|---|
| 972 | 988 | struct net_device *dev, |
|---|
| 973 | 989 | const unsigned char *addr, u16 vid, |
|---|
| 974 | | - u16 flags) |
|---|
| 990 | + u16 flags, |
|---|
| 991 | + struct netlink_ext_ack *extack) |
|---|
| 975 | 992 | { |
|---|
| 976 | 993 | struct macvlan_dev *vlan = netdev_priv(dev); |
|---|
| 977 | 994 | int err = -EINVAL; |
|---|
| .. | .. |
|---|
| 1027 | 1044 | const struct macvlan_dev *vlan = netdev_priv(dev); |
|---|
| 1028 | 1045 | |
|---|
| 1029 | 1046 | return __ethtool_get_link_ksettings(vlan->lowerdev, cmd); |
|---|
| 1047 | +} |
|---|
| 1048 | + |
|---|
| 1049 | +static int macvlan_ethtool_get_ts_info(struct net_device *dev, |
|---|
| 1050 | + struct ethtool_ts_info *info) |
|---|
| 1051 | +{ |
|---|
| 1052 | + struct net_device *real_dev = macvlan_dev_real_dev(dev); |
|---|
| 1053 | + const struct ethtool_ops *ops = real_dev->ethtool_ops; |
|---|
| 1054 | + struct phy_device *phydev = real_dev->phydev; |
|---|
| 1055 | + |
|---|
| 1056 | + if (phy_has_tsinfo(phydev)) { |
|---|
| 1057 | + return phy_ts_info(phydev, info); |
|---|
| 1058 | + } else if (ops->get_ts_info) { |
|---|
| 1059 | + return ops->get_ts_info(real_dev, info); |
|---|
| 1060 | + } else { |
|---|
| 1061 | + info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE | |
|---|
| 1062 | + SOF_TIMESTAMPING_SOFTWARE; |
|---|
| 1063 | + info->phc_index = -1; |
|---|
| 1064 | + } |
|---|
| 1065 | + |
|---|
| 1066 | + return 0; |
|---|
| 1030 | 1067 | } |
|---|
| 1031 | 1068 | |
|---|
| 1032 | 1069 | static netdev_features_t macvlan_fix_features(struct net_device *dev, |
|---|
| .. | .. |
|---|
| 1088 | 1125 | |
|---|
| 1089 | 1126 | vlan->netpoll = NULL; |
|---|
| 1090 | 1127 | |
|---|
| 1091 | | - __netpoll_free_async(netpoll); |
|---|
| 1128 | + __netpoll_free(netpoll); |
|---|
| 1092 | 1129 | } |
|---|
| 1093 | 1130 | #endif /* CONFIG_NET_POLL_CONTROLLER */ |
|---|
| 1094 | 1131 | |
|---|
| .. | .. |
|---|
| 1103 | 1140 | .get_link = ethtool_op_get_link, |
|---|
| 1104 | 1141 | .get_link_ksettings = macvlan_ethtool_get_link_ksettings, |
|---|
| 1105 | 1142 | .get_drvinfo = macvlan_ethtool_get_drvinfo, |
|---|
| 1143 | + .get_ts_info = macvlan_ethtool_get_ts_info, |
|---|
| 1106 | 1144 | }; |
|---|
| 1107 | 1145 | |
|---|
| 1108 | 1146 | static const struct net_device_ops macvlan_netdev_ops = { |
|---|
| .. | .. |
|---|
| 1112 | 1150 | .ndo_stop = macvlan_stop, |
|---|
| 1113 | 1151 | .ndo_start_xmit = macvlan_start_xmit, |
|---|
| 1114 | 1152 | .ndo_change_mtu = macvlan_change_mtu, |
|---|
| 1153 | + .ndo_do_ioctl = macvlan_do_ioctl, |
|---|
| 1115 | 1154 | .ndo_fix_features = macvlan_fix_features, |
|---|
| 1116 | 1155 | .ndo_change_rx_flags = macvlan_change_rx_flags, |
|---|
| 1117 | 1156 | .ndo_set_mac_address = macvlan_set_mac_address, |
|---|
| .. | .. |
|---|
| 1123 | 1162 | .ndo_fdb_add = macvlan_fdb_add, |
|---|
| 1124 | 1163 | .ndo_fdb_del = macvlan_fdb_del, |
|---|
| 1125 | 1164 | .ndo_fdb_dump = ndo_dflt_fdb_dump, |
|---|
| 1126 | | - .ndo_get_lock_subclass = macvlan_get_nest_level, |
|---|
| 1127 | 1165 | #ifdef CONFIG_NET_POLL_CONTROLLER |
|---|
| 1128 | 1166 | .ndo_poll_controller = macvlan_dev_poll_controller, |
|---|
| 1129 | 1167 | .ndo_netpoll_setup = macvlan_dev_netpoll_setup, |
|---|
| .. | .. |
|---|
| 1131 | 1169 | #endif |
|---|
| 1132 | 1170 | .ndo_get_iflink = macvlan_dev_get_iflink, |
|---|
| 1133 | 1171 | .ndo_features_check = passthru_features_check, |
|---|
| 1172 | + .ndo_change_proto_down = dev_change_proto_down_generic, |
|---|
| 1134 | 1173 | }; |
|---|
| 1135 | 1174 | |
|---|
| 1136 | 1175 | void macvlan_common_setup(struct net_device *dev) |
|---|
| 1137 | 1176 | { |
|---|
| 1138 | 1177 | ether_setup(dev); |
|---|
| 1139 | 1178 | |
|---|
| 1140 | | - dev->min_mtu = 0; |
|---|
| 1179 | + /* ether_setup() has set dev->min_mtu to ETH_MIN_MTU. */ |
|---|
| 1141 | 1180 | dev->max_mtu = ETH_MAX_MTU; |
|---|
| 1142 | 1181 | dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
|---|
| 1143 | 1182 | netif_keep_dst(dev); |
|---|
| .. | .. |
|---|
| 1221 | 1260 | |
|---|
| 1222 | 1261 | sa.sa_family = port->dev->type; |
|---|
| 1223 | 1262 | memcpy(&sa.sa_data, port->perm_addr, port->dev->addr_len); |
|---|
| 1224 | | - dev_set_mac_address(port->dev, &sa); |
|---|
| 1263 | + dev_set_mac_address(port->dev, &sa, NULL); |
|---|
| 1225 | 1264 | } |
|---|
| 1226 | 1265 | |
|---|
| 1227 | 1266 | kfree(port); |
|---|
| .. | .. |
|---|
| 1398 | 1437 | if (!tb[IFLA_ADDRESS]) |
|---|
| 1399 | 1438 | eth_hw_addr_random(dev); |
|---|
| 1400 | 1439 | |
|---|
| 1401 | | - if (!macvlan_port_exists(lowerdev)) { |
|---|
| 1440 | + if (!netif_is_macvlan_port(lowerdev)) { |
|---|
| 1402 | 1441 | err = macvlan_port_create(lowerdev); |
|---|
| 1403 | 1442 | if (err < 0) |
|---|
| 1404 | 1443 | return err; |
|---|
| .. | .. |
|---|
| 1419 | 1458 | vlan->dev = dev; |
|---|
| 1420 | 1459 | vlan->port = port; |
|---|
| 1421 | 1460 | vlan->set_features = MACVLAN_FEATURES; |
|---|
| 1422 | | - vlan->nest_level = dev_get_nest_level(lowerdev) + 1; |
|---|
| 1423 | 1461 | |
|---|
| 1424 | 1462 | vlan->mode = MACVLAN_MODE_VEPA; |
|---|
| 1425 | 1463 | if (data && data[IFLA_MACVLAN_MODE]) |
|---|
| .. | .. |
|---|
| 1471 | 1509 | /* the macvlan port may be freed by macvlan_uninit when fail to register. |
|---|
| 1472 | 1510 | * so we destroy the macvlan port only when it's valid. |
|---|
| 1473 | 1511 | */ |
|---|
| 1474 | | - if (create && macvlan_port_get_rtnl(lowerdev)) |
|---|
| 1512 | + if (create && macvlan_port_get_rtnl(lowerdev)) { |
|---|
| 1513 | + macvlan_flush_sources(port, vlan); |
|---|
| 1475 | 1514 | macvlan_port_destroy(port->dev); |
|---|
| 1515 | + } |
|---|
| 1476 | 1516 | return err; |
|---|
| 1477 | 1517 | } |
|---|
| 1478 | 1518 | EXPORT_SYMBOL_GPL(macvlan_common_newlink); |
|---|
| .. | .. |
|---|
| 1574 | 1614 | struct hlist_head *h = &vlan->port->vlan_source_hash[i]; |
|---|
| 1575 | 1615 | struct macvlan_source_entry *entry; |
|---|
| 1576 | 1616 | |
|---|
| 1577 | | - hlist_for_each_entry_rcu(entry, h, hlist) { |
|---|
| 1617 | + hlist_for_each_entry_rcu(entry, h, hlist, lockdep_rtnl_is_held()) { |
|---|
| 1578 | 1618 | if (entry->vlan != vlan) |
|---|
| 1579 | 1619 | continue; |
|---|
| 1580 | 1620 | if (nla_put(skb, IFLA_MACVLAN_MACADDR, ETH_ALEN, entry->addr)) |
|---|
| .. | .. |
|---|
| 1597 | 1637 | if (nla_put_u32(skb, IFLA_MACVLAN_MACADDR_COUNT, vlan->macaddr_count)) |
|---|
| 1598 | 1638 | goto nla_put_failure; |
|---|
| 1599 | 1639 | if (vlan->macaddr_count > 0) { |
|---|
| 1600 | | - nest = nla_nest_start(skb, IFLA_MACVLAN_MACADDR_DATA); |
|---|
| 1640 | + nest = nla_nest_start_noflag(skb, IFLA_MACVLAN_MACADDR_DATA); |
|---|
| 1601 | 1641 | if (nest == NULL) |
|---|
| 1602 | 1642 | goto nla_put_failure; |
|---|
| 1603 | 1643 | |
|---|
| .. | .. |
|---|
| 1658 | 1698 | struct macvlan_port *port; |
|---|
| 1659 | 1699 | LIST_HEAD(list_kill); |
|---|
| 1660 | 1700 | |
|---|
| 1661 | | - if (!macvlan_port_exists(dev)) |
|---|
| 1701 | + if (!netif_is_macvlan_port(dev)) |
|---|
| 1662 | 1702 | return NOTIFY_DONE; |
|---|
| 1663 | 1703 | |
|---|
| 1664 | 1704 | port = macvlan_port_get_rtnl(dev); |
|---|