#include "if.h"
#include "hash.h"
#include "jhash.h"
+#include "lib_errors.h"
#include "pimd.h"
#include "pim_igmp.h"
}
if (!join) {
- zlog_err(
+ flog_err_sys(
+ EC_LIB_SOCKET,
"IGMP socket fd=%d could not join any group on interface address %s",
fd, inet_ntoa(ifaddr));
close(fd);
uint16_t recv_checksum;
uint16_t checksum;
+ if (igmp->mtrace_only)
+ return 0;
+
memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr));
ifp = igmp->interface;
return -1;
}
+ /* Collecting IGMP Rx stats */
+ switch (query_version) {
+ case 1:
+ igmp->rx_stats.query_v1++;
+ break;
+ case 2:
+ igmp->rx_stats.query_v2++;
+ break;
+ case 3:
+ igmp->rx_stats.query_v3++;
+ break;
+ default:
+ igmp->rx_stats.unsupported++;
+ }
+
/*
* RFC 3376 defines some guidelines on operating in backwards
* compatibility with older versions of IGMP but there are some gaps in
on_trace(__PRETTY_FUNCTION__, igmp->interface, from);
+ if (igmp->mtrace_only)
+ return 0;
+
if (igmp_msg_len != IGMP_V12_MSG_SIZE) {
zlog_warn(
"Recv IGMP report v1 from %s on %s: size=%d other than correct=%d",
return -1;
}
+ /* Collecting IGMP Rx stats */
+ igmp->rx_stats.report_v1++;
+
if (PIM_DEBUG_IGMP_TRACE) {
zlog_warn("%s %s: FIXME WRITEME", __FILE__,
__PRETTY_FUNCTION__);
return igmp_mtrace_recv_response(igmp, ip_hdr, ip_hdr->ip_src,
from_str, igmp_msg,
igmp_msg_len);
- break;
case PIM_IGMP_MTRACE_QUERY_REQUEST:
return igmp_mtrace_recv_qry_req(igmp, ip_hdr, ip_hdr->ip_src,
from_str, igmp_msg,
zlog_warn("Ignoring unsupported IGMP message type: %d", msg_type);
+ /* Collecting IGMP Rx stats */
+ igmp->rx_stats.unsupported++;
+
return -1;
}
THREAD_OFF(igmp->t_igmp_read);
if (close(igmp->fd)) {
- zlog_err(
+ flog_err(
+ EC_LIB_SOCKET,
"Failure closing IGMP socket %s fd=%d on interface %s: errno=%d: %s",
inet_ntoa(igmp->ifaddr), igmp->fd,
igmp->interface->name, errno, safe_strerror(errno));
static void igmp_group_free(struct igmp_group *group)
{
- list_delete_and_null(&group->group_source_list);
+ list_delete(&group->group_source_list);
XFREE(MTYPE_PIM_IGMP_GROUP, group);
}
zassert(igmp->igmp_group_list);
zassert(!listcount(igmp->igmp_group_list));
- list_delete_and_null(&igmp->igmp_group_list);
+ list_delete(&igmp->igmp_group_list);
hash_free(igmp->igmp_group_hash);
XFREE(MTYPE_PIM_IGMP_SOCKET, igmp);
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,
- struct interface *ifp)
+ struct interface *ifp, int mtrace_only)
{
struct pim_interface *pim_ifp;
struct igmp_sock *igmp;
}
igmp = XCALLOC(MTYPE_PIM_IGMP_SOCKET, sizeof(*igmp));
- if (!igmp) {
- zlog_warn("%s %s: XCALLOC() failure", __FILE__,
- __PRETTY_FUNCTION__);
- return 0;
- }
igmp->igmp_group_list = list_new();
- if (!igmp->igmp_group_list) {
- zlog_err("%s %s: failure: igmp_group_list = list_new()",
- __FILE__, __PRETTY_FUNCTION__);
- return 0;
- }
igmp->igmp_group_list->del = (void (*)(void *))igmp_group_free;
snprintf(hash_name, 64, "IGMP %s hash", ifp->name);
pim_ifp->igmp_default_robustness_variable;
igmp->sock_creation = pim_time_monotonic_sec();
+ igmp_stats_init(&igmp->rx_stats);
+
+ if (mtrace_only) {
+ igmp->mtrace_only = mtrace_only;
+ return igmp;
+ }
+
+ igmp->mtrace_only = false;
+
/*
igmp_startup_mode_on() will reset QQI:
socklen_t fromlen = sizeof(from);
socklen_t tolen = sizeof(to);
ifindex_t ifindex = -1;
- int cont = 1;
int len;
- while (cont) {
+ while (1) {
len = pim_socket_recvfromto(igmp->fd, buf, sizeof(buf), &from,
&fromlen, &to, &tolen, &ifindex);
if (len < 0) {
struct igmp_sock *pim_igmp_sock_add(struct list *igmp_sock_list,
struct in_addr ifaddr,
- struct interface *ifp)
+ struct interface *ifp,
+ bool mtrace_only)
{
struct pim_interface *pim_ifp;
struct igmp_sock *igmp;
return 0;
}
- igmp = igmp_sock_new(fd, ifaddr, ifp);
- if (!igmp) {
- zlog_err("%s %s: igmp_sock_new() failure", __FILE__,
- __PRETTY_FUNCTION__);
- close(fd);
- return 0;
- }
+ igmp = igmp_sock_new(fd, ifaddr, ifp, mtrace_only);
igmp_read_on(igmp);
*/
group = XCALLOC(MTYPE_PIM_IGMP_GROUP, sizeof(*group));
- if (!group) {
- zlog_warn("%s %s: XCALLOC() failure", __FILE__,
- __PRETTY_FUNCTION__);
- return NULL; /* error, not found, could not create */
- }
group->group_source_list = list_new();
- if (!group->group_source_list) {
- zlog_warn("%s %s: list_new() failure", __FILE__,
- __PRETTY_FUNCTION__);
- XFREE(MTYPE_PIM_IGMP_GROUP, group); /* discard group */
- return NULL; /* error, not found, could not initialize */
- }
group->group_source_list->del = (void (*)(void *))igmp_source_free;
group->t_group_timer = NULL;