diff --git a/pimd/pim_bsm.c b/pimd/pim_bsm.c index cc19c1a777a6..dc921ef73e2b 100644 --- a/pimd/pim_bsm.c +++ b/pimd/pim_bsm.c @@ -258,66 +258,11 @@ static inline void pim_bs_timer_restart(struct bsm_scope *scope, int bs_timeout) static void bsm_unicast_sock_read(struct event *t) { struct bsm_scope *scope = EVENT_ARG(t); - struct sockaddr_storage from; - struct sockaddr_storage to; - socklen_t fromlen = sizeof(from); - socklen_t tolen = sizeof(to); - ifindex_t ifindex = 0; - struct interface *ifp; - uint8_t buf[PIM_PIM_BUFSIZE_READ]; - int len, i; + + pim_sock_read_helper(scope->unicast_sock, scope->pim, false); event_add_read(router->master, bsm_unicast_sock_read, scope, scope->unicast_sock, &scope->unicast_read); - - for (i = 0; i < router->packet_process; i++) { - pim_sgaddr sg; - - len = pim_socket_recvfromto(scope->unicast_sock, buf, - sizeof(buf), &from, &fromlen, &to, - &tolen, &ifindex); - if (len < 0) { - if (errno == EINTR) - continue; - if (errno == EWOULDBLOCK || errno == EAGAIN) - break; - - if (PIM_DEBUG_PIM_PACKETS) - zlog_debug("Received errno: %d %s", errno, - safe_strerror(errno)); - break; - } - -#if PIM_IPV == 4 - sg.src = ((struct sockaddr_in *)&from)->sin_addr; - sg.grp = ((struct sockaddr_in *)&to)->sin_addr; -#else - sg.src = ((struct sockaddr_in6 *)&from)->sin6_addr; - sg.grp = ((struct sockaddr_in6 *)&to)->sin6_addr; -#endif - - /* - * What? So with vrf's the incoming packet is received - * on the vrf interface but recvfromto above returns - * the right ifindex, so just use it. We know - * it's the right interface because we bind to it - */ - ifp = if_lookup_by_index(ifindex, scope->pim->vrf->vrf_id); - if (!ifp) { - zlog_warn("Received incoming PIM packet on unknown ifindex %d", - ifindex); - break; - } - - int fail = pim_pim_packet(ifp, buf, len, sg, false); - - if (fail) { - if (PIM_DEBUG_PIM_PACKETS) - zlog_debug("%s: pim_pim_packet() return=%d", - __func__, fail); - break; - } - } } void pim_bsm_proc_init(struct pim_instance *pim) diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c index e70abab1b93d..a41bbacea799 100644 --- a/pimd/pim_pim.c +++ b/pimd/pim_pim.c @@ -13,7 +13,6 @@ #include "network.h" #include "pimd.h" -#include "pim_instance.h" #include "pim_pim.h" #include "pim_time.h" #include "pim_iface.h" @@ -355,13 +354,9 @@ int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len, } } -static void pim_sock_read_on(struct interface *ifp); - -static void pim_sock_read(struct event *t) +int pim_sock_read_helper(int fd, struct pim_instance *pim, bool is_mcast) { - struct interface *ifp, *orig_ifp; - struct pim_interface *pim_ifp; - int fd; + struct interface *ifp = NULL; struct sockaddr_storage from; struct sockaddr_storage to; socklen_t fromlen = sizeof(from); @@ -369,16 +364,9 @@ static void pim_sock_read(struct event *t) uint8_t buf[PIM_PIM_BUFSIZE_READ]; int len; ifindex_t ifindex = -1; - int result = -1; /* defaults to bad */ - static long long count = 0; - int cont = 1; - - orig_ifp = ifp = EVENT_ARG(t); - fd = EVENT_FD(t); - - pim_ifp = ifp->info; + int i; - while (cont) { + for (i = 0; i < router->packet_process; i++) { pim_sgaddr sg; len = pim_socket_recvfromto(fd, buf, sizeof(buf), &from, @@ -392,7 +380,7 @@ static void pim_sock_read(struct event *t) if (PIM_DEBUG_PIM_PACKETS) zlog_debug("Received errno: %d %s", errno, safe_strerror(errno)); - goto done; + return -1; } /* @@ -401,14 +389,21 @@ static void pim_sock_read(struct event *t) * the right ifindex, so just use it. We know * it's the right interface because we bind to it */ - ifp = if_lookup_by_index(ifindex, pim_ifp->pim->vrf->vrf_id); - if (!ifp || !ifp->info) { + if (pim != NULL) + ifp = if_lookup_by_index(ifindex, pim->vrf->vrf_id); + + /* + * unicast BSM pkts (C-RP) may arrive on non pim interfaces + * mcast pkts are only expected in pim interfaces + */ + if (!ifp || (is_mcast && !ifp->info)) { if (PIM_DEBUG_PIM_PACKETS) - zlog_debug( - "%s: Received incoming pim packet on interface(%s:%d) not yet configured for pim", - __func__, ifp ? ifp->name : "Unknown", - ifindex); - goto done; + zlog_debug("%s: Received incoming pim packet on interface(%s:%d)%s", + __func__, + ifp ? ifp->name : "Unknown", ifindex, + is_mcast ? " not yet configured for pim" + : ""); + return -1; } #if PIM_IPV == 4 sg.src = ((struct sockaddr_in *)&from)->sin_addr; @@ -418,27 +413,34 @@ static void pim_sock_read(struct event *t) sg.grp = ((struct sockaddr_in6 *)&to)->sin6_addr; #endif - int fail = pim_pim_packet(ifp, buf, len, sg, true); + int fail = pim_pim_packet(ifp, buf, len, sg, is_mcast); if (fail) { if (PIM_DEBUG_PIM_PACKETS) zlog_debug("%s: pim_pim_packet() return=%d", __func__, fail); - goto done; + return -1; } - - count++; - if (count % router->packet_process == 0) - cont = 0; } + return 0; +} + +static void pim_sock_read_on(struct interface *ifp); + +static void pim_sock_read(struct event *t) +{ + struct interface *ifp; + struct pim_interface *pim_ifp; + int fd; - result = 0; /* good */ + ifp = EVENT_ARG(t); + fd = EVENT_FD(t); -done: - pim_sock_read_on(orig_ifp); + pim_ifp = ifp->info; - if (result) { + if (pim_sock_read_helper(fd, pim_ifp->pim, true) == 0) ++pim_ifp->pim_ifstat_hello_recvfail; - } + + pim_sock_read_on(ifp); } static void pim_sock_read_on(struct interface *ifp) diff --git a/pimd/pim_pim.h b/pimd/pim_pim.h index 13ccbb81b317..39b27bceda37 100644 --- a/pimd/pim_pim.h +++ b/pimd/pim_pim.h @@ -10,6 +10,7 @@ #include #include "if.h" +#include "pim_instance.h" #define PIM_PIM_BUFSIZE_READ (20000) #define PIM_PIM_BUFSIZE_WRITE (20000) @@ -48,4 +49,6 @@ int pim_msg_send(int fd, pim_addr src, pim_addr dst, uint8_t *pim_msg, int pim_msg_size, struct interface *ifp); int pim_hello_send(struct interface *ifp, uint16_t holdtime); + +int pim_sock_read_helper(int fd, struct pim_instance *pim, bool is_mcast); #endif /* PIM_PIM_H */