X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=pimd%2Fpim_igmp.c;h=3602d98a3ea3de930f2c5461553c5d5a0b6631ce;hb=0dcbec72aa2b508c194ec4391b6d821ea996fb08;hp=8a2efd41adbc86678b545744441eaee175f680e2;hpb=13894ce894b91f4242da3edce8f1cb0448b47f3d;p=mirror_frr.git diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c index 8a2efd41a..3602d98a3 100644 --- a/pimd/pim_igmp.c +++ b/pimd/pim_igmp.c @@ -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); + } +}