DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 1/3] kni: support for MAC addr change
@ 2017-11-30 11:46 Hemant Agrawal
  2017-11-30 11:46 ` [dpdk-dev] [PATCH 2/3] kni: add support for promisc mode set Hemant Agrawal
                   ` (3 more replies)
  0 siblings, 4 replies; 17+ messages in thread
From: Hemant Agrawal @ 2017-11-30 11:46 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds following:
1. Option to configure the mac address during create. Generate random
   address only if the user has not provided any valid address.
2. Inform usespace, if mac address is being changed in linux.
3. Implement default handling of mac address change in the corresponding
   ethernet device.

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 doc/guides/sample_app_ug/kernel_nic_interface.rst  | 41 +++++++++++++++++++++-
 examples/kni/main.c                                | 36 +++++++++++++++++++
 .../linuxapp/eal/include/exec-env/rte_kni_common.h |  3 ++
 lib/librte_eal/linuxapp/kni/kni_misc.c             | 17 +++++----
 lib/librte_eal/linuxapp/kni/kni_net.c              | 14 +++++++-
 lib/librte_kni/rte_kni.c                           | 40 +++++++++++++++++++--
 lib/librte_kni/rte_kni.h                           |  5 +++
 test/test/test_kni.c                               |  2 ++
 8 files changed, 147 insertions(+), 11 deletions(-)

diff --git a/doc/guides/sample_app_ug/kernel_nic_interface.rst b/doc/guides/sample_app_ug/kernel_nic_interface.rst
index e1ac415..d9d8e4a 100644
--- a/doc/guides/sample_app_ug/kernel_nic_interface.rst
+++ b/doc/guides/sample_app_ug/kernel_nic_interface.rst
@@ -209,6 +209,12 @@ Dumping the network traffic:
 
     #tcpdump -i vEth0_0
 
+Change the MAC address:
+
+.. code-block:: console
+
+    #ifconfig vEth0_0 hw ether 0C:01:02:03:04:08
+
 When the DPDK userspace application is closed, all the KNI devices are deleted from Linux*.
 
 Explanation
@@ -269,11 +275,15 @@ The code for allocating the kernel NIC interfaces for a specific port is as foll
                     conf.addr = dev_info.pci_dev->addr;
                     conf.id = dev_info.pci_dev->id;
 
+                    /* Get the interface default mac address */
+                    rte_eth_macaddr_get(port_id, struct ether_addr *)&conf.mac_addr);
+
                     memset(&ops, 0, sizeof(ops));
 
                     ops.port_id = port_id;
                     ops.change_mtu = kni_change_mtu;
                     ops.config_network_if = kni_config_network_interface;
+                    ops.config_mac_address = kni_config_mac_address;
 
                     kni = rte_kni_alloc(pktmbuf_pool, &conf, &ops);
                 } else
@@ -502,13 +512,19 @@ Callbacks for Kernel Requests
 
 To execute specific PMD operations in user space requested by some Linux* commands,
 callbacks must be implemented and filled in the struct rte_kni_ops structure.
-Currently, setting a new MTU and configuring the network interface (up/ down) are supported.
+Currently, setting a new MTU, change in mac address and configuring the network interface(up/ down)
+are supported.
+Default implementation for following is available in rte_kni library. Application
+may choose to not implement follwoing callbacks:
+	``config_mac_address``
+
 
 .. code-block:: c
 
     static struct rte_kni_ops kni_ops = {
         .change_mtu = kni_change_mtu,
         .config_network_if = kni_config_network_interface,
+        .config_mac_address = kni_config_mac_address,
     };
 
     /* Callback for request of changing MTU */
@@ -587,3 +603,26 @@ Currently, setting a new MTU and configuring the network interface (up/ down) ar
             RTE_LOG(ERR, APP, "Failed to start port %d\n", port_id);
         return ret;
     }
+
+    /* Callback for request of configuring device mac address */
+
+    static int
+    kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
+    {
+        int ret = 0;
+
+        if (port_id >= rte_eth_dev_count() || port_id >= RTE_MAX_ETHPORTS) {
+                RTE_LOG(ERR, KNI, "Invalid port id %d\n", port_id);
+                return -EINVAL;
+        }
+
+        RTE_LOG(INFO, KNI, "Configure mac address of %d", port_id);
+        /* Configure network interface mac address */
+        ret = rte_eth_dev_default_mac_addr_set(port_id,
+                                               (struct ether_addr *)mac_addr);
+        if (ret < 0)
+                RTE_LOG(ERR, KNI, "Failed to config mac_addr for port %d\n",
+                        port_id);
+
+        return ret;
+    }
diff --git a/examples/kni/main.c b/examples/kni/main.c
index 3f17385..1c251c2 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -163,6 +163,7 @@ static struct kni_interface_stats kni_stats[RTE_MAX_ETHPORTS];
 
 static int kni_change_mtu(uint16_t port_id, unsigned int new_mtu);
 static int kni_config_network_interface(uint16_t port_id, uint8_t if_up);
+static int kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[]);
 
 static rte_atomic32_t kni_stop = RTE_ATOMIC32_INIT(0);
 
@@ -766,6 +767,37 @@ kni_config_network_interface(uint16_t port_id, uint8_t if_up)
 	return ret;
 }
 
+static void
+print_ethaddr(const char *name, struct ether_addr *mac_addr)
+{
+	char buf[ETHER_ADDR_FMT_SIZE];
+	ether_format_addr(buf, ETHER_ADDR_FMT_SIZE, mac_addr);
+	RTE_LOG(INFO, APP, "\t%s%s\n", name, buf);
+}
+
+/* Callback for request of configuring mac address */
+static int
+kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
+{
+	int ret = 0;
+
+	if (port_id >= rte_eth_dev_count() || port_id >= RTE_MAX_ETHPORTS) {
+		RTE_LOG(ERR, APP, "Invalid port id %d\n", port_id);
+		return -EINVAL;
+	}
+
+	RTE_LOG(INFO, APP, "Configure mac address of %d\n", port_id);
+	print_ethaddr("Address:", (struct ether_addr *)mac_addr);
+
+	ret = rte_eth_dev_default_mac_addr_set(port_id,
+					       (struct ether_addr *)mac_addr);
+	if (ret < 0)
+		RTE_LOG(ERR, APP, "Failed to config mac_addr for port %d\n",
+			port_id);
+
+	return ret;
+}
+
 static int
 kni_alloc(uint16_t port_id)
 {
@@ -809,11 +841,15 @@ kni_alloc(uint16_t port_id)
 				conf.addr = dev_info.pci_dev->addr;
 				conf.id = dev_info.pci_dev->id;
 			}
+			/* Get the interface default mac address */
+			rte_eth_macaddr_get(port_id,
+					(struct ether_addr *)&conf.mac_addr);
 
 			memset(&ops, 0, sizeof(ops));
 			ops.port_id = port_id;
 			ops.change_mtu = kni_change_mtu;
 			ops.config_network_if = kni_config_network_interface;
+			ops.config_mac_address = kni_config_mac_address;
 
 			kni = rte_kni_alloc(pktmbuf_pool, &conf, &ops);
 		} else
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 2ac879f..1a760de 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
@@ -80,6 +80,7 @@ enum rte_kni_req_id {
 	RTE_KNI_REQ_UNKNOWN = 0,
 	RTE_KNI_REQ_CHANGE_MTU,
 	RTE_KNI_REQ_CFG_NETWORK_IF,
+	RTE_KNI_REQ_CHANGE_MAC_ADDR,
 	RTE_KNI_REQ_MAX,
 };
 
@@ -92,6 +93,7 @@ struct rte_kni_request {
 	union {
 		uint32_t new_mtu;    /**< New MTU */
 		uint8_t if_up;       /**< 1: interface up, 0: interface down */
+		uint8_t mac_addr[6]; /**< MAC address for interface */
 	};
 	int32_t result;               /**< Result for processing request */
 } __attribute__((__packed__));
@@ -168,6 +170,7 @@ struct rte_kni_device_info {
 
 	/* mbuf size */
 	unsigned mbuf_size;
+	char mac_addr[6];
 };
 
 #define KNI_DEVICE "kni"
