.. | .. |
---|
1624 | 1624 | |
---|
1625 | 1625 | team->dev = dev; |
---|
1626 | 1626 | team_set_no_mode(team); |
---|
| 1627 | + team->notifier_ctx = false; |
---|
1627 | 1628 | |
---|
1628 | 1629 | team->pcpu_stats = netdev_alloc_pcpu_stats(struct team_pcpu_stats); |
---|
1629 | 1630 | if (!team->pcpu_stats) |
---|
.. | .. |
---|
2121 | 2122 | static void team_setup_by_port(struct net_device *dev, |
---|
2122 | 2123 | struct net_device *port_dev) |
---|
2123 | 2124 | { |
---|
2124 | | - dev->header_ops = port_dev->header_ops; |
---|
| 2125 | + struct team *team = netdev_priv(dev); |
---|
| 2126 | + |
---|
| 2127 | + if (port_dev->type == ARPHRD_ETHER) |
---|
| 2128 | + dev->header_ops = team->header_ops_cache; |
---|
| 2129 | + else |
---|
| 2130 | + dev->header_ops = port_dev->header_ops; |
---|
2125 | 2131 | dev->type = port_dev->type; |
---|
2126 | 2132 | dev->hard_header_len = port_dev->hard_header_len; |
---|
2127 | 2133 | dev->needed_headroom = port_dev->needed_headroom; |
---|
.. | .. |
---|
2129 | 2135 | dev->mtu = port_dev->mtu; |
---|
2130 | 2136 | memcpy(dev->broadcast, port_dev->broadcast, port_dev->addr_len); |
---|
2131 | 2137 | eth_hw_addr_inherit(dev, port_dev); |
---|
| 2138 | + |
---|
| 2139 | + if (port_dev->flags & IFF_POINTOPOINT) { |
---|
| 2140 | + dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); |
---|
| 2141 | + dev->flags |= (IFF_POINTOPOINT | IFF_NOARP); |
---|
| 2142 | + } else if ((port_dev->flags & (IFF_BROADCAST | IFF_MULTICAST)) == |
---|
| 2143 | + (IFF_BROADCAST | IFF_MULTICAST)) { |
---|
| 2144 | + dev->flags |= (IFF_BROADCAST | IFF_MULTICAST); |
---|
| 2145 | + dev->flags &= ~(IFF_POINTOPOINT | IFF_NOARP); |
---|
| 2146 | + } |
---|
2132 | 2147 | } |
---|
2133 | 2148 | |
---|
2134 | 2149 | static int team_dev_type_check_change(struct net_device *dev, |
---|
.. | .. |
---|
2159 | 2174 | |
---|
2160 | 2175 | static void team_setup(struct net_device *dev) |
---|
2161 | 2176 | { |
---|
| 2177 | + struct team *team = netdev_priv(dev); |
---|
| 2178 | + |
---|
2162 | 2179 | ether_setup(dev); |
---|
2163 | 2180 | dev->max_mtu = ETH_MAX_MTU; |
---|
| 2181 | + team->header_ops_cache = dev->header_ops; |
---|
2164 | 2182 | |
---|
2165 | 2183 | dev->netdev_ops = &team_netdev_ops; |
---|
2166 | 2184 | dev->ethtool_ops = &team_ethtool_ops; |
---|
.. | .. |
---|
2185 | 2203 | |
---|
2186 | 2204 | dev->hw_features = TEAM_VLAN_FEATURES | |
---|
2187 | 2205 | NETIF_F_HW_VLAN_CTAG_RX | |
---|
2188 | | - NETIF_F_HW_VLAN_CTAG_FILTER; |
---|
| 2206 | + NETIF_F_HW_VLAN_CTAG_FILTER | |
---|
| 2207 | + NETIF_F_HW_VLAN_STAG_RX | |
---|
| 2208 | + NETIF_F_HW_VLAN_STAG_FILTER; |
---|
2189 | 2209 | |
---|
2190 | 2210 | dev->hw_features |= NETIF_F_GSO_ENCAP_ALL | NETIF_F_GSO_UDP_L4; |
---|
2191 | 2211 | dev->features |= dev->hw_features; |
---|
.. | .. |
---|
3016 | 3036 | team_del_slave(port->team->dev, dev); |
---|
3017 | 3037 | break; |
---|
3018 | 3038 | case NETDEV_FEAT_CHANGE: |
---|
3019 | | - team_compute_features(port->team); |
---|
| 3039 | + if (!port->team->notifier_ctx) { |
---|
| 3040 | + port->team->notifier_ctx = true; |
---|
| 3041 | + team_compute_features(port->team); |
---|
| 3042 | + port->team->notifier_ctx = false; |
---|
| 3043 | + } |
---|
3020 | 3044 | break; |
---|
3021 | 3045 | case NETDEV_PRECHANGEMTU: |
---|
3022 | 3046 | /* Forbid to change mtu of underlaying device */ |
---|