All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] VGT+ support
@ 2019-10-30 19:17 Ariel Levkovich
  2019-10-30 19:17 ` [PATCH 1/3] ip: Allow query link with extended vf properties Ariel Levkovich
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Ariel Levkovich @ 2019-10-30 19:17 UTC (permalink / raw)
  To: netdev; +Cc: Jiri Pirko, Ariel Levkovich

The following series introduces VGT+ support for SRIOV vf
devices.

VGT+ is an extention of the VGT (Virtual Guest Tagging)
where the guest is in charge of vlan tagging the packets
only with VGT+ the admin can limit the allowed vlan ids
the guest can use to a specific vlan trunk list.

The patches provide the API for admin users to set and
query these vlan trunk lists on the vfs using ip link
command.

Ariel Levkovich (3):
  ip: Allow query link with extended vf properties
  ip: Present the VF VLAN tagging mode
  ip: Add SR-IOV VF VGT+ support

 include/uapi/linux/if_link.h   | 34 ++++++++++++++++
 include/uapi/linux/rtnetlink.h |  1 +
 ip/ip_common.h                 |  2 +-
 ip/ipaddress.c                 | 89 +++++++++++++++++++++++++++++++++++++++++-
 ip/iplink.c                    | 52 +++++++++++++++++++++++-
 man/man8/ip-link.8.in          | 30 +++++++++++++-
 6 files changed, 201 insertions(+), 7 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/3] ip: Allow query link with extended vf properties
  2019-10-30 19:17 [PATCH 0/3] VGT+ support Ariel Levkovich
@ 2019-10-30 19:17 ` Ariel Levkovich
  2019-10-30 19:17 ` [PATCH 3/3] ip: Add SR-IOV VF VGT+ support Ariel Levkovich
  2019-10-30 19:17 ` [PATCH 2/3] ip: Present the VF VLAN tagging mode Ariel Levkovich
  2 siblings, 0 replies; 6+ messages in thread
From: Ariel Levkovich @ 2019-10-30 19:17 UTC (permalink / raw)
  To: netdev; +Cc: Jiri Pirko, Ariel Levkovich

Adding vf num filter to ip link show command for querying
extended information of a specific vf.

When specifying a vf num, the kernel may return additional
vf information that takes up large amount of memory and
can't be included when querying the entire list of vfs
due to attribute size limitation.

The usage is:
ip link show dev <ifname> vf <vf_num>

Only the specified VF's information will be returned
and presented in this case.

Signed-off-by: Ariel Levkovich <lariel@mellanox.com>
---
 include/uapi/linux/if_link.h   |  1 +
 include/uapi/linux/rtnetlink.h |  1 +
 ip/ip_common.h                 |  2 +-
 ip/ipaddress.c                 | 16 +++++++++++++++-
 ip/iplink.c                    |  6 ++++--
 man/man8/ip-link.8.in          | 13 ++++++++++++-
 6 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 1c49f43..d39017b 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -169,6 +169,7 @@ enum {
 	IFLA_MAX_MTU,
 	IFLA_PROP_LIST,
 	IFLA_ALT_IFNAME, /* Alternative ifname */
+	IFLA_VF_NUM,
 	__IFLA_MAX
 };
 
diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
index 4b93791..8fc7f5d 100644
--- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h
@@ -758,6 +758,7 @@ enum {
 #define RTEXT_FILTER_BRVLAN	(1 << 1)
 #define RTEXT_FILTER_BRVLAN_COMPRESSED	(1 << 2)
 #define	RTEXT_FILTER_SKIP_STATS	(1 << 3)
+#define	RTEXT_FILTER_VF_EXT	(1 << 4)
 
 /* End of information exported to user level */
 
diff --git a/ip/ip_common.h b/ip/ip_common.h
index cd916ec..4151232 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -83,7 +83,7 @@ int netns_identify_pid(const char *pidstr, char *name, int len);
 int do_seg6(int argc, char **argv);
 int do_ipnh(int argc, char **argv);
 
-int iplink_get(char *name, __u32 filt_mask);
+int iplink_get(char *name, __u32 filt_mask, int vf);
 int iplink_ifla_xstats(int argc, char **argv);
 
 int ip_link_list(req_filter_fn_t filter_fn, struct nlmsg_chain *linfo);
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index bc8f5ba..0521fdc 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -1874,9 +1874,11 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
 {
 	struct nlmsg_chain linfo = { NULL, NULL};
 	struct nlmsg_chain _ainfo = { NULL, NULL}, *ainfo = &_ainfo;
+	int filter_mask = RTEXT_FILTER_VF;
 	struct nlmsg_list *l;
 	char *filter_dev = NULL;
 	int no_link = 0;
+	int vf = -1;
 
 	ipaddr_reset_filter(oneline, 0);
 	filter.showqueue = 1;
@@ -1953,6 +1955,18 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
 			} else {
 				filter.kind = *argv;
 			}
+		} else if (strcmp(*argv, "vf") == 0) {
+			if (vf >= 0)
+				duparg2("vf", *argv);
+
+			if (!filter_dev)
+				missarg("dev");
+
+			NEXT_ARG();
+			if (get_integer(&vf,  *argv, 0))
+				invarg("Invalid \"vf\" value\n", *argv);
+			else
+				filter_mask = RTEXT_FILTER_VF_EXT;
 		} else {
 			if (strcmp(*argv, "dev") == 0)
 				NEXT_ARG();
@@ -2006,7 +2020,7 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
 	 * the link device
 	 */
 	if (filter_dev && filter.group == -1 && do_link == 1) {
-		if (iplink_get(filter_dev, RTEXT_FILTER_VF) < 0) {
+		if (iplink_get(filter_dev, filter_mask, vf) < 0) {
 			perror("Cannot send link get request");
 			delete_json_obj();
 			exit(1);
diff --git a/ip/iplink.c b/ip/iplink.c
index 212a088..ef33232 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -107,7 +107,7 @@ void iplink_usage(void)
 		"			[ protodown { on | off } ]\n"
 		"			[ gso_max_size BYTES ] | [ gso_max_segs PACKETS ]\n"
 		"\n"
-		"	ip link show [ DEVICE | group GROUP ] [up] [master DEV] [vrf NAME] [type TYPE]\n"
+		"	ip link show [ DEVICE | group GROUP ] [up] [master DEV] [vrf NAME] [type TYPE] [vf VF_NUM]\n"
 		"\n"
 		"	ip link xstats type TYPE [ ARGS ]\n"
 		"\n"
@@ -1092,7 +1092,7 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
 	return 0;
 }
 
-int iplink_get(char *name, __u32 filt_mask)
+int iplink_get(char *name, __u32 filt_mask, int vf)
 {
 	struct iplink_req req = {
 		.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
@@ -1107,6 +1107,8 @@ int iplink_get(char *name, __u32 filt_mask)
 			  IFLA_IFNAME, name, strlen(name) + 1);
 	}
 	addattr32(&req.n, sizeof(req), IFLA_EXT_MASK, filt_mask);
+	if (filt_mask & RTEXT_FILTER_VF_EXT)
+		addattr32(&req.n, sizeof(req), IFLA_VF_NUM, vf);
 
 	if (rtnl_talk(&rth, &req.n, &answer) < 0)
 		return -2;
diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in
index a8ae72d..29744d4 100644
--- a/man/man8/ip-link.8.in
+++ b/man/man8/ip-link.8.in
@@ -176,7 +176,9 @@ ip-link \- network device configuration
 .B type
 .IR ETYPE " ] ["
 .B vrf
-.IR NAME " ]"
+.IR NAME " ] ["
+.B vf
+.IR NUM " ]"
 
 .ti -8
 .B ip link xstats
@@ -2396,6 +2398,15 @@ interface list by comparing it with the relevant attribute in case the kernel
 didn't filter already. Therefore any string is accepted, but may lead to empty
 output.
 
+.TP
+.BI vf " NUM "
+.I NUM
+specifies a Virtual Function device to be configured.
+
+The associated PF device must be specified using the
+.B dev
+parameter.
+
 .SS  ip link xstats - display extended statistics
 
 .TP
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/3] ip: Present the VF VLAN tagging mode
  2019-10-30 19:17 [PATCH 0/3] VGT+ support Ariel Levkovich
  2019-10-30 19:17 ` [PATCH 1/3] ip: Allow query link with extended vf properties Ariel Levkovich
  2019-10-30 19:17 ` [PATCH 3/3] ip: Add SR-IOV VF VGT+ support Ariel Levkovich
@ 2019-10-30 19:17 ` Ariel Levkovich
  2019-10-30 23:29   ` Stephen Hemminger
  2 siblings, 1 reply; 6+ messages in thread
From: Ariel Levkovich @ 2019-10-30 19:17 UTC (permalink / raw)
  To: netdev; +Cc: Jiri Pirko, Ariel Levkovich

The change prints the VLAN tagging mode per VF on
link query.

The possible modes are:
1) VGT - Virtual Guest tagging mode.
2) VST - Virtual Switch tagging mode.
3) Trunk - Guest tagging mode with specific allowed VLAN access list.

For the full VLAN ids list in Trunk mode, it is required to
query the specific VF.

Signed-off-by: Ariel Levkovich <lariel@mellanox.com>
---
 include/uapi/linux/if_link.h | 14 ++++++++++++++
 ip/ipaddress.c               | 21 ++++++++++++++++++++-
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index d39017b..6304add 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -697,6 +697,7 @@ enum {
 	IFLA_VF_IB_PORT_GUID,	/* VF Infiniband port GUID */
 	IFLA_VF_VLAN_LIST,	/* nested list of vlans, option for QinQ */
 	IFLA_VF_BROADCAST,	/* VF broadcast */
+	IFLA_VF_VLAN_MODE,	/* vlan tagging mode */
 	__IFLA_VF_MAX,
 };
 
@@ -711,6 +712,19 @@ struct ifla_vf_broadcast {
 	__u8 broadcast[32];
 };
 
+enum {
+	IFLA_VF_VLAN_MODE_UNSPEC,
+	IFLA_VF_VLAN_MODE_VGT,
+	IFLA_VF_VLAN_MODE_VST,
+	IFLA_VF_VLAN_MODE_TRUNK,
+	__IFLA_VF_VLAN_MODE_MAX,
+};
+
+struct ifla_vf_vlan_mode {
+	__u32 vf;
+	__u32 mode; /* The VLAN tagging mode */
+};
+
 struct ifla_vf_vlan {
 	__u32 vf;
 	__u32 vlan; /* 0 - 4095, 0 disables VLAN filter */
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 0521fdc..a66ca02 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -357,7 +357,6 @@ static void print_vfinfo(FILE *fp, struct ifinfomsg *ifi, struct rtattr *vfinfo)
 	struct ifla_vf_broadcast *vf_broadcast;
 	struct ifla_vf_tx_rate *vf_tx_rate;
 	struct rtattr *vf[IFLA_VF_MAX + 1] = {};
-
 	SPRINT_BUF(b1);
 
 	if (vfinfo->rta_type != IFLA_VF_INFO) {
@@ -404,6 +403,26 @@ static void print_vfinfo(FILE *fp, struct ifinfomsg *ifi, struct rtattr *vfinfo)
 					       b1, sizeof(b1)));
 	}
 