diff --git a/lib/librte_eal/linuxapp/kni/kni_misc.c b/lib/librte_eal/linuxapp/kni/kni_misc.c
index 7590f1f..b524d30 100644
--- a/lib/librte_eal/linuxapp/kni/kni_misc.c
+++ b/lib/librte_eal/linuxapp/kni/kni_misc.c
@@ -458,12 +458,17 @@ kni_ioctl_create(struct net *net, uint32_t ioctl_num,
 
 	if (kni->lad_dev)
 		ether_addr_copy(net_dev->dev_addr, kni->lad_dev->dev_addr);
-	else
-		/*
-		 * Generate random mac address. eth_random_addr() is the newer
-		 * version of generating mac address in linux kernel.
-		 */
-		random_ether_addr(net_dev->dev_addr);
+	else {
+		/* if user has provided a valid mac address */
+		if (is_valid_ether_addr((unsigned char *)(dev_info.mac_addr)))
+			memcpy(net_dev->dev_addr, dev_info.mac_addr, ETH_ALEN);
+		else
+			/*
+			 * Generate random mac address. eth_random_addr() is the
+			 * newer version of generating mac address in kernel.
+			 */
+			random_ether_addr(net_dev->dev_addr);
+	}
 
 	ret = register_netdev(net_dev);
 	if (ret) {
diff --git a/lib/librte_eal/linuxapp/kni/kni_net.c b/lib/librte_eal/linuxapp/kni/kni_net.c
index db9f489..3e02ea1 100644
--- a/lib/librte_eal/linuxapp/kni/kni_net.c
+++ b/lib/librte_eal/linuxapp/kni/kni_net.c
@@ -668,12 +668,24 @@ kni_net_rebuild_header(struct sk_buff *skb)
 static int
 kni_net_set_mac(struct net_device *netdev, void *p)
 {
+	int ret;
+	struct rte_kni_request req;
+	struct kni_dev *kni;
 	struct sockaddr *addr = p;
 
+	memset(&req, 0, sizeof(req));
+	req.req_id = RTE_KNI_REQ_CHANGE_MAC_ADDR;
+
 	if (!is_valid_ether_addr((unsigned char *)(addr->sa_data)))
 		return -EADDRNOTAVAIL;
+
+	memcpy(req.mac_addr, addr->sa_data, netdev->addr_len);
 	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
-	return 0;
+
+	kni = netdev_priv(netdev);
+	ret = kni_net_process_request(kni, &req);
+
+	return (ret == 0 ? req.result : ret);
 }
 
 #ifdef HAVE_CHANGE_CARRIER_CB
diff --git a/lib/librte_kni/rte_kni.c b/lib/librte_kni/rte_kni.c
index 8eca8c0..04db3df 100644
--- a/lib/librte_kni/rte_kni.c
+++ b/lib/librte_kni/rte_kni.c
@@ -368,6 +368,8 @@ rte_kni_alloc(struct rte_mempool *pktmbuf_pool,
 	dev_info.group_id = conf->group_id;
 	dev_info.mbuf_size = conf->mbuf_size;
 
+	memcpy(dev_info.mac_addr, conf->mac_addr, ETHER_ADDR_LEN);
+
 	snprintf(ctx->name, RTE_KNI_NAMESIZE, "%s", intf_name);
 	snprintf(dev_info.name, RTE_KNI_NAMESIZE, "%s", intf_name);
 
@@ -528,6 +530,28 @@ rte_kni_release(struct rte_kni *kni)
 	return 0;
 }
 
+/* default callback for request of configuring device mac address */
+static int
+kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
+{
+	int ret = 0;
+
+	if (port_id >= rte_eth_dev_count() || port_id >= RTE_MAX_ETHPORTS) {
+		RTE_LOG(ERR, KNI, "Invalid port id %d\n", port_id);
+		return -EINVAL;
+	}
+
+	RTE_LOG(INFO, KNI, "Configure mac address of %d", port_id);
+
+	ret = rte_eth_dev_default_mac_addr_set(port_id,
+					       (struct ether_addr *)mac_addr);
+	if (ret < 0)
+		RTE_LOG(ERR, KNI, "Failed to config mac_addr for port %d\n",
+			port_id);
+
+	return ret;
+}
+
 int
 rte_kni_handle_request(struct rte_kni *kni)
 {
@@ -559,6 +583,14 @@ rte_kni_handle_request(struct rte_kni *kni)
 			req->result = kni->ops.config_network_if(\
 					kni->ops.port_id, req->if_up);
 		break;
+	case RTE_KNI_REQ_CHANGE_MAC_ADDR: /* Change MAC Address */
+		if (kni->ops.config_mac_address)
+			req->result = kni->ops.config_mac_address(
+					kni->ops.port_id, req->mac_addr);
+		else
+			req->result = kni_config_mac_address(
+					kni->ops.port_id, req->mac_addr);
+		break;
 	default:
 		RTE_LOG(ERR, KNI, "Unknown request id %u\n", req->req_id);
 		req->result = -EINVAL;
@@ -707,7 +739,9 @@ kni_check_request_register(struct rte_kni_ops *ops)
 	if( NULL == ops )
 		return KNI_REQ_NO_REGISTER;
 
-	if((NULL == ops->change_mtu) && (NULL == ops->config_network_if))
+	if ((NULL == ops->change_mtu)
+		&& (NULL == ops->config_network_if)
+		&& (NULL == ops->config_mac_address))
 		return KNI_REQ_NO_REGISTER;
 
 	return KNI_REQ_REGISTERED;
@@ -746,8 +780,8 @@ rte_kni_unregister_handlers(struct rte_kni *kni)
 		return -1;
 	}
 
-	kni->ops.change_mtu = NULL;
-	kni->ops.config_network_if = NULL;
+	memset(&kni->ops, 0, sizeof(struct rte_kni_ops));
+
 	return 0;
 }
 void
diff --git a/lib/librte_kni/rte_kni.h b/lib/librte_kni/rte_kni.h
index d43b5b2..a53329b 100644
--- a/lib/librte_kni/rte_kni.h
+++ b/lib/librte_kni/rte_kni.h
@@ -49,6 +49,7 @@
 #include <rte_pci.h>
 #include <rte_memory.h>
 #include <rte_mempool.h>
+#include <rte_ether.h>
 
 #include <exec-env/rte_kni_common.h>
 
@@ -70,6 +71,9 @@ struct rte_kni_ops {
 
 	/* Pointer to function of configuring network interface */
 	int (*config_network_if)(uint16_t port_id, uint8_t if_up);
+
+	/* Pointer to function of configuring mac address */
+	int (*config_mac_address)(uint16_t port_id, uint8_t mac_addr[]);
 };
 
 /**
@@ -87,6 +91,7 @@ struct rte_kni_conf {
 	unsigned mbuf_size; /* mbuf size */
 	struct rte_pci_addr addr;
 	struct rte_pci_id id;
+	char mac_addr[ETHER_ADDR_LEN]; /* MAC address assigned to KNI */
 
 	__extension__
 	uint8_t force_bind : 1; /* Flag to bind kernel thread */
diff --git a/test/test/test_kni.c b/test/test/test_kni.c
index b956727..06448c9 100644
--- a/test/test/test_kni.c
+++ b/test/test/test_kni.c
@@ -103,6 +103,7 @@ static const struct rte_eth_conf port_conf = {
 static struct rte_kni_ops kni_ops = {
 	.change_mtu = NULL,
 	.config_network_if = NULL,
+	.config_mac_address = NULL,
 };
 
 static unsigned lcore_master, lcore_ingress, lcore_egress;
@@ -260,6 +261,7 @@ test_kni_register_handler_mp(void)
 		struct rte_kni_ops ops = {
 			.change_mtu = kni_change_mtu,
 			.config_network_if = NULL,
+			.config_mac_address = NULL,
 		};
 
 		if (!kni) {
-- 
2.7.4

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH 2/3] kni: add support for promisc mode set
  2017-11-30 11:46 [dpdk-dev] [PATCH 1/3] kni: support for MAC addr change Hemant Agrawal
@ 2017-11-30 11:46 ` Hemant Agrawal
  2017-12-22 21:57   ` Ferruh Yigit
  2017-11-30 11:46 ` [dpdk-dev] [PATCH 3/3] kni: set initial value for MTU Hemant Agrawal
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 17+ messages in thread
From: Hemant Agrawal @ 2017-11-30 11:46 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

Inform userspace app about promisc mode change

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 doc/guides/sample_app_ug/kernel_nic_interface.rst  | 29 +++++++++++++++++---
 .../linuxapp/eal/include/exec-env/rte_kni_common.h |  2 ++
 lib/librte_eal/linuxapp/kni/kni_net.c              | 17 ++++++++++++
 lib/librte_kni/rte_kni.c                           | 31 +++++++++++++++++++++-
 lib/librte_kni/rte_kni.h                           |  3 +++
 test/test/test_kni.c                               |  2 ++
 6 files changed, 80 insertions(+), 4 deletions(-)

diff --git a/doc/guides/sample_app_ug/kernel_nic_interface.rst b/doc/guides/sample_app_ug/kernel_nic_interface.rst
index d9d8e4a..9cb8463 100644
--- a/doc/guides/sample_app_ug/kernel_nic_interface.rst
+++ b/doc/guides/sample_app_ug/kernel_nic_interface.rst
@@ -512,11 +512,11 @@ Callbacks for Kernel Requests
 
 To execute specific PMD operations in user space requested by some Linux* commands,
 callbacks must be implemented and filled in the struct rte_kni_ops structure.
-Currently, setting a new MTU, change in mac address and configuring the network interface(up/ down)
-are supported.
+Currently, setting a new MTU, change in mac address, configuring promiscusous mode
+and configuring the network interface(up/ down) are supported.
 Default implementation for following is available in rte_kni library. Application
 may choose to not implement follwoing callbacks:
-	``config_mac_address``
+	``config_mac_address`` and ``config_promiscusity``
 
 
 .. code-block:: c
@@ -525,6 +525,7 @@ may choose to not implement follwoing callbacks:
         .change_mtu = kni_change_mtu,
         .config_network_if = kni_config_network_interface,
         .config_mac_address = kni_config_mac_address,
+        .config_promiscusity = kni_config_promiscusity,
     };
 
     /* Callback for request of changing MTU */
@@ -626,3 +627,25 @@ may choose to not implement follwoing callbacks:
 
         return ret;
     }
+
+    /* Callback for request of configuring promiscuous mode */
+
+    static int
+    kni_config_promiscusity(uint16_t port_id, uint8_t to_on)
+    {
+        if (port_id >= rte_eth_dev_count() || port_id >= RTE_MAX_ETHPORTS) {
+                RTE_LOG(ERR, KNI, "Invalid port id %d\n", port_id);
+                return -EINVAL;
+        }
+
+        RTE_LOG(INFO, KNI, "Configure promiscuous mode of %d to %d\n",
+                port_id, to_on);
+
+        if (to_on)
+                rte_eth_promiscuous_enable(port_id);
+        else
+                rte_eth_promiscuous_disable(port_id);
+
+        return 0;
+    }
+
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 1a760de..f2ef48e 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
@@ -80,6 +80,7 @@ enum rte_kni_req_id {
 	RTE_KNI_REQ_UNKNOWN = 0,
 	RTE_KNI_REQ_CHANGE_MTU,
 	RTE_KNI_REQ_CFG_NETWORK_IF,
+	RTE_KNI_REQ_CHANGE_PROMISC,
 	RTE_KNI_REQ_CHANGE_MAC_ADDR,
 	RTE_KNI_REQ_MAX,
 };
@@ -94,6 +95,7 @@ struct rte_kni_request {
 		uint32_t new_mtu;    /**< New MTU */
 		uint8_t if_up;       /**< 1: interface up, 0: interface down */
 		uint8_t mac_addr[6]; /**< MAC address for interface */
+		uint8_t promiscusity;/**< 1: promisc mode enable, 0: disable */
 	};
 	int32_t result;               /**< Result for processing request */
 } __attribute__((__packed__));
diff --git a/lib/librte_eal/linuxapp/kni/kni_net.c b/lib/librte_eal/linuxapp/kni/kni_net.c
index 3e02ea1..e261c58 100644
--- a/lib/librte_eal/linuxapp/kni/kni_net.c
+++ b/lib/librte_eal/linuxapp/kni/kni_net.c
@@ -603,6 +603,22 @@ kni_net_change_mtu(struct net_device *dev, int new_mtu)
 	return (ret == 0) ? req.result : ret;
 }
 
+static void
+kni_net_set_promiscusity(struct net_device *netdev, int flags)
+{
+	struct rte_kni_request req;
+	struct kni_dev *kni = netdev_priv(netdev);
+
+	memset(&req, 0, sizeof(req));
+	req.req_id = RTE_KNI_REQ_CHANGE_PROMISC;
+
+	if (netdev->flags & IFF_PROMISC)
+		req.promiscusity = 1;
+	else
+		req.promiscusity = 0;
+	kni_net_process_request(kni, &req);
+}
+
 /*
  * Checks if the user space application provided the resp message
  */
@@ -712,6 +728,7 @@ static const struct net_device_ops kni_net_netdev_ops = {
 	.ndo_open = kni_net_open,
 	.ndo_stop = kni_net_release,
 	.ndo_set_config = kni_net_config,
+	.ndo_change_rx_flags = kni_net_set_promiscusity,
 	.ndo_start_xmit = kni_net_tx,
 	.ndo_change_mtu = kni_net_change_mtu,
 	.ndo_do_ioctl = kni_net_ioctl,
diff --git a/lib/librte_kni/rte_kni.c b/lib/librte_kni/rte_kni.c
index 04db3df..e8cd297 100644
--- a/lib/librte_kni/rte_kni.c
+++ b/lib/librte_kni/rte_kni.c
@@ -552,6 +552,26 @@ kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
 	return ret;
 }
 
+/* default callback for request of configuring promiscuous mode */
+static int
+kni_config_promiscusity(uint16_t port_id, uint8_t to_on)
+{
+	if (port_id >= rte_eth_dev_count() || port_id >= RTE_MAX_ETHPORTS) {
+		RTE_LOG(ERR, KNI, "Invalid port id %d\n", port_id);
+		return -EINVAL;
+	}
+
+	RTE_LOG(INFO, KNI, "Configure promiscuous mode of %d to %d\n",
+		port_id, to_on);
+
+	if (to_on)
+		rte_eth_promiscuous_enable(port_id);
+	else
+		rte_eth_promiscuous_disable(port_id);
+
+	return 0;
+}
+
 int
 rte_kni_handle_request(struct rte_kni *kni)
 {
@@ -591,6 +611,14 @@ rte_kni_handle_request(struct rte_kni *kni)
 			req->result = kni_config_mac_address(
 					kni->ops.port_id, req->mac_addr);
 		break;
+	case RTE_KNI_REQ_CHANGE_PROMISC: /* Change PROMISCUOUS MODE */
+		if (kni->ops.config_promiscusity)
+			req->result = kni->ops.config_promiscusity(
+					kni->ops.port_id, req->promiscusity);
+		else
+			req->result = kni_config_promiscusity(
+					kni->ops.port_id, req->promiscusity);
+		break;
 	default:
 		RTE_LOG(ERR, KNI, "Unknown request id %u\n", req->req_id);
 		req->result = -EINVAL;
@@ -741,7 +769,8 @@ kni_check_request_register(struct rte_kni_ops *ops)
 
 	if ((NULL == ops->change_mtu)
 		&& (NULL == ops->config_network_if)
-		&& (NULL == ops->config_mac_address))
+		&& (NULL == ops->config_mac_address)
+		&& (NULL == ops->config_promiscusity))
 		return KNI_REQ_NO_REGISTER;
 
 	return KNI_REQ_REGISTERED;
diff --git a/lib/librte_kni/rte_kni.h b/lib/librte_kni/rte_kni.h
index a53329b..bc5ead7 100644
--- a/lib/librte_kni/rte_kni.h
+++ b/lib/librte_kni/rte_kni.h
@@ -72,6 +72,9 @@ struct rte_kni_ops {
 	/* Pointer to function of configuring network interface */
 	int (*config_network_if)(uint16_t port_id, uint8_t if_up);
 
+	/* Pointer to function of configuring promiscuous mode */
+	int (*config_promiscusity)(uint16_t port_id, uint8_t to_on);
+
 	/* Pointer to function of configuring mac address */
 	int (*config_mac_address)(uint16_t port_id, uint8_t mac_addr[]);
 };
diff --git a/test/test/test_kni.c b/test/test/test_kni.c
index 06448c9..56a7f3b 100644
--- a/test/test/test_kni.c
+++ b/test/test/test_kni.c
@@ -104,6 +104,7 @@ static struct rte_kni_ops kni_ops = {
 	.change_mtu = NULL,
 	.config_network_if = NULL,
 	.config_mac_address = NULL,
+	.config_promiscusity = NULL,
 };
 
 static unsigned lcore_master, lcore_ingress, lcore_egress;
@@ -262,6 +263,7 @@ test_kni_register_handler_mp(void)
 			.change_mtu = kni_change_mtu,
 			.config_network_if = NULL,
 			.config_mac_address = NULL,
+			.config_promiscusity = NULL,
 		};
 
 		if (!kni) {
-- 
2.7.4

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH 3/3] kni: set initial value for MTU
  2017-11-30 11:46 [dpdk-dev] [PATCH 1/3] kni: support for MAC addr change Hemant Agrawal
  2017-11-30 11:46 ` [dpdk-dev] [PATCH 2/3] kni: add support for promisc mode set Hemant Agrawal
@ 2017-11-30 11:46 ` Hemant Agrawal
  2017-12-22 22:01   ` Ferruh Yigit
  2017-12-22 21:55 ` [dpdk-dev] [PATCH 1/3] kni: support for MAC addr change Ferruh Yigit
  2017-12-26 10:36 ` [dpdk-dev] [PATCH v2 " Hemant Agrawal
  3 siblings, 1 reply; 17+ messages in thread
From: Hemant Agrawal @ 2017-11-30 11:46 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

Configure initial application provided  mtu on the KNI interface.

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 examples/kni/main.c                                           | 2 ++
 lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h | 1 +
 lib/librte_eal/linuxapp/kni/kni_misc.c                        | 3 +++
 lib/librte_kni/rte_kni.c                                      | 1 +
 lib/librte_kni/rte_kni.h                                      | 1 +
 5 files changed, 8 insertions(+)

diff --git a/examples/kni/main.c b/examples/kni/main.c
index 1c251c2..d9c9fa5 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -845,6 +845,8 @@ kni_alloc(uint16_t port_id)
 			rte_eth_macaddr_get(port_id,
 					(struct ether_addr *)&conf.mac_addr);
 
+			rte_eth_dev_get_mtu(port_id, &conf.mtu);
+
 			memset(&ops, 0, sizeof(ops));
 			ops.port_id = port_id;
 			ops.change_mtu = kni_change_mtu;
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 f2ef48e..9fdaed9 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
@@ -172,6 +172,7 @@ struct rte_kni_device_info {
 
 	/* mbuf size */
 	unsigned mbuf_size;
+	unsigned int mtu;
 	char mac_addr[6];
 };
 
diff --git a/lib/librte_eal/linuxapp/kni/kni_misc.c b/lib/librte_eal/linuxapp/kni/kni_misc.c
index b524d30..0ccd227 100644
--- a/lib/librte_eal/linuxapp/kni/kni_misc.c
+++ b/lib/librte_eal/linuxapp/kni/kni_misc.c
@@ -470,6 +470,9 @@ kni_ioctl_create(struct net *net, uint32_t ioctl_num,
 			random_ether_addr(net_dev->dev_addr);
 	}
 
+	if (dev_info.mtu)
+		net_dev->mtu = dev_info.mtu;
+
 	ret = register_netdev(net_dev);
 	if (ret) {
 		pr_err("error %i registering device \"%s\"\n",
diff --git a/lib/librte_kni/rte_kni.c b/lib/librte_kni/rte_kni.c
index e8cd297..8b31747 100644
--- a/lib/librte_kni/rte_kni.c
+++ b/lib/librte_kni/rte_kni.c
@@ -367,6 +367,7 @@ rte_kni_alloc(struct rte_mempool *pktmbuf_pool,
 	dev_info.force_bind = conf->force_bind;
 	dev_info.group_id = conf->group_id;
 	dev_info.mbuf_size = conf->mbuf_size;
+	dev_info.mtu = conf->mtu;
 
 	memcpy(dev_info.mac_addr, conf->mac_addr, ETHER_ADDR_LEN);
 
diff --git a/lib/librte_kni/rte_kni.h b/lib/librte_kni/rte_kni.h
index bc5ead7..37dded6 100644
--- a/lib/librte_kni/rte_kni.h
+++ b/lib/librte_kni/rte_kni.h
@@ -95,6 +95,7 @@ struct rte_kni_conf {
 	struct rte_pci_addr addr;
 	struct rte_pci_id id;
 	char mac_addr[ETHER_ADDR_LEN]; /* MAC address assigned to KNI */
+	uint16_t mtu;
 
 	__extension__
 	uint8_t force_bind : 1; /* Flag to bind kernel thread */
-- 
2.7.4

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [dpdk-dev] [PATCH 1/3] kni: support for MAC addr change
  2017-11-30 11:46 [dpdk-dev] [PATCH 1/3] kni: support for MAC addr change Hemant Agrawal
  2017-11-30 11:46 ` [dpdk-dev] [PATCH 2/3] kni: add support for promisc mode set Hemant Agrawal
  2017-11-30 11:46 ` [dpdk-dev] [PATCH 3/3] kni: set initial value for MTU Hemant Agrawal
@ 2017-12-22 21:55 ` Ferruh Yigit
  2017-12-26 10:08   ` Hemant Agrawal
  2017-12-26 10:36 ` [dpdk-dev] [PATCH v2 " Hemant Agrawal
  3 siblings, 1 reply; 17+ messages in thread
From: Ferruh Yigit @ 2017-12-22 21:55 UTC (permalink / raw)
  To: Hemant Agrawal, dev

On 11/30/2017 3:46 AM, Hemant Agrawal wrote:
> This patch adds following:
> 1. Option to configure the mac address during create. Generate random
>    address only if the user has not provided any valid address.
> 2. Inform usespace, if mac address is being changed in linux.
> 3. Implement default handling of mac address change in the corresponding
>    ethernet device.>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>

Overall lgtm, there are a few issues commented below.

Thanks,
ferruh

<...>

> @@ -269,11 +275,15 @@ The code for allocating the kernel NIC interfaces for a specific port is as foll
>                      conf.addr = dev_info.pci_dev->addr;
>                      conf.id = dev_info.pci_dev->id;
>  
> +                    /* Get the interface default mac address */
> +                    rte_eth_macaddr_get(port_id, struct ether_addr *)&conf.mac_addr);

a parentheses is missing, good to fix although this is document :)

<...>

> @@ -587,3 +603,26 @@ Currently, setting a new MTU and configuring the network interface (up/ down) ar
>              RTE_LOG(ERR, APP, "Failed to start port %d\n", port_id);
>          return ret;
>      }
> +
> +    /* Callback for request of configuring device mac address */
> +
> +    static int
> +    kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
> +    {
> +        int ret = 0;
> +
> +        if (port_id >= rte_eth_dev_count() || port_id >= RTE_MAX_ETHPORTS) {
> +                RTE_LOG(ERR, KNI, "Invalid port id %d\n", port_id);
> +                return -EINVAL;
> +        }
> +
> +        RTE_LOG(INFO, KNI, "Configure mac address of %d", port_id);
> +        /* Configure network interface mac address */
> +        ret = rte_eth_dev_default_mac_addr_set(port_id,
> +                                               (struct ether_addr *)mac_addr);
> +        if (ret < 0)
> +                RTE_LOG(ERR, KNI, "Failed to config mac_addr for port %d\n",
> +                        port_id);
> +
> +        return ret;
> +    }


It is hard to maintain code in doc, I am aware other related code is already in
document but what do you think keeping this minimal, like:

    static int
    kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
    {
       ....
    }


<...>

> @@ -559,6 +583,14 @@ rte_kni_handle_request(struct rte_kni *kni)
>  			req->result = kni->ops.config_network_if(\
>  					kni->ops.port_id, req->if_up);
>  		break;
> +	case RTE_KNI_REQ_CHANGE_MAC_ADDR: /* Change MAC Address */
> +		if (kni->ops.config_mac_address)
> +			req->result = kni->ops.config_mac_address(
> +					kni->ops.port_id, req->mac_addr);
> +		else
> +			req->result = kni_config_mac_address(
> +					kni->ops.port_id, req->mac_addr);

ops.port_id can be unset if there is no physically backing device the kni
interface. And I guess for that case port_id will be 0 and it will corrupt other
interface's data. There needs to find a way to handle the port_id not set case.

Since kni sample always creates a KNI interface backed by pyhsical device, this
is not an issue for kni sample app but please think about kni pmd case.

<...>

> @@ -87,6 +91,7 @@ struct rte_kni_conf {
>  	unsigned mbuf_size; /* mbuf size */
>  	struct rte_pci_addr addr;
>  	struct rte_pci_id id;
> +	char mac_addr[ETHER_ADDR_LEN]; /* MAC address assigned to KNI */
>  
>  	__extension__
>  	uint8_t force_bind : 1; /* Flag to bind kernel thread */

"struct rte_kni_conf" is a public struct. Adding a variable into the middle of
the struct will break the ABI.
But I think it is OK to add to the end, unless struct is not used as array.

<...>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [dpdk-dev] [PATCH 2/3] kni: add support for promisc mode set
  2017-11-30 11:46 ` [dpdk-dev] [PATCH 2/3] kni: add support for promisc mode set Hemant Agrawal
@ 2017-12-22 21:57   ` Ferruh Yigit
  0 siblings, 0 replies; 17+ messages in thread
From: Ferruh Yigit @ 2017-12-22 21:57 UTC (permalink / raw)
  To: Hemant Agrawal, dev

On 11/30/2017 3:46 AM, Hemant Agrawal wrote:
> Inform userspace app about promisc mode change

Same two concerns here with prev patch.
- Breaking ABI
- And handling ops.port_id not set by application case.

> 
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>

<...>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [dpdk-dev] [PATCH 3/3] kni: set initial value for MTU
  2017-11-30 11:46 ` [dpdk-dev] [PATCH 3/3] kni: set initial value for MTU Hemant Agrawal
@ 2017-12-22 22:01   ` Ferruh Yigit
  0 siblings, 0 replies; 17+ messages in thread
From: Ferruh Yigit @ 2017-12-22 22:01 UTC (permalink / raw)
  To: Hemant Agrawal, dev

On 11/30/2017 3:46 AM, Hemant Agrawal wrote:
> Configure initial application provided  mtu on the KNI interface.
> 
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>

<...>

> @@ -95,6 +95,7 @@ struct rte_kni_conf {
>  	struct rte_pci_addr addr;
>  	struct rte_pci_id id;
>  	char mac_addr[ETHER_ADDR_LEN]; /* MAC address assigned to KNI */
> +	uint16_t mtu;

Same issue here, adding a new field into middle of the public struct.
I think it would be OK to add to the end, but to be sure would you please run
ABI check script (validate-abi.sh) after adding to the end?

Thanks,
ferruh

>  
>  	__extension__
>  	uint8_t force_bind : 1; /* Flag to bind kernel thread */
> 

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [dpdk-dev] [PATCH 1/3] kni: support for MAC addr change
  2017-12-22 21:55 ` [dpdk-dev] [PATCH 1/3] kni: support for MAC addr change Ferruh Yigit
@ 2017-12-26 10:08   ` Hemant Agrawal
  0 siblings, 0 replies; 17+ messages in thread
From: Hemant Agrawal @ 2017-12-26 10:08 UTC (permalink / raw)
  To: Ferruh Yigit, dev

Hi Ferruh,

On 12/23/2017 3:25 AM, Ferruh Yigit wrote:
> On 11/30/2017 3:46 AM, Hemant Agrawal wrote:
>> This patch adds following:
>> 1. Option to configure the mac address during create. Generate random
>>    address only if the user has not provided any valid address.
>> 2. Inform usespace, if mac address is being changed in linux.
>> 3. Implement default handling of mac address change in the corresponding
>>    ethernet device.>
>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>
> Overall lgtm, there are a few issues commented below.
>
> Thanks,
> ferruh
>
> <...>


>> @@ -587,3 +603,26 @@ Currently, setting a new MTU and configuring the network interface (up/ down) ar
>>              RTE_LOG(ERR, APP, "Failed to start port %d\n", port_id);
>>          return ret;
>>      }
>> +
>> +    /* Callback for request of configuring device mac address */
>> +
>> +    static int
>> +    kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
>> +    {
>> +        int ret = 0;
>> +
>> +        if (port_id >= rte_eth_dev_count() || port_id >= RTE_MAX_ETHPORTS) {
>> +                RTE_LOG(ERR, KNI, "Invalid port id %d\n", port_id);
>> +                return -EINVAL;
>> +        }
>> +
>> +        RTE_LOG(INFO, KNI, "Configure mac address of %d", port_id);
>> +        /* Configure network interface mac address */
>> +        ret = rte_eth_dev_default_mac_addr_set(port_id,
>> +                                               (struct ether_addr *)mac_addr);
>> +        if (ret < 0)
>> +                RTE_LOG(ERR, KNI, "Failed to config mac_addr for port %d\n",
>> +                        port_id);
>> +
>> +        return ret;
>> +    }
>
>
> It is hard to maintain code in doc, I am aware other related code is already in
> document but what do you think keeping this minimal, like:
>
>     static int
>     kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
>     {
>        ....
>     }

agree.

>
>
> <...>
>
>> @@ -559,6 +583,14 @@ rte_kni_handle_request(struct rte_kni *kni)
>>  			req->result = kni->ops.config_network_if(\
>>  					kni->ops.port_id, req->if_up);
>>  		break;
>> +	case RTE_KNI_REQ_CHANGE_MAC_ADDR: /* Change MAC Address */
>> +		if (kni->ops.config_mac_address)
>> +			req->result = kni->ops.config_mac_address(
>> +					kni->ops.port_id, req->mac_addr);
>> +		else
>> +			req->result = kni_config_mac_address(
>> +					kni->ops.port_id, req->mac_addr);
>
> ops.port_id can be unset if there is no physically backing device the kni
> interface. And I guess for that case port_id will be 0 and it will corrupt other
> interface's data. There needs to find a way to handle the port_id not set case.

got it. I will set it as UINT16_MAX and check for it.

>
> Since kni sample always creates a KNI interface backed by pyhsical device, this
> is not an issue for kni sample app but please think about kni pmd case.
>



> <...>
>
>> @@ -87,6 +91,7 @@ struct rte_kni_conf {
>>  	unsigned mbuf_size; /* mbuf size */
>>  	struct rte_pci_addr addr;
>>  	struct rte_pci_id id;
>> +	char mac_addr[ETHER_ADDR_LEN]; /* MAC address assigned to KNI */
>>
>>  	__extension__
>>  	uint8_t force_bind : 1; /* Flag to bind kernel thread */
>
> "struct rte_kni_conf" is a public struct. Adding a variable into the middle of
> the struct will break the ABI.
> But I think it is OK to add to the end, unless struct is not used as array.
>
> <...>
>
yes. adding it into middle breaks the ABIs. However adding into end is ok.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v2 1/3] kni: support for MAC addr change
  2017-11-30 11:46 [dpdk-dev] [PATCH 1/3] kni: support for MAC addr change Hemant Agrawal
                   ` (2 preceding siblings ...)
  2017-12-22 21:55 ` [dpdk-dev] [PATCH 1/3] kni: support for MAC addr change Ferruh Yigit
@ 2017-12-26 10:36 ` Hemant Agrawal
  2017-12-26 10:36   ` [dpdk-dev] [PATCH v2 2/3] kni: add support for promisc mode set Hemant Agrawal
                     ` (2 more replies)
  3 siblings, 3 replies; 17+ messages in thread
From: Hemant Agrawal @ 2017-12-26 10:36 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds following:
1. Option to configure the mac address during create. Generate random
   address only if the user has not provided any valid address.
2. Inform usespace, if mac address is being changed in linux.
3. Implement default handling of mac address change in the corresponding
   ethernet device.

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
v2: 
* fix ABI breakage
* reducing the code in documentation.
* initialize ops.portid to UNIT16_MAX for vdev case
    

 doc/guides/sample_app_ug/kernel_nic_interface.rst  | 26 +++++++++++++-
 examples/kni/main.c                                | 36 +++++++++++++++++++
 .../linuxapp/eal/include/exec-env/rte_kni_common.h |  3 ++
 lib/librte_eal/linuxapp/kni/kni_misc.c             | 17 +++++----
 lib/librte_eal/linuxapp/kni/kni_net.c              | 14 +++++++-
 lib/librte_kni/rte_kni.c                           | 42 ++++++++++++++++++++--
 lib/librte_kni/rte_kni.h                           |  5 +++
 test/test/test_kni.c                               |  2 ++
 8 files changed, 134 insertions(+), 11 deletions(-)

diff --git a/doc/guides/sample_app_ug/kernel_nic_interface.rst b/doc/guides/sample_app_ug/kernel_nic_interface.rst
index e1ac415..2c143da 100644
--- a/doc/guides/sample_app_ug/kernel_nic_interface.rst
+++ b/doc/guides/sample_app_ug/kernel_nic_interface.rst
@@ -209,6 +209,12 @@ Dumping the network traffic:
 
     #tcpdump -i vEth0_0
 
+Change the MAC address:
+
+.. code-block:: console
+
+    #ifconfig vEth0_0 hw ether 0C:01:02:03:04:08
+
 When the DPDK userspace application is closed, all the KNI devices are deleted from Linux*.
 
 Explanation
@@ -269,11 +275,15 @@ The code for allocating the kernel NIC interfaces for a specific port is as foll
                     conf.addr = dev_info.pci_dev->addr;
                     conf.id = dev_info.pci_dev->id;
 
+                    /* Get the interface default mac address */
+                    rte_eth_macaddr_get(port_id, (struct ether_addr *)&conf.mac_addr);
+
                     memset(&ops, 0, sizeof(ops));
 
                     ops.port_id = port_id;
                     ops.change_mtu = kni_change_mtu;
                     ops.config_network_if = kni_config_network_interface;
+                    ops.config_mac_address = kni_config_mac_address;
 
                     kni = rte_kni_alloc(pktmbuf_pool, &conf, &ops);
                 } else
@@ -502,13 +512,19 @@ Callbacks for Kernel Requests
 
 To execute specific PMD operations in user space requested by some Linux* commands,
 callbacks must be implemented and filled in the struct rte_kni_ops structure.
-Currently, setting a new MTU and configuring the network interface (up/ down) are supported.
+Currently, setting a new MTU, change in mac address and configuring the network interface(up/ down)
+are supported.
+Default implementation for following is available in rte_kni library. Application
+may choose to not implement follwoing callbacks:
+	``config_mac_address``
+
 
 .. code-block:: c
 
     static struct rte_kni_ops kni_ops = {
         .change_mtu = kni_change_mtu,
         .config_network_if = kni_config_network_interface,
+        .config_mac_address = kni_config_mac_address,
     };
 
     /* Callback for request of changing MTU */
@@ -587,3 +603,11 @@ Currently, setting a new MTU and configuring the network interface (up/ down) ar
             RTE_LOG(ERR, APP, "Failed to start port %d\n", port_id);
         return ret;
     }
+
+    /* Callback for request of configuring device mac address */
+
+    static int
+    kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
+    {
+        .....
+    }
diff --git a/examples/kni/main.c b/examples/kni/main.c
index 3f17385..1c251c2 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -163,6 +163,7 @@ static struct kni_interface_stats kni_stats[RTE_MAX_ETHPORTS];
 
 static int kni_change_mtu(uint16_t port_id, unsigned int new_mtu);
 static int kni_config_network_interface(uint16_t port_id, uint8_t if_up);
+static int kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[]);
 
 static rte_atomic32_t kni_stop = RTE_ATOMIC32_INIT(0);
 
@@ -766,6 +767,37 @@ kni_config_network_interface(uint16_t port_id, uint8_t if_up)
 	return ret;
 }
 
+static void
+print_ethaddr(const char *name, struct ether_addr *mac_addr)
+{
+	char buf[ETHER_ADDR_FMT_SIZE];
+	ether_format_addr(buf, ETHER_ADDR_FMT_SIZE, mac_addr);
+	RTE_LOG(INFO, APP, "\t%s%s\n", name, buf);
+}
+
+/* Callback for request of configuring mac address */
+static int
+kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
+{
+	int ret = 0;
+
+	if (port_id >= rte_eth_dev_count() || port_id >= RTE_MAX_ETHPORTS) {
+		RTE_LOG(ERR, APP, "Invalid port id %d\n", port_id);
+		return -EINVAL;
+	}
+
+	RTE_LOG(INFO, APP, "Configure mac address of %d\n", port_id);
+	print_ethaddr("Address:", (struct ether_addr *)mac_addr);
+
+	ret = rte_eth_dev_default_mac_addr_set(port_id,
+					       (struct ether_addr *)mac_addr);
+	if (ret < 0)
+		RTE_LOG(ERR, APP, "Failed to config mac_addr for port %d\n",
+			port_id);
+
+	return ret;
+}
+
 static int
 kni_alloc(uint16_t port_id)
 {
@@ -809,11 +841,15 @@ kni_alloc(uint16_t port_id)
 				conf.addr = dev_info.pci_dev->addr;
 				conf.id = dev_info.pci_dev->id;
 			}
+			/* Get the interface default mac address */
+			rte_eth_macaddr_get(port_id,
+					(struct ether_addr *)&conf.mac_addr);
 
 			memset(&ops, 0, sizeof(ops));
 			ops.port_id = port_id;
 			ops.change_mtu = kni_change_mtu;
 			ops.config_network_if = kni_config_network_interface;
+			ops.config_mac_address = kni_config_mac_address;
 
 			kni = rte_kni_alloc(pktmbuf_pool, &conf, &ops);
 		} else
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 2ac879f..1a760de 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
@@ -80,6 +80,7 @@ enum rte_kni_req_id {
 	RTE_KNI_REQ_UNKNOWN = 0,
 	RTE_KNI_REQ_CHANGE_MTU,
 	RTE_KNI_REQ_CFG_NETWORK_IF,
+	RTE_KNI_REQ_CHANGE_MAC_ADDR,
 	RTE_KNI_REQ_MAX,
 };
 
@@ -92,6 +93,7 @@ struct rte_kni_request {
 	union {
 		uint32_t new_mtu;    /**< New MTU */
 		uint8_t if_up;       /**< 1: interface up, 0: interface down */
+		uint8_t mac_addr[6]; /**< MAC address for interface */
 	};
 	int32_t result;               /**< Result for processing request */
 } __attribute__((__packed__));
@@ -168,6 +170,7 @@ struct rte_kni_device_info {
 
 	/* mbuf size */
 	unsigned mbuf_size;
+	char mac_addr[6];
 };
 
 #define KNI_DEVICE "kni"
diff --git a/lib/librte_eal/linuxapp/kni/kni_misc.c b/lib/librte_eal/linuxapp/kni/kni_misc.c
index 7590f1f..b524d30 100644
--- a/lib/librte_eal/linuxapp/kni/kni_misc.c
+++ b/lib/librte_eal/linuxapp/kni/kni_misc.c
@@ -458,12 +458,17 @@ kni_ioctl_create(struct net *net, uint32_t ioctl_num,
 
 	if (kni->lad_dev)
 		ether_addr_copy(net_dev->dev_addr, kni->lad_dev->dev_addr);
-	else
-		/*
-		 * Generate random mac address. eth_random_addr() is the newer
-		 * version of generating mac address in linux kernel.
-		 */
-		random_ether_addr(net_dev->dev_addr);
+	else {
+		/* if user has provided a valid mac address */
+		if (is_valid_ether_addr((unsigned char *)(dev_info.mac_addr)))
+			memcpy(net_dev->dev_addr, dev_info.mac_addr, ETH_ALEN);
+		else
+			/*
+			 * Generate random mac address. eth_random_addr() is the
+			 * newer version of generating mac address in kernel.
+			 */
+			random_ether_addr(net_dev->dev_addr);
+	}
 
 	ret = register_netdev(net_dev);
 	if (ret) {
diff --git a/lib/librte_eal/linuxapp/kni/kni_net.c b/lib/librte_eal/linuxapp/kni/kni_net.c
index db9f489..3e02ea1 100644
--- a/lib/librte_eal/linuxapp/kni/kni_net.c
+++ b/lib/librte_eal/linuxapp/kni/kni_net.c
@@ -668,12 +668,24 @@ kni_net_rebuild_header(struct sk_buff *skb)
 static int
 kni_net_set_mac(struct net_device *netdev, void *p)
 {
+	int ret;
+	struct rte_kni_request req;
+	struct kni_dev *kni;
 	struct sockaddr *addr = p;
 
+	memset(&req, 0, sizeof(req));
+	req.req_id = RTE_KNI_REQ_CHANGE_MAC_ADDR;
+
 	if (!is_valid_ether_addr((unsigned char *)(addr->sa_data)))
 		return -EADDRNOTAVAIL;
+
+	memcpy(req.mac_addr, addr->sa_data, netdev->addr_len);
 	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
-	return 0;
+
+	kni = netdev_priv(netdev);
+	ret = kni_net_process_request(kni, &req);
+
+	return (ret == 0 ? req.result : ret);
 }
 
 #ifdef HAVE_CHANGE_CARRIER_CB
diff --git a/lib/librte_kni/rte_kni.c b/lib/librte_kni/rte_kni.c
index 8eca8c0..a5ee210 100644
--- a/lib/librte_kni/rte_kni.c
+++ b/lib/librte_kni/rte_kni.c
@@ -356,6 +356,8 @@ rte_kni_alloc(struct rte_mempool *pktmbuf_pool,
 	memset(ctx, 0, sizeof(struct rte_kni));
 	if (ops)
 		memcpy(&ctx->ops, ops, sizeof(struct rte_kni_ops));
+	else
+		ctx->ops.port_id = UINT16_MAX;
 
 	memset(&dev_info, 0, sizeof(dev_info));
 	dev_info.bus = conf->addr.bus;
@@ -368,6 +370,8 @@ rte_kni_alloc(struct rte_mempool *pktmbuf_pool,
 	dev_info.group_id = conf->group_id;
 	dev_info.mbuf_size = conf->mbuf_size;
 
+	memcpy(dev_info.mac_addr, conf->mac_addr, ETHER_ADDR_LEN);
+
 	snprintf(ctx->name, RTE_KNI_NAMESIZE, "%s", intf_name);
 	snprintf(dev_info.name, RTE_KNI_NAMESIZE, "%s", intf_name);
 
@@ -528,6 +532,28 @@ rte_kni_release(struct rte_kni *kni)
 	return 0;
 }
 
+/* default callback for request of configuring device mac address */
+static int
+kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
+{
+	int ret = 0;
+
+	if (port_id >= rte_eth_dev_count() || port_id >= RTE_MAX_ETHPORTS) {
+		RTE_LOG(ERR, KNI, "Invalid port id %d\n", port_id);
+		return -EINVAL;
+	}
+
+	RTE_LOG(INFO, KNI, "Configure mac address of %d", port_id);
+
+	ret = rte_eth_dev_default_mac_addr_set(port_id,
+					       (struct ether_addr *)mac_addr);
+	if (ret < 0)
+		RTE_LOG(ERR, KNI, "Failed to config mac_addr for port %d\n",
+			port_id);
+
+	return ret;
+}
+
 int
 rte_kni_handle_request(struct rte_kni *kni)
 {
@@ -559,6 +585,14 @@ rte_kni_handle_request(struct rte_kni *kni)
 			req->result = kni->ops.config_network_if(\
 					kni->ops.port_id, req->if_up);
 		break;
+	case RTE_KNI_REQ_CHANGE_MAC_ADDR: /* Change MAC Address */
+		if (kni->ops.config_mac_address)
+			req->result = kni->ops.config_mac_address(
+					kni->ops.port_id, req->mac_addr);
+		else if (kni->ops.port_id != UNIT16_MAX)
+			req->result = kni_config_mac_address(
+					kni->ops.port_id, req->mac_addr);
+		break;
 	default:
 		RTE_LOG(ERR, KNI, "Unknown request id %u\n", req->req_id);
 		req->result = -EINVAL;
@@ -707,7 +741,9 @@ kni_check_request_register(struct rte_kni_ops *ops)
 	if( NULL == ops )
 		return KNI_REQ_NO_REGISTER;
 
-	if((NULL == ops->change_mtu) && (NULL == ops->config_network_if))
+	if ((NULL == ops->change_mtu)
+		&& (NULL == ops->config_network_if)
+		&& (NULL == ops->config_mac_address))
 		return KNI_REQ_NO_REGISTER;
 
 	return KNI_REQ_REGISTERED;
@@ -746,8 +782,8 @@ rte_kni_unregister_handlers(struct rte_kni *kni)
 		return -1;
 	}
 
-	kni->ops.change_mtu = NULL;
-	kni->ops.config_network_if = NULL;
+	memset(&kni->ops, 0, sizeof(struct rte_kni_ops));
+
 	return 0;
 }
 void
diff --git a/lib/librte_kni/rte_kni.h b/lib/librte_kni/rte_kni.h
index d43b5b2..9bdc9f3 100644
--- a/lib/librte_kni/rte_kni.h
+++ b/lib/librte_kni/rte_kni.h
@@ -49,6 +49,7 @@
 #include <rte_pci.h>
 #include <rte_memory.h>
 #include <rte_mempool.h>
+#include <rte_ether.h>
 
 #include <exec-env/rte_kni_common.h>
 
@@ -70,6 +71,9 @@ struct rte_kni_ops {
 
 	/* Pointer to function of configuring network interface */
 	int (*config_network_if)(uint16_t port_id, uint8_t if_up);
+
+	/* Pointer to function of configuring mac address */
+	int (*config_mac_address)(uint16_t port_id, uint8_t mac_addr[]);
 };
 
 /**
@@ -90,6 +94,7 @@ struct rte_kni_conf {
 
 	__extension__
 	uint8_t force_bind : 1; /* Flag to bind kernel thread */
+	char mac_addr[ETHER_ADDR_LEN]; /* MAC address assigned to KNI */
 };
 
 /**
diff --git a/test/test/test_kni.c b/test/test/test_kni.c
index b956727..06448c9 100644
--- a/test/test/test_kni.c
+++ b/test/test/test_kni.c
@@ -103,6 +103,7 @@ static const struct rte_eth_conf port_conf = {
 static struct rte_kni_ops kni_ops = {
 	.change_mtu = NULL,
 	.config_network_if = NULL,
+	.config_mac_address = NULL,
 };
 
 static unsigned lcore_master, lcore_ingress, lcore_egress;
@@ -260,6 +261,7 @@ test_kni_register_handler_mp(void)
 		struct rte_kni_ops ops = {
 			.change_mtu = kni_change_mtu,
 			.config_network_if = NULL,
+			.config_mac_address = NULL,
 		};
 
 		if (!kni) {
-- 
2.7.4

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v2 2/3] kni: add support for promisc mode set
  2017-12-26 10:36 ` [dpdk-dev] [PATCH v2 " Hemant Agrawal
@ 2017-12-26 10:36   ` Hemant Agrawal
  2017-12-26 10:36   ` [dpdk-dev] [PATCH v2 3/3] kni: set initial value for MTU Hemant Agrawal
  2018-01-18  6:12   ` [dpdk-dev] [PATCH v3 1/3] kni: support for MAC addr change Hemant Agrawal
  2 siblings, 0 replies; 17+ messages in thread
From: Hemant Agrawal @ 2017-12-26 10:36 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

Inform userspace app about promisc mode change

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
v2:
* fix ABI breakage
* check for ops.port_id for vdev case


 doc/guides/sample_app_ug/kernel_nic_interface.rst  | 15 ++++++++---
 .../linuxapp/eal/include/exec-env/rte_kni_common.h |  2 ++
 lib/librte_eal/linuxapp/kni/kni_net.c              | 17 ++++++++++++
 lib/librte_kni/rte_kni.c                           | 31 +++++++++++++++++++++-
 lib/librte_kni/rte_kni.h                           |  3 +++
 test/test/test_kni.c                               |  2 ++
 6 files changed, 66 insertions(+), 4 deletions(-)

diff --git a/doc/guides/sample_app_ug/kernel_nic_interface.rst b/doc/guides/sample_app_ug/kernel_nic_interface.rst
index 2c143da..4dd1f82 100644
--- a/doc/guides/sample_app_ug/kernel_nic_interface.rst
+++ b/doc/guides/sample_app_ug/kernel_nic_interface.rst
@@ -512,11 +512,11 @@ Callbacks for Kernel Requests
 
 To execute specific PMD operations in user space requested by some Linux* commands,
 callbacks must be implemented and filled in the struct rte_kni_ops structure.
-Currently, setting a new MTU, change in mac address and configuring the network interface(up/ down)
-are supported.
+Currently, setting a new MTU, change in mac address, configuring promiscusous mode
+and configuring the network interface(up/ down) are supported.
 Default implementation for following is available in rte_kni library. Application
 may choose to not implement follwoing callbacks:
-	``config_mac_address``
+	``config_mac_address`` and ``config_promiscusity``
 
 
 .. code-block:: c
@@ -525,6 +525,7 @@ may choose to not implement follwoing callbacks:
         .change_mtu = kni_change_mtu,
         .config_network_if = kni_config_network_interface,
         .config_mac_address = kni_config_mac_address,
+        .config_promiscusity = kni_config_promiscusity,
     };
 
     /* Callback for request of changing MTU */
@@ -611,3 +612,11 @@ may choose to not implement follwoing callbacks:
     {
         .....
     }
+
+    /* Callback for request of configuring promiscuous mode */
+
+    static int
+    kni_config_promiscusity(uint16_t port_id, uint8_t to_on)
+    {
+        .....
+    }
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 1a760de..b519db5 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
@@ -81,6 +81,7 @@ enum rte_kni_req_id {
 	RTE_KNI_REQ_CHANGE_MTU,
 	RTE_KNI_REQ_CFG_NETWORK_IF,
 	RTE_KNI_REQ_CHANGE_MAC_ADDR,
+	RTE_KNI_REQ_CHANGE_PROMISC,
 	RTE_KNI_REQ_MAX,
 };
 
@@ -94,6 +95,7 @@ struct rte_kni_request {
 		uint32_t new_mtu;    /**< New MTU */
 		uint8_t if_up;       /**< 1: interface up, 0: interface down */
 		uint8_t mac_addr[6]; /**< MAC address for interface */
+		uint8_t promiscusity;/**< 1: promisc mode enable, 0: disable */
 	};
 	int32_t result;               /**< Result for processing request */
 } __attribute__((__packed__));
diff --git a/lib/librte_eal/linuxapp/kni/kni_net.c b/lib/librte_eal/linuxapp/kni/kni_net.c
index 3e02ea1..e261c58 100644
--- a/lib/librte_eal/linuxapp/kni/kni_net.c
+++ b/lib/librte_eal/linuxapp/kni/kni_net.c
@@ -603,6 +603,22 @@ kni_net_change_mtu(struct net_device *dev, int new_mtu)
 	return (ret == 0) ? req.result : ret;
 }
 
+static void
+kni_net_set_promiscusity(struct net_device *netdev, int flags)
+{
+	struct rte_kni_request req;
+	struct kni_dev *kni = netdev_priv(netdev);
+
+	memset(&req, 0, sizeof(req));
+	req.req_id = RTE_KNI_REQ_CHANGE_PROMISC;
+
+	if (netdev->flags & IFF_PROMISC)
+		req.promiscusity = 1;
+	else
+		req.promiscusity = 0;
+	kni_net_process_request(kni, &req);
+}
+
 /*
  * Checks if the user space application provided the resp message
  */
@@ -712,6 +728,7 @@ static const struct net_device_ops kni_net_netdev_ops = {
 	.ndo_open = kni_net_open,
 	.ndo_stop = kni_net_release,
 	.ndo_set_config = kni_net_config,
+	.ndo_change_rx_flags = kni_net_set_promiscusity,
 	.ndo_start_xmit = kni_net_tx,
 	.ndo_change_mtu = kni_net_change_mtu,
 	.ndo_do_ioctl = kni_net_ioctl,
diff --git a/lib/librte_kni/rte_kni.c b/lib/librte_kni/rte_kni.c
index a5ee210..bed3f20 100644
--- a/lib/librte_kni/rte_kni.c
+++ b/lib/librte_kni/rte_kni.c
@@ -554,6 +554,26 @@ kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
 	return ret;
 }
 
+/* default callback for request of configuring promiscuous mode */
+static int
+kni_config_promiscusity(uint16_t port_id, uint8_t to_on)
+{
+	if (port_id >= rte_eth_dev_count() || port_id >= RTE_MAX_ETHPORTS) {
+		RTE_LOG(ERR, KNI, "Invalid port id %d\n", port_id);
+		return -EINVAL;
+	}
+
+	RTE_LOG(INFO, KNI, "Configure promiscuous mode of %d to %d\n",
+		port_id, to_on);
+
+	if (to_on)
+		rte_eth_promiscuous_enable(port_id);
+	else
+		rte_eth_promiscuous_disable(port_id);
+
+	return 0;
+}
+
 int
 rte_kni_handle_request(struct rte_kni *kni)
 {
@@ -593,6 +613,14 @@ rte_kni_handle_request(struct rte_kni *kni)
 			req->result = kni_config_mac_address(
 					kni->ops.port_id, req->mac_addr);
 		break;
+	case RTE_KNI_REQ_CHANGE_PROMISC: /* Change PROMISCUOUS MODE */
+		if (kni->ops.config_promiscusity)
+			req->result = kni->ops.config_promiscusity(
+					kni->ops.port_id, req->promiscusity);
+		else if (kni->ops.port_id != UNIT16_MAX)
+			req->result = kni_config_promiscusity(
+					kni->ops.port_id, req->promiscusity);
+		break;
 	default:
 		RTE_LOG(ERR, KNI, "Unknown request id %u\n", req->req_id);
 		req->result = -EINVAL;
@@ -743,7 +771,8 @@ kni_check_request_register(struct rte_kni_ops *ops)
 
 	if ((NULL == ops->change_mtu)
 		&& (NULL == ops->config_network_if)
-		&& (NULL == ops->config_mac_address))
+		&& (NULL == ops->config_mac_address)
+		&& (NULL == ops->config_promiscusity))
 		return KNI_REQ_NO_REGISTER;
 
 	return KNI_REQ_REGISTERED;
diff --git a/lib/librte_kni/rte_kni.h b/lib/librte_kni/rte_kni.h
index 9bdc9f3..4530bdd 100644
--- a/lib/librte_kni/rte_kni.h
+++ b/lib/librte_kni/rte_kni.h
@@ -74,6 +74,9 @@ struct rte_kni_ops {
 
 	/* Pointer to function of configuring mac address */
 	int (*config_mac_address)(uint16_t port_id, uint8_t mac_addr[]);
+
+	/* Pointer to function of configuring promiscuous mode */
+	int (*config_promiscusity)(uint16_t port_id, uint8_t to_on);
 };
 
 /**
diff --git a/test/test/test_kni.c b/test/test/test_kni.c
index 06448c9..56a7f3b 100644
--- a/test/test/test_kni.c
+++ b/test/test/test_kni.c
@@ -104,6 +104,7 @@ static struct rte_kni_ops kni_ops = {
 	.change_mtu = NULL,
 	.config_network_if = NULL,
 	.config_mac_address = NULL,
+	.config_promiscusity = NULL,
 };
 
 static unsigned lcore_master, lcore_ingress, lcore_egress;
@@ -262,6 +263,7 @@ test_kni_register_handler_mp(void)
 			.change_mtu = kni_change_mtu,
 			.config_network_if = NULL,
 			.config_mac_address = NULL,
+			.config_promiscusity = NULL,
 		};
 
 		if (!kni) {
-- 
2.7.4

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v2 3/3] kni: set initial value for MTU
  2017-12-26 10:36 ` [dpdk-dev] [PATCH v2 " Hemant Agrawal
  2017-12-26 10:36   ` [dpdk-dev] [PATCH v2 2/3] kni: add support for promisc mode set Hemant Agrawal
@ 2017-12-26 10:36   ` Hemant Agrawal
  2018-01-18  6:12   ` [dpdk-dev] [PATCH v3 1/3] kni: support for MAC addr change Hemant Agrawal
  2 siblings, 0 replies; 17+ messages in thread
From: Hemant Agrawal @ 2017-12-26 10:36 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

Configure initial application provided  mtu on the KNI interface.

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
v2: fix ABI breakage

 examples/kni/main.c                                           | 2 ++
 lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h | 1 +
 lib/librte_eal/linuxapp/kni/kni_misc.c                        | 3 +++
 lib/librte_kni/rte_kni.c                                      | 1 +
 lib/librte_kni/rte_kni.h                                      | 1 +
 5 files changed, 8 insertions(+)

diff --git a/examples/kni/main.c b/examples/kni/main.c
index 1c251c2..d9c9fa5 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -845,6 +845,8 @@ kni_alloc(uint16_t port_id)
 			rte_eth_macaddr_get(port_id,
 					(struct ether_addr *)&conf.mac_addr);
 
+			rte_eth_dev_get_mtu(port_id, &conf.mtu);
+
 			memset(&ops, 0, sizeof(ops));
 			ops.port_id = port_id;
 			ops.change_mtu = kni_change_mtu;
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 b519db5..2e393c0 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
@@ -172,6 +172,7 @@ struct rte_kni_device_info {
 
 	/* mbuf size */
 	unsigned mbuf_size;
+	unsigned int mtu;
 	char mac_addr[6];
 };
 
