]> git.proxmox.com Git - mirror_frr.git/blobdiff - pimd/pim_igmp.c
Merge pull request #5498 from mjstapp/sharp_with_labels
[mirror_frr.git] / pimd / pim_igmp.c
index 8a2efd41adbc86678b545744441eaee175f680e2..3602d98a3ea3de930f2c5461553c5d5a0b6631ce 100644 (file)
@@ -250,8 +250,8 @@ void pim_igmp_other_querier_timer_on(struct igmp_sock *igmp)
                        other_querier_present_interval_msec % 1000);
        }
 
-       thread_add_timer_msec(master, pim_igmp_other_querier_expire, igmp,
-                             other_querier_present_interval_msec,
+       thread_add_timer_msec(router->master, pim_igmp_other_querier_expire,
+                             igmp, other_querier_present_interval_msec,
                              &igmp->t_other_querier_timer);
 }
 
@@ -305,6 +305,20 @@ static int igmp_recv_query(struct igmp_sock *igmp, int query_version,
                return -1;
        }
 
+       if (!pim_if_connected_to_source(ifp, from)) {
+               if (PIM_DEBUG_IGMP_PACKETS)
+                       zlog_debug("Recv IGMP query on interface: %s from a non-connected source: %s",
+                                  ifp->name, from_str);
+               return 0;
+       }
+
+       if (if_lookup_address(&from, AF_INET, ifp->vrf_id)) {
+               if (PIM_DEBUG_IGMP_PACKETS)
+                       zlog_debug("Recv IGMP query on interface: %s from ourself %s",
+                                  ifp->name, from_str);
+               return 0;
+       }
+
        /* Collecting IGMP Rx stats */
        switch (query_version) {
        case 1:
@@ -464,21 +478,14 @@ int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len)
 
        ip_hlen = ip_hdr->ip_hl << 2; /* ip_hl gives length in 4-byte words */
 
-       if (PIM_DEBUG_IGMP_PACKETS) {
-               zlog_debug(
-                       "Recv IP packet from %s to %s on %s: size=%zu ip_header_size=%zu ip_proto=%d",
-                       from_str, to_str, igmp->interface->name, len, ip_hlen,
-                       ip_hdr->ip_p);
-       }
-
        igmp_msg = buf + ip_hlen;
        msg_type = *igmp_msg;
        igmp_msg_len = len - ip_hlen;
 
        if (PIM_DEBUG_IGMP_PACKETS) {
                zlog_debug(
-                       "Recv IGMP packet from %s to %s on %s: ttl=%d msg_type=%d msg_size=%d",
-                       from_str, to_str, igmp->interface->name, ip_hdr->ip_ttl,
+                       "Recv IGMP packet from %s to %s on %s: size=%zu ttl=%d msg_type=%d msg_size=%d",
+                       from_str, to_str, igmp->interface->name, len, ip_hdr->ip_ttl,
                        msg_type, igmp_msg_len);
        }
 
@@ -603,8 +610,8 @@ void pim_igmp_general_query_on(struct igmp_sock *igmp)
                        startup_mode ? "startup" : "non-startup", igmp->fd);
        }
        igmp->t_igmp_query_timer = NULL;
-       thread_add_timer(master, pim_igmp_general_query, igmp, query_interval,
-                        &igmp->t_igmp_query_timer);
+       thread_add_timer(router->master, pim_igmp_general_query, igmp,
+                        query_interval, &igmp->t_igmp_query_timer);
 }
 
 void pim_igmp_general_query_off(struct igmp_sock *igmp)
@@ -741,7 +748,7 @@ static void igmp_group_free(struct igmp_group *group)
        XFREE(MTYPE_PIM_IGMP_GROUP, group);
 }
 
-static void igmp_group_delete(struct igmp_group *group)
+void igmp_group_delete(struct igmp_group *group)
 {
        struct listnode *src_node;
        struct listnode *src_nextnode;
@@ -829,22 +836,22 @@ void igmp_sock_delete_all(struct interface *ifp)
        }
 }
 
-static unsigned int igmp_group_hash_key(void *arg)
+static unsigned int igmp_group_hash_key(const void *arg)
 {
-       struct igmp_group *group = (struct igmp_group *)arg;
+       const struct igmp_group *group = arg;
 
        return jhash_1word(group->group_addr.s_addr, 0);
 }
 
-static int igmp_group_hash_equal(const void *arg1, const void *arg2)
+static bool igmp_group_hash_equal(const void *arg1, const void *arg2)
 {
        const struct igmp_group *g1 = (const struct igmp_group *)arg1;
        const struct igmp_group *g2 = (const struct igmp_group *)arg2;
 
        if (g1->group_addr.s_addr == g2->group_addr.s_addr)
-               return 1;
+               return true;
 
-       return 0;
+       return false;
 }
 
 static struct igmp_sock *igmp_sock_new(int fd, struct in_addr ifaddr,
@@ -940,7 +947,7 @@ static void igmp_read_on(struct igmp_sock *igmp)
                           igmp->fd);
        }
        igmp->t_igmp_read = NULL;
-       thread_add_read(master, pim_igmp_read, igmp, igmp->fd,
+       thread_add_read(router->master, pim_igmp_read, igmp, igmp->fd,
                        &igmp->t_igmp_read);
 }
 
@@ -1067,8 +1074,8 @@ void igmp_group_timer_on(struct igmp_group *group, long interval_msec,
        */
        zassert(group->group_filtermode_isexcl);
 
-       thread_add_timer_msec(master, igmp_group_timer, group, interval_msec,
-                             &group->t_group_timer);
+       thread_add_timer_msec(router->master, igmp_group_timer, group,
+                             interval_msec, &group->t_group_timer);
 }
 
 struct igmp_group *find_group_by_addr(struct igmp_sock *igmp,
@@ -1180,3 +1187,42 @@ void igmp_send_query(int igmp_version, struct igmp_group *group, int fd,
                                   group_addr, query_max_response_time_dsec);
        }
 }
+
+void igmp_send_query_on_intf(struct interface *ifp, int igmp_ver)
+{
+       struct pim_interface *pim_ifp = ifp->info;
+       struct listnode *sock_node = NULL;
+       struct igmp_sock *igmp = NULL;
+       struct in_addr dst_addr;
+       struct in_addr group_addr;
+       int query_buf_size;
+
+       if (!igmp_ver)
+               igmp_ver = 2;
+
+       if (igmp_ver == 3)
+               query_buf_size = PIM_IGMP_BUFSIZE_WRITE;
+       else
+               query_buf_size = IGMP_V12_MSG_SIZE;
+
+       dst_addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP);
+       group_addr.s_addr = PIM_NET_INADDR_ANY;
+
+       if (PIM_DEBUG_IGMP_TRACE)
+               zlog_debug("Issuing general query on request on %s",
+                               ifp->name);
+
+       for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
+
+               char query_buf[query_buf_size];
+
+               igmp_send_query(igmp_ver, 0 /* igmp_group */, igmp->fd,
+                               igmp->interface->name, query_buf,
+                               sizeof(query_buf), 0 /* num_sources */,
+                               dst_addr, group_addr,
+                               pim_ifp->igmp_query_max_response_time_dsec,
+                               1 /* s_flag: always set for general queries */,
+                               igmp->querier_robustness_variable,
+                               igmp->querier_query_interval);
+       }
+}