From patchwork Tue Mar 1 10:29:24 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ravali.burra@wipro.com X-Patchwork-Id: 590448 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from archives.nicira.com (archives.nicira.com [96.126.127.54]) by ozlabs.org (Postfix) with ESMTP id 44B9714033B for ; Tue, 1 Mar 2016 21:30:03 +1100 (AEDT) Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id 51BD710668; Tue, 1 Mar 2016 02:30:01 -0800 (PST) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx1e3.cudamail.com (mx1.cudamail.com [69.90.118.67]) by archives.nicira.com (Postfix) with ESMTPS id 811DF10665 for ; Tue, 1 Mar 2016 02:29:59 -0800 (PST) Received: from bar5.cudamail.com (localhost [127.0.0.1]) by mx1e3.cudamail.com (Postfix) with ESMTPS id E44BB42033D for ; Tue, 1 Mar 2016 03:29:57 -0700 (MST) X-ASG-Debug-ID: 1456828195-09eadd2b12f47b0001-byXFYA Received: from mx3-pf3.cudamail.com ([192.168.14.3]) by bar5.cudamail.com with ESMTP id DOJfCPdCqRVHnpFF (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 01 Mar 2016 03:29:55 -0700 (MST) X-Barracuda-Envelope-From: ravali.burra@wipro.com X-Barracuda-RBL-Trusted-Forwarder: 192.168.14.3 Received: from unknown (HELO wipro-blr-out01.wipro.com) (203.91.198.74) by mx3-pf3.cudamail.com with ESMTPS (DHE-RSA-AES256-SHA encrypted); 1 Mar 2016 11:18:39 -0000 Received-SPF: pass (mx3-pf3.cudamail.com: SPF record at wipro.com designates 203.91.198.74 as permitted sender) X-Barracuda-Apparent-Source-IP: 203.91.198.74 X-Barracuda-RBL-IP: 203.91.198.74 X-AuditID: cb5bdd57-f79556d0000048bc-9e-56d56f1c9c47 X-Invalid-Recipients: Received: from BLR-OUT-EDG02.wipro.com ( [203.91.193.76]) by wipro-blr-out01.wipro.com (Symantec Mail Security) with SMTP id B6.EF.18620.C1F65D65; Tue, 1 Mar 2016 15:59:48 +0530 (IST) Received: from BLR-EC-MBX2.wipro.com (10.208.51.112) by BLR-OUT-EDG02.wipro.com (203.91.193.32) with Microsoft SMTP Server (TLS) id 14.3.266.1; Tue, 1 Mar 2016 15:59:30 +0530 Received: from wipro-blr-tls01.wipro.com (203.91.193.64) by BLR-EC-MBX2.wipro.com (10.208.51.112) with Microsoft SMTP Server (TLS) id 14.3.266.1; Tue, 1 Mar 2016 15:59:29 +0530 Received: from APC01-HK2-obe.outbound.protection.outlook.com (65.55.88.214) by wipro-blr-tls01.wipro.com (203.91.193.64) with Microsoft SMTP Server (TLS) id 14.3.266.1; Tue, 1 Mar 2016 15:59:24 +0530 Received: from SG2PR03MB1456.apcprd03.prod.outlook.com (10.169.54.30) by SG2PR03MB1456.apcprd03.prod.outlook.com (10.169.54.30) with Microsoft SMTP Server (TLS) id 15.1.427.16; Tue, 1 Mar 2016 10:29:24 +0000 Received: from SG2PR03MB1456.apcprd03.prod.outlook.com ([10.169.54.30]) by SG2PR03MB1456.apcprd03.prod.outlook.com ([10.169.54.30]) with mapi id 15.01.0427.016; Tue, 1 Mar 2016 10:29:24 +0000 X-CudaMail-Envelope-Sender: ravali.burra@wipro.com From: To: X-CudaMail-MID: CM-V3-229004316 X-CudaMail-DTE: 030116 X-CudaMail-Originating-IP: 203.91.198.74 Thread-Topic: [ovs-dev][PATCH 1/1]KNI support in OVS-DPDK X-ASG-Orig-Subj: [##CM-V3-229004316##][ovs-dev][PATCH 1/1]KNI support in OVS-DPDK Thread-Index: AdFzpJw/2VsVkc7KSZeFMwUpyIndNg== Date: Tue, 1 Mar 2016 10:29:24 +0000 Message-ID: Accept-Language: en-IN, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: openvswitch.org; dkim=none (message not signed) header.d=none; openvswitch.org; dmarc=none action=none header.from=wipro.com; x-originating-ip: [203.91.215.55] x-ms-office365-filtering-correlation-id: 499cfcd0-45f2-462d-fecf-08d341bc5c64 x-microsoft-exchange-diagnostics: 1; SG2PR03MB1456; 5:d/hqP2UQnfBrNhIcdhVlr7sfi0A14GyzBBMRfK28pctdsF2cdrHCXYjcMvacnOVkKAAX8DWXDEXQTXtzQoCgYOzquCW/8c+2C6Ah9YdrhUQt5nCQZ7Is799hvVcGZ1QuYhhE9x48tRWfwfEaJYS3vg==; 24:6J5m9/DlBXQ4KGsnfdolFO7CvUItOdZNS+OnLs+PIjarh1KPcLfmo0OXh6s4HCXCFPHpgjZeG9LO52jrlqavKhoTZNulHIW8fOBcDMGwm+U= x-microsoft-antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:SG2PR03MB1456; x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(62627912741753); x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(61425038)(601004)(2401047)(5005006)(8121501046)(3002001)(10201501046)(61426038)(61427038); SRVR:SG2PR03MB1456; BCL:0; PCL:0; RULEID:; SRVR:SG2PR03MB1456; x-forefront-prvs: 086831DFB4 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(377424004)(77096005)(1220700001)(1096002)(107886002)(110136002)(6116002)(586003)(102836003)(3846002)(790700001)(3280700002)(2906002)(5008740100001)(19580405001)(19580395003)(66066001)(122556002)(40100003)(1730700002)(2900100001)(3660700001)(86362001)(87936001)(15975445007)(450100001)(50986999)(54356999)(229853001)(74316001)(2351001)(5004730100002)(10400500002)(16236675004)(5002640100001)(5003600100002)(11100500001)(33656002)(19625215002)(92566002)(5001960100003)(19300405004)(81156008)(189998001)(76576001)(2501003)(579004)(559001); DIR:OUT; SFP:1101; SCL:1; SRVR:SG2PR03MB1456; H:SG2PR03MB1456.apcprd03.prod.outlook.com; FPR:; SPF:None; MLV:sfv; LANG:en; spamdiagnosticoutput: 1:23 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-MS-Exchange-CrossTenant-originalarrivaltime: 01 Mar 2016 10:29:24.8057 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 258ac4e4-146a-411e-9dc8-79a9e12fd6da X-MS-Exchange-Transport-CrossTenantHeadersStamped: SG2PR03MB1456 X-OrganizationHeadersPreserved: SG2PR03MB1456.apcprd03.prod.outlook.com X-CrossPremisesHeadersPromoted: BLR-HES-EDG03.wipro.com X-CrossPremisesHeadersFiltered: BLR-HES-EDG03.wipro.com X-CFilter-Loop: Reflected X-GBUdb-Analysis: 0, 203.91.198.74, Ugly c=0.308711 p=-0.4 Source Normal X-MessageSniffer-Rules: 0-0-0-32767-c X-Barracuda-Connect: UNKNOWN[192.168.14.3] X-Barracuda-Start-Time: 1456828195 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://web.cudamail.com:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at cudamail.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.10 X-Barracuda-Spam-Status: No, SCORE=1.10 using per-user scores of TAG_LEVEL=3.5 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=4.0 tests=BSF_SC0_MV0713, BSF_SC5_MJ1963, HTML_MESSAGE, NO_REAL_NAME, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.27464 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 NO_REAL_NAME From: does not include a real name 0.00 HTML_MESSAGE BODY: HTML included in message 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC0_MV0713 Custom rule MV0713 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Content-Filtered-By: Mailman/MimeDel 2.1.16 Subject: [ovs-dev] [PATCH 1/1]KNI support in OVS-DPDK X-BeenThere: dev@openvswitch.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@openvswitch.org Sender: "dev" Hi Team, Please find the configuration and patch details of KNI support in OVS-DPDK This patch contains support for creating KNI interfaces. It also has the required modifications in netdev-dpdk.c, netdev.c files for creation/deletion of kni interfaces in ovs. This patch also adds NETDEV_DPDK_CLASS w.r.t dpdkkni and also has some changes in structure for netdev-dpdk for the support of kni interfaces. Implemented below helper functions * netdev_dpdk_veth_construct * netdev_dpdk_veth_destruct * netdev_dpdk_veth_send * netdev_dpdk_veth_get_stats * netdev_dpdk_veth_rxq_recv. Commands to handle for creation/deletion of KNI interfaces ovs-vsctl --no-wait add-port -- set Interface type=dpdkkni //adds the KNI interface ovs-vsctl --no-wait del-port //deletes the KNI interface Appropriate ovs-ofctl rules to be added to forward/receive packet to/from KNI Signed-off-by: Ravali Burra ravali.burra@wipro.com void netdev_rxq_wait(struct netdev_rxq *rx) { + if (rx->netdev->netdev_class->rxq_wait != NULL) rx->netdev->netdev_class->rxq_wait(rx); } Thanks & Regards, Ravali The information contained in this electronic message and any attachments to this message are intended for the exclusive use of the addressee(s) and may contain proprietary, confidential or privileged information. If you are not the intended recipient, you should not disseminate, distribute or copy this e-mail. Please notify the sender immediately and destroy all copies of this message and any attachments. WARNING: Computer viruses can be transmitted via email. The recipient should check this email and any attachments for the presence of viruses. The company accepts no liability for any damage caused by any virus transmitted by this email. www.wipro.com --- /root/base/nopenvswitch-2.4.0.1/DPDK/lib/librte_kni/rte_kni.c 2015-04-03 10:13:45.000000000 -0400 +++ /root/base/openvswitch-2.4.0.1/DPDK/lib/librte_kni/rte_kni.c 2016-03-01 09:02:21.449863228 -0500 @@ -432,7 +432,7 @@ dev_info.sync_va = mz->addr; dev_info.sync_phys = mz->phys_addr; - + memset(mz_name,0, sizeof(mz_name)); /* MBUF mempool */ snprintf(mz_name, sizeof(mz_name), RTE_MEMPOOL_OBJ_NAME, pktmbuf_pool->name); @@ -749,3 +749,8 @@ close(kni_fd); kni_fd = -1; } +int +rte_kni_get_fd(void) +{ + return kni_fd; +} --- /root/base/nopenvswitch-2.4.0.1/DPDK/lib/librte_kni/rte_kni.h 2015-04-03 10:13:45.000000000 -0400 +++ /root/base/openvswitch-2.4.0.1/DPDK/lib/librte_kni/rte_kni.h 2016-03-01 09:04:26.128870730 -0500 @@ -297,6 +297,15 @@ * void */ extern void rte_kni_close(void); +/** + * get fd for KNI device. + * + * @param void + * + * @return + * int + */ +extern int rte_kni_get_fd(void); #ifdef __cplusplus } --- /root/base/nopenvswitch-2.4.0.1/DPDK/lib/librte_eal/linuxapp/kni/kni_net.c 2015-04-03 10:13:45.000000000 -0400 +++ /root/base/openvswitch-2.4.0.1/DPDK/lib/librte_eal/linuxapp/kni/kni_net.c 2016-03-01 09:43:46.935012781 -0500 @@ -72,12 +72,13 @@ if (kni->lad_dev) memcpy(dev->dev_addr, kni->lad_dev->dev_addr, ETH_ALEN); - else + else if(strlen(dev->dev_addr)==0){ /* * Generate random mac address. eth_random_addr() is the newer * version of generating mac address in linux kernel. */ random_ether_addr(dev->dev_addr); + } netif_start_queue(dev); --- /root/base/nopenvswitch-2.4.0.1/openvswitch-2.4.0/lib/netdev-dpdk.c 2015-08-20 20:18:21.386479276 -0400 +++ /root/base/openvswitch-2.4.0.1/openvswitch-2.4.0/lib/netdev-dpdk.c 2016-03-01 10:01:11.569075636 -0500 @@ -53,6 +53,7 @@ #include "rte_config.h" #include "rte_mbuf.h" #include "rte_virtio_net.h" +#include VLOG_DEFINE_THIS_MODULE(dpdk); static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20); @@ -62,6 +63,13 @@ #define OVS_CACHE_LINE_SIZE CACHE_LINE_SIZE #define OVS_VPORT_DPDK "ovs_dpdk" +#define MAX_PACKET_SZ 2048 +#define NUM_KNI_INTERFACES 16 +#define PORT_VETH_RX_BURST_SIZE 32 +#define PORT_VETH_TX_BURST_SIZE 32 +#define VETH_RETRY_NUM 4 +#define VETH_RETRY_DELAY_US 10 + /* * need to reserve tons of extra space in the mbufs so we can align the * DMA addresses to 4KB. @@ -130,6 +138,7 @@ enum dpdk_dev_type { DPDK_DEV_ETH = 0, DPDK_DEV_VHOST = 1, + DPDK_DEV_KNI = 2 }; static int rte_eal_init_ret = ENODEV; @@ -223,7 +232,10 @@ /* virtio-net structure for vhost device */ OVSRCU_TYPE(struct virtio_net *) virtio_dev; - + + /* kni structure for veth device */ + struct rte_kni *veth; + /* Identifier used to distinguish vhost devices from each other */ char vhost_id[PATH_MAX]; @@ -235,6 +247,7 @@ struct netdev_rxq up; int port_id; }; +int kni_dpdk_set_mac(struct netdev_dpdk *); static bool thread_is_pmd(void); @@ -535,7 +548,49 @@ dev->flags = NETDEV_UP | NETDEV_PROMISC; return 0; } +static int +dpdk_veth_dev_init(struct netdev_dpdk *dev) OVS_REQUIRES(dpdk_mutex) +{ + int err=0; + struct rte_kni *veth = NULL; + struct rte_kni_conf conf; + static int port_id = 1; + + if (rte_kni_get(dev->up.name)){ + VLOG_ERR("Kni interface %s already exists",dev->up.name); + return EAGAIN; + } + /* invoke init before rte_kni_alloc.Currently hardcoded the num of kni interfaces as 2 */ + if (rte_kni_get_fd() == -1) + rte_kni_init(NUM_KNI_INTERFACES); + + kni_dpdk_set_mac(dev); + /* Clear conf at first */ + memset(&conf, 0, sizeof(conf)); + memcpy(conf.name, dev->up.name, RTE_KNI_NAMESIZE); + conf.group_id = (uint16_t)port_id; /* currently group id is hardcoded */ + conf.mbuf_size = MAX_PACKET_SZ; + + veth = rte_kni_alloc(dev->dpdk_mp->mp, &conf, NULL); + if (veth != NULL){ + port_id ++; /* increment the port id for the next kni interface */ + dev->veth = veth; + } + else + err = ENOMEM; + + return err; +} +int kni_dpdk_set_mac(struct netdev_dpdk *dev) +{ + struct ether_addr addr; + if(!is_zero_ether_addr(&addr)){ + eth_random_addr(&addr); + memcpy(dev->hwaddr, addr.addr_bytes,ETH_ADDR_LEN); + } + return 0; +} static struct netdev_dpdk * netdev_dpdk_cast(const struct netdev *netdev) { @@ -619,6 +674,12 @@ goto unlock; } } + else if(type == DPDK_DEV_KNI) { + err = dpdk_veth_dev_init(netdev); + if (err) { + goto unlock; + } + } list_push_back(&dpdk_list, &netdev->list_node); @@ -693,7 +754,25 @@ ovs_mutex_unlock(&dpdk_mutex); return err; } +static int +netdev_dpdk_veth_construct(struct netdev *netdev_) +{ + struct netdev_dpdk *netdev = netdev_dpdk_cast(netdev_); + int err=0; + + if (rte_eal_init_ret) { + return rte_eal_init_ret; + } + + ovs_mutex_lock(&dpdk_mutex); + err = netdev_dpdk_init(netdev_, -1, DPDK_DEV_KNI); + ovs_mutex_unlock(&dpdk_mutex); + rte_spinlock_init(&netdev->vhost_tx_lock); /* using same structure host_tx_lock for kni */ + + return err; + +} static int netdev_dpdk_construct(struct netdev *netdev) { @@ -748,7 +827,23 @@ dpdk_mp_put(dev->dpdk_mp); ovs_mutex_unlock(&dpdk_mutex); } +static void +netdev_dpdk_veth_destruct(struct netdev *netdev_) +{ + struct netdev_dpdk *dev = netdev_dpdk_cast(netdev_); + ovs_mutex_lock(&dev->mutex); + if (rte_kni_release(dev->veth)) { + VLOG_ERR("Failed to release KNI interface"); + return; + } + ovs_mutex_unlock(&dev->mutex); + + ovs_mutex_lock(&dpdk_mutex); + list_remove(&dev->list_node); + dpdk_mp_put(dev->dpdk_mp); + ovs_mutex_unlock(&dpdk_mutex); +} static void netdev_dpdk_dealloc(struct netdev *netdev_) { @@ -972,7 +1067,36 @@ *c = (int) nb_rx; return 0; } +static int +netdev_dpdk_veth_rxq_recv(struct netdev_rxq *rxq_, + struct dp_packet **packets, int *c) +{ + struct netdev_rxq_dpdk *rx = netdev_rxq_dpdk_cast(rxq_); + struct netdev *netdev = rx->up.netdev; + struct netdev_dpdk *veth_dev = netdev_dpdk_cast(netdev); + uint16_t nb_rx = 0; + struct rte_kni *veth = NULL; + veth = veth_dev->veth; + + if (veth != NULL) + { + /* receive and free */ + nb_rx = rte_kni_rx_burst(veth, (struct rte_mbuf **)packets, PORT_VETH_RX_BURST_SIZE); + /* handle callbacks (i.e. ifconfig) before we return */ + rte_kni_handle_request(veth); + if (!nb_rx) { + return EAGAIN; + } + rte_spinlock_lock(&veth_dev->stats_lock); + veth_dev->stats.rx_packets += (uint64_t)nb_rx; + rte_spinlock_unlock(&veth_dev->stats_lock); + + *c = (int) nb_rx; + return 0; + } + return EAGAIN; +} static int netdev_dpdk_rxq_recv(struct netdev_rxq *rxq_, struct dp_packet **packets, int *c) @@ -1191,6 +1315,62 @@ } return 0; } +static int +netdev_dpdk_veth_send(struct netdev *netdev_, int qid OVS_UNUSED, struct dp_packet **pkts, + int cnt, bool may_steal) +{ + struct netdev_dpdk *netdev = netdev_dpdk_cast(netdev_); + struct rte_kni *veth = NULL; + struct rte_mbuf **cur_pkts = (struct rte_mbuf **)pkts; + unsigned int tx_pkts = 0, dropped_pkts = 0, i; + + if (!thread_is_pmd()) { + ovs_mutex_lock(&nonpmd_mempool_mutex); + } + veth = netdev->veth; + if (veth == NULL) + { + rte_spinlock_lock(&netdev->stats_lock); + netdev->stats.tx_dropped+= cnt; + rte_spinlock_unlock(&netdev->stats_lock); + goto out; + + } + rte_spinlock_lock(&netdev->vhost_tx_lock); + + for (i=0;idata_off < RTE_PKTMBUF_HEADROOM) + ++dropped_pkts; + + else if (rte_kni_tx_burst(veth, + (struct rte_mbuf **) &cur_pkts[i], 1)) + ++tx_pkts; + else + ++dropped_pkts; + + } + rte_spinlock_unlock(&netdev->vhost_tx_lock); + + /* statistics for the no of packets sent */ + rte_spinlock_lock(&netdev->stats_lock); + netdev->stats.tx_packets += tx_pkts; + netdev->stats.tx_dropped += dropped_pkts; + rte_spinlock_unlock(&netdev->stats_lock); + + if (!thread_is_pmd()) { + ovs_mutex_unlock(&nonpmd_mempool_mutex); + } + +out: if (may_steal) { + int i; + for (i = 0; i < cnt; i++) { + dp_packet_delete(pkts[i]); + } + } + return 0; + +} static inline void netdev_dpdk_send__(struct netdev_dpdk *dev, int qid, @@ -1394,7 +1574,45 @@ return 0; } +static int +netdev_dpdk_veth_get_stats(const struct netdev *netdev, + struct netdev_stats *stats) +{ + struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); + + ovs_mutex_lock(&dev->mutex); + memset(stats, 0, sizeof(*stats)); + /* Unsupported Stats */ + stats->rx_errors = UINT64_MAX; + stats->tx_errors = UINT64_MAX; + stats->multicast = UINT64_MAX; + stats->collisions = UINT64_MAX; + stats->rx_crc_errors = UINT64_MAX; + stats->rx_fifo_errors = UINT64_MAX; + stats->rx_frame_errors = UINT64_MAX; + stats->rx_length_errors = UINT64_MAX; + stats->rx_missed_errors = UINT64_MAX; + stats->rx_over_errors = UINT64_MAX; + stats->tx_aborted_errors = UINT64_MAX; + stats->tx_carrier_errors = UINT64_MAX; + stats->tx_errors = UINT64_MAX; + stats->tx_fifo_errors = UINT64_MAX; + stats->tx_heartbeat_errors = UINT64_MAX; + stats->tx_window_errors = UINT64_MAX; + stats->rx_bytes += UINT64_MAX; + stats->rx_dropped += UINT64_MAX; + stats->tx_bytes += UINT64_MAX; + + rte_spinlock_lock(&dev->stats_lock); + /* Supported Stats */ + stats->rx_packets += dev->stats.rx_packets; + stats->tx_packets += dev->stats.tx_packets; + stats->tx_dropped += dev->stats.tx_dropped; + rte_spinlock_unlock(&dev->stats_lock); + ovs_mutex_unlock(&dev->mutex); + return 0; +} static int netdev_dpdk_get_stats(const struct netdev *netdev, struct netdev_stats *stats) { @@ -2177,6 +2395,20 @@ NULL, netdev_dpdk_vhost_rxq_recv); +static const struct netdev_class dpdk_kni_class = + NETDEV_DPDK_CLASS( + "dpdkkni", + NULL, + netdev_dpdk_veth_construct, + netdev_dpdk_veth_destruct, + NULL, + netdev_dpdk_veth_send, + NULL, + netdev_dpdk_veth_get_stats, + NULL, + NULL, + netdev_dpdk_veth_rxq_recv); + void netdev_dpdk_register(void) { @@ -2195,6 +2427,7 @@ #else netdev_register_provider(&dpdk_vhost_user_class); #endif + netdev_register_provider(&dpdk_kni_class); ovsthread_once_done(&once); } } --- /root/base/nopenvswitch-2.4.0.1/openvswitch-2.4.0/lib/netdev.c 2015-08-20 20:18:21.430479276 -0400 +++ /root/base/openvswitch-2.4.0.1/openvswitch-2.4.0/lib/netdev.c 2016-03-01 09:41:53.295005943 -0500 @@ -112,7 +112,8 @@ return (!strcmp(netdev->netdev_class->type, "dpdk") || !strcmp(netdev->netdev_class->type, "dpdkr") || !strcmp(netdev->netdev_class->type, "dpdkvhostcuse") || - !strcmp(netdev->netdev_class->type, "dpdkvhostuser")); + !strcmp(netdev->netdev_class->type, "dpdkvhostuser")|| + !strcmp(netdev->netdev_class->type, "dpdkkni")); } static void @@ -661,6 +662,7 @@