diff --git a/lib/librte_eal/linuxapp/kni/kni_misc.c b/lib/librte_eal/linuxapp/kni/kni_misc.c
index b524d30..0ccd227 100644
--- a/lib/librte_eal/linuxapp/kni/kni_misc.c
+++ b/lib/librte_eal/linuxapp/kni/kni_misc.c
@@ -470,6 +470,9 @@ kni_ioctl_create(struct net *net, uint32_t ioctl_num,
 			random_ether_addr(net_dev->dev_addr);
 	}
 
+	if (dev_info.mtu)
+		net_dev->mtu = dev_info.mtu;
+
 	ret = register_netdev(net_dev);
 	if (ret) {
 		pr_err("error %i registering device \"%s\"\n",
diff --git a/lib/librte_kni/rte_kni.c b/lib/librte_kni/rte_kni.c
index bed3f20..2461b47 100644
--- a/lib/librte_kni/rte_kni.c
+++ b/lib/librte_kni/rte_kni.c
@@ -369,6 +369,7 @@ rte_kni_alloc(struct rte_mempool *pktmbuf_pool,
 	dev_info.force_bind = conf->force_bind;
 	dev_info.group_id = conf->group_id;
 	dev_info.mbuf_size = conf->mbuf_size;
+	dev_info.mtu = conf->mtu;
 
 	memcpy(dev_info.mac_addr, conf->mac_addr, ETHER_ADDR_LEN);
 
diff --git a/lib/librte_kni/rte_kni.h b/lib/librte_kni/rte_kni.h
index 4530bdd..cbf3188 100644
--- a/lib/librte_kni/rte_kni.h
+++ b/lib/librte_kni/rte_kni.h
@@ -98,6 +98,7 @@ struct rte_kni_conf {
 	__extension__
 	uint8_t force_bind : 1; /* Flag to bind kernel thread */
 	char mac_addr[ETHER_ADDR_LEN]; /* MAC address assigned to KNI */
+	uint16_t mtu;
 };
 
 /**
-- 
2.7.4

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v3 1/3] kni: support for MAC addr change
  2017-12-26 10:36 ` [dpdk-dev] [PATCH v2 " Hemant Agrawal
  2017-12-26 10:36   ` [dpdk-dev] [PATCH v2 2/3] kni: add support for promisc mode set Hemant Agrawal
  2017-12-26 10:36   ` [dpdk-dev] [PATCH v2 3/3] kni: set initial value for MTU Hemant Agrawal
@ 2018-01-18  6:12   ` Hemant Agrawal
  2018-01-18  6:12     ` [dpdk-dev] [PATCH v3 2/3] kni: add support for promisc mode set Hemant Agrawal
                       ` (2 more replies)
  2 siblings, 3 replies; 17+ messages in thread
From: Hemant Agrawal @ 2018-01-18  6:12 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds following:
1. Option to configure the mac address during create. Generate random
   address only if the user has not provided any valid address.
2. Inform usespace, if mac address is being changed in linux.
3. Implement default handling of mac address change in the corresponding
   ethernet device.

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
v3: fix compilation err and checkpatch warnings

 doc/guides/sample_app_ug/kernel_nic_interface.rst  | 26 +++++++++++++-
 examples/kni/main.c                                | 36 +++++++++++++++++++
 .../linuxapp/eal/include/exec-env/rte_kni_common.h |  3 ++
 lib/librte_eal/linuxapp/kni/kni_misc.c             | 17 +++++----
 lib/librte_eal/linuxapp/kni/kni_net.c              | 14 +++++++-
 lib/librte_kni/rte_kni.c                           | 42 ++++++++++++++++++++--
 lib/librte_kni/rte_kni.h                           |  5 +++
 test/test/test_kni.c                               |  2 ++
 8 files changed, 134 insertions(+), 11 deletions(-)

diff --git a/doc/guides/sample_app_ug/kernel_nic_interface.rst b/doc/guides/sample_app_ug/kernel_nic_interface.rst
index 67f2140..d7989bf 100644
--- a/doc/guides/sample_app_ug/kernel_nic_interface.rst
+++ b/doc/guides/sample_app_ug/kernel_nic_interface.rst
@@ -209,6 +209,12 @@ Dumping the network traffic:
 
     #tcpdump -i vEth0_0
 
+Change the MAC address:
+
+.. code-block:: console
+
+    #ifconfig vEth0_0 hw ether 0C:01:02:03:04:08
+
 When the DPDK userspace application is closed, all the KNI devices are deleted from Linux*.
 
 Explanation
@@ -269,11 +275,15 @@ The code for allocating the kernel NIC interfaces for a specific port is as foll
                     conf.addr = dev_info.pci_dev->addr;
                     conf.id = dev_info.pci_dev->id;
 
+                    /* Get the interface default mac address */
+                    rte_eth_macaddr_get(port_id, (struct ether_addr *)&conf.mac_addr);
+
                     memset(&ops, 0, sizeof(ops));
 
                     ops.port_id = port_id;
                     ops.change_mtu = kni_change_mtu;
                     ops.config_network_if = kni_config_network_interface;
+                    ops.config_mac_address = kni_config_mac_address;
 
                     kni = rte_kni_alloc(pktmbuf_pool, &conf, &ops);
                 } else
@@ -502,13 +512,19 @@ Callbacks for Kernel Requests
 
 To execute specific PMD operations in user space requested by some Linux* commands,
 callbacks must be implemented and filled in the struct rte_kni_ops structure.
-Currently, setting a new MTU and configuring the network interface (up/ down) are supported.
+Currently, setting a new MTU, change in mac address and configuring the network interface(up/ down)
+are supported.
+Default implementation for following is available in rte_kni library. Application
+may choose to not implement follwoing callbacks:
+	``config_mac_address``
+
 
 .. code-block:: c
 
     static struct rte_kni_ops kni_ops = {
         .change_mtu = kni_change_mtu,
         .config_network_if = kni_config_network_interface,
+        .config_mac_address = kni_config_mac_address,
     };
 
     /* Callback for request of changing MTU */
@@ -587,3 +603,11 @@ Currently, setting a new MTU and configuring the network interface (up/ down) ar
             RTE_LOG(ERR, APP, "Failed to start port %d\n", port_id);
         return ret;
     }
+
+    /* Callback for request of configuring device mac address */
+
+    static int
+    kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
+    {
+        .....
+    }
diff --git a/examples/kni/main.c b/examples/kni/main.c
index 5700740..ebec433 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -131,6 +131,7 @@ static struct kni_interface_stats kni_stats[RTE_MAX_ETHPORTS];
 
 static int kni_change_mtu(uint16_t port_id, unsigned int new_mtu);
 static int kni_config_network_interface(uint16_t port_id, uint8_t if_up);
+static int kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[]);
 
 static rte_atomic32_t kni_stop = RTE_ATOMIC32_INIT(0);
 
