|
|
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 |
|