From patchwork Fri Jun 30 16:51:32 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ferruh Yigit X-Patchwork-Id: 26124 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id A82C97CCE; Fri, 30 Jun 2017 18:52:35 +0200 (CEST) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by dpdk.org (Postfix) with ESMTP id 0227A5587 for ; Fri, 30 Jun 2017 18:52:04 +0200 (CEST) Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 30 Jun 2017 09:52:02 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.40,287,1496127600"; d="scan'208";a="103233260" Received: from silpixa00372839.ir.intel.com (HELO silpixa00372839.ger.corp.intel.com) ([10.237.222.154]) by orsmga004.jf.intel.com with ESMTP; 30 Jun 2017 09:52:00 -0700 From: Ferruh Yigit To: dev@dpdk.org Cc: Ferruh Yigit , Stephen Hemminger , Bruce Richardson , Anatoly Burakov Date: Fri, 30 Jun 2017 17:51:32 +0100 Message-Id: <20170630165140.59594-13-ferruh.yigit@intel.com> X-Mailer: git-send-email 2.13.0 In-Reply-To: <20170630165140.59594-1-ferruh.yigit@intel.com> References: <20170621110651.75299-1-ferruh.yigit@intel.com> <20170630165140.59594-1-ferruh.yigit@intel.com> Subject: [dpdk-dev] [PATCH v9 12/20] unci: add netdevice ops X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add ndos for virtual interface. Almost all ndos use netlink exec to pass command to userspace and read response. Signed-off-by: Ferruh Yigit --- .../eal/include/exec-env/rte_unci_common.h | 17 +++ lib/librte_eal/linuxapp/unci/unci_net.c | 132 ++++++++++++++++++++- 2 files changed, 148 insertions(+), 1 deletion(-) diff --git a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h index 474f62606..3daa8a6ec 100644 --- a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h +++ b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_unci_common.h @@ -89,4 +89,21 @@ enum { #define IFLA_UNCI_MAX (__IFLA_UNCI_MAX - 1) +/* + * Request id. + */ +enum unci_req_id { + UNCI_REQ_UNKNOWN = (1 << 16), + UNCI_REQ_CHANGE_MTU, + UNCI_REQ_CFG_NETWORK_IF, + UNCI_REQ_GET_STATS, + UNCI_REQ_GET_MAC, + UNCI_REQ_SET_MAC, + UNCI_REQ_START_PORT, + UNCI_REQ_STOP_PORT, + UNCI_REQ_SET_PROMISC, + UNCI_REQ_SET_ALLMULTI, + UNCI_REQ_MAX, +}; + #endif /* _RTE_UNCI_COMMON_H_ */ diff --git a/lib/librte_eal/linuxapp/unci/unci_net.c b/lib/librte_eal/linuxapp/unci/unci_net.c index 72099e596..2ce337a48 100644 --- a/lib/librte_eal/linuxapp/unci/unci_net.c +++ b/lib/librte_eal/linuxapp/unci/unci_net.c @@ -22,12 +22,142 @@ * Intel Corporation */ +#include #include +#include #include #include "unci_dev.h" -static const struct net_device_ops unci_net_netdev_ops = { 0 }; +static int unci_net_init(struct net_device *dev) +{ + u8 mac[ETH_ALEN] = {0}; + + unci_nl_exec(UNCI_REQ_GET_MAC, dev, NULL, 0, mac, ETH_ALEN); + memcpy(dev->dev_addr, mac, dev->addr_len); + return 0; +} + +static int unci_net_open(struct net_device *dev) +{ + /* DPDK port already started, stop it first */ + unci_nl_exec(UNCI_REQ_STOP_PORT, dev, NULL, 0, NULL, 0); + unci_nl_exec(UNCI_REQ_START_PORT, dev, NULL, 0, NULL, 0); + netif_start_queue(dev); + return 0; +} + +static int unci_net_close(struct net_device *dev) +{ + unci_nl_exec(UNCI_REQ_STOP_PORT, dev, NULL, 0, NULL, 0); + netif_stop_queue(dev); + return 0; +} + +static int unci_net_xmit(struct sk_buff *skb, struct net_device *dev) +{ + dev_kfree_skb(skb); + return NETDEV_TX_OK; +} + +static void unci_net_change_rx_flags(struct net_device *dev, int flags) +{ + u32 on = 1; + u32 off = 0; + + if (flags & IFF_PROMISC) + unci_nl_exec(UNCI_REQ_SET_PROMISC, dev, + dev->flags & IFF_PROMISC ? &on : &off, + sizeof(u32), NULL, 0); + + if (flags & IFF_ALLMULTI) + unci_nl_exec(UNCI_REQ_SET_ALLMULTI, dev, + dev->flags & IFF_ALLMULTI ? &on : &off, + sizeof(u32), NULL, 0); +} + +static int unci_net_set_mac(struct net_device *dev, void *p) +{ + struct sockaddr *addr = p; + int err; + + if (!is_valid_ether_addr(addr->sa_data)) + return -EADDRNOTAVAIL; + + err = unci_nl_exec(UNCI_REQ_SET_MAC, dev, addr->sa_data, + dev->addr_len, NULL, 0); + if (err < 0) + return -EADDRNOTAVAIL; + + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + + return 0; +} + +static int unci_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + return -EOPNOTSUPP; +} + +/* + * Configuration changes (passed on by ifconfig) + */ +static int unci_net_config(struct net_device *dev, struct ifmap *map) +{ + if (dev->flags & IFF_UP) + return -EBUSY; + + return -EOPNOTSUPP; +} + +static int unci_net_change_mtu(struct net_device *dev, int new_mtu) +{ + int err = 0; + + err = unci_nl_exec(UNCI_REQ_CHANGE_MTU, dev, &new_mtu, sizeof(int), + NULL, 0); + + if (err == 0) + dev->mtu = new_mtu; + + return err; +} + +static void unci_net_stats64(struct net_device *dev, + struct rtnl_link_stats64 *stats) +{ + int err; + + err = unci_nl_exec(UNCI_REQ_GET_STATS, dev, NULL, 0, + stats, sizeof(struct rtnl_link_stats64)); +} + +#if (KERNEL_VERSION(3, 9, 0) <= LINUX_VERSION_CODE) +static int unci_net_change_carrier(struct net_device *dev, bool new_carrier) +{ + if (new_carrier) + netif_carrier_on(dev); + else + netif_carrier_off(dev); + return 0; +} +#endif + +static const struct net_device_ops unci_net_netdev_ops = { + .ndo_init = unci_net_init, + .ndo_open = unci_net_open, + .ndo_stop = unci_net_close, + .ndo_start_xmit = unci_net_xmit, + .ndo_change_rx_flags = unci_net_change_rx_flags, + .ndo_set_mac_address = unci_net_set_mac, + .ndo_do_ioctl = unci_net_ioctl, + .ndo_set_config = unci_net_config, + .ndo_change_mtu = unci_net_change_mtu, + .ndo_get_stats64 = unci_net_stats64, +#if (KERNEL_VERSION(3, 9, 0) <= LINUX_VERSION_CODE) + .ndo_change_carrier = unci_net_change_carrier, +#endif +}; static void unci_net_setup(struct net_device *dev) {