All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Netlink messages for multicast HW addr programming
@ 2016-01-21 11:47 Patrick Ruddy
  2016-01-21 20:04 ` Jiri Pirko
  0 siblings, 1 reply; 9+ messages in thread
From: Patrick Ruddy @ 2016-01-21 11:47 UTC (permalink / raw)
  To: netdev; +Cc: Patrick Ruddy

Add RTM_NEWADDR and RTM_DELADDR netlink messages to indicate
interest in specific multicast hardware addresses. These messages
are sent when addressed are added or deleted from the appropriate
interface driver.

Signed-off-by: Patrick Ruddy <pruddy@brocade.com>

diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c
index c0548d2..a0ebadd 100644
--- a/net/core/dev_addr_lists.c
+++ b/net/core/dev_addr_lists.c
@@ -12,6 +12,7 @@
  */
 
 #include <linux/netdevice.h>
+#include <net/netlink.h>
 #include <linux/rtnetlink.h>
 #include <linux/export.h>
 #include <linux/list.h>
@@ -661,6 +662,62 @@ out:
 }
 EXPORT_SYMBOL(dev_mc_add_excl);
 
+static int fill_addr(struct sk_buff *skb, struct net_device *dev,
+		     const unsigned char *addr, int type)
+{
+	struct nlmsghdr *nlh;
+	struct ifaddrmsg *ifm;
+
+	nlh = nlmsg_put(skb, 0, 0, type, sizeof(*ifm), 0);
+	if (nlh == NULL)
+		return -EMSGSIZE;
+
+	ifm = nlmsg_data(nlh);
+	ifm->ifa_family = AF_UNSPEC;
+	ifm->ifa_prefixlen = 0;
+	ifm->ifa_flags = IFA_F_PERMANENT;
+	ifm->ifa_scope = RT_SCOPE_LINK;
+	ifm->ifa_index = dev->ifindex;
+	if (nla_put(skb, IFA_ADDRESS, dev->addr_len, addr))
+		goto nla_put_failure;
+	nlmsg_end(skb, nlh);
+	return 0;
+
+nla_put_failure:
+	nlmsg_cancel(skb, nlh);
+	return -EMSGSIZE;
+}
+
+static inline size_t addr_nlmsg_size(void)
+{
+	return NLMSG_ALIGN(sizeof(struct ifaddrmsg))
+		+ nla_total_size(MAX_ADDR_LEN);
+}
+
+static void mc_addr_notify(struct net_device *dev, const unsigned char * addr,
+			   int type)
+{
+	struct net *net = dev_net(dev);
+	struct sk_buff *skb;
+	int err = -ENOBUFS;
+
+	skb = nlmsg_new(addr_nlmsg_size(), GFP_ATOMIC);
+	if (skb == NULL)
+		goto errout;
+
+	err = fill_addr(skb, dev, addr, type);
+	if (err < 0) {
+		WARN_ON(err == -EMSGSIZE);
+		kfree_skb(skb);
+		goto errout;
+	}
+	rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
+	return;
+errout:
+	if (err < 0)
+		rtnl_set_sk_err(net, RTNLGRP_LINK, err);
+}
+
 static int __dev_mc_add(struct net_device *dev, const unsigned char *addr,
 			bool global)
 {
@@ -669,8 +726,10 @@ static int __dev_mc_add(struct net_device *dev, const unsigned char *addr,
 	netif_addr_lock_bh(dev);
 	err = __hw_addr_add_ex(&dev->mc, addr, dev->addr_len,
 			       NETDEV_HW_ADDR_T_MULTICAST, global, false, 0);
-	if (!err)
+	if (!err) {
 		__dev_set_rx_mode(dev);
+		mc_addr_notify(dev, addr, RTM_NEWADDR);
+	}
 	netif_addr_unlock_bh(dev);
 	return err;
 }
@@ -709,8 +768,10 @@ static int __dev_mc_del(struct net_device *dev, const unsigned char *addr,
 	netif_addr_lock_bh(dev);
 	err = __hw_addr_del_ex(&dev->mc, addr, dev->addr_len,
 			       NETDEV_HW_ADDR_T_MULTICAST, global, false);
-	if (!err)
+	if (!err) {
 		__dev_set_rx_mode(dev);
+		mc_addr_notify(dev, addr, RTM_DELADDR);
+	}
 	netif_addr_unlock_bh(dev);
 	return err;
 }
-- 
2.1.4

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

end of thread, other threads:[~2016-02-03 23:41 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-21 11:47 [PATCH] Netlink messages for multicast HW addr programming Patrick Ruddy
2016-01-21 20:04 ` Jiri Pirko
2016-01-22 14:51   ` Patrick Ruddy
2016-01-22 15:05     ` Jiri Pirko
2016-01-22 15:49       ` Patrick Ruddy
2016-01-23  7:53         ` Jiri Pirko
2016-02-03 14:14           ` Patrick Ruddy
2016-02-03 14:22             ` Jiri Pirko
2016-02-03 23:41             ` Stephen Hemminger

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.