[dpdk-dev] [PATCH] kni: Add link status update

Zhang, Helin helin.zhang at intel.com
Tue May 19 02:54:22 CEST 2015


Hello

> -----Original Message-----
> From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Vijayakumar
> Muthuvel Manickam
> Sent: Tuesday, May 19, 2015 7:33 AM
> To: dev at dpdk.org
> Subject: [dpdk-dev] [PATCH] kni: Add link status update
> 
> Add an ioctl command in rte_kni module to enable DPDK applications to
> propagate link state changes to kni virtual interfaces.
> 
> Signed-off-by: Vijayakumar Muthuvel Manickam <mmvijay at gmail.com>
> ---
>  .../linuxapp/eal/include/exec-env/rte_kni_common.h |  2 ++
>  lib/librte_eal/linuxapp/kni/kni_misc.c             | 39
> ++++++++++++++++++++++
>  lib/librte_kni/rte_kni.c                           | 18 ++++++++++
>  lib/librte_kni/rte_kni.h                           | 17 ++++++++++
>  4 files changed, 76 insertions(+)
> 
> diff --git
> a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h
> b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h
> index 1e55c2d..b68001d 100644
> --- a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h
> +++ b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h
> @@ -163,6 +163,7 @@ struct rte_kni_device_info {
> 
>  	/* mbuf size */
>  	unsigned mbuf_size;
> +	uint8_t link_state;
How about transfer more states from user space to kernel space, such as link speed, duplex, etc?

>  };
> 
>  #define KNI_DEVICE "kni"
> @@ -170,5 +171,6 @@ struct rte_kni_device_info {
>  #define RTE_KNI_IOCTL_TEST    _IOWR(0, 1, int)
>  #define RTE_KNI_IOCTL_CREATE  _IOWR(0, 2, struct
> rte_kni_device_info)  #define RTE_KNI_IOCTL_RELEASE _IOWR(0, 3,
> struct rte_kni_device_info)
> +#define RTE_KNI_IOCTL_LINK_UPDATE _IOWR(0, 4, struct
> +rte_kni_device_info)
> 
>  #endif /* _RTE_KNI_COMMON_H_ */
> diff --git a/lib/librte_eal/linuxapp/kni/kni_misc.c
> b/lib/librte_eal/linuxapp/kni/kni_misc.c
> index 1935d32..b1015cd 100644
> --- a/lib/librte_eal/linuxapp/kni/kni_misc.c
> +++ b/lib/librte_eal/linuxapp/kni/kni_misc.c
> @@ -548,6 +548,42 @@ kni_ioctl_release(unsigned int ioctl_num,
> unsigned long ioctl_param)  }
> 
>  static int
> +kni_ioctl_update_link_state(unsigned int ioctl_num, unsigned long
> +ioctl_param) {
> +	int ret = -EINVAL;
> +	struct kni_dev *dev, *n;
> +	struct rte_kni_device_info dev_info;
> +
> +	if (_IOC_SIZE(ioctl_num) > sizeof(dev_info))
> +			return -EINVAL;
> +
> +	ret = copy_from_user(&dev_info, (void *)ioctl_param,
> sizeof(dev_info));
> +	if (ret) {
> +		KNI_ERR("copy_from_user in kni_ioctl_update_link_status");
> +		return -EIO;
> +	}
> +
> +	if (strlen(dev_info.name) == 0)
> +		return ret;
> +
> +	down_write(&kni_list_lock);
> +	list_for_each_entry_safe(dev, n, &kni_list_head, list) {
> +		if (strncmp(dev->name, dev_info.name, RTE_KNI_NAMESIZE) !=
> 0)
> +			continue;
> +
> +		if (dev_info.link_state == 0)
> +			netif_carrier_off(dev->net_dev);
> +		else
> +			netif_carrier_on(dev->net_dev);
> +		ret = 0;
> +		break;
> +	}
> +	up_write(&kni_list_lock);
> +
> +	return ret;
> +}
> +
> +static int
>  kni_ioctl(struct inode *inode,
>  	unsigned int ioctl_num,
>  	unsigned long ioctl_param)
> @@ -569,6 +605,9 @@ kni_ioctl(struct inode *inode,
>  	case _IOC_NR(RTE_KNI_IOCTL_RELEASE):
>  		ret = kni_ioctl_release(ioctl_num, ioctl_param);
>  		break;
> +	case _IOC_NR(RTE_KNI_IOCTL_LINK_UPDATE):
> +		ret = kni_ioctl_update_link_state(ioctl_num, ioctl_param);
> +		break;
>  	default:
>  		KNI_DBG("IOCTL default \n");
>  		break;
> diff --git a/lib/librte_kni/rte_kni.c b/lib/librte_kni/rte_kni.c index
> 4e70fa0..b6eda8a 100644
> --- a/lib/librte_kni/rte_kni.c
> +++ b/lib/librte_kni/rte_kni.c
> @@ -512,6 +512,24 @@ rte_kni_release(struct rte_kni *kni)  }
> 
>  int
> +rte_kni_update_link_state(struct rte_kni *kni, uint8_t if_up) {
> +	struct rte_kni_device_info dev_info;
> +
> +	if (!kni || !kni->in_use)
> +		return -1;
> +
> +	snprintf(dev_info.name, sizeof(dev_info.name), "%s", kni->name);
> +	dev_info.link_state = if_up;
> +	if (ioctl(kni_fd, RTE_KNI_IOCTL_LINK_UPDATE, &dev_info) < 0) {
> +		RTE_LOG(ERR, KNI, "Fail to update link state\n");
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
This new interface should be called at the end of rte_kni_alloc() to notify
the link status after a KNI interface is created.

Thanks,
Helin

> +int
>  rte_kni_handle_request(struct rte_kni *kni)  {
>  	unsigned ret;
> diff --git a/lib/librte_kni/rte_kni.h b/lib/librte_kni/rte_kni.h index
> 98edd72..a1bafd9 100644
> --- a/lib/librte_kni/rte_kni.h
> +++ b/lib/librte_kni/rte_kni.h
> @@ -167,6 +167,23 @@ extern struct rte_kni *rte_kni_create(uint8_t
> port_id,  extern int rte_kni_release(struct rte_kni *kni);
> 
>  /**
> + * Send link state changes to KNI interface in kernel space
> + *
> + * rte_kni_update_link_state is thread safe.
> + *
> + * @param kni
> + *  The pointer to the context of an existent KNI interface.
> + * @param if_up
> + *  interface link status
> + *
> + * @return
> + *  - 0 indicates success.
> + *  - negative value indicates failure.
> + */
> +
> +extern int rte_kni_update_link_state(struct rte_kni *kni, uint8_t
> +if_up);
> +
> +/**
>   * It is used to handle the request mbufs sent from kernel space.
>   * Then analyzes it and calls the specific actions for the specific requests.
>   * Finally constructs the response mbuf and puts it back to the resp_q.
> --
> 1.8.1.4



More information about the dev mailing list