+	if (vf[IFLA_VF_VLAN_MODE]) {
+		struct ifla_vf_vlan_mode *vlan_mode = RTA_DATA(vf[IFLA_VF_VLAN_MODE]);
+
+		if (vlan_mode->mode == IFLA_VF_VLAN_MODE_TRUNK)
+			print_string(PRINT_ANY,
+				     "vlan-mode",
+				      ", vlan-mode %s",
+				      "trunk");
+		else if (vlan_mode->mode == IFLA_VF_VLAN_MODE_VST)
+			print_string(PRINT_ANY,
+				     "vlan-mode",
+				     ", vlan_mode %s",
+				     "vst");
+		else if (vlan_mode->mode == IFLA_VF_VLAN_MODE_VGT)
+			print_string(PRINT_ANY,
+				     "vlan-mode",
+				     ", vlan-mode %s",
+				     "vgt");
+	}
+
 	if (vf[IFLA_VF_VLAN_LIST]) {
 		struct rtattr *i, *vfvlanlist = vf[IFLA_VF_VLAN_LIST];
 		int rem = RTA_PAYLOAD(vfvlanlist);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/3] ip: Add SR-IOV VF VGT+ support
  2019-10-30 19:17 [PATCH 0/3] VGT+ support Ariel Levkovich
  2019-10-30 19:17 ` [PATCH 1/3] ip: Allow query link with extended vf properties Ariel Levkovich
@ 2019-10-30 19:17 ` Ariel Levkovich
  2019-10-30 19:17 ` [PATCH 2/3] ip: Present the VF VLAN tagging mode Ariel Levkovich
  2 siblings, 0 replies; 6+ messages in thread
From: Ariel Levkovich @ 2019-10-30 19:17 UTC (permalink / raw)
  To: netdev; +Cc: Jiri Pirko, Ariel Levkovich

Introduce a new API that can add/remove allowed vlan-ids per VF to
support the VGT+ feature.
Also intoroduce a new API to query the current allowed vlan-ids per VF.

VGT+ is a security feature that gives the administrator the ability of
controlling the allowed vlan-ids list that can be transmitted/received
from/to the VF.
The allowed vlan-ids list is called "trunk".
Admin can add/delete a range of allowed vlan-ids via iptool.

Example:
After this series of configuration :
1) ip link set eth3 vf 0 trunk add 10 100 (allow vlan-id 10-100, default tpid 0x8100)
2) ip link set eth3 vf 0 trunk add 105 proto 802.1q (allow vlan-id 105 tpid 0x8100)
3) ip link set eth3 vf 0 trunk add 105 proto 802.1ad (allow vlan-id 105 tpid 0x88a8)
4) ip link set eth3 vf 0 trunk rem 90 (block vlan-id 90)
5) ip link set eth3 vf 0 trunk rem 50 60 (block vlan-ids 50-60)
The VF 0 can only communicate on vlan-ids: 10-49,61-89,91-100,105 with tpid 0x8100
and vlan-id 105 with tpid 0x88a8.

For this purpose we added the following netlink sr-iov commands:
1) IFLA_VF_VLAN_RANGE: used to add/remove allowed vlan-ids range.
we added the ifla_vf_vlan_range struct to specify the range we want to
add/remove from the userspace.
2) IFLA_VF_VLAN_TRUNK: used to query the allowed vlan-ids trunk.
we added ifla_vf_vlan_trunk struct for sending the allowed vlan-ids
trunk to the userspace.
The allowed vlan-ids will be presented only when the query is for
a specific vf.

Example:
Running the following command will set the vlan trunk to include 10-100:
1)ip link set eth3 vf 0 trunk add 10 100

Then running:
2)ip link show dev eth3 vf 0
Will show:
vf 0     link/ether 00:00:00:00:00:00 brd 00:00:00:00:00:f3, spoof checking off, link-state auto, trust off, query_rss off
    Allowed 802.1Q VLANs: 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
    29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
    53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
    77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100.

Signed-off-by: Ariel Levkovich <lariel@mellanox.com>
---
 include/uapi/linux/if_link.h | 19 ++++++++++++++++
 ip/ipaddress.c               | 52 ++++++++++++++++++++++++++++++++++++++++++++
 ip/iplink.c                  | 46 +++++++++++++++++++++++++++++++++++++++
 man/man8/ip-link.8.in        | 17 ++++++++++++++-
 4 files changed, 133 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 6304add..ff29803 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -698,6 +698,8 @@ enum {
 	IFLA_VF_VLAN_LIST,	/* nested list of vlans, option for QinQ */
 	IFLA_VF_BROADCAST,	/* VF broadcast */
 	IFLA_VF_VLAN_MODE,	/* vlan tagging mode */
+	IFLA_VF_VLAN_RANGE,	/* VF add/remove vlan-ids range */
+	IFLA_VF_VLAN_TRUNK,	/* VF allowed vlan-ids trunk */
 	__IFLA_VF_MAX,
 };
 
@@ -747,6 +749,23 @@ struct ifla_vf_vlan_info {
 	__be16 vlan_proto; /* VLAN protocol either 802.1Q or 802.1ad */
 };
 
+struct ifla_vf_vlan_range {
+	__u32 vf;
+	__u32 start_vid;   /* 0 - 4095, 0 - for untagged and priority tagged */
+	__u32 end_vid;     /* 0 - 4095, 0 - for untagged and priority tagged */
+	__u32 setting;     /* 0 : Add range , 1 : Remove range */
+	__be16 vlan_proto; /* VLAN protocol either 802.1Q or 802.1ad */
+};
+
+#define BITS_PER_BYTE		8
+#define VLAN_N_VID		4096
+#define VF_VLAN_BITMAP		__KERNEL_DIV_ROUND_UP(VLAN_N_VID, sizeof(__u64) * BITS_PER_BYTE)
+struct ifla_vf_vlan_trunk {
+	__u32 vf;
+	__u64 trunk_vid_8021q_bitmap[VF_VLAN_BITMAP];
+	__u64 trunk_vid_8021ad_bitmap[VF_VLAN_BITMAP];
+};
+
 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 a66ca02..90efbff 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -350,6 +350,7 @@ static void print_af_spec(FILE *fp, struct rtattr *af_spec_attr)
 }
 
 static void print_vf_stats64(FILE *fp, struct rtattr *vfstats);
+static void print_vf_vlan_trunk(FILE *fp, __u64 *bitmap, const char *proto);
 
 static void print_vfinfo(FILE *fp, struct ifinfomsg *ifi, struct rtattr *vfinfo)
 {
@@ -548,6 +549,18 @@ static void print_vfinfo(FILE *fp, struct ifinfomsg *ifi, struct rtattr *vfinfo)
 
 	if (vf[IFLA_VF_STATS] && show_stats)
 		print_vf_stats64(fp, vf[IFLA_VF_STATS]);
+
+	/*
+	 * VF trunk query should always be the last if-condition because it adds
+	 * new lines to the end of the vf info output.
+	 */
+	if (vf[IFLA_VF_VLAN_TRUNK]) {
+		struct ifla_vf_vlan_trunk *vf_trunk =
+				RTA_DATA(vf[IFLA_VF_VLAN_TRUNK]);
+
+		print_vf_vlan_trunk(fp, vf_trunk->trunk_vid_8021q_bitmap, "802.1Q");
+		print_vf_vlan_trunk(fp, vf_trunk->trunk_vid_8021ad_bitmap, "802.1ad");
+	}
 }
 
 void print_num(FILE *fp, unsigned int width, uint64_t count)
@@ -590,6 +603,45 @@ void print_num(FILE *fp, unsigned int width, uint64_t count)
 	fprintf(fp, "%-*s ", width, buf);
 }
 
+static void print_vf_vlan_trunk(FILE *fp, __u64 *bitmap, const char *proto)
+{
+#define VF_VLAN_TRUNK_LINE_SZ	100
+	int vids_per_dword = sizeof(bitmap[0]) * 8;
+	char trunk_line[2 * VF_VLAN_TRUNK_LINE_SZ] = {0};
+	bool printed_title = false;
+	bool need_newline = false;
+	int vid;
+
+	for (vid = 0; vid < VLAN_N_VID ; vid++) {
+		if ((bitmap[vid / vids_per_dword] >> (vid % vids_per_dword)) & 0x1) {
+			if (strlen(trunk_line) >= VF_VLAN_TRUNK_LINE_SZ)
+				need_newline = true;
+
+			if (!printed_title) {
+				sprintf(trunk_line,
+					"\n    Allowed %s VLANs: ", proto);
+				printed_title = true;
+			}
+
+			if (need_newline) {
+				fprintf(fp, "%s", trunk_line);
+				trunk_line[0] = '\0';
+			}
+
+			sprintf(trunk_line, "%s%s%d, ", trunk_line,
+				(need_newline ? "\n    " : ""), vid);
+
+			need_newline = false;
+		}
+	}
+
+	if (strlen(trunk_line)) {
+		trunk_line[strlen(trunk_line) - 2] = '.';
+		trunk_line[strlen(trunk_line) - 1] = '\0';
+		fprintf(fp, "%s", trunk_line);
+	}
+}
+
 static void print_vf_stats64(FILE *fp, struct rtattr *vfstats)
 {
 	struct rtattr *vf[IFLA_VF_STATS_MAX + 1];
diff --git a/ip/iplink.c b/ip/iplink.c
index ef33232..31076fc 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -89,6 +89,7 @@ void iplink_usage(void)
 		"			[ alias NAME ]\n"
 		"			[ vf NUM [ mac LLADDR ]\n"
 		"				 [ vlan VLANID [ qos VLAN-QOS ] [ proto VLAN-PROTO ] ]\n"
+		"				 [ trunk { add | rem } START-VLANID [ END-VLANID ] [ proto VLAN-PROTO ] ]\n"
 		"				 [ rate TXRATE ]\n"
 		"				 [ max_tx_rate TXRATE ]\n"
 		"				 [ min_tx_rate TXRATE ]\n"
@@ -429,6 +430,51 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp,
 				}
 				addattr_nest_end(&req->n, vfvlanlist);
 			}
+		} else if (matches(*argv, "trunk") == 0) {
+			struct ifla_vf_vlan_range ivvr;
+
+			ivvr.vf = vf;
+			ivvr.vlan_proto = htons(ETH_P_8021Q);
+			NEXT_ARG();
+			if (matches(*argv, "add") && matches(*argv, "rem"))
+				invarg("Invalid \"trunk\" operation\n", *argv);
+			ivvr.setting = !matches(*argv, "add");
+			NEXT_ARG();
+			if (get_unsigned(&ivvr.start_vid, *argv, 0))
+				invarg("Invalid \"trunk\" start value\n", *argv);
+			ivvr.end_vid = ivvr.start_vid;
+			if (NEXT_ARG_OK()) {
+				NEXT_ARG();
+				if (get_unsigned(&ivvr.end_vid, *argv, 0))
+					PREV_ARG();
+			}
+			if (NEXT_ARG_OK()) {
+				NEXT_ARG();
+				if (matches(*argv, "proto") == 0) {
+					NEXT_ARG();
+					if (ll_proto_a2n(&ivvr.vlan_proto, *argv))
+						invarg("protocol is invalid\n", *argv);
+					if (ivvr.vlan_proto != htons(ETH_P_8021AD) &&
+					    ivvr.vlan_proto != htons(ETH_P_8021Q)) {
+						SPRINT_BUF(b1);
+						SPRINT_BUF(b2);
+						char msg[64 + sizeof(b1) + sizeof(b2)];
+
+						sprintf(msg,
+							"Invalid \"vlan protocol\" value - supported %s, %s\n",
+							ll_proto_n2a(htons(ETH_P_8021Q),
+								     b1, sizeof(b1)),
+							ll_proto_n2a(htons(ETH_P_8021AD),
+								     b2, sizeof(b2)));
+						invarg(msg, *argv);
+					}
+				} else {
+					/* rewind arg */
+					PREV_ARG();
+				}
+			}
+			addattr_l(&req->n, sizeof(*req),
+				  IFLA_VF_VLAN_RANGE, &ivvr, sizeof(ivvr));
 		} else if (matches(*argv, "rate") == 0) {
 			struct ifla_vf_tx_rate ivt;
 
diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in
index 29744d4..23f6235 100644
--- a/man/man8/ip-link.8.in
+++ b/man/man8/ip-link.8.in
@@ -128,7 +128,12 @@ ip-link \- network device configuration
 .br
 .RB "[ " node_guid " eui64 ]"
 .br
-.RB "[ " port_guid " eui64 ] ]"
+.RB "[ " port_guid " eui64 ]"
+.br
+.RB "[ " trunk " { " add " | " rem " } "
+.IR START-VLAN-ID " [ " END-VLAN-ID " ] "
+.RB "[ " proto
+.IR VLAN-PROTO " ] ] ] "
 .br
 .in -9
 .RB "[ { " xdp " | " xdpgeneric  " | " xdpdrv " | " xdpoffload " } { " off " | "
@@ -2043,6 +2048,16 @@ performance. (e.g. VF multicast promiscuous mode)
 .sp
 .BI port_guid " eui64"
 - configure port GUID for Infiniband VFs.
+.sp
+.BI trunk " add|rem START-VLANID [END-VLANID] [proto VLAN-PROTO] "
+- add or remove allowed vlan-ids range that can be used by the VF. Range 0-4095
+while 0 is used for untagged and priority tagged traffic.
+.B vf
+parameter must be specified.
+.B END-VLANID
+parameter is optional. If omitted, assumes range of one vlan-id.
+.B proto
+parameter is optional, either 802.1Q or 802.1ad. If omitted, assumes 802.1Q.
 .in -8
 
 .TP
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/3] ip: Present the VF VLAN tagging mode
  2019-10-30 19:17 ` [PATCH 2/3] ip: Present the VF VLAN tagging mode Ariel Levkovich
