From: Greg Rose <gregory.v.rose@intel.com>
Date: Thu, 13 Oct 2011 20:31:32 +0000
Subject: iproute2: Add new command to ip link to enable/disable VF spoof check
Patch-mainline: v3.2.0
Git-commit: 7b8179c780a1abd547e5002c4e6fba898c6d72bb
References: bnc#838349

Add ip link command parsing for VF spoof checking enable/disable

V2 - Fixed problem with parsing of dump info on kernels that don't
     support the spoof checking option and also wrapped the ifla_vf_info
     structure in #ifdef __KERNEL__ to prevent user space from directly
     accessing the structure
V3 - Improved parsing of vfinfo
V4 - Put Makefile back to proper list of subdirs
V5 - Remove struct ifla_vf_info, it is only used by the kernel
V6 - Make sure spoof check is reported by the driver - rtnl will set
     it to -1 to indicate driver didn't report a value.

Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

Conflicts:
	ip/iplink.c
	man/man8/ip.8

SLE11-SP3: also included relevant part of

  9044a454  Update to 3.2.0-rc2 headers
---
 include/linux/if_link.h |  6 ++++++
 ip/ipaddress.c          | 19 +++++++++++++++++++
 ip/iplink.c             | 15 +++++++++++++++
 man/man8/ip.8           |  4 +++-
 4 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 04bdbb6..a58e3e4 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -218,6 +218,7 @@ enum {
 	IFLA_VF_MAC,		/* Hardware queue specific attributes */
 	IFLA_VF_VLAN,
 	IFLA_VF_TX_RATE,	/* TX Bandwidth Allocation */
+	IFLA_VF_SPOOFCHK,	/* Spoof Checking on/off switch */
 	__IFLA_VF_MAX,
 };
 
@@ -239,6 +240,11 @@ struct ifla_vf_tx_rate {
    __u32 rate; /* Max TX bandwidth in Mbps, 0 disables throttling */
 };
 
+struct ifla_vf_spoofchk {
+	__u32 vf;
+	__u32 setting;
+};
+
 struct ifla_vf_info {
    __u32 vf;
    __u8 mac[32];
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 691a098..140ffef 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -192,7 +192,9 @@ 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 rtattr *vf[IFLA_VF_MAX+1];
+	struct rtattr *tmp;
 	SPRINT_BUF(b1);
 
 	if (vfinfo->rta_type != IFLA_VF_INFO) {
@@ -206,6 +208,17 @@ static void print_vfinfo(FILE *fp, struct rtattr *vfinfo)
 	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
+	 * this kernel.
+	 */
+	tmp = (struct rtattr *)((char *)vf[IFLA_VF_TX_RATE] +
+			vf[IFLA_VF_TX_RATE]->rta_len);
+
+	if (tmp->rta_type != IFLA_VF_SPOOFCHK)
+		vf_spoofchk = NULL;
+	else
+		vf_spoofchk = RTA_DATA(vf[IFLA_VF_SPOOFCHK]);
+
 	fprintf(fp, "\n    vf %d MAC %s", vf_mac->vf,
 		ll_addr_n2a((unsigned char *)&vf_mac->mac,
 		ETH_ALEN, 0, b1, sizeof(b1)));
@@ -215,6 +228,12 @@ static void print_vfinfo(FILE *fp, struct rtattr *vfinfo)
 		fprintf(fp, ", qos %d", vf_vlan->qos);
 	if (vf_tx_rate->rate)
 		fprintf(fp, ", tx rate %d (Mbps)", vf_tx_rate->rate);
+	if (vf_spoofchk && vf_spoofchk->setting != -1) {
+		if (vf_spoofchk->setting)
+			fprintf(fp, ", spoof checking on");
+		else
+			fprintf(fp, ", spoof checking off");
+	}
 }
 
 int print_linkinfo(const struct sockaddr_nl *who,
diff --git a/ip/iplink.c b/ip/iplink.c
index d90c31f..0075190 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -71,7 +71,10 @@ void iplink_usage(void)
 	fprintf(stderr, "			  [ alias NAME ]\n");
 	fprintf(stderr, "	                  [ vf NUM [ mac LLADDR ]\n");
 	fprintf(stderr, "				   [ vlan VLANID [ qos VLAN-QOS ] ]\n");
+
 	fprintf(stderr, "				   [ rate TXRATE ] ] \n");
+
+	fprintf(stderr, "				   [ spoofchk { on | off} ] ] \n");
 	fprintf(stderr, "       ip link show [ DEVICE ]\n");
 
 	if (iplink_have_newlink()) {
@@ -226,6 +229,18 @@ int iplink_parse_vf(int vf, int *argcp, char ***argvp,
 			ivt.vf = vf;
 			addattr_l(&req->n, sizeof(*req), IFLA_VF_TX_RATE, &ivt, sizeof(ivt));
 		
+		} else if (matches(*argv, "spoofchk") == 0) {
+			struct ifla_vf_spoofchk ivs;
+			NEXT_ARG();
+			if (matches(*argv, "on") == 0)
+				ivs.setting = 1;
+			else if (matches(*argv, "off") == 0)
+				ivs.setting = 0;
+			else
+				invarg("Invalid \"spoofchk\" value\n", *argv);
+			ivs.vf = vf;
+			addattr_l(&req->n, sizeof(*req), IFLA_VF_SPOOFCHK, &ivs, sizeof(ivs));
+
 		} else {
 			/* rewind arg */
 			PREV_ARG();
diff --git a/man/man8/ip.8 b/man/man8/ip.8
index 89504f6..5760388 100644
--- a/man/man8/ip.8
+++ b/man/man8/ip.8
@@ -98,7 +98,9 @@ ip \- show / manipulate routing, devices, policy routing and tunnels
 .B qos
 .IR VLAN-QOS " ] ] ["
 .B rate
-.IR TXRATE " ]"
+.IR TXRATE " ] ["
+.B spoofchk { on | off }
+]
 .BR " }"
 
 
-- 
1.8.1.4

