pimd: Add command to join any-source multicast.

Allow 'ip igmp join' to join group for any source if no source is
specified.
Disallow joining source "0.0.0.0" as it is used to define an
any-source multicast group.

Signed-off-by: Liam McBirnie <liam.mcbirnie@boeing.com>
This commit is contained in:
Liam McBirnie 2019-12-05 21:57:50 +01:00 committed by Liam McBirnie
parent 670812fd13
commit 771ce8ad24
4 changed files with 59 additions and 26 deletions

View File

@ -211,10 +211,10 @@ is in a vrf, enter the interface command with the vrf keyword at the end.
Tell pim to receive IGMP reports and Query on this interface. The default
version is v3. This command is useful on a LHR.
.. index:: ip igmp join A.B.C.D A.B.C.D
.. clicmd:: ip igmp join A.B.C.D A.B.C.D
.. index:: ip igmp join A.B.C.D [A.B.C.D]
.. clicmd:: ip igmp join A.B.C.D [A.B.C.D]
Join multicast source-group on an interface.
Join multicast group or source-group on an interface.
.. index:: ip igmp query-interval (1-1800)
.. clicmd:: ip igmp query-interval (1-1800)

View File

@ -6707,7 +6707,7 @@ DEFUN (interface_no_ip_igmp,
DEFUN (interface_ip_igmp_join,
interface_ip_igmp_join_cmd,
"ip igmp join A.B.C.D A.B.C.D",
"ip igmp join A.B.C.D [A.B.C.D]",
IP_STR
IFACE_IGMP_STR
"IGMP join multicast group\n"
@ -6733,12 +6733,21 @@ DEFUN (interface_ip_igmp_join,
}
/* Source address */
source_str = argv[idx_ipv4_2]->arg;
result = inet_pton(AF_INET, source_str, &source_addr);
if (result <= 0) {
vty_out(vty, "Bad source address %s: errno=%d: %s\n",
source_str, errno, safe_strerror(errno));
return CMD_WARNING_CONFIG_FAILED;
if (argc == (idx_ipv4_2 + 1)) {
source_str = argv[idx_ipv4_2]->arg;
result = inet_pton(AF_INET, source_str, &source_addr);
if (result <= 0) {
vty_out(vty, "Bad source address %s: errno=%d: %s\n",
source_str, errno, safe_strerror(errno));
return CMD_WARNING_CONFIG_FAILED;
}
/* Reject 0.0.0.0. Reserved for any source. */
if (source_addr.s_addr == INADDR_ANY) {
vty_out(vty, "Bad source address %s\n", source_str);
return CMD_WARNING_CONFIG_FAILED;
}
} else {
source_addr.s_addr = INADDR_ANY;
}
CMD_FERR_RETURN(pim_if_igmp_join_add(ifp, group_addr, source_addr),
@ -6749,7 +6758,7 @@ DEFUN (interface_ip_igmp_join,
DEFUN (interface_no_ip_igmp_join,
interface_no_ip_igmp_join_cmd,
"no ip igmp join A.B.C.D A.B.C.D",
"no ip igmp join A.B.C.D [A.B.C.D]",
NO_STR
IP_STR
IFACE_IGMP_STR
@ -6776,12 +6785,22 @@ DEFUN (interface_no_ip_igmp_join,
}
/* Source address */
source_str = argv[idx_ipv4_2]->arg;
result = inet_pton(AF_INET, source_str, &source_addr);
if (result <= 0) {
vty_out(vty, "Bad source address %s: errno=%d: %s\n",
source_str, errno, safe_strerror(errno));
return CMD_WARNING_CONFIG_FAILED;
if (argc == (idx_ipv4_2 + 1)) {
source_str = argv[idx_ipv4_2]->arg;
result = inet_pton(AF_INET, source_str, &source_addr);
if (result <= 0) {
vty_out(vty, "Bad source address %s: errno=%d: %s\n",
source_str, errno, safe_strerror(errno));
return CMD_WARNING_CONFIG_FAILED;
}
/* Reject 0.0.0.0. Reserved for any source. */
if (source_addr.s_addr == INADDR_ANY) {
vty_out(vty, "Bad source address %s\n", source_str);
return CMD_WARNING_CONFIG_FAILED;
}
} else {
source_str = "*";
source_addr.s_addr = INADDR_ANY;
}
result = pim_if_igmp_join_del(ifp, group_addr, source_addr);

View File

@ -26,6 +26,10 @@
#define SOL_IP IPPROTO_IP
#endif
#ifndef MCAST_JOIN_GROUP
#define MCAST_JOIN_GROUP 42
#endif
#ifndef MCAST_JOIN_SOURCE_GROUP
#define MCAST_JOIN_SOURCE_GROUP 46
struct group_source_req {
@ -58,8 +62,12 @@ static int pim_igmp_join_source(int fd, ifindex_t ifindex,
req.gsr_interface = ifindex;
return setsockopt(fd, SOL_IP, MCAST_JOIN_SOURCE_GROUP, &req,
sizeof(req));
if (source_addr.s_addr == INADDR_ANY)
return setsockopt(fd, SOL_IP, MCAST_JOIN_GROUP, &req,
sizeof(req));
else
return setsockopt(fd, SOL_IP, MCAST_JOIN_SOURCE_GROUP, &req,
sizeof(req));
}
#endif /* PIM_IGMP_JOIN_H */

View File

@ -379,13 +379,19 @@ int pim_interface_config_write(struct vty *vty)
ij->group_addr,
group_str,
sizeof(group_str));
inet_ntop(AF_INET,
&ij->source_addr,
source_str,
sizeof(source_str));
vty_out(vty,
" ip igmp join %s %s\n",
group_str, source_str);
if (ij->source_addr.s_addr == INADDR_ANY) {
vty_out(vty,
" ip igmp join %s\n",
group_str);
} else {
inet_ntop(AF_INET,
&ij->source_addr,
source_str,
sizeof(source_str));
vty_out(vty,
" ip igmp join %s %s\n",
group_str, source_str);
}
++writes;
}
}