@ 2019-10-30 23:29   ` Stephen Hemminger
  2019-10-31 14:50     ` Ariel Levkovich
  0 siblings, 1 reply; 6+ messages in thread
From: Stephen Hemminger @ 2019-10-30 23:29 UTC (permalink / raw)
  To: Ariel Levkovich; +Cc: netdev, Jiri Pirko

On Wed, 30 Oct 2019 19:17:32 +0000
Ariel Levkovich <lariel@mellanox.com> wrote:

> +		if (vlan_mode->mode == IFLA_VF_VLAN_MODE_TRUNK)
> +			print_string(PRINT_ANY,
> +				     "vlan-mode",
> +				      ", vlan-mode %s",
> +				      "trunk");
> +		else if (vlan_mode->mode == IFLA_VF_VLAN_MODE_VST)
> +			print_string(PRINT_ANY,
> +				     "vlan-mode",
> +				     ", vlan_mode %s",
> +				     "vst");
> +		else if (vlan_mode->mode == IFLA_VF_VLAN_MODE_VGT)
> +			print_string(PRINT_ANY,
> +				     "vlan-mode",
> +				     ", vlan-mode %s",
> +				     "vgt");

This seems like you want something like:

		print_string(PRINT_ANY, "vlan-mode", ", vlan-mode %s",
				vlan_mode_str(vlan_mode->mode);

and why the comma in the output? the convention for ip commands is that
the output format is equivalent to the command line.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: [PATCH 2/3] ip: Present the VF VLAN tagging mode
  2019-10-30 23:29   ` Stephen Hemminger
@ 2019-10-31 14:50     ` Ariel Levkovich
  0 siblings, 0 replies; 6+ messages in thread
From: Ariel Levkovich @ 2019-10-31 14:50 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Jiri Pirko

On Wed, 30 Oct 2019 19:29:32 +0000
Stephen Hemminger <stephen@networkplumber.org> wrote
> On Wed, 30 Oct 2019 19:17:32 +0000
> Ariel Levkovich <lariel@mellanox.com> wrote:
> 
> > +		if (vlan_mode->mode == IFLA_VF_VLAN_MODE_TRUNK)
> > +			print_string(PRINT_ANY,
> > +				     "vlan-mode",
> > +				      ", vlan-mode %s",
> > +				      "trunk");
> > +		else if (vlan_mode->mode == IFLA_VF_VLAN_MODE_VST)
> > +			print_string(PRINT_ANY,
> > +				     "vlan-mode",
> > +				     ", vlan_mode %s",
> > +				     "vst");
> > +		else if (vlan_mode->mode == IFLA_VF_VLAN_MODE_VGT)
> > +			print_string(PRINT_ANY,
> > +				     "vlan-mode",
> > +				     ", vlan-mode %s",
> > +				     "vgt");
> 
> This seems like you want something like:
> 
> 		print_string(PRINT_ANY, "vlan-mode", ", vlan-mode %s",
> 				vlan_mode_str(vlan_mode->mode);
> 
> and why the comma in the output? the convention for ip commands is that
> the output format is equivalent to the command line.
Thanks for your review Stephen.
I'll fix the if/else to the suggested line.
I see the comma is used when presenting other VF attributes as well like link-state, spoof, trust.
So what is the right convention here?

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2019-10-31 14:50 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-30 19:17 [PATCH 0/3] VGT+ support Ariel Levkovich
2019-10-30 19:17 ` [PATCH 1/3] ip: Allow query link with extended vf properties Ariel Levkovich
2019-10-30 19:17 ` [PATCH 3/3] ip: Add SR-IOV VF VGT+ support Ariel Levkovich
2019-10-30 19:17 ` [PATCH 2/3] ip: Present the VF VLAN tagging mode Ariel Levkovich
2019-10-30 23:29   ` Stephen Hemminger
2019-10-31 14:50     ` Ariel Levkovich

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.