Skip to content

Commit

Permalink
add dpdk patch file
Browse files Browse the repository at this point in the history
  • Loading branch information
ywc689 committed Oct 11, 2017
1 parent ff5a4df commit d658bd1
Showing 1 changed file with 107 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
From 8d6d303be80c246cf0c92b143432aede255c9238 Mon Sep 17 00:00:00 2001
From: Lei Chen <raychen@qiyi.com>
Date: Fri, 3 Mar 2017 14:49:17 +0800
Subject: [PATCH] kni: use netlink event for multicast (driver part).

kni driver send netlink event every time hw-multicast list updated by
kernel, the user kni app should capture the event and update multicast
to kni device.

original way is using rte_kni_request to pass hw-multicast to user kni
module. that method works but finally memory corruption found, which is
not easy to address.
---
lib/librte_eal/linuxapp/kni/kni_net.c | 67 +++++++++++++++++++++++++++++++++++
1 file changed, 67 insertions(+)

diff --git a/lib/librte_eal/linuxapp/kni/kni_net.c b/lib/librte_eal/linuxapp/kni/kni_net.c
index fc82193..952e9b8 100644
--- a/lib/librte_eal/linuxapp/kni/kni_net.c
+++ b/lib/librte_eal/linuxapp/kni/kni_net.c
@@ -35,6 +35,8 @@
#include <linux/skbuff.h>
#include <linux/kthread.h>
#include <linux/delay.h>
+#include <linux/inetdevice.h>
+#include <net/netlink.h>

#include <exec-env/rte_kni_common.h>
#include <kni_fifo.h>
@@ -527,9 +529,74 @@ kni_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
return 0;
}

+static size_t kni_nlmsg_size(void)
+{
+ return NLMSG_ALIGN(sizeof(struct ifaddrmsg))
+ + nla_total_size(4) /* IFA_ADDRESS */
+ + nla_total_size(4) /* IFA_LOCAL */
+ + nla_total_size(4) /* IFA_BROADCAST */
+ + nla_total_size(IFNAMSIZ) /* IFA_LABEL */
+ + nla_total_size(4) /* IFA_FLAGS */
+ + nla_total_size(sizeof(struct ifa_cacheinfo)); /* IFA_CACHEINFO */
+}
+
static void
kni_net_set_rx_mode(struct net_device *dev)
{
+ /*
+ * send event to notify user (DPDK KNI app) that multicast list changed,
+ * so that it can monitor multicast join/leave and set HW mc-addrs to
+ * kni dev accordinglly.
+ *
+ * this event is just an notification, we do not save any mc-addr here
+ * (so attribute space for us). user kni app should get maddrs after
+ * receive this notification.
+ *
+ * I was expecting kernel send some rtnl event for multicast join/leave,
+ * but it doesn't. By checking the call-chain of SIOCADDMULTI (ip maddr,
+ * manages only hardware multicast) and IP_ADD_MEMBERSHIP (ip_mc_join_group,
+ * used to for IPv4 multicast), no rtnl event sent.
+ *
+ * so as workaround, modify kni driver here to send RTM_NEWADDR.
+ * it may not suitalbe to use this event for mcast, but that should works.
+ * hope that won't affect other listener to this event.
+ *
+ * previous solution was using rte_kni_request to pass hw-maddr list to user.
+ * it "works" for times but finally memory corruption found, which is
+ * not easy to address (lock was added and reviewed). That's why we use
+ * netlink event instead.
+ */
+ struct sk_buff *skb;
+ struct net *net = dev_net(dev);
+ struct nlmsghdr *nlh;
+ struct ifaddrmsg *ifm;
+
+ skb = nlmsg_new(kni_nlmsg_size(), GFP_KERNEL);
+ if (!skb)
+ return;
+
+ /* no other event for us ? */
+ nlh = nlmsg_put(skb, 0, 0, RTM_NEWADDR, sizeof(*ifm), 0);
+ if (!nlh) {
+ kfree_skb(skb);
+ return;
+ }
+
+ /* just send an notification so no other info */
+ ifm = nlmsg_data(nlh);
+ memset(ifm, 0, sizeof(*ifm));
+ ifm->ifa_family = AF_UNSPEC;
+ ifm->ifa_prefixlen = 0;
+ ifm->ifa_flags = 0;
+ ifm->ifa_scope = RT_SCOPE_NOWHERE;
+ ifm->ifa_index = 0;
+
+ nlmsg_end(skb, nlh);
+
+ /* other group ? */
+ KNI_DBG("%s: rx-mode/multicast-list changed\n", __func__);
+ rtnl_notify(skb, net, 0, RTNLGRP_NOTIFY, NULL, GFP_KERNEL);
+ return;
}

static int
--
2.7.4

0 comments on commit d658bd1

Please sign in to comment.