From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-oi0-f66.google.com (mail-oi0-f66.google.com [209.85.218.66]) by dpdk.org (Postfix) with ESMTP id AAAB91B54B for ; Fri, 29 Jun 2018 03:56:02 +0200 (CEST) Received: by mail-oi0-f66.google.com with SMTP id i12-v6so2633499oik.2 for ; Thu, 28 Jun 2018 18:56:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=cdEl1hq7skaMWXoPPo1VTqfPWn0cWRE6baagA8ej7DY=; b=jLz8xkEkp3ZKTS9Odw8IECk9MhaRMtQfyAeMXu7jBKXxS4dXpOp4w2CXUlxMFJkq1i ElCcjT5C/hWxLZ66xDPDf2UzI/vDsAcqK4+0r7UqgUVjDT+DLxAZKcyRFrzgib7+cl4Y JFNumSRV+PJKe5Viue4xrkt0c86fSRmiOyjpfEdi0yzdsbKcnN5iVznV8Em+w3MjfaAP yGY7dA3XNzB849wheumZ2lIb4KXcWgntkjVn59nj9beUR1RAdFPFNAz33f3SRB/K6Ppp 2LMv/U+qOTUaahsXNObtn6EOILcaUICviteCs0ro41gWHYS1A2Rr75CLHF1on0oCDQKQ us0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=cdEl1hq7skaMWXoPPo1VTqfPWn0cWRE6baagA8ej7DY=; b=V/wCLDNUcMo4zcBWKDh3PQxzWE+5qPVFElJxS4vdgNL8MYqexJFSXW329ucw61HujV ZnEeR9tVcPog3FVDLApxSamcbn73Lo30Vlm5vs3mtCLIDynp0/v6MG9X4A1kqmXPn0NB ZQcPgmgc2mkW6lIP1Er1hwb6vFxRKxz8RByUWPakIV6lGqpnBrG1c9bX70l6SfgjL/j6 ZhtSVtErJ/AT1hG7//KOdDG+97V8Viqeh2Qkn5Ooo3ltAdH9v4CSJ7Ak69k7kFFGcaKI O32oByGvZc7mef+rkJ0eHpp9SUjjclaeyp5HUnMRoiMRvl5EcKFkhWftBVXKmPWwgnMV lvAA== X-Gm-Message-State: APt69E38C3MHnetgoglhY26xn3Gq1NCM9Q+l5e/0YOC5uByKSHvYgbR+ 2fQDLwgBTAbZ7uYxI7pUOHo= X-Google-Smtp-Source: AAOMgpcFPg5Gw9lAtaUjy7IPys0uRAwGvgI35SFQL/r1DDZsibznxEu0nU+utF2Go0Uzq7OdwB5XHA== X-Received: by 2002:aca:3d05:: with SMTP id k5-v6mr6709993oia.86.1530237361871; Thu, 28 Jun 2018 18:56:01 -0700 (PDT) Received: from linux.adax.com (172-11-198-60.lightspeed.sntcca.sbcglobal.net. [172.11.198.60]) by smtp.gmail.com with ESMTPSA id n3-v6sm3941288otk.38.2018.06.28.18.56.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 28 Jun 2018 18:56:01 -0700 (PDT) Sender: Dan Gora From: Dan Gora To: ferruh.yigit@intel.com Cc: dev@dpdk.org, Dan Gora Date: Thu, 28 Jun 2018 18:55:08 -0700 Message-Id: <20180629015508.26599-11-dg@adax.com> X-Mailer: git-send-email 2.18.0.rc1.1.g6f333ff2f In-Reply-To: <20180629015508.26599-1-dg@adax.com> References: <20180628224513.18391-1-dg@adax.com> <20180629015508.26599-1-dg@adax.com> Subject: [dpdk-dev] [PATCH v2 10/10] kni: add API to set link status on kernel interface X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 29 Jun 2018 01:56:03 -0000 Add a new API function to KNI, rte_kni_update_link() to allow DPDK applications to update the link state for the KNI network interfaces in the linux kernel. Note that the default carrier state is set to off when the interface is opened. Signed-off-by: Dan Gora --- kernel/linux/kni/kni_misc.c | 63 +++++++++++++++++++ kernel/linux/kni/kni_net.c | 2 + .../eal/include/exec-env/rte_kni_common.h | 19 ++++++ lib/librte_kni/rte_kni.c | 37 ++++++++++- lib/librte_kni/rte_kni.h | 16 +++++ 5 files changed, 136 insertions(+), 1 deletion(-) diff --git a/kernel/linux/kni/kni_misc.c b/kernel/linux/kni/kni_misc.c index 1c38cfa1a..b5784ad1b 100644 --- a/kernel/linux/kni/kni_misc.c +++ b/kernel/linux/kni/kni_misc.c @@ -585,6 +585,66 @@ kni_ioctl_free(struct net *net, uint32_t ioctl_num, return ret; } +static int +kni_ioctl_linkstat(struct net *net, uint32_t ioctl_num, + unsigned long ioctl_param) +{ + struct kni_net *knet = net_generic(net, kni_net_id); + int ret = -EINVAL; + struct kni_dev *dev, *n; + struct rte_kni_link_info link_info; + struct net_device *netdev; + uint16_t link; + + if (_IOC_SIZE(ioctl_num) > sizeof(link_info)) + return -EINVAL; + + ret = copy_from_user(&link_info, (void *)ioctl_param, + sizeof(link_info)); + if (ret) { + pr_err("copy_from_user in kni_ioctl_release"); + return -EIO; + } + + /* Release the network device according to its name */ + if (strlen(link_info.name) == 0) + return ret; + + down_read(&knet->kni_list_lock); + list_for_each_entry_safe(dev, n, &knet->kni_list_head, list) { + if (strncmp(dev->name, link_info.name, RTE_KNI_NAMESIZE) != 0) + continue; + + netdev = dev->net_dev; + if (netdev == NULL) { + up_read(&knet->kni_list_lock); + return ret; + } + + link = link_info.link_status; + + if (!netif_carrier_ok(netdev) && link) { + pr_info("%s NIC Link is Up %d Mbps %s.\n", + netdev->name, + link_info.link_speed, + link_info.link_duplex == + RTE_KNI_LINK_FULL_DUPLEX ? + "Full Duplex" : "Half Duplex"); + netif_carrier_on(netdev); + } else if (netif_carrier_ok(netdev) && !link) { + pr_info("%s NIC Link is Down.\n", + netdev->name); + netif_carrier_off(netdev); + } + + ret = 0; + break; + } + up_read(&knet->kni_list_lock); + + return ret; +} + static int kni_ioctl(struct inode *inode, uint32_t ioctl_num, unsigned long ioctl_param) { @@ -609,6 +669,9 @@ kni_ioctl(struct inode *inode, uint32_t ioctl_num, unsigned long ioctl_param) case _IOC_NR(RTE_KNI_IOCTL_FREE): ret = kni_ioctl_free(net, ioctl_num, ioctl_param); break; + case _IOC_NR(RTE_KNI_IOCTL_LINKSTAT): + ret = kni_ioctl_linkstat(net, ioctl_num, ioctl_param); + break; default: pr_debug("IOCTL default\n"); break; diff --git a/kernel/linux/kni/kni_net.c b/kernel/linux/kni/kni_net.c index 0850be434..fea3ec7e7 100644 --- a/kernel/linux/kni/kni_net.c +++ b/kernel/linux/kni/kni_net.c @@ -134,6 +134,7 @@ kni_net_open(struct net_device *dev) struct kni_dev *kni = netdev_priv(dev); netif_start_queue(dev); + netif_carrier_off(dev); memset(&req, 0, sizeof(req)); req.req_id = RTE_KNI_REQ_CFG_NETWORK_IF; @@ -153,6 +154,7 @@ kni_net_release(struct net_device *dev) struct kni_dev *kni = netdev_priv(dev); netif_stop_queue(dev); /* can't transmit any more */ + netif_carrier_off(dev); memset(&req, 0, sizeof(req)); req.req_id = RTE_KNI_REQ_CFG_NETWORK_IF; 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 318a3f939..f617d8026 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 @@ -124,11 +124,30 @@ struct rte_kni_device_info { char mac_addr[6]; }; + +struct rte_kni_link_info { + char name[RTE_KNI_NAMESIZE]; /**< Network device name for KNI */ + uint32_t link_speed; /**< ETH_SPEED_NUM_ */ + +#define RTE_KNI_LINK_HALF_DUPLEX 0 /**< Half-duplex connection. */ +#define RTE_KNI_LINK_FULL_DUPLEX 1 /**< Full-duplex connection. */ + uint16_t link_duplex : 1; /**< RTE_KNI_LINK_[HALF/FULL]_DUPLEX */ + +#define RTE_KNI_LINK_FIXED 0 /**< No autonegotiation. */ +#define RTE_KNI_LINK_AUTONEG 1 /**< Autonegotiated. */ + uint16_t link_autoneg : 1; /**< RTE_KNI_LINK_[AUTONEG/FIXED] */ + +#define RTE_KNI_LINK_DOWN 0 /**< Link is down. */ +#define RTE_KNI_LINK_UP 1 /**< Link is up. */ + uint16_t link_status : 1; /**< RTE_KNI_LINK_[DOWN/UP] */ +}; + #define KNI_DEVICE "kni" #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_FREE _IOWR(0, 4, struct rte_kni_device_info) +#define RTE_KNI_IOCTL_LINKSTAT _IOWR(0, 5, struct rte_kni_link_info) #endif /* _RTE_KNI_COMMON_H_ */ diff --git a/lib/librte_kni/rte_kni.c b/lib/librte_kni/rte_kni.c index 6ef0859bf..aa3559306 100644 --- a/lib/librte_kni/rte_kni.c +++ b/lib/librte_kni/rte_kni.c @@ -13,7 +13,6 @@ #include #include -#include #include #include #include @@ -817,6 +816,42 @@ rte_kni_unregister_handlers(struct rte_kni *kni) return 0; } + +int +rte_kni_update_link(struct rte_kni *kni, struct rte_eth_link *link) +{ + struct rte_kni_link_info link_info; + + if (kni == NULL || !kni->in_use || link == NULL) + return -1; + + snprintf(link_info.name, sizeof(link_info.name), "%s", kni->name); + + link_info.link_speed = link->link_speed; + if (link->link_duplex == ETH_LINK_FULL_DUPLEX) + link_info.link_duplex = RTE_KNI_LINK_FULL_DUPLEX; + else + link_info.link_duplex = RTE_KNI_LINK_FULL_DUPLEX; + + if (link->link_autoneg == ETH_LINK_FIXED) + link_info.link_autoneg = RTE_KNI_LINK_FIXED; + else + link_info.link_autoneg = RTE_KNI_LINK_AUTONEG; + + if (link->link_status == ETH_LINK_UP) + link_info.link_status = RTE_KNI_LINK_UP; + else + link_info.link_status = RTE_KNI_LINK_DOWN; + + if (ioctl(kni_fd, RTE_KNI_IOCTL_LINKSTAT, &link_info) < 0) { + RTE_LOG(ERR, KNI, + "Failed to update kni link info for dev '%s'.\n", + kni->name); + return -1; + } + return 0; +} + void rte_kni_close(void) { diff --git a/lib/librte_kni/rte_kni.h b/lib/librte_kni/rte_kni.h index 94516c38f..02d781a32 100644 --- a/lib/librte_kni/rte_kni.h +++ b/lib/librte_kni/rte_kni.h @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -255,6 +256,21 @@ int rte_kni_register_handlers(struct rte_kni *kni, struct rte_kni_ops *ops); */ int rte_kni_unregister_handlers(struct rte_kni *kni); +/** + * Update link status info for KNI port. + * + * Update the linkup/linkdown status of a KNI interface in the kernel. + * + * @param kni + * pointer to struct rte_kni. + * + * @return + * On success: 0 + * On failure: -1 + */ +int __rte_experimental +rte_kni_update_link(struct rte_kni *kni, struct rte_eth_link *link); + /** * Close KNI device. */ -- 2.18.0.rc1.1.g6f333ff2f