@@ -767,6 +768,37 @@ kni_config_network_interface(uint16_t port_id, uint8_t if_up)
 	return ret;
 }
 
+static void
+print_ethaddr(const char *name, struct ether_addr *mac_addr)
+{
+	char buf[ETHER_ADDR_FMT_SIZE];
+	ether_format_addr(buf, ETHER_ADDR_FMT_SIZE, mac_addr);
+	RTE_LOG(INFO, APP, "\t%s%s\n", name, buf);
+}
+
+/* Callback for request of configuring mac address */
+static int
+kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
+{
+	int ret = 0;
+
+	if (port_id >= rte_eth_dev_count() || port_id >= RTE_MAX_ETHPORTS) {
+		RTE_LOG(ERR, APP, "Invalid port id %d\n", port_id);
+		return -EINVAL;
+	}
+
+	RTE_LOG(INFO, APP, "Configure mac address of %d\n", port_id);
+	print_ethaddr("Address:", (struct ether_addr *)mac_addr);
+
+	ret = rte_eth_dev_default_mac_addr_set(port_id,
+					       (struct ether_addr *)mac_addr);
+	if (ret < 0)
+		RTE_LOG(ERR, APP, "Failed to config mac_addr for port %d\n",
+			port_id);
+
+	return ret;
+}
+
 static int
 kni_alloc(uint16_t port_id)
 {
@@ -810,11 +842,15 @@ kni_alloc(uint16_t port_id)
 				conf.addr = dev_info.pci_dev->addr;
 				conf.id = dev_info.pci_dev->id;
 			}
