Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: Update API for VF vlan protocol 802.1ad support

Introduce new rtnl UAPI that exposes a list of vlans per VF, giving
the ability for user-space application to specify it for the VF, as an
option to support 802.1ad.
We adjusted IP Link tool to support this option.

For future use cases, the new UAPI supports multiple vlans. For now we
limit the list size to a single vlan in kernel.
Add IFLA_VF_VLAN_LIST in addition to IFLA_VF_VLAN to keep backward
compatibility with older versions of IP Link tool.

Add a vlan protocol parameter to the ndo_set_vf_vlan callback.
We kept 802.1Q as the drivers' default vlan protocol.
Suitable ip link tool command examples:
Set vf vlan protocol 802.1ad:
ip link set eth0 vf 1 vlan 100 proto 802.1ad
Set vf to VST (802.1Q) mode:
ip link set eth0 vf 1 vlan 100 proto 802.1Q
Or by omitting the new parameter
ip link set eth0 vf 1 vlan 100

Signed-off-by: Moshe Shemesh <moshe@mellanox.com>
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Moshe Shemesh and committed by
David S. Miller
79aab093 0815fe3a

+161 -42
+2 -1
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
··· 492 492 int bnx2x_get_vf_config(struct net_device *dev, int vf, 493 493 struct ifla_vf_info *ivi); 494 494 int bnx2x_set_vf_mac(struct net_device *dev, int queue, u8 *mac); 495 - int bnx2x_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos); 495 + int bnx2x_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos, 496 + __be16 vlan_proto); 496 497 497 498 /* select_queue callback */ 498 499 u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb,
+7 -2
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
··· 2521 2521 for_each_vf(bp, vfidx) { 2522 2522 bulletin = BP_VF_BULLETIN(bp, vfidx); 2523 2523 if (bulletin->valid_bitmap & (1 << VLAN_VALID)) 2524 - bnx2x_set_vf_vlan(bp->dev, vfidx, bulletin->vlan, 0); 2524 + bnx2x_set_vf_vlan(bp->dev, vfidx, bulletin->vlan, 0, 2525 + htons(ETH_P_8021Q)); 2525 2526 } 2526 2527 } 2527 2528 ··· 2782 2781 return 0; 2783 2782 } 2784 2783 2785 - int bnx2x_set_vf_vlan(struct net_device *dev, int vfidx, u16 vlan, u8 qos) 2784 + int bnx2x_set_vf_vlan(struct net_device *dev, int vfidx, u16 vlan, u8 qos, 2785 + __be16 vlan_proto) 2786 2786 { 2787 2787 struct pf_vf_bulletin_content *bulletin = NULL; 2788 2788 struct bnx2x *bp = netdev_priv(dev); ··· 2797 2795 BNX2X_ERR("illegal vlan value %d\n", vlan); 2798 2796 return -EINVAL; 2799 2797 } 2798 + 2799 + if (vlan_proto != htons(ETH_P_8021Q)) 2800 + return -EPROTONOSUPPORT; 2800 2801 2801 2802 DP(BNX2X_MSG_IOV, "configuring VF %d with VLAN %d qos %d\n", 2802 2803 vfidx, vlan, 0);
+5 -1
drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
··· 174 174 return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); 175 175 } 176 176 177 - int bnxt_set_vf_vlan(struct net_device *dev, int vf_id, u16 vlan_id, u8 qos) 177 + int bnxt_set_vf_vlan(struct net_device *dev, int vf_id, u16 vlan_id, u8 qos, 178 + __be16 vlan_proto) 178 179 { 179 180 struct hwrm_func_cfg_input req = {0}; 180 181 struct bnxt *bp = netdev_priv(dev); ··· 185 184 186 185 if (bp->hwrm_spec_code < 0x10201) 187 186 return -ENOTSUPP; 187 + 188 + if (vlan_proto != htons(ETH_P_8021Q)) 189 + return -EPROTONOSUPPORT; 188 190 189 191 rc = bnxt_vf_ndo_prep(bp, vf_id); 190 192 if (rc)
+1 -1
drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h
··· 12 12 13 13 int bnxt_get_vf_config(struct net_device *, int, struct ifla_vf_info *); 14 14 int bnxt_set_vf_mac(struct net_device *, int, u8 *); 15 - int bnxt_set_vf_vlan(struct net_device *, int, u16, u8); 15 + int bnxt_set_vf_vlan(struct net_device *, int, u16, u8, __be16); 16 16 int bnxt_set_vf_bw(struct net_device *, int, int, int); 17 17 int bnxt_set_vf_link_state(struct net_device *, int, int); 18 18 int bnxt_set_vf_spoofchk(struct net_device *, int, bool);
+5 -1
drivers/net/ethernet/emulex/benet/be_main.c
··· 1895 1895 return 0; 1896 1896 } 1897 1897 1898 - static int be_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos) 1898 + static int be_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos, 1899 + __be16 vlan_proto) 1899 1900 { 1900 1901 struct be_adapter *adapter = netdev_priv(netdev); 1901 1902 struct be_vf_cfg *vf_cfg = &adapter->vf_cfg[vf]; ··· 1907 1906 1908 1907 if (vf >= adapter->num_vfs || vlan > 4095 || qos > 7) 1909 1908 return -EINVAL; 1909 + 1910 + if (vlan_proto != htons(ETH_P_8021Q)) 1911 + return -EPROTONOSUPPORT; 1910 1912 1911 1913 if (vlan || qos) { 1912 1914 vlan |= qos << VLAN_PRIO_SHIFT;
+1 -1
drivers/net/ethernet/intel/fm10k/fm10k.h
··· 507 507 s32 fm10k_iov_update_pvid(struct fm10k_intfc *interface, u16 glort, u16 pvid); 508 508 int fm10k_ndo_set_vf_mac(struct net_device *netdev, int vf_idx, u8 *mac); 509 509 int fm10k_ndo_set_vf_vlan(struct net_device *netdev, 510 - int vf_idx, u16 vid, u8 qos); 510 + int vf_idx, u16 vid, u8 qos, __be16 vlan_proto); 511 511 int fm10k_ndo_set_vf_bw(struct net_device *netdev, int vf_idx, int rate, 512 512 int unused); 513 513 int fm10k_ndo_get_vf_config(struct net_device *netdev,
+5 -1
drivers/net/ethernet/intel/fm10k/fm10k_iov.c
··· 445 445 } 446 446 447 447 int fm10k_ndo_set_vf_vlan(struct net_device *netdev, int vf_idx, u16 vid, 448 - u8 qos) 448 + u8 qos, __be16 vlan_proto) 449 449 { 450 450 struct fm10k_intfc *interface = netdev_priv(netdev); 451 451 struct fm10k_iov_data *iov_data = interface->iov_data; ··· 459 459 /* QOS is unsupported and VLAN IDs accepted range 0-4094 */ 460 460 if (qos || (vid > (VLAN_VID_MASK - 1))) 461 461 return -EINVAL; 462 + 463 + /* VF VLAN Protocol part to default is unsupported */ 464 + if (vlan_proto != htons(ETH_P_8021Q)) 465 + return -EPROTONOSUPPORT; 462 466 463 467 vf_info = &iov_data->vf_info[vf_idx]; 464 468
+9 -2
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
··· 2747 2747 * @vf_id: VF identifier 2748 2748 * @vlan_id: mac address 2749 2749 * @qos: priority setting 2750 + * @vlan_proto: vlan protocol 2750 2751 * 2751 2752 * program VF vlan id and/or qos 2752 2753 **/ 2753 - int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, 2754 - int vf_id, u16 vlan_id, u8 qos) 2754 + int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id, 2755 + u16 vlan_id, u8 qos, __be16 vlan_proto) 2755 2756 { 2756 2757 u16 vlanprio = vlan_id | (qos << I40E_VLAN_PRIORITY_SHIFT); 2757 2758 struct i40e_netdev_priv *np = netdev_priv(netdev); ··· 2772 2771 if ((vlan_id > I40E_MAX_VLANID) || (qos > 7)) { 2773 2772 dev_err(&pf->pdev->dev, "Invalid VF Parameters\n"); 2774 2773 ret = -EINVAL; 2774 + goto error_pvid; 2775 + } 2776 + 2777 + if (vlan_proto != htons(ETH_P_8021Q)) { 2778 + dev_err(&pf->pdev->dev, "VF VLAN protocol is not supported\n"); 2779 + ret = -EPROTONOSUPPORT; 2775 2780 goto error_pvid; 2776 2781 } 2777 2782
+2 -2
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
··· 129 129 130 130 /* VF configuration related iplink handlers */ 131 131 int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac); 132 - int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, 133 - int vf_id, u16 vlan_id, u8 qos); 132 + int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id, 133 + u16 vlan_id, u8 qos, __be16 vlan_proto); 134 134 int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate, 135 135 int max_tx_rate); 136 136 int i40e_ndo_set_vf_trust(struct net_device *netdev, int vf_id, bool setting);
+6 -3
drivers/net/ethernet/intel/igb/igb_main.c
··· 169 169 static void igb_restore_vf_multicasts(struct igb_adapter *adapter); 170 170 static int igb_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac); 171 171 static int igb_ndo_set_vf_vlan(struct net_device *netdev, 172 - int vf, u16 vlan, u8 qos); 172 + int vf, u16 vlan, u8 qos, __be16 vlan_proto); 173 173 static int igb_ndo_set_vf_bw(struct net_device *, int, int, int); 174 174 static int igb_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, 175 175 bool setting); ··· 6222 6222 return 0; 6223 6223 } 6224 6224 6225 - static int igb_ndo_set_vf_vlan(struct net_device *netdev, 6226 - int vf, u16 vlan, u8 qos) 6225 + static int igb_ndo_set_vf_vlan(struct net_device *netdev, int vf, 6226 + u16 vlan, u8 qos, __be16 vlan_proto) 6227 6227 { 6228 6228 struct igb_adapter *adapter = netdev_priv(netdev); 6229 6229 6230 6230 if ((vf >= adapter->vfs_allocated_count) || (vlan > 4095) || (qos > 7)) 6231 6231 return -EINVAL; 6232 + 6233 + if (vlan_proto != htons(ETH_P_8021Q)) 6234 + return -EPROTONOSUPPORT; 6232 6235 6233 6236 return (vlan || qos) ? igb_enable_port_vlan(adapter, vf, vlan, qos) : 6234 6237 igb_disable_port_vlan(adapter, vf);
+4 -1
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
··· 1354 1354 return err; 1355 1355 } 1356 1356 1357 - int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos) 1357 + int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, 1358 + u8 qos, __be16 vlan_proto) 1358 1359 { 1359 1360 int err = 0; 1360 1361 struct ixgbe_adapter *adapter = netdev_priv(netdev); 1361 1362 1362 1363 if ((vf >= adapter->num_vfs) || (vlan > 4095) || (qos > 7)) 1363 1364 return -EINVAL; 1365 + if (vlan_proto != htons(ETH_P_8021Q)) 1366 + return -EPROTONOSUPPORT; 1364 1367 if (vlan || qos) { 1365 1368 /* Check if there is already a port VLAN set, if so 1366 1369 * we have to delete the old one first before we
+1 -1
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
··· 43 43 void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter); 44 44 int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int queue, u8 *mac); 45 45 int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int queue, u16 vlan, 46 - u8 qos); 46 + u8 qos, __be16 vlan_proto); 47 47 int ixgbe_link_mbps(struct ixgbe_adapter *adapter); 48 48 int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int min_tx_rate, 49 49 int max_tx_rate);
+5 -1
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
··· 2400 2400 return mlx4_set_vf_mac(mdev->dev, en_priv->port, queue, mac_u64); 2401 2401 } 2402 2402 2403 - static int mlx4_en_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos) 2403 + static int mlx4_en_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos, 2404 + __be16 vlan_proto) 2404 2405 { 2405 2406 struct mlx4_en_priv *en_priv = netdev_priv(dev); 2406 2407 struct mlx4_en_dev *mdev = en_priv->mdev; 2408 + 2409 + if (vlan_proto != htons(ETH_P_8021Q)) 2410 + return -EPROTONOSUPPORT; 2407 2411 2408 2412 return mlx4_set_vf_vlan(mdev->dev, en_priv->port, vf, vlan, qos); 2409 2413 }
+5 -1
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
··· 2917 2917 return mlx5_eswitch_set_vport_mac(mdev->priv.eswitch, vf + 1, mac); 2918 2918 } 2919 2919 2920 - static int mlx5e_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos) 2920 + static int mlx5e_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos, 2921 + __be16 vlan_proto) 2921 2922 { 2922 2923 struct mlx5e_priv *priv = netdev_priv(dev); 2923 2924 struct mlx5_core_dev *mdev = priv->mdev; 2925 + 2926 + if (vlan_proto != htons(ETH_P_8021Q)) 2927 + return -EPROTONOSUPPORT; 2924 2928 2925 2929 return mlx5_eswitch_set_vport_vlan(mdev->priv.eswitch, vf + 1, 2926 2930 vlan, qos);
+5 -1
drivers/net/ethernet/qlogic/qede/qede_main.c
··· 100 100 static void qede_link_update(void *dev, struct qed_link_output *link); 101 101 102 102 #ifdef CONFIG_QED_SRIOV 103 - static int qede_set_vf_vlan(struct net_device *ndev, int vf, u16 vlan, u8 qos) 103 + static int qede_set_vf_vlan(struct net_device *ndev, int vf, u16 vlan, u8 qos, 104 + __be16 vlan_proto) 104 105 { 105 106 struct qede_dev *edev = netdev_priv(ndev); 106 107 ··· 109 108 DP_NOTICE(edev, "Illegal vlan value %d\n", vlan); 110 109 return -EINVAL; 111 110 } 111 + 112 + if (vlan_proto != htons(ETH_P_8021Q)) 113 + return -EPROTONOSUPPORT; 112 114 113 115 DP_VERBOSE(edev, QED_MSG_IOV, "Setting Vlan 0x%04x to VF [%d]\n", 114 116 vlan, vf);
+1 -1
drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h
··· 238 238 int qlcnic_sriov_set_vf_tx_rate(struct net_device *, int, int, int); 239 239 int qlcnic_sriov_get_vf_config(struct net_device *, int , 240 240 struct ifla_vf_info *); 241 - int qlcnic_sriov_set_vf_vlan(struct net_device *, int, u16, u8); 241 + int qlcnic_sriov_set_vf_vlan(struct net_device *, int, u16, u8, __be16); 242 242 int qlcnic_sriov_set_vf_spoofchk(struct net_device *, int, bool); 243 243 #else 244 244 static inline void qlcnic_sriov_pf_disable(struct qlcnic_adapter *adapter) {}
+4 -1
drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
··· 1915 1915 } 1916 1916 1917 1917 int qlcnic_sriov_set_vf_vlan(struct net_device *netdev, int vf, 1918 - u16 vlan, u8 qos) 1918 + u16 vlan, u8 qos, __be16 vlan_proto) 1919 1919 { 1920 1920 struct qlcnic_adapter *adapter = netdev_priv(netdev); 1921 1921 struct qlcnic_sriov *sriov = adapter->ahw->sriov; ··· 1927 1927 1928 1928 if (vf >= sriov->num_vfs || qos > 7) 1929 1929 return -EINVAL; 1930 + 1931 + if (vlan_proto != htons(ETH_P_8021Q)) 1932 + return -EPROTONOSUPPORT; 1930 1933 1931 1934 if (vlan > MAX_VLAN_ID) { 1932 1935 netdev_err(netdev,
+4 -1
drivers/net/ethernet/sfc/sriov.c
··· 22 22 } 23 23 24 24 int efx_sriov_set_vf_vlan(struct net_device *net_dev, int vf_i, u16 vlan, 25 - u8 qos) 25 + u8 qos, __be16 vlan_proto) 26 26 { 27 27 struct efx_nic *efx = netdev_priv(net_dev); 28 28 ··· 30 30 if ((vlan & ~VLAN_VID_MASK) || 31 31 (qos & ~(VLAN_PRIO_MASK >> VLAN_PRIO_SHIFT))) 32 32 return -EINVAL; 33 + 34 + if (vlan_proto != htons(ETH_P_8021Q)) 35 + return -EPROTONOSUPPORT; 33 36 34 37 return efx->type->sriov_set_vf_vlan(efx, vf_i, vlan, qos); 35 38 } else {
+1 -1
drivers/net/ethernet/sfc/sriov.h
··· 16 16 17 17 int efx_sriov_set_vf_mac(struct net_device *net_dev, int vf_i, u8 *mac); 18 18 int efx_sriov_set_vf_vlan(struct net_device *net_dev, int vf_i, u16 vlan, 19 - u8 qos); 19 + u8 qos, __be16 vlan_proto); 20 20 int efx_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf_i, 21 21 bool spoofchk); 22 22 int efx_sriov_get_vf_config(struct net_device *net_dev, int vf_i,
+1
include/linux/if_link.h
··· 25 25 __u32 max_tx_rate; 26 26 __u32 rss_query_en; 27 27 __u32 trusted; 28 + __be16 vlan_proto; 28 29 }; 29 30 #endif /* _LINUX_IF_LINK_H */
+4 -2
include/linux/netdevice.h
··· 946 946 * 947 947 * SR-IOV management functions. 948 948 * int (*ndo_set_vf_mac)(struct net_device *dev, int vf, u8* mac); 949 - * int (*ndo_set_vf_vlan)(struct net_device *dev, int vf, u16 vlan, u8 qos); 949 + * int (*ndo_set_vf_vlan)(struct net_device *dev, int vf, u16 vlan, 950 + * u8 qos, __be16 proto); 950 951 * int (*ndo_set_vf_rate)(struct net_device *dev, int vf, int min_tx_rate, 951 952 * int max_tx_rate); 952 953 * int (*ndo_set_vf_spoofchk)(struct net_device *dev, int vf, bool setting); ··· 1188 1187 int (*ndo_set_vf_mac)(struct net_device *dev, 1189 1188 int queue, u8 *mac); 1190 1189 int (*ndo_set_vf_vlan)(struct net_device *dev, 1191 - int queue, u16 vlan, u8 qos); 1190 + int queue, u16 vlan, 1191 + u8 qos, __be16 proto); 1192 1192 int (*ndo_set_vf_rate)(struct net_device *dev, 1193 1193 int vf, int min_tx_rate, 1194 1194 int max_tx_rate);
+18 -1
include/uapi/linux/if_link.h
··· 619 619 enum { 620 620 IFLA_VF_UNSPEC, 621 621 IFLA_VF_MAC, /* Hardware queue specific attributes */ 622 - IFLA_VF_VLAN, 622 + IFLA_VF_VLAN, /* VLAN ID and QoS */ 623 623 IFLA_VF_TX_RATE, /* Max TX Bandwidth Allocation */ 624 624 IFLA_VF_SPOOFCHK, /* Spoof Checking on/off switch */ 625 625 IFLA_VF_LINK_STATE, /* link state enable/disable/auto switch */ ··· 631 631 IFLA_VF_TRUST, /* Trust VF */ 632 632 IFLA_VF_IB_NODE_GUID, /* VF Infiniband node GUID */ 633 633 IFLA_VF_IB_PORT_GUID, /* VF Infiniband port GUID */ 634 + IFLA_VF_VLAN_LIST, /* nested list of vlans, option for QinQ */ 634 635 __IFLA_VF_MAX, 635 636 }; 636 637 ··· 646 645 __u32 vf; 647 646 __u32 vlan; /* 0 - 4095, 0 disables VLAN filter */ 648 647 __u32 qos; 648 + }; 649 + 650 + enum { 651 + IFLA_VF_VLAN_INFO_UNSPEC, 652 + IFLA_VF_VLAN_INFO, /* VLAN ID, QoS and VLAN protocol */ 653 + __IFLA_VF_VLAN_INFO_MAX, 654 + }; 655 + 656 + #define IFLA_VF_VLAN_INFO_MAX (__IFLA_VF_VLAN_INFO_MAX - 1) 657 + #define MAX_VLAN_LIST_LEN 1 658 + 659 + struct ifla_vf_vlan_info { 660 + __u32 vf; 661 + __u32 vlan; /* 0 - 4095, 0 disables VLAN filter */ 662 + __u32 qos; 663 + __be16 vlan_proto; /* VLAN protocol either 802.1Q or 802.1ad */ 649 664 }; 650 665 651 666 struct ifla_vf_tx_rate {
+65 -15
net/core/rtnetlink.c
··· 843 843 size += nla_total_size(num_vfs * sizeof(struct nlattr)); 844 844 size += num_vfs * 845 845 (nla_total_size(sizeof(struct ifla_vf_mac)) + 846 - nla_total_size(sizeof(struct ifla_vf_vlan)) + 846 + nla_total_size(MAX_VLAN_LIST_LEN * 847 + sizeof(struct nlattr)) + 848 + nla_total_size(MAX_VLAN_LIST_LEN * 849 + sizeof(struct ifla_vf_vlan_info)) + 847 850 nla_total_size(sizeof(struct ifla_vf_spoofchk)) + 848 851 nla_total_size(sizeof(struct ifla_vf_rate)) + 849 852 nla_total_size(sizeof(struct ifla_vf_link_state)) + ··· 1114 1111 struct nlattr *vfinfo) 1115 1112 { 1116 1113 struct ifla_vf_rss_query_en vf_rss_query_en; 1114 + struct nlattr *vf, *vfstats, *vfvlanlist; 1117 1115 struct ifla_vf_link_state vf_linkstate; 1116 + struct ifla_vf_vlan_info vf_vlan_info; 1118 1117 struct ifla_vf_spoofchk vf_spoofchk; 1119 1118 struct ifla_vf_tx_rate vf_tx_rate; 1120 1119 struct ifla_vf_stats vf_stats; 1121 1120 struct ifla_vf_trust vf_trust; 1122 1121 struct ifla_vf_vlan vf_vlan; 1123 1122 struct ifla_vf_rate vf_rate; 1124 - struct nlattr *vf, *vfstats; 1125 1123 struct ifla_vf_mac vf_mac; 1126 1124 struct ifla_vf_info ivi; 1127 1125 ··· 1139 1135 * IFLA_VF_LINK_STATE_AUTO which equals zero 1140 1136 */ 1141 1137 ivi.linkstate = 0; 1138 + /* VLAN Protocol by default is 802.1Q */ 1139 + ivi.vlan_proto = htons(ETH_P_8021Q); 1142 1140 if (dev->netdev_ops->ndo_get_vf_config(dev, vfs_num, &ivi)) 1143 1141 return 0; 1144 1142 1145 1143 vf_mac.vf = 1146 1144 vf_vlan.vf = 1145 + vf_vlan_info.vf = 1147 1146 vf_rate.vf = 1148 1147 vf_tx_rate.vf = 1149 1148 vf_spoofchk.vf = ··· 1157 1150 memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac)); 1158 1151 vf_vlan.vlan = ivi.vlan; 1159 1152 vf_vlan.qos = ivi.qos; 1153 + vf_vlan_info.vlan = ivi.vlan; 1154 + vf_vlan_info.qos = ivi.qos; 1155 + vf_vlan_info.vlan_proto = ivi.vlan_proto; 1160 1156 vf_tx_rate.rate = ivi.max_tx_rate; 1161 1157 vf_rate.min_tx_rate = ivi.min_tx_rate; 1162 1158 vf_rate.max_tx_rate = ivi.max_tx_rate; ··· 1168 1158 vf_rss_query_en.setting = ivi.rss_query_en; 1169 1159 vf_trust.setting = ivi.trusted; 1170 1160 vf = nla_nest_start(skb, IFLA_VF_INFO); 1171 - if (!vf) { 1172 - nla_nest_cancel(skb, vfinfo); 1173 - return -EMSGSIZE; 1174 - } 1161 + if (!vf) 1162 + goto nla_put_vfinfo_failure; 1175 1163 if (nla_put(skb, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac) || 1176 1164 nla_put(skb, IFLA_VF_VLAN, sizeof(vf_vlan), &vf_vlan) || 1177 1165 nla_put(skb, IFLA_VF_RATE, sizeof(vf_rate), ··· 1185 1177 &vf_rss_query_en) || 1186 1178 nla_put(skb, IFLA_VF_TRUST, 1187 1179 sizeof(vf_trust), &vf_trust)) 1188 - return -EMSGSIZE; 1180 + goto nla_put_vf_failure; 1181 + vfvlanlist = nla_nest_start(skb, IFLA_VF_VLAN_LIST); 1182 + if (!vfvlanlist) 1183 + goto nla_put_vf_failure; 1184 + if (nla_put(skb, IFLA_VF_VLAN_INFO, sizeof(vf_vlan_info), 1185 + &vf_vlan_info)) { 1186 + nla_nest_cancel(skb, vfvlanlist); 1187 + goto nla_put_vf_failure; 1188 + } 1189 + nla_nest_end(skb, vfvlanlist); 1189 1190 memset(&vf_stats, 0, sizeof(vf_stats)); 1190 1191 if (dev->netdev_ops->ndo_get_vf_stats) 1191 1192 dev->netdev_ops->ndo_get_vf_stats(dev, vfs_num, 1192 1193 &vf_stats); 1193 1194 vfstats = nla_nest_start(skb, IFLA_VF_STATS); 1194 - if (!vfstats) { 1195 - nla_nest_cancel(skb, vf); 1196 - nla_nest_cancel(skb, vfinfo); 1197 - return -EMSGSIZE; 1198 - } 1195 + if (!vfstats) 1196 + goto nla_put_vf_failure; 1199 1197 if (nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_PACKETS, 1200 1198 vf_stats.rx_packets, IFLA_VF_STATS_PAD) || 1201 1199 nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_PACKETS, ··· 1213 1199 nla_put_u64_64bit(skb, IFLA_VF_STATS_BROADCAST, 1214 1200 vf_stats.broadcast, IFLA_VF_STATS_PAD) || 1215 1201 nla_put_u64_64bit(skb, IFLA_VF_STATS_MULTICAST, 1216 - vf_stats.multicast, IFLA_VF_STATS_PAD)) 1217 - return -EMSGSIZE; 1202 + vf_stats.multicast, IFLA_VF_STATS_PAD)) { 1203 + nla_nest_cancel(skb, vfstats); 1204 + goto nla_put_vf_failure; 1205 + } 1218 1206 nla_nest_end(skb, vfstats); 1219 1207 nla_nest_end(skb, vf); 1220 1208 return 0; 1209 + 1210 + nla_put_vf_failure: 1211 + nla_nest_cancel(skb, vf); 1212 + nla_put_vfinfo_failure: 1213 + nla_nest_cancel(skb, vfinfo); 1214 + return -EMSGSIZE; 1221 1215 } 1222 1216 1223 1217 static int rtnl_fill_link_ifmap(struct sk_buff *skb, struct net_device *dev) ··· 1470 1448 static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = { 1471 1449 [IFLA_VF_MAC] = { .len = sizeof(struct ifla_vf_mac) }, 1472 1450 [IFLA_VF_VLAN] = { .len = sizeof(struct ifla_vf_vlan) }, 1451 + [IFLA_VF_VLAN_LIST] = { .type = NLA_NESTED }, 1473 1452 [IFLA_VF_TX_RATE] = { .len = sizeof(struct ifla_vf_tx_rate) }, 1474 1453 [IFLA_VF_SPOOFCHK] = { .len = sizeof(struct ifla_vf_spoofchk) }, 1475 1454 [IFLA_VF_RATE] = { .len = sizeof(struct ifla_vf_rate) }, ··· 1727 1704 err = -EOPNOTSUPP; 1728 1705 if (ops->ndo_set_vf_vlan) 1729 1706 err = ops->ndo_set_vf_vlan(dev, ivv->vf, ivv->vlan, 1730 - ivv->qos); 1707 + ivv->qos, 1708 + htons(ETH_P_8021Q)); 1709 + if (err < 0) 1710 + return err; 1711 + } 1712 + 1713 + if (tb[IFLA_VF_VLAN_LIST]) { 1714 + struct ifla_vf_vlan_info *ivvl[MAX_VLAN_LIST_LEN]; 1715 + struct nlattr *attr; 1716 + int rem, len = 0; 1717 + 1718 + err = -EOPNOTSUPP; 1719 + if (!ops->ndo_set_vf_vlan) 1720 + return err; 1721 + 1722 + nla_for_each_nested(attr, tb[IFLA_VF_VLAN_LIST], rem) { 1723 + if (nla_type(attr) != IFLA_VF_VLAN_INFO || 1724 + nla_len(attr) < NLA_HDRLEN) { 1725 + return -EINVAL; 1726 + } 1727 + if (len >= MAX_VLAN_LIST_LEN) 1728 + return -EOPNOTSUPP; 1729 + ivvl[len] = nla_data(attr); 1730 + 1731 + len++; 1732 + } 1733 + err = ops->ndo_set_vf_vlan(dev, ivvl[0]->vf, ivvl[0]->vlan, 1734 + ivvl[0]->qos, ivvl[0]->vlan_proto); 1731 1735 if (err < 0) 1732 1736 return err; 1733 1737 }