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 qos;
 | 
				
			||||||
	__u32 tx_rate;
 | 
						__u32 tx_rate;
 | 
				
			||||||
	__u32 spoofchk;
 | 
						__u32 spoofchk;
 | 
				
			||||||
 | 
						__u32 linkstate;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
#endif /* _LINUX_IF_LINK_H */
 | 
					#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_set_vf_spoofchk)(struct net_device *dev, int vf, bool setting);
 | 
				
			||||||
 * int (*ndo_get_vf_config)(struct net_device *dev,
 | 
					 * int (*ndo_get_vf_config)(struct net_device *dev,
 | 
				
			||||||
 *			    int vf, struct ifla_vf_info *ivf);
 | 
					 *			    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,
 | 
					 * int (*ndo_set_vf_port)(struct net_device *dev, int vf,
 | 
				
			||||||
 *			  struct nlattr *port[]);
 | 
					 *			  struct nlattr *port[]);
 | 
				
			||||||
 * int (*ndo_get_vf_port)(struct net_device *dev, int vf, struct sk_buff *skb);
 | 
					 * 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			(*ndo_get_vf_config)(struct net_device *dev,
 | 
				
			||||||
						     int vf,
 | 
											     int vf,
 | 
				
			||||||
						     struct ifla_vf_info *ivf);
 | 
											     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			(*ndo_set_vf_port)(struct net_device *dev,
 | 
				
			||||||
						   int vf,
 | 
											   int vf,
 | 
				
			||||||
						   struct nlattr *port[]);
 | 
											   struct nlattr *port[]);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -338,6 +338,7 @@ enum {
 | 
				
			||||||
	IFLA_VF_VLAN,
 | 
						IFLA_VF_VLAN,
 | 
				
			||||||
	IFLA_VF_TX_RATE,	/* TX Bandwidth Allocation */
 | 
						IFLA_VF_TX_RATE,	/* TX Bandwidth Allocation */
 | 
				
			||||||
	IFLA_VF_SPOOFCHK,	/* Spoof Checking on/off switch */
 | 
						IFLA_VF_SPOOFCHK,	/* Spoof Checking on/off switch */
 | 
				
			||||||
 | 
						IFLA_VF_LINK_STATE,	/* link state enable/disable/auto switch */
 | 
				
			||||||
	__IFLA_VF_MAX,
 | 
						__IFLA_VF_MAX,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -364,6 +365,18 @@ struct ifla_vf_spoofchk {
 | 
				
			||||||
	__u32 setting;
 | 
						__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
 | 
					/* VF ports management section
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *	Nested layout of set/get msg is:
 | 
					 *	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_vlan vf_vlan;
 | 
				
			||||||
			struct ifla_vf_tx_rate vf_tx_rate;
 | 
								struct ifla_vf_tx_rate vf_tx_rate;
 | 
				
			||||||
			struct ifla_vf_spoofchk vf_spoofchk;
 | 
								struct ifla_vf_spoofchk vf_spoofchk;
 | 
				
			||||||
 | 
								struct ifla_vf_link_state vf_linkstate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/*
 | 
								/*
 | 
				
			||||||
			 * Not all SR-IOV capable drivers support the
 | 
								 * 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;
 | 
								ivi.spoofchk = -1;
 | 
				
			||||||
			memset(ivi.mac, 0, sizeof(ivi.mac));
 | 
								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))
 | 
								if (dev->netdev_ops->ndo_get_vf_config(dev, i, &ivi))
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			vf_mac.vf =
 | 
								vf_mac.vf =
 | 
				
			||||||
				vf_vlan.vf =
 | 
									vf_vlan.vf =
 | 
				
			||||||
				vf_tx_rate.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));
 | 
								memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac));
 | 
				
			||||||
			vf_vlan.vlan = ivi.vlan;
 | 
								vf_vlan.vlan = ivi.vlan;
 | 
				
			||||||
			vf_vlan.qos = ivi.qos;
 | 
								vf_vlan.qos = ivi.qos;
 | 
				
			||||||
			vf_tx_rate.rate = ivi.tx_rate;
 | 
								vf_tx_rate.rate = ivi.tx_rate;
 | 
				
			||||||
			vf_spoofchk.setting = ivi.spoofchk;
 | 
								vf_spoofchk.setting = ivi.spoofchk;
 | 
				
			||||||
 | 
								vf_linkstate.link_state = ivi.linkstate;
 | 
				
			||||||
			vf = nla_nest_start(skb, IFLA_VF_INFO);
 | 
								vf = nla_nest_start(skb, IFLA_VF_INFO);
 | 
				
			||||||
			if (!vf) {
 | 
								if (!vf) {
 | 
				
			||||||
				nla_nest_cancel(skb, vfinfo);
 | 
									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),
 | 
								    nla_put(skb, IFLA_VF_TX_RATE, sizeof(vf_tx_rate),
 | 
				
			||||||
				    &vf_tx_rate) ||
 | 
									    &vf_tx_rate) ||
 | 
				
			||||||
			    nla_put(skb, IFLA_VF_SPOOFCHK, sizeof(vf_spoofchk),
 | 
								    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;
 | 
									goto nla_put_failure;
 | 
				
			||||||
			nla_nest_end(skb, vf);
 | 
								nla_nest_end(skb, vf);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -1238,6 +1247,15 @@ static int do_setvfinfo(struct net_device *dev, struct nlattr *attr)
 | 
				
			||||||
							       ivs->setting);
 | 
												       ivs->setting);
 | 
				
			||||||
			break;
 | 
								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:
 | 
							default:
 | 
				
			||||||
			err = -EINVAL;
 | 
								err = -EINVAL;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue