aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMoshe Shemesh <moshe@mellanox.com>2016-09-22 05:11:15 -0400
committerDavid S. Miller <davem@davemloft.net>2016-09-24 08:01:26 -0400
commit79aab093a0b5370d7fc4e99df75996f4744dc03f (patch)
tree335687dd409f13fcadcd420e63ca9425016d4d54
parent0815fe3a86a01cdf81361459c465761be7138665 (diff)
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>
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h3
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c9
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c6
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h2
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c6
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k.h2
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_iov.c6
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c11
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h4
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c9
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c5
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_main.c6
-rw-r--r--drivers/net/ethernet/qlogic/qede/qede_main.c6
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h2
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c5
-rw-r--r--drivers/net/ethernet/sfc/sriov.c5
-rw-r--r--drivers/net/ethernet/sfc/sriov.h2
-rw-r--r--include/linux/if_link.h1
-rw-r--r--include/linux/netdevice.h6
-rw-r--r--include/uapi/linux/if_link.h19
-rw-r--r--net/core/rtnetlink.c80
23 files changed, 161 insertions, 42 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
index 0e68fadecfdb..243cb9748d35 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
@@ -492,7 +492,8 @@ int __bnx2x_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
492int bnx2x_get_vf_config(struct net_device *dev, int vf, 492int bnx2x_get_vf_config(struct net_device *dev, int vf,
493 struct ifla_vf_info *ivi); 493 struct ifla_vf_info *ivi);
494int bnx2x_set_vf_mac(struct net_device *dev, int queue, u8 *mac); 494int bnx2x_set_vf_mac(struct net_device *dev, int queue, u8 *mac);
495int bnx2x_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos); 495int bnx2x_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos,
496 __be16 vlan_proto);
496 497
497/* select_queue callback */ 498/* select_queue callback */
498u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb, 499u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb,
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
index 6c586b045d1d..3f77d0863543 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
@@ -2521,7 +2521,8 @@ void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp)
2521 for_each_vf(bp, vfidx) { 2521 for_each_vf(bp, vfidx) {
2522 bulletin = BP_VF_BULLETIN(bp, vfidx); 2522 bulletin = BP_VF_BULLETIN(bp, vfidx);
2523 if (bulletin->valid_bitmap & (1 << VLAN_VALID)) 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
@@ -2781,7 +2782,8 @@ static int bnx2x_set_vf_vlan_filter(struct bnx2x *bp, struct bnx2x_virtf *vf,
2781 return 0; 2782 return 0;
2782} 2783}
2783 2784
2784int bnx2x_set_vf_vlan(struct net_device *dev, int vfidx, u16 vlan, u8 qos) 2785int bnx2x_set_vf_vlan(struct net_device *dev, int vfidx, u16 vlan, u8 qos,
2786 __be16 vlan_proto)
2785{ 2787{
2786 struct pf_vf_bulletin_content *bulletin = NULL; 2788 struct pf_vf_bulletin_content *bulletin = NULL;
2787 struct bnx2x *bp = netdev_priv(dev); 2789 struct bnx2x *bp = netdev_priv(dev);
@@ -2796,6 +2798,9 @@ int bnx2x_set_vf_vlan(struct net_device *dev, int vfidx, u16 vlan, u8 qos)
2796 return -EINVAL; 2798 return -EINVAL;
2797 } 2799 }
2798 2800
2801 if (vlan_proto != htons(ETH_P_8021Q))
2802 return -EPROTONOSUPPORT;
2803
2799 DP(BNX2X_MSG_IOV, "configuring VF %d with VLAN %d qos %d\n", 2804 DP(BNX2X_MSG_IOV, "configuring VF %d with VLAN %d qos %d\n",
2800 vfidx, vlan, 0); 2805 vfidx, vlan, 0);
2801 2806
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
index 8be718508600..ec6cd18842c3 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
@@ -174,7 +174,8 @@ int bnxt_set_vf_mac(struct net_device *dev, int vf_id, u8 *mac)
174 return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); 174 return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
175} 175}
176 176
177int bnxt_set_vf_vlan(struct net_device *dev, int vf_id, u16 vlan_id, u8 qos) 177int bnxt_set_vf_vlan(struct net_device *dev, int vf_id, u16 vlan_id, u8 qos,
178 __be16 vlan_proto)
178{ 179{
179 struct hwrm_func_cfg_input req = {0}; 180 struct hwrm_func_cfg_input req = {0};
180 struct bnxt *bp = netdev_priv(dev); 181 struct bnxt *bp = netdev_priv(dev);
@@ -185,6 +186,9 @@ int bnxt_set_vf_vlan(struct net_device *dev, int vf_id, u16 vlan_id, u8 qos)
185 if (bp->hwrm_spec_code < 0x10201) 186 if (bp->hwrm_spec_code < 0x10201)
186 return -ENOTSUPP; 187 return -ENOTSUPP;
187 188
189 if (vlan_proto != htons(ETH_P_8021Q))
190 return -EPROTONOSUPPORT;
191
188 rc = bnxt_vf_ndo_prep(bp, vf_id); 192 rc = bnxt_vf_ndo_prep(bp, vf_id);
189 if (rc) 193 if (rc)
190 return rc; 194 return rc;
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h
index 0392670ab49c..1ab72e4820af 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h
@@ -12,7 +12,7 @@
12 12
13int bnxt_get_vf_config(struct net_device *, int, struct ifla_vf_info *); 13int bnxt_get_vf_config(struct net_device *, int, struct ifla_vf_info *);
14int bnxt_set_vf_mac(struct net_device *, int, u8 *); 14int bnxt_set_vf_mac(struct net_device *, int, u8 *);
15int bnxt_set_vf_vlan(struct net_device *, int, u16, u8); 15int bnxt_set_vf_vlan(struct net_device *, int, u16, u8, __be16);
16int bnxt_set_vf_bw(struct net_device *, int, int, int); 16int bnxt_set_vf_bw(struct net_device *, int, int, int);
17int bnxt_set_vf_link_state(struct net_device *, int, int); 17int bnxt_set_vf_link_state(struct net_device *, int, int);
18int bnxt_set_vf_spoofchk(struct net_device *, int, bool); 18int bnxt_set_vf_spoofchk(struct net_device *, int, bool);
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 9a94840c5757..ac513e6627d1 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -1895,7 +1895,8 @@ static int be_clear_vf_tvt(struct be_adapter *adapter, int vf)
1895 return 0; 1895 return 0;
1896} 1896}
1897 1897
1898static int be_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos) 1898static int be_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos,
1899 __be16 vlan_proto)
1899{ 1900{
1900 struct be_adapter *adapter = netdev_priv(netdev); 1901 struct be_adapter *adapter = netdev_priv(netdev);
1901 struct be_vf_cfg *vf_cfg = &adapter->vf_cfg[vf]; 1902 struct be_vf_cfg *vf_cfg = &adapter->vf_cfg[vf];
@@ -1907,6 +1908,9 @@ static int be_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos)
1907 if (vf >= adapter->num_vfs || vlan > 4095 || qos > 7) 1908 if (vf >= adapter->num_vfs || vlan > 4095 || qos > 7)
1908 return -EINVAL; 1909 return -EINVAL;
1909 1910
1911 if (vlan_proto != htons(ETH_P_8021Q))
1912 return -EPROTONOSUPPORT;
1913
1910 if (vlan || qos) { 1914 if (vlan || qos) {
1911 vlan |= qos << VLAN_PRIO_SHIFT; 1915 vlan |= qos << VLAN_PRIO_SHIFT;
1912 status = be_set_vf_tvt(adapter, vf, vlan); 1916 status = be_set_vf_tvt(adapter, vf, vlan);
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k.h b/drivers/net/ethernet/intel/fm10k/fm10k.h
index 67ff01aeb11a..4d19e46f7c55 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k.h
+++ b/drivers/net/ethernet/intel/fm10k/fm10k.h
@@ -507,7 +507,7 @@ int fm10k_iov_configure(struct pci_dev *pdev, int num_vfs);
507s32 fm10k_iov_update_pvid(struct fm10k_intfc *interface, u16 glort, u16 pvid); 507s32 fm10k_iov_update_pvid(struct fm10k_intfc *interface, u16 glort, u16 pvid);
508int fm10k_ndo_set_vf_mac(struct net_device *netdev, int vf_idx, u8 *mac); 508int fm10k_ndo_set_vf_mac(struct net_device *netdev, int vf_idx, u8 *mac);
509int fm10k_ndo_set_vf_vlan(struct net_device *netdev, 509int 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);
511int fm10k_ndo_set_vf_bw(struct net_device *netdev, int vf_idx, int rate, 511int fm10k_ndo_set_vf_bw(struct net_device *netdev, int vf_idx, int rate,
512 int unused); 512 int unused);
513int fm10k_ndo_get_vf_config(struct net_device *netdev, 513int fm10k_ndo_get_vf_config(struct net_device *netdev,
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_iov.c b/drivers/net/ethernet/intel/fm10k/fm10k_iov.c
index d9dec81f6b6d..5f4dac0d36ef 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_iov.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_iov.c
@@ -445,7 +445,7 @@ int fm10k_ndo_set_vf_mac(struct net_device *netdev, int vf_idx, u8 *mac)
445} 445}
446 446
447int fm10k_ndo_set_vf_vlan(struct net_device *netdev, int vf_idx, u16 vid, 447int 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 struct fm10k_intfc *interface = netdev_priv(netdev); 450 struct fm10k_intfc *interface = netdev_priv(netdev);
451 struct fm10k_iov_data *iov_data = interface->iov_data; 451 struct fm10k_iov_data *iov_data = interface->iov_data;
@@ -460,6 +460,10 @@ int fm10k_ndo_set_vf_vlan(struct net_device *netdev, int vf_idx, u16 vid,
460 if (qos || (vid > (VLAN_VID_MASK - 1))) 460 if (qos || (vid > (VLAN_VID_MASK - 1)))
461 return -EINVAL; 461 return -EINVAL;
462 462
463 /* VF VLAN Protocol part to default is unsupported */
464 if (vlan_proto != htons(ETH_P_8021Q))
465 return -EPROTONOSUPPORT;
466
463 vf_info = &iov_data->vf_info[vf_idx]; 467 vf_info = &iov_data->vf_info[vf_idx];
464 468
465 /* exit if there is nothing to do */ 469 /* exit if there is nothing to do */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index da3423561b3a..724d8740d4cc 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -2747,11 +2747,12 @@ error_param:
2747 * @vf_id: VF identifier 2747 * @vf_id: VF identifier
2748 * @vlan_id: mac address 2748 * @vlan_id: mac address
2749 * @qos: priority setting 2749 * @qos: priority setting
2750 * @vlan_proto: vlan protocol
2750 * 2751 *
2751 * program VF vlan id and/or qos 2752 * program VF vlan id and/or qos
2752 **/ 2753 **/
2753int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, 2754int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id,
2754 int vf_id, u16 vlan_id, u8 qos) 2755 u16 vlan_id, u8 qos, __be16 vlan_proto)
2755{ 2756{
2756 u16 vlanprio = vlan_id | (qos << I40E_VLAN_PRIORITY_SHIFT); 2757 u16 vlanprio = vlan_id | (qos << I40E_VLAN_PRIORITY_SHIFT);
2757 struct i40e_netdev_priv *np = netdev_priv(netdev); 2758 struct i40e_netdev_priv *np = netdev_priv(netdev);
@@ -2774,6 +2775,12 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev,
2774 goto error_pvid; 2775 goto error_pvid;
2775 } 2776 }
2776 2777
2778 if (vlan_proto != htons(ETH_P_8021Q)) {
2779 dev_err(&pf->pdev->dev, "VF VLAN protocol is not supported\n");
2780 ret = -EPROTONOSUPPORT;
2781 goto error_pvid;
2782 }
2783
2777 vf = &(pf->vf[vf_id]); 2784 vf = &(pf->vf[vf_id]);
2778 vsi = pf->vsi[vf->lan_vsi_idx]; 2785 vsi = pf->vsi[vf->lan_vsi_idx];
2779 if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states)) { 2786 if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states)) {
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
index 875174141451..4012d069939a 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
@@ -129,8 +129,8 @@ void i40e_vc_notify_vf_reset(struct i40e_vf *vf);
129 129
130/* VF configuration related iplink handlers */ 130/* VF configuration related iplink handlers */
131int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac); 131int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac);
132int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, 132int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id,
133 int vf_id, u16 vlan_id, u8 qos); 133 u16 vlan_id, u8 qos, __be16 vlan_proto);
134int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate, 134int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate,
135 int max_tx_rate); 135 int max_tx_rate);
136int i40e_ndo_set_vf_trust(struct net_device *netdev, int vf_id, bool setting); 136int i40e_ndo_set_vf_trust(struct net_device *netdev, int vf_id, bool setting);
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index af75eac5fa16..a83aa13a5bf4 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -169,7 +169,7 @@ static int igb_set_vf_mac(struct igb_adapter *, int, unsigned char *);
169static void igb_restore_vf_multicasts(struct igb_adapter *adapter); 169static void igb_restore_vf_multicasts(struct igb_adapter *adapter);
170static int igb_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac); 170static int igb_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac);
171static int igb_ndo_set_vf_vlan(struct net_device *netdev, 171static 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);
173static int igb_ndo_set_vf_bw(struct net_device *, int, int, int); 173static int igb_ndo_set_vf_bw(struct net_device *, int, int, int);
174static int igb_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, 174static int igb_ndo_set_vf_spoofchk(struct net_device *netdev, int vf,
175 bool setting); 175 bool setting);
@@ -6222,14 +6222,17 @@ static int igb_disable_port_vlan(struct igb_adapter *adapter, int vf)
6222 return 0; 6222 return 0;
6223} 6223}
6224 6224
6225static int igb_ndo_set_vf_vlan(struct net_device *netdev, 6225static int igb_ndo_set_vf_vlan(struct net_device *netdev, int vf,
6226 int vf, u16 vlan, u8 qos) 6226 u16 vlan, u8 qos, __be16 vlan_proto)
6227{ 6227{
6228 struct igb_adapter *adapter = netdev_priv(netdev); 6228 struct igb_adapter *adapter = netdev_priv(netdev);
6229 6229
6230 if ((vf >= adapter->vfs_allocated_count) || (vlan > 4095) || (qos > 7)) 6230 if ((vf >= adapter->vfs_allocated_count) || (vlan > 4095) || (qos > 7))
6231 return -EINVAL; 6231 return -EINVAL;
6232 6232
6233 if (vlan_proto != htons(ETH_P_8021Q))
6234 return -EPROTONOSUPPORT;
6235
6233 return (vlan || qos) ? igb_enable_port_vlan(adapter, vf, vlan, qos) : 6236 return (vlan || qos) ? igb_enable_port_vlan(adapter, vf, vlan, qos) :
6234 igb_disable_port_vlan(adapter, vf); 6237 igb_disable_port_vlan(adapter, vf);
6235} 6238}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index 8618599dfd6f..b18590a995db 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -1354,13 +1354,16 @@ static int ixgbe_disable_port_vlan(struct ixgbe_adapter *adapter, int vf)
1354 return err; 1354 return err;
1355} 1355}
1356 1356
1357int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos) 1357int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan,
1358 u8 qos, __be16 vlan_proto)
1358{ 1359{
1359 int err = 0; 1360 int err = 0;
1360 struct ixgbe_adapter *adapter = netdev_priv(netdev); 1361 struct ixgbe_adapter *adapter = netdev_priv(netdev);
1361 1362
1362 if ((vf >= adapter->num_vfs) || (vlan > 4095) || (qos > 7)) 1363 if ((vf >= adapter->num_vfs) || (vlan > 4095) || (qos > 7))
1363 return -EINVAL; 1364 return -EINVAL;
1365 if (vlan_proto != htons(ETH_P_8021Q))
1366 return -EPROTONOSUPPORT;
1364 if (vlan || qos) { 1367 if (vlan || qos) {
1365 /* Check if there is already a port VLAN set, if so 1368 /* Check if there is already a port VLAN set, if so
1366 * we have to delete the old one first before we 1369 * we have to delete the old one first before we
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
index 47e65e2f886a..0c7977d27b71 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
@@ -43,7 +43,7 @@ void ixgbe_disable_tx_rx(struct ixgbe_adapter *adapter);
43void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter); 43void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter);
44int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int queue, u8 *mac); 44int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int queue, u8 *mac);
45int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int queue, u16 vlan, 45int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int queue, u16 vlan,
46 u8 qos); 46 u8 qos, __be16 vlan_proto);
47int ixgbe_link_mbps(struct ixgbe_adapter *adapter); 47int ixgbe_link_mbps(struct ixgbe_adapter *adapter);
48int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int min_tx_rate, 48int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int min_tx_rate,
49 int max_tx_rate); 49 int max_tx_rate);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index a94f8a3f026c..132eeeafcdc4 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -2400,11 +2400,15 @@ static int mlx4_en_set_vf_mac(struct net_device *dev, int queue, u8 *mac)
2400 return mlx4_set_vf_mac(mdev->dev, en_priv->port, queue, mac_u64); 2400 return mlx4_set_vf_mac(mdev->dev, en_priv->port, queue, mac_u64);
2401} 2401}
2402 2402
2403static int mlx4_en_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos) 2403static int mlx4_en_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos,
2404 __be16 vlan_proto)
2404{ 2405{
2405 struct mlx4_en_priv *en_priv = netdev_priv(dev); 2406 struct mlx4_en_priv *en_priv = netdev_priv(dev);
2406 struct mlx4_en_dev *mdev = en_priv->mdev; 2407 struct mlx4_en_dev *mdev = en_priv->mdev;
2407 2408
2409 if (vlan_proto != htons(ETH_P_8021Q))
2410 return -EPROTONOSUPPORT;
2411
2408 return mlx4_set_vf_vlan(mdev->dev, en_priv->port, vf, vlan, qos); 2412 return mlx4_set_vf_vlan(mdev->dev, en_priv->port, vf, vlan, qos);
2409} 2413}
2410 2414
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index c12792314be7..b58cfe37dead 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -2917,11 +2917,15 @@ static int mlx5e_set_vf_mac(struct net_device *dev, int vf, u8 *mac)
2917 return mlx5_eswitch_set_vport_mac(mdev->priv.eswitch, vf + 1, mac); 2917 return mlx5_eswitch_set_vport_mac(mdev->priv.eswitch, vf + 1, mac);
2918} 2918}
2919 2919
2920static int mlx5e_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos) 2920static int mlx5e_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos,
2921 __be16 vlan_proto)
2921{ 2922{
2922 struct mlx5e_priv *priv = netdev_priv(dev); 2923 struct mlx5e_priv *priv = netdev_priv(dev);
2923 struct mlx5_core_dev *mdev = priv->mdev; 2924 struct mlx5_core_dev *mdev = priv->mdev;
2924 2925
2926 if (vlan_proto != htons(ETH_P_8021Q))
2927 return -EPROTONOSUPPORT;
2928
2925 return mlx5_eswitch_set_vport_vlan(mdev->priv.eswitch, vf + 1, 2929 return mlx5_eswitch_set_vport_vlan(mdev->priv.eswitch, vf + 1,
2926 vlan, qos); 2930 vlan, qos);
2927} 2931}
diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c
index cd23a2946db7..0e198fe89d1a 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -100,7 +100,8 @@ static int qede_alloc_rx_buffer(struct qede_dev *edev,
100static void qede_link_update(void *dev, struct qed_link_output *link); 100static void qede_link_update(void *dev, struct qed_link_output *link);
101 101
102#ifdef CONFIG_QED_SRIOV 102#ifdef CONFIG_QED_SRIOV
103static int qede_set_vf_vlan(struct net_device *ndev, int vf, u16 vlan, u8 qos) 103static int qede_set_vf_vlan(struct net_device *ndev, int vf, u16 vlan, u8 qos,
104 __be16 vlan_proto)
104{ 105{
105 struct qede_dev *edev = netdev_priv(ndev); 106 struct qede_dev *edev = netdev_priv(ndev);
106 107
@@ -109,6 +110,9 @@ static int qede_set_vf_vlan(struct net_device *ndev, int vf, u16 vlan, u8 qos)
109 return -EINVAL; 110 return -EINVAL;
110 } 111 }
111 112
113 if (vlan_proto != htons(ETH_P_8021Q))
114 return -EPROTONOSUPPORT;
115
112 DP_VERBOSE(edev, QED_MSG_IOV, "Setting Vlan 0x%04x to VF [%d]\n", 116 DP_VERBOSE(edev, QED_MSG_IOV, "Setting Vlan 0x%04x to VF [%d]\n",
113 vlan, vf); 117 vlan, vf);
114 118
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h
index 24061b9b92e8..5f327659efa7 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h
@@ -238,7 +238,7 @@ int qlcnic_sriov_set_vf_mac(struct net_device *, int, u8 *);
238int qlcnic_sriov_set_vf_tx_rate(struct net_device *, int, int, int); 238int qlcnic_sriov_set_vf_tx_rate(struct net_device *, int, int, int);
239int qlcnic_sriov_get_vf_config(struct net_device *, int , 239int qlcnic_sriov_get_vf_config(struct net_device *, int ,
240 struct ifla_vf_info *); 240 struct ifla_vf_info *);
241int qlcnic_sriov_set_vf_vlan(struct net_device *, int, u16, u8); 241int qlcnic_sriov_set_vf_vlan(struct net_device *, int, u16, u8, __be16);
242int qlcnic_sriov_set_vf_spoofchk(struct net_device *, int, bool); 242int qlcnic_sriov_set_vf_spoofchk(struct net_device *, int, bool);
243#else 243#else
244static inline void qlcnic_sriov_pf_disable(struct qlcnic_adapter *adapter) {} 244static inline void qlcnic_sriov_pf_disable(struct qlcnic_adapter *adapter) {}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
index afd687e5e779..50eaafa3eaba 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
@@ -1915,7 +1915,7 @@ int qlcnic_sriov_set_vf_tx_rate(struct net_device *netdev, int vf,
1915} 1915}
1916 1916
1917int qlcnic_sriov_set_vf_vlan(struct net_device *netdev, int vf, 1917int 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 struct qlcnic_adapter *adapter = netdev_priv(netdev); 1920 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1921 struct qlcnic_sriov *sriov = adapter->ahw->sriov; 1921 struct qlcnic_sriov *sriov = adapter->ahw->sriov;
@@ -1928,6 +1928,9 @@ int qlcnic_sriov_set_vf_vlan(struct net_device *netdev, int vf,
1928 if (vf >= sriov->num_vfs || qos > 7) 1928 if (vf >= sriov->num_vfs || qos > 7)
1929 return -EINVAL; 1929 return -EINVAL;
1930 1930
1931 if (vlan_proto != htons(ETH_P_8021Q))
1932 return -EPROTONOSUPPORT;
1933
1931 if (vlan > MAX_VLAN_ID) { 1934 if (vlan > MAX_VLAN_ID) {
1932 netdev_err(netdev, 1935 netdev_err(netdev,
1933 "Invalid VLAN ID, allowed range is [0 - %d]\n", 1936 "Invalid VLAN ID, allowed range is [0 - %d]\n",
diff --git a/drivers/net/ethernet/sfc/sriov.c b/drivers/net/ethernet/sfc/sriov.c
index 816c44689e67..9abcf4aded30 100644
--- a/drivers/net/ethernet/sfc/sriov.c
+++ b/drivers/net/ethernet/sfc/sriov.c
@@ -22,7 +22,7 @@ int efx_sriov_set_vf_mac(struct net_device *net_dev, int vf_i, u8 *mac)
22} 22}
23 23
24int efx_sriov_set_vf_vlan(struct net_device *net_dev, int vf_i, u16 vlan, 24int 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 struct efx_nic *efx = netdev_priv(net_dev); 27 struct efx_nic *efx = netdev_priv(net_dev);
28 28
@@ -31,6 +31,9 @@ int efx_sriov_set_vf_vlan(struct net_device *net_dev, int vf_i, u16 vlan,
31 (qos & ~(VLAN_PRIO_MASK >> VLAN_PRIO_SHIFT))) 31 (qos & ~(VLAN_PRIO_MASK >> VLAN_PRIO_SHIFT)))
32 return -EINVAL; 32 return -EINVAL;
33 33
34 if (vlan_proto != htons(ETH_P_8021Q))
35 return -EPROTONOSUPPORT;
36
34 return efx->type->sriov_set_vf_vlan(efx, vf_i, vlan, qos); 37 return efx->type->sriov_set_vf_vlan(efx, vf_i, vlan, qos);
35 } else { 38 } else {
36 return -EOPNOTSUPP; 39 return -EOPNOTSUPP;
diff --git a/drivers/net/ethernet/sfc/sriov.h b/drivers/net/ethernet/sfc/sriov.h
index 400df526586d..ba1762e7f216 100644
--- a/drivers/net/ethernet/sfc/sriov.h
+++ b/drivers/net/ethernet/sfc/sriov.h
@@ -16,7 +16,7 @@
16 16
17int efx_sriov_set_vf_mac(struct net_device *net_dev, int vf_i, u8 *mac); 17int efx_sriov_set_vf_mac(struct net_device *net_dev, int vf_i, u8 *mac);
18int efx_sriov_set_vf_vlan(struct net_device *net_dev, int vf_i, u16 vlan, 18int efx_sriov_set_vf_vlan(struct net_device *net_dev, int vf_i, u16 vlan,
19 u8 qos); 19 u8 qos, __be16 vlan_proto);
20int efx_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf_i, 20int efx_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf_i,
21 bool spoofchk); 21 bool spoofchk);
22int efx_sriov_get_vf_config(struct net_device *net_dev, int vf_i, 22int efx_sriov_get_vf_config(struct net_device *net_dev, int vf_i,
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index f923d15b432c..0b17c585b5cd 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -25,5 +25,6 @@ struct ifla_vf_info {
25 __u32 max_tx_rate; 25 __u32 max_tx_rate;
26 __u32 rss_query_en; 26 __u32 rss_query_en;
27 __u32 trusted; 27 __u32 trusted;
28 __be16 vlan_proto;
28}; 29};
29#endif /* _LINUX_IF_LINK_H */ 30#endif /* _LINUX_IF_LINK_H */
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 69f242c71865..1e8a5c734d72 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -946,7 +946,8 @@ struct netdev_xdp {
946 * 946 *
947 * SR-IOV management functions. 947 * SR-IOV management functions.
948 * int (*ndo_set_vf_mac)(struct net_device *dev, int vf, u8* mac); 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 * int (*ndo_set_vf_rate)(struct net_device *dev, int vf, int min_tx_rate, 951 * int (*ndo_set_vf_rate)(struct net_device *dev, int vf, int min_tx_rate,
951 * int max_tx_rate); 952 * int max_tx_rate);
952 * int (*ndo_set_vf_spoofchk)(struct net_device *dev, int vf, bool setting); 953 * int (*ndo_set_vf_spoofchk)(struct net_device *dev, int vf, bool setting);
@@ -1187,7 +1188,8 @@ struct net_device_ops {
1187 int (*ndo_set_vf_mac)(struct net_device *dev, 1188 int (*ndo_set_vf_mac)(struct net_device *dev,
1188 int queue, u8 *mac); 1189 int queue, u8 *mac);
1189 int (*ndo_set_vf_vlan)(struct net_device *dev, 1190 int (*ndo_set_vf_vlan)(struct net_device *dev,
1190 int queue, u16 vlan, u8 qos); 1191 int queue, u16 vlan,
1192 u8 qos, __be16 proto);
1191 int (*ndo_set_vf_rate)(struct net_device *dev, 1193 int (*ndo_set_vf_rate)(struct net_device *dev,
1192 int vf, int min_tx_rate, 1194 int vf, int min_tx_rate,
1193 int max_tx_rate); 1195 int max_tx_rate);
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 7ec9e99d5491..b4fba662cd32 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -619,7 +619,7 @@ enum {
619enum { 619enum {
620 IFLA_VF_UNSPEC, 620 IFLA_VF_UNSPEC,
621 IFLA_VF_MAC, /* Hardware queue specific attributes */ 621 IFLA_VF_MAC, /* Hardware queue specific attributes */
622 IFLA_VF_VLAN, 622 IFLA_VF_VLAN, /* VLAN ID and QoS */
623 IFLA_VF_TX_RATE, /* Max TX Bandwidth Allocation */ 623 IFLA_VF_TX_RATE, /* Max TX Bandwidth Allocation */
624 IFLA_VF_SPOOFCHK, /* Spoof Checking on/off switch */ 624 IFLA_VF_SPOOFCHK, /* Spoof Checking on/off switch */
625 IFLA_VF_LINK_STATE, /* link state enable/disable/auto switch */ 625 IFLA_VF_LINK_STATE, /* link state enable/disable/auto switch */
@@ -631,6 +631,7 @@ enum {
631 IFLA_VF_TRUST, /* Trust VF */ 631 IFLA_VF_TRUST, /* Trust VF */
632 IFLA_VF_IB_NODE_GUID, /* VF Infiniband node GUID */ 632 IFLA_VF_IB_NODE_GUID, /* VF Infiniband node GUID */
633 IFLA_VF_IB_PORT_GUID, /* VF Infiniband port GUID */ 633 IFLA_VF_IB_PORT_GUID, /* VF Infiniband port GUID */
634 IFLA_VF_VLAN_LIST, /* nested list of vlans, option for QinQ */
634 __IFLA_VF_MAX, 635 __IFLA_VF_MAX,
635}; 636};
636 637
@@ -647,6 +648,22 @@ struct ifla_vf_vlan {
647 __u32 qos; 648 __u32 qos;
648}; 649};
649 650
651enum {
652 IFLA_VF_VLAN_INFO_UNSPEC,
653 IFLA_VF_VLAN_INFO, /* VLAN ID, QoS and VLAN protocol */
654 __IFLA_VF_VLAN_INFO_MAX,
655};
656
657#define IFLA_VF_VLAN_INFO_MAX (__IFLA_VF_VLAN_INFO_MAX - 1)
658#define MAX_VLAN_LIST_LEN 1
659
660struct ifla_vf_vlan_info {
661 __u32 vf;
662 __u32 vlan; /* 0 - 4095, 0 disables VLAN filter */
663 __u32 qos;
664 __be16 vlan_proto; /* VLAN protocol either 802.1Q or 802.1ad */
665};
666
650struct ifla_vf_tx_rate { 667struct ifla_vf_tx_rate {
651 __u32 vf; 668 __u32 vf;
652 __u32 rate; /* Max TX bandwidth in Mbps, 0 disables throttling */ 669 __u32 rate; /* Max TX bandwidth in Mbps, 0 disables throttling */
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 0dbae4244a89..3ac8946bf244 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -843,7 +843,10 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev,
843 size += nla_total_size(num_vfs * sizeof(struct nlattr)); 843 size += nla_total_size(num_vfs * sizeof(struct nlattr));
844 size += num_vfs * 844 size += num_vfs *
845 (nla_total_size(sizeof(struct ifla_vf_mac)) + 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 nla_total_size(sizeof(struct ifla_vf_spoofchk)) + 850 nla_total_size(sizeof(struct ifla_vf_spoofchk)) +
848 nla_total_size(sizeof(struct ifla_vf_rate)) + 851 nla_total_size(sizeof(struct ifla_vf_rate)) +
849 nla_total_size(sizeof(struct ifla_vf_link_state)) + 852 nla_total_size(sizeof(struct ifla_vf_link_state)) +
@@ -1111,14 +1114,15 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
1111 struct nlattr *vfinfo) 1114 struct nlattr *vfinfo)
1112{ 1115{
1113 struct ifla_vf_rss_query_en vf_rss_query_en; 1116 struct ifla_vf_rss_query_en vf_rss_query_en;
1117 struct nlattr *vf, *vfstats, *vfvlanlist;
1114 struct ifla_vf_link_state vf_linkstate; 1118 struct ifla_vf_link_state vf_linkstate;
1119 struct ifla_vf_vlan_info vf_vlan_info;
1115 struct ifla_vf_spoofchk vf_spoofchk; 1120 struct ifla_vf_spoofchk vf_spoofchk;
1116 struct ifla_vf_tx_rate vf_tx_rate; 1121 struct ifla_vf_tx_rate vf_tx_rate;
1117 struct ifla_vf_stats vf_stats; 1122 struct ifla_vf_stats vf_stats;
1118 struct ifla_vf_trust vf_trust; 1123 struct ifla_vf_trust vf_trust;
1119 struct ifla_vf_vlan vf_vlan; 1124 struct ifla_vf_vlan vf_vlan;
1120 struct ifla_vf_rate vf_rate; 1125 struct ifla_vf_rate vf_rate;
1121 struct nlattr *vf, *vfstats;
1122 struct ifla_vf_mac vf_mac; 1126 struct ifla_vf_mac vf_mac;
1123 struct ifla_vf_info ivi; 1127 struct ifla_vf_info ivi;
1124 1128
@@ -1135,11 +1139,14 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
1135 * IFLA_VF_LINK_STATE_AUTO which equals zero 1139 * IFLA_VF_LINK_STATE_AUTO which equals zero
1136 */ 1140 */
1137 ivi.linkstate = 0; 1141 ivi.linkstate = 0;
1142 /* VLAN Protocol by default is 802.1Q */
1143 ivi.vlan_proto = htons(ETH_P_8021Q);
1138 if (dev->netdev_ops->ndo_get_vf_config(dev, vfs_num, &ivi)) 1144 if (dev->netdev_ops->ndo_get_vf_config(dev, vfs_num, &ivi))
1139 return 0; 1145 return 0;
1140 1146
1141 vf_mac.vf = 1147 vf_mac.vf =
1142 vf_vlan.vf = 1148 vf_vlan.vf =
1149 vf_vlan_info.vf =
1143 vf_rate.vf = 1150 vf_rate.vf =
1144 vf_tx_rate.vf = 1151 vf_tx_rate.vf =
1145 vf_spoofchk.vf = 1152 vf_spoofchk.vf =
@@ -1150,6 +1157,9 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
1150 memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac)); 1157 memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac));
1151 vf_vlan.vlan = ivi.vlan; 1158 vf_vlan.vlan = ivi.vlan;
1152 vf_vlan.qos = ivi.qos; 1159 vf_vlan.qos = ivi.qos;
1160 vf_vlan_info.vlan = ivi.vlan;
1161 vf_vlan_info.qos = ivi.qos;
1162 vf_vlan_info.vlan_proto = ivi.vlan_proto;
1153 vf_tx_rate.rate = ivi.max_tx_rate; 1163 vf_tx_rate.rate = ivi.max_tx_rate;
1154 vf_rate.min_tx_rate = ivi.min_tx_rate; 1164 vf_rate.min_tx_rate = ivi.min_tx_rate;
1155 vf_rate.max_tx_rate = ivi.max_tx_rate; 1165 vf_rate.max_tx_rate = ivi.max_tx_rate;
@@ -1158,10 +1168,8 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
1158 vf_rss_query_en.setting = ivi.rss_query_en; 1168 vf_rss_query_en.setting = ivi.rss_query_en;
1159 vf_trust.setting = ivi.trusted; 1169 vf_trust.setting = ivi.trusted;
1160 vf = nla_nest_start(skb, IFLA_VF_INFO); 1170 vf = nla_nest_start(skb, IFLA_VF_INFO);
1161 if (!vf) { 1171 if (!vf)
1162 nla_nest_cancel(skb, vfinfo); 1172 goto nla_put_vfinfo_failure;
1163 return -EMSGSIZE;
1164 }
1165 if (nla_put(skb, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac) || 1173 if (nla_put(skb, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac) ||
1166 nla_put(skb, IFLA_VF_VLAN, sizeof(vf_vlan), &vf_vlan) || 1174 nla_put(skb, IFLA_VF_VLAN, sizeof(vf_vlan), &vf_vlan) ||
1167 nla_put(skb, IFLA_VF_RATE, sizeof(vf_rate), 1175 nla_put(skb, IFLA_VF_RATE, sizeof(vf_rate),
@@ -1177,17 +1185,23 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
1177 &vf_rss_query_en) || 1185 &vf_rss_query_en) ||
1178 nla_put(skb, IFLA_VF_TRUST, 1186 nla_put(skb, IFLA_VF_TRUST,
1179 sizeof(vf_trust), &vf_trust)) 1187 sizeof(vf_trust), &vf_trust))
1180 return -EMSGSIZE; 1188 goto nla_put_vf_failure;
1189 vfvlanlist = nla_nest_start(skb, IFLA_VF_VLAN_LIST);
1190 if (!vfvlanlist)
1191 goto nla_put_vf_failure;
1192 if (nla_put(skb, IFLA_VF_VLAN_INFO, sizeof(vf_vlan_info),
1193 &vf_vlan_info)) {
1194 nla_nest_cancel(skb, vfvlanlist);
1195 goto nla_put_vf_failure;
1196 }
1197 nla_nest_end(skb, vfvlanlist);
1181 memset(&vf_stats, 0, sizeof(vf_stats)); 1198 memset(&vf_stats, 0, sizeof(vf_stats));
1182 if (dev->netdev_ops->ndo_get_vf_stats) 1199 if (dev->netdev_ops->ndo_get_vf_stats)
1183 dev->netdev_ops->ndo_get_vf_stats(dev, vfs_num, 1200 dev->netdev_ops->ndo_get_vf_stats(dev, vfs_num,
1184 &vf_stats); 1201 &vf_stats);
1185 vfstats = nla_nest_start(skb, IFLA_VF_STATS); 1202 vfstats = nla_nest_start(skb, IFLA_VF_STATS);
1186 if (!vfstats) { 1203 if (!vfstats)
1187 nla_nest_cancel(skb, vf); 1204 goto nla_put_vf_failure;
1188 nla_nest_cancel(skb, vfinfo);
1189 return -EMSGSIZE;
1190 }
1191 if (nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_PACKETS, 1205 if (nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_PACKETS,
1192 vf_stats.rx_packets, IFLA_VF_STATS_PAD) || 1206 vf_stats.rx_packets, IFLA_VF_STATS_PAD) ||
1193 nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_PACKETS, 1207 nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_PACKETS,
@@ -1199,11 +1213,19 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
1199 nla_put_u64_64bit(skb, IFLA_VF_STATS_BROADCAST, 1213 nla_put_u64_64bit(skb, IFLA_VF_STATS_BROADCAST,
1200 vf_stats.broadcast, IFLA_VF_STATS_PAD) || 1214 vf_stats.broadcast, IFLA_VF_STATS_PAD) ||
1201 nla_put_u64_64bit(skb, IFLA_VF_STATS_MULTICAST, 1215 nla_put_u64_64bit(skb, IFLA_VF_STATS_MULTICAST,
1202 vf_stats.multicast, IFLA_VF_STATS_PAD)) 1216 vf_stats.multicast, IFLA_VF_STATS_PAD)) {
1203 return -EMSGSIZE; 1217 nla_nest_cancel(skb, vfstats);
1218 goto nla_put_vf_failure;
1219 }
1204 nla_nest_end(skb, vfstats); 1220 nla_nest_end(skb, vfstats);
1205 nla_nest_end(skb, vf); 1221 nla_nest_end(skb, vf);
1206 return 0; 1222 return 0;
1223
1224nla_put_vf_failure:
1225 nla_nest_cancel(skb, vf);
1226nla_put_vfinfo_failure:
1227 nla_nest_cancel(skb, vfinfo);
1228 return -EMSGSIZE;
1207} 1229}
1208 1230
1209static int rtnl_fill_link_ifmap(struct sk_buff *skb, struct net_device *dev) 1231static int rtnl_fill_link_ifmap(struct sk_buff *skb, struct net_device *dev)
@@ -1448,6 +1470,7 @@ static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
1448static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = { 1470static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = {
1449 [IFLA_VF_MAC] = { .len = sizeof(struct ifla_vf_mac) }, 1471 [IFLA_VF_MAC] = { .len = sizeof(struct ifla_vf_mac) },
1450 [IFLA_VF_VLAN] = { .len = sizeof(struct ifla_vf_vlan) }, 1472 [IFLA_VF_VLAN] = { .len = sizeof(struct ifla_vf_vlan) },
1473 [IFLA_VF_VLAN_LIST] = { .type = NLA_NESTED },
1451 [IFLA_VF_TX_RATE] = { .len = sizeof(struct ifla_vf_tx_rate) }, 1474 [IFLA_VF_TX_RATE] = { .len = sizeof(struct ifla_vf_tx_rate) },
1452 [IFLA_VF_SPOOFCHK] = { .len = sizeof(struct ifla_vf_spoofchk) }, 1475 [IFLA_VF_SPOOFCHK] = { .len = sizeof(struct ifla_vf_spoofchk) },
1453 [IFLA_VF_RATE] = { .len = sizeof(struct ifla_vf_rate) }, 1476 [IFLA_VF_RATE] = { .len = sizeof(struct ifla_vf_rate) },
@@ -1704,7 +1727,34 @@ static int do_setvfinfo(struct net_device *dev, struct nlattr **tb)
1704 err = -EOPNOTSUPP; 1727 err = -EOPNOTSUPP;
1705 if (ops->ndo_set_vf_vlan) 1728 if (ops->ndo_set_vf_vlan)
1706 err = ops->ndo_set_vf_vlan(dev, ivv->vf, ivv->vlan, 1729 err = ops->ndo_set_vf_vlan(dev, ivv->vf, ivv->vlan,
1707 ivv->qos); 1730 ivv->qos,
1731 htons(ETH_P_8021Q));
1732 if (err < 0)
1733 return err;
1734 }
1735
1736 if (tb[IFLA_VF_VLAN_LIST]) {
1737 struct ifla_vf_vlan_info *ivvl[MAX_VLAN_LIST_LEN];
1738 struct nlattr *attr;
1739 int rem, len = 0;
1740
1741 err = -EOPNOTSUPP;
1742 if (!ops->ndo_set_vf_vlan)
1743 return err;
1744
1745 nla_for_each_nested(attr, tb[IFLA_VF_VLAN_LIST], rem) {
1746 if (nla_type(attr) != IFLA_VF_VLAN_INFO ||
1747 nla_len(attr) < NLA_HDRLEN) {
1748 return -EINVAL;
1749 }
1750 if (len >= MAX_VLAN_LIST_LEN)
1751 return -EOPNOTSUPP;
1752 ivvl[len] = nla_data(attr);
1753
1754 len++;
1755 }
1756 err = ops->ndo_set_vf_vlan(dev, ivvl[0]->vf, ivvl[0]->vlan,
1757 ivvl[0]->qos, ivvl[0]->vlan_proto);
1708 if (err < 0) 1758 if (err < 0)
1709 return err; 1759 return err;
1710 } 1760 }