+			/* Get the interface default mac address */
+			rte_eth_macaddr_get(port_id,
+					(struct ether_addr *)&conf.mac_addr);
 
 			memset(&ops, 0, sizeof(ops));
 			ops.port_id = port_id;
 			ops.change_mtu = kni_change_mtu;
 			ops.config_network_if = kni_config_network_interface;
+			ops.config_mac_address = kni_config_mac_address;
 
 			kni = rte_kni_alloc(pktmbuf_pool, &conf, &ops);
 		} else
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 61ace6f..62b4a05 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
@@ -28,6 +28,7 @@ enum rte_kni_req_id {
 	RTE_KNI_REQ_UNKNOWN = 0,
 	RTE_KNI_REQ_CHANGE_MTU,
 	RTE_KNI_REQ_CFG_NETWORK_IF,
+	RTE_KNI_REQ_CHANGE_MAC_ADDR,
 	RTE_KNI_REQ_MAX,
 };
 
@@ -40,6 +41,7 @@ struct rte_kni_request {
 	union {
 		uint32_t new_mtu;    /**< New MTU */
 		uint8_t if_up;       /**< 1: interface up, 0: interface down */
+		uint8_t mac_addr[6]; /**< MAC address for interface */
 	};
 	int32_t result;               /**< Result for processing request */
 } __attribute__((__packed__));
