forked from mirrors/linux
		
	net/core: Add VF link state control
Add netlink directives and ndo entry to allow for controling VF link, which can be in one of three states: Auto - VF link state reflects the PF link state (default) Up - VF link state is up, traffic from VF to VF works even if the actual PF link is down Down - VF link state is down, no traffic from/to this VF, can be of use while configuring the VF Signed-off-by: Rony Efraim <ronye@mellanox.com> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									3dc6475c0c
								
							
						
					
					
						commit
						1d8faf48c7
					
				
					 4 changed files with 37 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -12,5 +12,6 @@ struct ifla_vf_info {
 | 
			
		|||
	__u32 qos;
 | 
			
		||||
	__u32 tx_rate;
 | 
			
		||||
	__u32 spoofchk;
 | 
			
		||||
	__u32 linkstate;
 | 
			
		||||
};
 | 
			
		||||
#endif /* _LINUX_IF_LINK_H */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -829,6 +829,7 @@ struct netdev_fcoe_hbainfo {
 | 
			
		|||
 * int (*ndo_set_vf_spoofchk)(struct net_device *dev, int vf, bool setting);
 | 
			
		||||
 * int (*ndo_get_vf_config)(struct net_device *dev,
 | 
			
		||||
 *			    int vf, struct ifla_vf_info *ivf);
 | 
			
		||||
 * int (*ndo_set_vf_link_state)(struct net_device *dev, int vf, int link_state);
 | 
			
		||||
 * int (*ndo_set_vf_port)(struct net_device *dev, int vf,
 | 
			
		||||
 *			  struct nlattr *port[]);
 | 
			
		||||
 * int (*ndo_get_vf_port)(struct net_device *dev, int vf, struct sk_buff *skb);
 | 
			
		||||
| 
						 | 
				
			
			@ -986,6 +987,8 @@ struct net_device_ops {
 | 
			
		|||
	int			(*ndo_get_vf_config)(struct net_device *dev,
 | 
			
		||||
						     int vf,
 | 
			
		||||
						     struct ifla_vf_info *ivf);
 | 
			
		||||
	int			(*ndo_set_vf_link_state)(struct net_device *dev,
 | 
			
		||||
							 int vf, int link_state);
 | 
			
		||||
	int			(*ndo_set_vf_port)(struct net_device *dev,
 | 
			
		||||
						   int vf,
 | 
			
		||||
						   struct nlattr *port[]);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -338,6 +338,7 @@ enum {
 | 
			
		|||
	IFLA_VF_VLAN,
 | 
			
		||||
	IFLA_VF_TX_RATE,	/* TX Bandwidth Allocation */
 | 
			
		||||
	IFLA_VF_SPOOFCHK,	/* Spoof Checking on/off switch */
 | 
			
		||||
	IFLA_VF_LINK_STATE,	/* link state enable/disable/auto switch */
 | 
			
		||||
	__IFLA_VF_MAX,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -364,6 +365,18 @@ struct ifla_vf_spoofchk {
 | 
			
		|||
	__u32 setting;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
	IFLA_VF_LINK_STATE_AUTO,	/* link state of the uplink */
 | 
			
		||||
	IFLA_VF_LINK_STATE_ENABLE,	/* link always up */
 | 
			
		||||
	IFLA_VF_LINK_STATE_DISABLE,	/* link always down */
 | 
			
		||||
	__IFLA_VF_LINK_STATE_MAX,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct ifla_vf_link_state {
 | 
			
		||||
	__u32 vf;
 | 
			
		||||
	__u32 link_state;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* VF ports management section
 | 
			
		||||
 *
 | 
			
		||||
 *	Nested layout of set/get msg is:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -947,6 +947,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
 | 
			
		|||
			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;
 | 
			
		||||
 | 
			
		||||
			/*
 | 
			
		||||
			 * Not all SR-IOV capable drivers support the
 | 
			
		||||
| 
						 | 
				
			
			@ -956,18 +957,24 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
 | 
			
		|||
			 */
 | 
			
		||||
			ivi.spoofchk = -1;
 | 
			
		||||
			memset(ivi.mac, 0, sizeof(ivi.mac));
 | 
			
		||||
			/* The default value for VF link state is "auto"
 | 
			
		||||
			 * IFLA_VF_LINK_STATE_AUTO which equals zero
 | 
			
		||||
			 */
 | 
			
		||||
			ivi.linkstate = 0;
 | 
			
		||||
			if (dev->netdev_ops->ndo_get_vf_config(dev, i, &ivi))
 | 
			
		||||
				break;
 | 
			
		||||
			vf_mac.vf =
 | 
			
		||||
				vf_vlan.vf =
 | 
			
		||||
				vf_tx_rate.vf =
 | 
			
		||||
				vf_spoofchk.vf = ivi.vf;
 | 
			
		||||
				vf_spoofchk.vf =
 | 
			
		||||
				vf_linkstate.vf = ivi.vf;
 | 
			
		||||
 | 
			
		||||
			memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac));
 | 
			
		||||
			vf_vlan.vlan = ivi.vlan;
 | 
			
		||||
			vf_vlan.qos = ivi.qos;
 | 
			
		||||
			vf_tx_rate.rate = ivi.tx_rate;
 | 
			
		||||
			vf_spoofchk.setting = ivi.spoofchk;
 | 
			
		||||
			vf_linkstate.link_state = ivi.linkstate;
 | 
			
		||||
			vf = nla_nest_start(skb, IFLA_VF_INFO);
 | 
			
		||||
			if (!vf) {
 | 
			
		||||
				nla_nest_cancel(skb, vfinfo);
 | 
			
		||||
| 
						 | 
				
			
			@ -978,7 +985,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
 | 
			
		|||
			    nla_put(skb, IFLA_VF_TX_RATE, sizeof(vf_tx_rate),
 | 
			
		||||
				    &vf_tx_rate) ||
 | 
			
		||||
			    nla_put(skb, IFLA_VF_SPOOFCHK, sizeof(vf_spoofchk),
 | 
			
		||||
				    &vf_spoofchk))
 | 
			
		||||
				    &vf_spoofchk) ||
 | 
			
		||||
			    nla_put(skb, IFLA_VF_LINK_STATE, sizeof(vf_linkstate),
 | 
			
		||||
				    &vf_linkstate))
 | 
			
		||||
				goto nla_put_failure;
 | 
			
		||||
			nla_nest_end(skb, vf);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -1238,6 +1247,15 @@ static int do_setvfinfo(struct net_device *dev, struct nlattr *attr)
 | 
			
		|||
							       ivs->setting);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		case IFLA_VF_LINK_STATE: {
 | 
			
		||||
			struct ifla_vf_link_state *ivl;
 | 
			
		||||
			ivl = nla_data(vf);
 | 
			
		||||
			err = -EOPNOTSUPP;
 | 
			
		||||
			if (ops->ndo_set_vf_link_state)
 | 
			
		||||
				err = ops->ndo_set_vf_link_state(dev, ivl->vf,
 | 
			
		||||
								 ivl->link_state);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		default:
 | 
			
		||||
			err = -EINVAL;
 | 
			
		||||
			break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue