]> git.proxmox.com Git - mirror_frr.git/commitdiff
pimd: IGMP conformance 5.10 test case is failing
authorMobashshera Rasool <mrasool@vmware.com>
Thu, 17 Dec 2020 11:40:13 +0000 (11:40 +0000)
committerMobashshera Rasool <mrasool@vmware.com>
Thu, 24 Dec 2020 06:39:12 +0000 (06:39 +0000)
Test case 5.10 sends leave message to unicast address, the leave
packet is accepted and a query message is sent in response to this.
No validation for address is present in the function

Add check for addresses as per RFC. Leave messages are allowed only
sent to either ALL-ROUTERS (224.0.0.2) or group address.

Signed-off-by: Mobashshera Rasool <mrasool@vmware.com>
pimd/pim_igmp.c
pimd/pim_igmpv2.c
pimd/pim_igmpv2.h

index 9924e335b00839a82d6da220582b337dd1677604..73e42e9d83867785bc9830a3471bb8c787851dca 100644 (file)
@@ -558,8 +558,8 @@ int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len)
                                           igmp_msg, igmp_msg_len);
 
        case PIM_IGMP_V2_LEAVE_GROUP:
-               return igmp_v2_recv_leave(igmp, ip_hdr->ip_src, from_str,
-                                         igmp_msg, igmp_msg_len);
+               return igmp_v2_recv_leave(igmp, ip_hdr, from_str, igmp_msg,
+                                         igmp_msg_len);
 
        case PIM_IGMP_MTRACE_RESPONSE:
                return igmp_mtrace_recv_response(igmp, ip_hdr, ip_hdr->ip_src,
index d836c66cbbc5d91c2f53bcb9d9506c2f7ed1bbc9..7f3c7a0f8cb8c0902b6d42b8e9fbfe764b8a924b 100644 (file)
@@ -158,12 +158,13 @@ int igmp_v2_recv_report(struct igmp_sock *igmp, struct in_addr from,
        return 0;
 }
 
-int igmp_v2_recv_leave(struct igmp_sock *igmp, struct in_addr from,
+int igmp_v2_recv_leave(struct igmp_sock *igmp, struct ip *ip_hdr,
                       const char *from_str, char *igmp_msg, int igmp_msg_len)
 {
        struct interface *ifp = igmp->interface;
        struct in_addr group_addr;
        char group_str[INET_ADDRSTRLEN];
+       struct in_addr from = ip_hdr->ip_src;
 
        on_trace(__func__, igmp->interface, from);
 
@@ -184,8 +185,6 @@ int igmp_v2_recv_leave(struct igmp_sock *igmp, struct in_addr from,
                return -1;
        }
 
-       /* Collecting IGMP Rx stats */
-       igmp->rx_stats.leave_v2++;
 
        memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr));
 
@@ -195,6 +194,32 @@ int igmp_v2_recv_leave(struct igmp_sock *igmp, struct in_addr from,
                zlog_debug("Recv IGMPv2 LEAVE from %s on %s for %s", from_str,
                           ifp->name, group_str);
        }
+       /*
+        * As per RFC 2236, section 9:
+        Message Type                  Destination Group
+        ------------                  -----------------
+        General Query                 ALL-SYSTEMS (224.0.0.1)
+        Group-Specific Query          The group being queried
+        Membership Report             The group being reported
+        Leave Message                 ALL-ROUTERS (224.0.0.2)
+
+        Note: in older (i.e., non-standard and now obsolete) versions of
+        IGMPv2, hosts send Leave Messages to the group being left.  A
+        router SHOULD accept Leave Messages addressed to the group being
+        left in the interests of backwards compatibility with such hosts.
+        In all cases, however, hosts MUST send to the ALL-ROUTERS address
+        to be compliant with this specification.
+       */
+       if ((ntohl(ip_hdr->ip_dst.s_addr) != INADDR_ALLRTRS_GROUP)
+           && (ip_hdr->ip_dst.s_addr != group_addr.s_addr)) {
+               if (PIM_DEBUG_IGMP_EVENTS)
+                       zlog_debug(
+                               "IGMPv2 Leave message is ignored since received on address other than ALL-ROUTERS or Group-address");
+               return -1;
+       }
+
+       /* Collecting IGMP Rx stats */
+       igmp->rx_stats.leave_v2++;
 
        /*
         * RFC 3376
index f0a6fdc5fb31708d68d2146ce5e8141f8e542c53..29591ff16cb12ade7c6bdd8acf799c123af5b68a 100644 (file)
@@ -29,7 +29,7 @@ void igmp_v2_send_query(struct igmp_group *group, int fd, const char *ifname,
 int igmp_v2_recv_report(struct igmp_sock *igmp, struct in_addr from,
                        const char *from_str, char *igmp_msg, int igmp_msg_len);
 
-int igmp_v2_recv_leave(struct igmp_sock *igmp, struct in_addr from,
+int igmp_v2_recv_leave(struct igmp_sock *igmp, struct ip *ip_hdr,
                       const char *from_str, char *igmp_msg, int igmp_msg_len);
 
 #endif /* PIM_IGMPV2_H */