naccyde / rpms / iproute

Forked from rpms/iproute 9 months ago
Clone

Blame SOURCES/0150-ip-enable-configuring-multicast-group-autojoin.patch

049c96
From 24aff639b62b443b15281c5fc44e28483c22236b Mon Sep 17 00:00:00 2001
049c96
From: Phil Sutter <psutter@redhat.com>
049c96
Date: Mon, 30 May 2016 18:37:49 +0200
049c96
Subject: [PATCH] ip: enable configuring multicast group autojoin
049c96
049c96
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1333513
049c96
Upstream Status: iproute2.git commit e31867ac30cf9
049c96
Conflicts: Minor context conflict due to previously applied commit
049c96
	   c079e121a73af ("libnetlink: add size argument to rtnl_talk").
049c96
049c96
commit e31867ac30cf95155d113bbfaedf6b99f98a677f
049c96
Author: Madhu Challa <challa@noironetworks.com>
049c96
Date:   Wed Mar 4 10:30:10 2015 -0800
049c96
049c96
    ip: enable configuring multicast group autojoin
049c96
049c96
    Joining multicast group on ethernet level via "ip maddr" command would
049c96
    not work if we have an Ethernet switch that does igmp snooping since
049c96
    the switch would not replicate multicast packets on ports that did not
049c96
    have IGMP reports for the multicast addresses.
049c96
049c96
    Linux vxlan interfaces created via "ip link add vxlan" have the group option
049c96
    that enables then to do the required join.
049c96
049c96
    By extending ip address command with option "autojoin" we can get similar
049c96
    functionality for openvswitch vxlan interfaces as well as other tunneling
049c96
    mechanisms that need to receive multicast traffic.
049c96
049c96
    example:
049c96
    ip address add 224.1.1.10/24 dev eth5 autojoin
049c96
    ip address del 224.1.1.10/24 dev eth5
049c96
---
049c96
 ip/ipaddress.c | 26 +++++++++++++++++++++++++-
049c96
 1 file changed, 25 insertions(+), 1 deletion(-)
049c96
049c96
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
049c96
index 8681bf9..ffcc076 100644
049c96
--- a/ip/ipaddress.c
049c96
+++ b/ip/ipaddress.c
049c96
@@ -83,7 +83,7 @@ static void usage(void)
049c96
 	fprintf(stderr, "           [-]tentative | [-]deprecated | [-]dadfailed | temporary |\n");
049c96
 	fprintf(stderr, "           CONFFLAG-LIST ]\n");
049c96
 	fprintf(stderr, "CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG\n");
049c96
-	fprintf(stderr, "CONFFLAG  := [ home | nodad | mngtmpaddr | noprefixroute ]\n");
049c96
+	fprintf(stderr, "CONFFLAG  := [ home | nodad | mngtmpaddr | noprefixroute | autojoin ]\n");
049c96
 	fprintf(stderr, "LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]\n");
049c96
 	fprintf(stderr, "LFT := forever | SECONDS\n");
049c96
 
049c96
@@ -868,6 +868,10 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
049c96
 		ifa_flags &= ~IFA_F_NOPREFIXROUTE;
049c96
 		fprintf(fp, "noprefixroute ");
049c96
 	}
049c96
+	if (ifa_flags & IFA_F_MCAUTOJOIN) {
049c96
+		ifa_flags &= ~IFA_F_MCAUTOJOIN;
049c96
+		fprintf(fp, "autojoin ");
049c96
+	}
049c96
 	if (!(ifa_flags & IFA_F_PERMANENT)) {
049c96
 		fprintf(fp, "dynamic ");
049c96
 	} else
049c96
@@ -1272,6 +1276,9 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
049c96
 		} else if (strcmp(*argv, "noprefixroute") == 0) {
049c96
 			filter.flags |= IFA_F_NOPREFIXROUTE;
049c96
 			filter.flagmask |= IFA_F_NOPREFIXROUTE;
049c96
+		} else if (strcmp(*argv, "autojoin") == 0) {
049c96
+			filter.flags |= IFA_F_MCAUTOJOIN;
049c96
+			filter.flagmask |= IFA_F_MCAUTOJOIN;
049c96
 		} else if (strcmp(*argv, "dadfailed") == 0) {
049c96
 			filter.flags |= IFA_F_DADFAILED;
049c96
 			filter.flagmask |= IFA_F_DADFAILED;
049c96
@@ -1408,6 +1415,16 @@ static int default_scope(inet_prefix *lcl)
049c96
 	return 0;
049c96
 }
049c96
 
049c96
+static bool ipaddr_is_multicast(inet_prefix *a)
049c96
+{
049c96
+	if (a->family == AF_INET)
049c96
+		return IN_MULTICAST(ntohl(a->data[0]));
049c96
+	else if (a->family == AF_INET6)
049c96
+		return IN6_IS_ADDR_MULTICAST(a->data);
049c96
+	else
049c96
+		return false;
049c96
+}
049c96
+
049c96
 static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
049c96
 {
049c96
 	struct {
049c96
@@ -1515,6 +1532,8 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
049c96
 			ifa_flags |= IFA_F_MANAGETEMPADDR;
049c96
 		} else if (strcmp(*argv, "noprefixroute") == 0) {
049c96
 			ifa_flags |= IFA_F_NOPREFIXROUTE;
049c96
+		} else if (strcmp(*argv, "autojoin") == 0) {
049c96
+			ifa_flags |= IFA_F_MCAUTOJOIN;
049c96
 		} else {
049c96
 			if (strcmp(*argv, "local") == 0) {
049c96
 				NEXT_ARG();
049c96
@@ -1605,6 +1624,11 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
049c96
 			  sizeof(cinfo));
049c96
 	}
049c96
 
049c96
+	if ((ifa_flags & IFA_F_MCAUTOJOIN) && !ipaddr_is_multicast(&lcl)) {
049c96
+		fprintf(stderr, "autojoin needs multicast address\n");
049c96
+		return -1;
049c96
+	}
049c96
+
049c96
 	if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
049c96
 		return -2;
049c96
 
049c96
-- 
049c96
1.8.3.1
049c96