@@ -116,6 +118,7 @@ struct rte_kni_device_info {
 
 	/* mbuf size */
 	unsigned mbuf_size;
+	char mac_addr[6];
 };
 
 #define KNI_DEVICE "kni"
diff --git a/lib/librte_eal/linuxapp/kni/kni_misc.c b/lib/librte_eal/linuxapp/kni/kni_misc.c
index def4f1e..83649ce 100644
--- a/lib/librte_eal/linuxapp/kni/kni_misc.c
+++ b/lib/librte_eal/linuxapp/kni/kni_misc.c
@@ -439,12 +439,17 @@ kni_ioctl_create(struct net *net, uint32_t ioctl_num,
 
 	if (kni->lad_dev)
 		ether_addr_copy(net_dev->dev_addr, kni->lad_dev->dev_addr);
-	else
-		/*
-		 * Generate random mac address. eth_random_addr() is the newer
-		 * version of generating mac address in linux kernel.
-		 */
-		random_ether_addr(net_dev->dev_addr);
+	else {
+		/* if user has provided a valid mac address */
+		if (is_valid_ether_addr((unsigned char *)(dev_info.mac_addr)))
+			memcpy(net_dev->dev_addr, dev_info.mac_addr, ETH_ALEN);
+		else
+			/*
+			 * Generate random mac address. eth_random_addr() is the
+			 * newer version of generating mac address in kernel.
+			 */
+			random_ether_addr(net_dev->dev_addr);
+	}
 
 	ret = register_netdev(net_dev);
 	if (ret) {
diff --git a/lib/librte_eal/linuxapp/kni/kni_net.c b/lib/librte_eal/linuxapp/kni/kni_net.c
index 07d6fdb..3e35008 100644
--- a/lib/librte_eal/linuxapp/kni/kni_net.c
+++ b/lib/librte_eal/linuxapp/kni/kni_net.c
@@ -649,12 +649,24 @@ kni_net_rebuild_header(struct sk_buff *skb)
 static int
 kni_net_set_mac(struct net_device *netdev, void *p)
 {
+	int ret;
+	struct rte_kni_request req;
+	struct kni_dev *kni;
 	struct sockaddr *addr = p;
 
+	memset(&req, 0, sizeof(req));
+	req.req_id = RTE_KNI_REQ_CHANGE_MAC_ADDR;
+
 	if (!is_valid_ether_addr((unsigned char *)(addr->sa_data)))
 		return -EADDRNOTAVAIL;
+
+	memcpy(req.mac_addr, addr->sa_data, netdev->addr_len);
 	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
-	return 0;
+
+	kni = netdev_priv(netdev);
+	ret = kni_net_process_request(kni, &req);
+
+	return (ret == 0 ? req.result : ret);
 }
 
 #ifdef HAVE_CHANGE_CARRIER_CB
diff --git a/lib/librte_kni/rte_kni.c b/lib/librte_kni/rte_kni.c
index f4fa994..a140dfc 100644
--- a/lib/librte_kni/rte_kni.c
+++ b/lib/librte_kni/rte_kni.c
@@ -327,6 +327,8 @@ rte_kni_alloc(struct rte_mempool *pktmbuf_pool,
 	memset(ctx, 0, sizeof(struct rte_kni));
 	if (ops)
 		memcpy(&ctx->ops, ops, sizeof(struct rte_kni_ops));
+	else
+		ctx->ops.port_id = UINT16_MAX;
 
 	memset(&dev_info, 0, sizeof(dev_info));
 	dev_info.bus = conf->addr.bus;
@@ -339,6 +341,8 @@ rte_kni_alloc(struct rte_mempool *pktmbuf_pool,
 	dev_info.group_id = conf->group_id;
 	dev_info.mbuf_size = conf->mbuf_size;
 
+	memcpy(dev_info.mac_addr, conf->mac_addr, ETHER_ADDR_LEN);
+
 	snprintf(ctx->name, RTE_KNI_NAMESIZE, "%s", intf_name);
 	snprintf(dev_info.name, RTE_KNI_NAMESIZE, "%s", intf_name);
 
@@ -499,6 +503,28 @@ rte_kni_release(struct rte_kni *kni)
 	return 0;
 }
 
+/* default callback for request of configuring device mac address */
+static int
+kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
+{
+	int ret = 0;
+
+	if (port_id >= rte_eth_dev_count() || port_id >= RTE_MAX_ETHPORTS) {
+		RTE_LOG(ERR, KNI, "Invalid port id %d\n", port_id);
+		return -EINVAL;
+	}
+
+	RTE_LOG(INFO, KNI, "Configure mac address of %d", port_id);
+
+	ret = rte_eth_dev_default_mac_addr_set(port_id,
+					       (struct ether_addr *)mac_addr);
+	if (ret < 0)
+		RTE_LOG(ERR, KNI, "Failed to config mac_addr for port %d\n",
+			port_id);
+
+	return ret;
+}
+
 int
 rte_kni_handle_request(struct rte_kni *kni)
 {
@@ -530,6 +556,14 @@ rte_kni_handle_request(struct rte_kni *kni)
 			req->result = kni->ops.config_network_if(\
 					kni->ops.port_id, req->if_up);
 		break;
+	case RTE_KNI_REQ_CHANGE_MAC_ADDR: /* Change MAC Address */
+		if (kni->ops.config_mac_address)
+			req->result = kni->ops.config_mac_address(
+					kni->ops.port_id, req->mac_addr);
+		else if (kni->ops.port_id != UINT16_MAX)
+			req->result = kni_config_mac_address(
+					kni->ops.port_id, req->mac_addr);
+		break;
 	default:
 		RTE_LOG(ERR, KNI, "Unknown request id %u\n", req->req_id);
 		req->result = -EINVAL;
@@ -678,7 +712,9 @@ kni_check_request_register(struct rte_kni_ops *ops)
 	if( NULL == ops )
 		return KNI_REQ_NO_REGISTER;
 
-	if((NULL == ops->change_mtu) && (NULL == ops->config_network_if))
+	if ((ops->change_mtu == NULL)
+		&& (ops->config_network_if == NULL)
+		&& (ops->config_mac_address == NULL))
 		return KNI_REQ_NO_REGISTER;
 
 	return KNI_REQ_REGISTERED;
@@ -717,8 +753,8 @@ rte_kni_unregister_handlers(struct rte_kni *kni)
 		return -1;
 	}
 
-	kni->ops.change_mtu = NULL;
-	kni->ops.config_network_if = NULL;
+	memset(&kni->ops, 0, sizeof(struct rte_kni_ops));
+
 	return 0;
 }
 void
diff --git a/lib/librte_kni/rte_kni.h b/lib/librte_kni/rte_kni.h
index c4dcfff..370b02a 100644
--- a/lib/librte_kni/rte_kni.h
+++ b/lib/librte_kni/rte_kni.h
@@ -20,6 +20,7 @@
 #include <rte_pci.h>
 #include <rte_memory.h>
 #include <rte_mempool.h>
+#include <rte_ether.h>
 
 #include <exec-env/rte_kni_common.h>
 
@@ -41,6 +42,9 @@ struct rte_kni_ops {
 
 	/* Pointer to function of configuring network interface */
 	int (*config_network_if)(uint16_t port_id, uint8_t if_up);
+
+	/* Pointer to function of configuring mac address */
+	int (*config_mac_address)(uint16_t port_id, uint8_t mac_addr[]);
 };
 
 /**
@@ -61,6 +65,7 @@ struct rte_kni_conf {
 
 	__extension__
 	uint8_t force_bind : 1; /* Flag to bind kernel thread */
+	char mac_addr[ETHER_ADDR_LEN]; /* MAC address assigned to KNI */
 };
 
 /**
diff --git a/test/test/test_kni.c b/test/test/test_kni.c
index 539d231..4513de1 100644
--- a/test/test/test_kni.c
+++ b/test/test/test_kni.c
@@ -74,6 +74,7 @@ static const struct rte_eth_conf port_conf = {
 static struct rte_kni_ops kni_ops = {
 	.change_mtu = NULL,
 	.config_network_if = NULL,
+	.config_mac_address = NULL,
 };
 
 static unsigned lcore_master, lcore_ingress, lcore_egress;
@@ -231,6 +232,7 @@ test_kni_register_handler_mp(void)
 		struct rte_kni_ops ops = {
 			.change_mtu = kni_change_mtu,
 			.config_network_if = NULL,
+			.config_mac_address = NULL,
 		};
 
 		if (!kni) {
-- 
2.7.4

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v3 2/3] kni: add support for promisc mode set
  2018-01-18  6:12   ` [dpdk-dev] [PATCH v3 1/3] kni: support for MAC addr change Hemant Agrawal
@ 2018-01-18  6:12     ` Hemant Agrawal
  2018-01-18  6:13     ` [dpdk-dev] [PATCH v3 3/3] kni: set initial value for MTU Hemant Agrawal
  2018-01-21 22:07     ` [dpdk-dev] [PATCH v3 1/3] kni: support for MAC addr change Ferruh Yigit
  2 siblings, 0 replies; 17+ messages in thread
From: Hemant Agrawal @ 2018-01-18  6:12 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

Inform userspace app about promisc mode change

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
v3: fix checkpatch warning and compilation err

 doc/guides/sample_app_ug/kernel_nic_interface.rst  | 15 ++++++++---
 .../linuxapp/eal/include/exec-env/rte_kni_common.h |  2 ++
 lib/librte_eal/linuxapp/kni/kni_net.c              | 17 ++++++++++++
 lib/librte_kni/rte_kni.c                           | 31 +++++++++++++++++++++-
 lib/librte_kni/rte_kni.h                           |  3 +++
 test/test/test_kni.c                               |  2 ++
 6 files changed, 66 insertions(+), 4 deletions(-)

diff --git a/doc/guides/sample_app_ug/kernel_nic_interface.rst b/doc/guides/sample_app_ug/kernel_nic_interface.rst
index d7989bf..fdd061e 100644
--- a/doc/guides/sample_app_ug/kernel_nic_interface.rst
+++ b/doc/guides/sample_app_ug/kernel_nic_interface.rst
@@ -512,11 +512,11 @@ Callbacks for Kernel Requests
 
 To execute specific PMD operations in user space requested by some Linux* commands,
 callbacks must be implemented and filled in the struct rte_kni_ops structure.
-Currently, setting a new MTU, change in mac address and configuring the network interface(up/ down)
-are supported.
+Currently, setting a new MTU, change in mac address, configuring promiscusous mode
+and configuring the network interface(up/ down) are supported.
 Default implementation for following is available in rte_kni library. Application
 may choose to not implement follwoing callbacks:
-	``config_mac_address``
+	``config_mac_address`` and ``config_promiscusity``
 
 
 .. code-block:: c
@@ -525,6 +525,7 @@ may choose to not implement follwoing callbacks:
         .change_mtu = kni_change_mtu,
         .config_network_if = kni_config_network_interface,
         .config_mac_address = kni_config_mac_address,
+        .config_promiscusity = kni_config_promiscusity,
     };
 
     /* Callback for request of changing MTU */
@@ -611,3 +612,11 @@ may choose to not implement follwoing callbacks:
     {
         .....
     }
+
+    /* Callback for request of configuring promiscuous mode */
+
+    static int
+    kni_config_promiscusity(uint16_t port_id, uint8_t to_on)
+    {
+        .....
+    }
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 62b4a05..b186417 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
@@ -29,6 +29,7 @@ enum rte_kni_req_id {
 	RTE_KNI_REQ_CHANGE_MTU,
 	RTE_KNI_REQ_CFG_NETWORK_IF,
 	RTE_KNI_REQ_CHANGE_MAC_ADDR,
+	RTE_KNI_REQ_CHANGE_PROMISC,
 	RTE_KNI_REQ_MAX,
 };
 
@@ -42,6 +43,7 @@ struct rte_kni_request {
 		uint32_t new_mtu;    /**< New MTU */
 		uint8_t if_up;       /**< 1: interface up, 0: interface down */
 		uint8_t mac_addr[6]; /**< MAC address for interface */
+		uint8_t promiscusity;/**< 1: promisc mode enable, 0: disable */
 	};
 	int32_t result;               /**< Result for processing request */
 } __attribute__((__packed__));
