[1/2] kni: add API to set link status on kernel interface
Checks
Commit Message
Add a new API function to KNI, rte_kni_update_link() to allow DPDK
applications to update the link status for KNI network interfaces in
the linux kernel.
Signed-off-by: Dan Gora <dg@adax.com>
---
lib/librte_kni/rte_kni.c | 57 ++++++++++++++++++++++++++++++++++++++++
lib/librte_kni/rte_kni.h | 18 +++++++++++++
2 files changed, 75 insertions(+)
Comments
On 9/12/2018 12:29 AM, Dan Gora wrote:
> Add a new API function to KNI, rte_kni_update_link() to allow DPDK
> applications to update the link status for KNI network interfaces in
> the linux kernel.
>
> Signed-off-by: Dan Gora <dg@adax.com>
+1 to sysfs implementation.
But right now this API is not used at all which makes it hard to test and catch
when API broken.
Can you please implement the API either on kni sample app or kni unit test?
Also you need to add new API to .map file for shared library build. (you would
catch this if API implemented somewhere...)
On Tue, Sep 18, 2018 at 1:54 PM, Ferruh Yigit <ferruh.yigit@intel.com> wrote:
> On 9/12/2018 12:29 AM, Dan Gora wrote:
>> Add a new API function to KNI, rte_kni_update_link() to allow DPDK
>> applications to update the link status for KNI network interfaces in
>> the linux kernel.
>>
>> Signed-off-by: Dan Gora <dg@adax.com>
>
> +1 to sysfs implementation.
>
> But right now this API is not used at all which makes it hard to test and catch
> when API broken.
> Can you please implement the API either on kni sample app or kni unit test?
>
> Also you need to add new API to .map file for shared library build. (you would
> catch this if API implemented somewhere...)
Understood.. I'll work on this ASAP.
-dan
@@ -790,6 +790,63 @@ rte_kni_unregister_handlers(struct rte_kni *kni)
return 0;
}
+
+int
+rte_kni_update_link(struct rte_kni *kni, struct rte_eth_link *link)
+{
+ char path[64];
+ char carrier[2];
+ const char *new_carrier;
+ int fd, ret;
+
+ if (kni == NULL || link == NULL)
+ return -1;
+
+ snprintf(path, sizeof(path), "/sys/devices/virtual/net/%s/carrier",
+ kni->name);
+
+ fd = open(path, O_RDWR);
+ if (fd == -1) {
+ RTE_LOG(ERR, KNI, "Failed to open file: %s.\n", path);
+ return -1;
+ }
+
+ ret = read(fd, carrier, 2);
+ if (ret < 1) {
+ /* Cannot read carrier until interface is marked
+ * 'up', so don't log an error.
+ */
+ close(fd);
+ return -1;
+ }
+
+ new_carrier = (link->link_status == ETH_LINK_UP) ? "1" : "0";
+ ret = write(fd, new_carrier, 1);
+ if (ret < 1) {
+ RTE_LOG(ERR, KNI, "Failed to write file: %s.\n", path);
+ close(fd);
+ return -1;
+ }
+
+ if (strncmp(carrier, new_carrier, 1)) {
+ if (link->link_status == ETH_LINK_UP) {
+ RTE_LOG(INFO, KNI, "%s NIC Link is Up %d Mbps %s %s.\n",
+ kni->name,
+ link->link_speed,
+ link->link_autoneg ? "(Fixed)" : "(AutoNeg)",
+ link->link_duplex ?
+ "Full Duplex" : "Half Duplex");
+ } else {
+ RTE_LOG(INFO, KNI, "%s NIC Link is Down.\n",
+ kni->name);
+ }
+ }
+
+ close(fd);
+
+ return 0;
+}
+
void
rte_kni_close(void)
{
@@ -21,6 +21,7 @@
#include <rte_memory.h>
#include <rte_mempool.h>
#include <rte_ether.h>
+#include <rte_ethdev.h>
#include <exec-env/rte_kni_common.h>
@@ -228,6 +229,23 @@ 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.
+ * @param link
+ * pointer to struct rte_eth_link containing new interface status.
+ *
+ * @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.
*/