Re: [PATCH iproute2] ip link: Add support to configure SR-IOV VF to vlan protocol 802.1ad (VST QinQ)

2016-10-09 Thread Stephen Hemminger
On Wed, 28 Sep 2016 10:58:59 +0300
Tariq Toukan  wrote:

> From: Moshe Shemesh 
> 
> Introduce a new API that exposes a list of vlans per VF (IFLA_VF_VLAN_LIST),
> giving the ability for user-space application to specify it for the VF as
> an option to support 802.1ad (VST QinQ).
> 
> We introduce struct vf_vlan_info, which extends struct vf_vlan and adds
> an optional VF VLAN proto parameter.
> Default VLAN-protocol is 802.1Q.
> 
> Add IFLA_VF_VLAN_LIST in addition to IFLA_VF_VLAN to keep backward
> compatibility with older kernel versions.
> 
> Suitable ip link tool command examples:
>  - Set vf vlan protocol 802.1ad (S-TAG)
>   ip link set eth0 vf 1 vlan 100 proto 802.1ad
>  - Set vf vlan S-TAG and vlan C-TAG (VST QinQ)
>   ip link set eth0 vf 1 vlan 100 proto 802.1ad vlan 30 proto 802.1Q
>  - Set vf to VST (802.1Q) mode
>   ip link set eth0 vf 1 vlan 100 proto 802.1Q
>  - Or by omitting the new parameter (backward compatible)
>   ip link set eth0 vf 1 vlan 100
> 
> Signed-off-by: Moshe Shemesh 
> Signed-off-by: Tariq Toukan 

Applied to net-next (for 4.9)


[PATCH iproute2] ip link: Add support to configure SR-IOV VF to vlan protocol 802.1ad (VST QinQ)

2016-09-28 Thread Tariq Toukan
From: Moshe Shemesh 

Introduce a new API that exposes a list of vlans per VF (IFLA_VF_VLAN_LIST),
giving the ability for user-space application to specify it for the VF as
an option to support 802.1ad (VST QinQ).

We introduce struct vf_vlan_info, which extends struct vf_vlan and adds
an optional VF VLAN proto parameter.
Default VLAN-protocol is 802.1Q.

Add IFLA_VF_VLAN_LIST in addition to IFLA_VF_VLAN to keep backward
compatibility with older kernel versions.

Suitable ip link tool command examples:
 - Set vf vlan protocol 802.1ad (S-TAG)
ip link set eth0 vf 1 vlan 100 proto 802.1ad
 - Set vf vlan S-TAG and vlan C-TAG (VST QinQ)
ip link set eth0 vf 1 vlan 100 proto 802.1ad vlan 30 proto 802.1Q
 - Set vf to VST (802.1Q) mode
ip link set eth0 vf 1 vlan 100 proto 802.1Q
 - Or by omitting the new parameter (backward compatible)
ip link set eth0 vf 1 vlan 100

Signed-off-by: Moshe Shemesh 
Signed-off-by: Tariq Toukan 
---
 include/linux/if_link.h |  18 -
 ip/ipaddress.c  |  35 ++---
 ip/iplink.c | 102 
 man/man8/ip-link.8.in   |  30 --
 4 files changed, 157 insertions(+), 28 deletions(-)

diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 1feb708902ac..d8d349fb120f 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -615,7 +615,7 @@ enum {
 enum {
IFLA_VF_UNSPEC,
IFLA_VF_MAC,/* Hardware queue specific attributes */
-   IFLA_VF_VLAN,
+   IFLA_VF_VLAN,   /* VLAN ID and QoS */
IFLA_VF_TX_RATE,/* Max TX Bandwidth Allocation */
IFLA_VF_SPOOFCHK,   /* Spoof Checking on/off switch */
IFLA_VF_LINK_STATE, /* link state enable/disable/auto switch */
@@ -627,6 +627,7 @@ enum {
IFLA_VF_TRUST,  /* Trust VF */
IFLA_VF_IB_NODE_GUID,   /* VF Infiniband node GUID */
IFLA_VF_IB_PORT_GUID,   /* VF Infiniband port GUID */
+   IFLA_VF_VLAN_LIST,  /* nested list of vlans, option for QinQ */
__IFLA_VF_MAX,
 };
 
@@ -643,6 +644,21 @@ struct ifla_vf_vlan {
__u32 qos;
 };
 
+enum {
+   IFLA_VF_VLAN_INFO_UNSPEC,
+   IFLA_VF_VLAN_INFO,  /* VLAN ID, QoS and VLAN protocol */
+   __IFLA_VF_VLAN_INFO_MAX,
+};
+
+#define IFLA_VF_VLAN_INFO_MAX (__IFLA_VF_VLAN_INFO_MAX - 1)
+
+struct ifla_vf_vlan_info {
+   __u32 vf;
+   __u32 vlan; /* 0 - 4095, 0 disables VLAN filter */
+   __u32 qos;
+   __be16 vlan_proto; /* VLAN protocol either 802.1Q or 802.1ad */
+};
+
 struct ifla_vf_tx_rate {
__u32 vf;
__u32 rate; /* Max TX bandwidth in Mbps, 0 disables throttling */
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index fcc3c538d1bd..a12c34e03664 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -321,7 +321,6 @@ static void print_vf_stats64(FILE *fp, struct rtattr 
*vfstats);
 static void print_vfinfo(FILE *fp, struct rtattr *vfinfo)
 {
struct ifla_vf_mac *vf_mac;
-   struct ifla_vf_vlan *vf_vlan;
struct ifla_vf_tx_rate *vf_tx_rate;
struct ifla_vf_spoofchk *vf_spoofchk;
struct ifla_vf_link_state *vf_linkstate;
@@ -338,7 +337,6 @@ static void print_vfinfo(FILE *fp, struct rtattr *vfinfo)
parse_rtattr_nested(vf, IFLA_VF_MAX, vfinfo);
 
vf_mac = RTA_DATA(vf[IFLA_VF_MAC]);
-   vf_vlan = RTA_DATA(vf[IFLA_VF_VLAN]);
vf_tx_rate = RTA_DATA(vf[IFLA_VF_TX_RATE]);
 
/* Check if the spoof checking vf info type is supported by
@@ -369,10 +367,35 @@ static void print_vfinfo(FILE *fp, struct rtattr *vfinfo)
fprintf(fp, "%svf %d MAC %s", _SL_, vf_mac->vf,
ll_addr_n2a((unsigned char *)&vf_mac->mac,
ETH_ALEN, 0, b1, sizeof(b1)));
-   if (vf_vlan->vlan)
-   fprintf(fp, ", vlan %d", vf_vlan->vlan);
-   if (vf_vlan->qos)
-   fprintf(fp, ", qos %d", vf_vlan->qos);
+   if (vf[IFLA_VF_VLAN_LIST]) {
+   struct rtattr *i, *vfvlanlist = vf[IFLA_VF_VLAN_LIST];
+   int rem = RTA_PAYLOAD(vfvlanlist);
+
+   for (i = RTA_DATA(vfvlanlist);
+ RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
+   struct ifla_vf_vlan_info *vf_vlan_info =
+   RTA_DATA(i);
+   SPRINT_BUF(b2);
+
+   if (vf_vlan_info->vlan)
+   fprintf(fp, ", vlan %d", vf_vlan_info->vlan);
+   if (vf_vlan_info->qos)
+   fprintf(fp, ", qos %d", vf_vlan_info->qos);
+   if (vf_vlan_info->vlan_proto &&
+   vf_vlan_info->vlan_proto != htons(ETH_P_8021Q))
+   fprintf(fp, ", vlan protocol %s",
+   ll_proto_n2a(vf_vlan_info->vlan_proto,
+b2, sizeof(b2)