diff --git a/lib/librte_eal/linuxapp/kni/kni_net.c b/lib/librte_eal/linuxapp/kni/kni_net.c
index 3e35008..9f9b798 100644
--- a/lib/librte_eal/linuxapp/kni/kni_net.c
+++ b/lib/librte_eal/linuxapp/kni/kni_net.c
@@ -584,6 +584,22 @@ kni_net_change_mtu(struct net_device *dev, int new_mtu)
 	return (ret == 0) ? req.result : ret;
 }
 
+static void
+kni_net_set_promiscusity(struct net_device *netdev, int flags)
+{
+	struct rte_kni_request req;
+	struct kni_dev *kni = netdev_priv(netdev);
+
+	memset(&req, 0, sizeof(req));
+	req.req_id = RTE_KNI_REQ_CHANGE_PROMISC;
+
+	if (netdev->flags & IFF_PROMISC)
+		req.promiscusity = 1;
+	else
+		req.promiscusity = 0;
+	kni_net_process_request(kni, &req);
+}
+
 /*
  * Checks if the user space application provided the resp message
  */
@@ -693,6 +709,7 @@ static const struct net_device_ops kni_net_netdev_ops = {
 	.ndo_open = kni_net_open,
 	.ndo_stop = kni_net_release,
 	.ndo_set_config = kni_net_config,
+	.ndo_change_rx_flags = kni_net_set_promiscusity,
 	.ndo_start_xmit = kni_net_tx,
 	.ndo_change_mtu = kni_net_change_mtu,
 	.ndo_do_ioctl = kni_net_ioctl,
diff --git a/lib/librte_kni/rte_kni.c b/lib/librte_kni/rte_kni.c
index a140dfc..c089a49 100644
--- a/lib/librte_kni/rte_kni.c
+++ b/lib/librte_kni/rte_kni.c
@@ -525,6 +525,26 @@ kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
 	return ret;
 }
 
+/* default callback for request of configuring promiscuous mode */
+static int
+kni_config_promiscusity(uint16_t port_id, uint8_t to_on)
+{
+	if (port_id >= rte_eth_dev_count() || port_id >= RTE_MAX_ETHPORTS) {
+		RTE_LOG(ERR, KNI, "Invalid port id %d\n", port_id);
+		return -EINVAL;
+	}
+
+	RTE_LOG(INFO, KNI, "Configure promiscuous mode of %d to %d\n",
+		port_id, to_on);
+
+	if (to_on)
+		rte_eth_promiscuous_enable(port_id);
+	else
+		rte_eth_promiscuous_disable(port_id);
+
+	return 0;
+}
+
 int
 rte_kni_handle_request(struct rte_kni *kni)
 {
@@ -564,6 +584,14 @@ rte_kni_handle_request(struct rte_kni *kni)
 			req->result = kni_config_mac_address(
 					kni->ops.port_id, req->mac_addr);
 		break;
+	case RTE_KNI_REQ_CHANGE_PROMISC: /* Change PROMISCUOUS MODE */
+		if (kni->ops.config_promiscusity)
+			req->result = kni->ops.config_promiscusity(
+					kni->ops.port_id, req->promiscusity);
+		else if (kni->ops.port_id != UINT16_MAX)
+			req->result = kni_config_promiscusity(
+					kni->ops.port_id, req->promiscusity);
+		break;
 	default:
 		RTE_LOG(ERR, KNI, "Unknown request id %u\n", req->req_id);
 		req->result = -EINVAL;
@@ -714,7 +742,8 @@ kni_check_request_register(struct rte_kni_ops *ops)
 
 	if ((ops->change_mtu == NULL)
 		&& (ops->config_network_if == NULL)
-		&& (ops->config_mac_address == NULL))
+		&& (ops->config_mac_address == NULL)
+		&& (ops->config_promiscusity == NULL))
 		return KNI_REQ_NO_REGISTER;
 
 	return KNI_REQ_REGISTERED;
