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:
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);
}
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;
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);
+ }
+}