diff --git a/lib/librte_kni/rte_kni.h b/lib/librte_kni/rte_kni.h
index 370b02a..711c2a9 100644
--- a/lib/librte_kni/rte_kni.h
+++ b/lib/librte_kni/rte_kni.h
@@ -45,6 +45,9 @@ struct rte_kni_ops {
 
 	/* Pointer to function of configuring mac address */
 	int (*config_mac_address)(uint16_t port_id, uint8_t mac_addr[]);
+
+	/* Pointer to function of configuring promiscuous mode */
+	int (*config_promiscusity)(uint16_t port_id, uint8_t to_on);
 };
 
 /**
diff --git a/test/test/test_kni.c b/test/test/test_kni.c
index 4513de1..9917e8a 100644
--- a/test/test/test_kni.c
+++ b/test/test/test_kni.c
@@ -75,6 +75,7 @@ static struct rte_kni_ops kni_ops = {
 	.change_mtu = NULL,
 	.config_network_if = NULL,
 	.config_mac_address = NULL,
+	.config_promiscusity = NULL,
 };
 
 static unsigned lcore_master, lcore_ingress, lcore_egress;
@@ -233,6 +234,7 @@ test_kni_register_handler_mp(void)
 			.change_mtu = kni_change_mtu,
 			.config_network_if = NULL,
 			.config_mac_address = NULL,
+			.config_promiscusity = NULL,
 		};
 
 		if (!kni) {
-- 
2.7.4

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v3 3/3] kni: set initial value for MTU
  2018-01-18  6:12   ` [dpdk-dev] [PATCH v3 1/3] kni: support for MAC addr change Hemant Agrawal
  2018-01-18  6:12     ` [dpdk-dev] [PATCH v3 2/3] kni: add support for promisc mode set Hemant Agrawal
@ 2018-01-18  6:13     ` Hemant Agrawal
  2018-01-21 22:07     ` [dpdk-dev] [PATCH v3 1/3] kni: support for MAC addr change Ferruh Yigit
  2 siblings, 0 replies; 17+ messages in thread
From: Hemant Agrawal @ 2018-01-18  6:13 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

Configure initial application provided  mtu on the KNI interface.

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
 examples/kni/main.c                                           | 2 ++
 lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h | 1 +
 lib/librte_eal/linuxapp/kni/kni_misc.c                        | 3 +++
 lib/librte_kni/rte_kni.c                                      | 1 +
 lib/librte_kni/rte_kni.h                                      | 1 +
 5 files changed, 8 insertions(+)

diff --git a/examples/kni/main.c b/examples/kni/main.c
index ebec433..e5cc30e 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -846,6 +846,8 @@ kni_alloc(uint16_t port_id)
 			rte_eth_macaddr_get(port_id,
 					(struct ether_addr *)&conf.mac_addr);
 
+			rte_eth_dev_get_mtu(port_id, &conf.mtu);
+
 			memset(&ops, 0, sizeof(ops));
 			ops.port_id = port_id;
 			ops.change_mtu = kni_change_mtu;
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 b186417..cfa9448 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
@@ -120,6 +120,7 @@ struct rte_kni_device_info {
 
 	/* mbuf size */
 	unsigned mbuf_size;
+	unsigned int mtu;
 	char mac_addr[6];
 };
 
diff --git a/lib/librte_eal/linuxapp/kni/kni_misc.c b/lib/librte_eal/linuxapp/kni/kni_misc.c
index 83649ce..01574ec 100644
--- a/lib/librte_eal/linuxapp/kni/kni_misc.c
+++ b/lib/librte_eal/linuxapp/kni/kni_misc.c
@@ -451,6 +451,9 @@ kni_ioctl_create(struct net *net, uint32_t ioctl_num,
 			random_ether_addr(net_dev->dev_addr);
 	}
 
+	if (dev_info.mtu)
+		net_dev->mtu = dev_info.mtu;
+
 	ret = register_netdev(net_dev);
 	if (ret) {
 		pr_err("error %i registering device \"%s\"\n",
diff --git a/lib/librte_kni/rte_kni.c b/lib/librte_kni/rte_kni.c
index c089a49..2867411 100644
--- a/lib/librte_kni/rte_kni.c
+++ b/lib/librte_kni/rte_kni.c
@@ -340,6 +340,7 @@ rte_kni_alloc(struct rte_mempool *pktmbuf_pool,
 	dev_info.force_bind = conf->force_bind;
 	dev_info.group_id = conf->group_id;
 	dev_info.mbuf_size = conf->mbuf_size;
+	dev_info.mtu = conf->mtu;
 
 	memcpy(dev_info.mac_addr, conf->mac_addr, ETHER_ADDR_LEN);
 
diff --git a/lib/librte_kni/rte_kni.h b/lib/librte_kni/rte_kni.h
index 711c2a9..99055e2 100644
--- a/lib/librte_kni/rte_kni.h
+++ b/lib/librte_kni/rte_kni.h
@@ -69,6 +69,7 @@ struct rte_kni_conf {
 	__extension__
 	uint8_t force_bind : 1; /* Flag to bind kernel thread */
 	char mac_addr[ETHER_ADDR_LEN]; /* MAC address assigned to KNI */
+	uint16_t mtu;
 };
 
 /**
-- 
2.7.4

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [dpdk-dev] [PATCH v3 1/3] kni: support for MAC addr change
  2018-01-18  6:12   ` [dpdk-dev] [PATCH v3 1/3] kni: support for MAC addr change Hemant Agrawal
  2018-01-18  6:12     ` [dpdk-dev] [PATCH v3 2/3] kni: add support for promisc mode set Hemant Agrawal
  2018-01-18  6:13     ` [dpdk-dev] [PATCH v3 3/3] kni: set initial value for MTU Hemant Agrawal
@ 2018-01-21 22:07     ` Ferruh Yigit
  2018-01-22  5:20       ` Hemant Agrawal
  2 siblings, 1 reply; 17+ messages in thread
From: Ferruh Yigit @ 2018-01-21 22:07 UTC (permalink / raw)
  To: Hemant Agrawal, dev

On 1/18/2018 6:12 AM, Hemant Agrawal wrote:
> This patch adds following:
> 1. Option to configure the mac address during create. Generate random
>    address only if the user has not provided any valid address.
> 2. Inform usespace, if mac address is being changed in linux.
> 3. Implement default handling of mac address change in the corresponding
>    ethernet device.
> 
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>

<...>

> @@ -530,6 +556,14 @@ rte_kni_handle_request(struct rte_kni *kni)
>  			req->result = kni->ops.config_network_if(\
>  					kni->ops.port_id, req->if_up);
>  		break;
> +	case RTE_KNI_REQ_CHANGE_MAC_ADDR: /* Change MAC Address */
> +		if (kni->ops.config_mac_address)
> +			req->result = kni->ops.config_mac_address(
> +					kni->ops.port_id, req->mac_addr);
> +		else if (kni->ops.port_id != UINT16_MAX)

This won't be enough. rte_kni_alloc() can be called with NULL ops value. For
that case m_ctx->ops won't be updated. And by default ops will have all zeros,
not sure how to differentiate it from real port_id zero.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [dpdk-dev] [PATCH v3 1/3] kni: support for MAC addr change
  2018-01-21 22:07     ` [dpdk-dev] [PATCH v3 1/3] kni: support for MAC addr change Ferruh Yigit
@ 2018-01-22  5:20       ` Hemant Agrawal
  2018-01-22 15:48         ` Ferruh Yigit
  0 siblings, 1 reply; 17+ messages in thread
From: Hemant Agrawal @ 2018-01-22  5:20 UTC (permalink / raw)
  To: Ferruh Yigit, dev

Hi Ferruh,

On 1/22/2018 3:37 AM, Ferruh Yigit wrote:
> On 1/18/2018 6:12 AM, Hemant Agrawal wrote:
>> This patch adds following:
>> 1. Option to configure the mac address during create. Generate random
>>    address only if the user has not provided any valid address.
>> 2. Inform usespace, if mac address is being changed in linux.
>> 3. Implement default handling of mac address change in the corresponding
>>    ethernet device.
>>
>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>
> <...>
>
>> @@ -530,6 +556,14 @@ rte_kni_handle_request(struct rte_kni *kni)
>>  			req->result = kni->ops.config_network_if(\
>>  					kni->ops.port_id, req->if_up);
>>  		break;
>> +	case RTE_KNI_REQ_CHANGE_MAC_ADDR: /* Change MAC Address */
>> +		if (kni->ops.config_mac_address)
>> +			req->result = kni->ops.config_mac_address(
>> +					kni->ops.port_id, req->mac_addr);
>> +		else if (kni->ops.port_id != UINT16_MAX)
>
> This won't be enough. rte_kni_alloc() can be called with NULL ops value. For
> that case m_ctx->ops won't be updated. And by default ops will have all zeros,
> not sure how to differentiate it from real port_id zero.
>

I think, I tried to address that in the first patch.

rte_kni_alloc(struct rte_mempool *pktmbuf_pool,
  	memset(ctx, 0, sizeof(struct rte_kni));
  	if (ops)
  		memcpy(&ctx->ops, ops, sizeof(struct rte_kni_ops));
+	else
+		ctx->ops.port_id = UINT16_MAX;

Do you still see issue?

Regards,
Hemant

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [dpdk-dev] [PATCH v3 1/3] kni: support for MAC addr change
  2018-01-22  5:20       ` Hemant Agrawal
@ 2018-01-22 15:48         ` Ferruh Yigit
  2018-02-01  0:04           ` Thomas Monjalon
  0 siblings, 1 reply; 17+ messages in thread
From: Ferruh Yigit @ 2018-01-22 15:48 UTC (permalink / raw)
  To: Hemant Agrawal, dev

On 1/22/2018 5:20 AM, Hemant Agrawal wrote:
> Hi Ferruh,
> 
> On 1/22/2018 3:37 AM, Ferruh Yigit wrote:
>> On 1/18/2018 6:12 AM, Hemant Agrawal wrote:
>>> This patch adds following:
>>> 1. Option to configure the mac address during create. Generate random
>>>    address only if the user has not provided any valid address.
>>> 2. Inform usespace, if mac address is being changed in linux.
>>> 3. Implement default handling of mac address change in the corresponding
>>>    ethernet device.
>>>
>>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>>
>> <...>
>>
>>> @@ -530,6 +556,14 @@ rte_kni_handle_request(struct rte_kni *kni)
>>>  			req->result = kni->ops.config_network_if(\
>>>  					kni->ops.port_id, req->if_up);
>>>  		break;
>>> +	case RTE_KNI_REQ_CHANGE_MAC_ADDR: /* Change MAC Address */
>>> +		if (kni->ops.config_mac_address)
>>> +			req->result = kni->ops.config_mac_address(
>>> +					kni->ops.port_id, req->mac_addr);
>>> +		else if (kni->ops.port_id != UINT16_MAX)
>>
>> This won't be enough. rte_kni_alloc() can be called with NULL ops value. For
>> that case m_ctx->ops won't be updated. And by default ops will have all zeros,
>> not sure how to differentiate it from real port_id zero.
>>
> 
> I think, I tried to address that in the first patch.
> 
> rte_kni_alloc(struct rte_mempool *pktmbuf_pool,
>   	memset(ctx, 0, sizeof(struct rte_kni));
>   	if (ops)
>   		memcpy(&ctx->ops, ops, sizeof(struct rte_kni_ops));
> +	else
> +		ctx->ops.port_id = UINT16_MAX;
> 
> Do you still see issue?

You are right, this fixes it, I missed this part. So patch lgtm:

Series,
Acked-by: Ferruh Yigit <ferruh.yigit@intel.com>

> 
> Regards,
> Hemant
> 

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [dpdk-dev] [PATCH v3 1/3] kni: support for MAC addr change
  2018-01-22 15:48         ` Ferruh Yigit
@ 2018-02-01  0:04           ` Thomas Monjalon
  0 siblings, 0 replies; 17+ messages in thread
From: Thomas Monjalon @ 2018-02-01  0:04 UTC (permalink / raw)
  To: Hemant Agrawal; +Cc: dev, Ferruh Yigit

22/01/2018 16:48, Ferruh Yigit:
> >> On 1/18/2018 6:12 AM, Hemant Agrawal wrote:
> >>> This patch adds following:
> >>> 1. Option to configure the mac address during create. Generate random
> >>>    address only if the user has not provided any valid address.
> >>> 2. Inform usespace, if mac address is being changed in linux.
> >>> 3. Implement default handling of mac address change in the corresponding
> >>>    ethernet device.
> >>>
> >>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> >>
> Series,
> Acked-by: Ferruh Yigit <ferruh.yigit@intel.com>

Applied with few fixes in RST doc.

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2018-02-01  0:04 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-30 11:46 [dpdk-dev] [PATCH 1/3] kni: support for MAC addr change Hemant Agrawal
2017-11-30 11:46 ` [dpdk-dev] [PATCH 2/3] kni: add support for promisc mode set Hemant Agrawal
2017-12-22 21:57   ` Ferruh Yigit
2017-11-30 11:46 ` [dpdk-dev] [PATCH 3/3] kni: set initial value for MTU Hemant Agrawal
2017-12-22 22:01   ` Ferruh Yigit
2017-12-22 21:55 ` [dpdk-dev] [PATCH 1/3] kni: support for MAC addr change Ferruh Yigit
2017-12-26 10:08   ` Hemant Agrawal
2017-12-26 10:36 ` [dpdk-dev] [PATCH v2 " Hemant Agrawal
2017-12-26 10:36   ` [dpdk-dev] [PATCH v2 2/3] kni: add support for promisc mode set Hemant Agrawal
2017-12-26 10:36   ` [dpdk-dev] [PATCH v2 3/3] kni: set initial value for MTU Hemant Agrawal
2018-01-18  6:12   ` [dpdk-dev] [PATCH v3 1/3] kni: support for MAC addr change Hemant Agrawal
2018-01-18  6:12     ` [dpdk-dev] [PATCH v3 2/3] kni: add support for promisc mode set Hemant Agrawal
2018-01-18  6:13     ` [dpdk-dev] [PATCH v3 3/3] kni: set initial value for MTU Hemant Agrawal
2018-01-21 22:07     ` [dpdk-dev] [PATCH v3 1/3] kni: support for MAC addr change Ferruh Yigit
2018-01-22  5:20       ` Hemant Agrawal
2018-01-22 15:48         ` Ferruh Yigit
2018-02-01  0:04           ` Thomas Monjalon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).