diff options
Diffstat (limited to 'pimd/pim_pim.c')
| -rw-r--r-- | pimd/pim_pim.c | 145 |
1 files changed, 83 insertions, 62 deletions
diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c index 30dc6b3e92..82f735465a 100644 --- a/pimd/pim_pim.c +++ b/pimd/pim_pim.c @@ -42,7 +42,7 @@ #include "pim_errors.h" #include "pim_bsm.h" -static int on_pim_hello_send(struct thread *t); +static void on_pim_hello_send(struct thread *t); static const char *pim_pim_msgtype2str(enum pim_msg_type type) { @@ -138,31 +138,33 @@ void pim_sock_delete(struct interface *ifp, const char *delete_message) } /* For now check dst address for hello, assrt and join/prune is all pim rtr */ -static bool pim_pkt_dst_addr_ok(enum pim_msg_type type, in_addr_t addr) +static bool pim_pkt_dst_addr_ok(enum pim_msg_type type, pim_addr addr) { if ((type == PIM_MSG_TYPE_HELLO) || (type == PIM_MSG_TYPE_ASSERT) || (type == PIM_MSG_TYPE_JOIN_PRUNE)) { - if (addr != qpim_all_pim_routers_addr.s_addr) + if (pim_addr_cmp(addr, qpim_all_pim_routers_addr)) return false; } return true; } -int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len) +int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len, + pim_sgaddr sg) { - struct ip *ip_hdr; +#if PIM_IPV == 4 + struct ip *ip_hdr = (struct ip *)buf; size_t ip_hlen; /* ip header length in bytes */ - char src_str[INET_ADDRSTRLEN]; - char dst_str[INET_ADDRSTRLEN]; +#endif uint8_t *pim_msg; - int pim_msg_len; + uint32_t pim_msg_len = 0; uint16_t pim_checksum; /* received checksum */ uint16_t checksum; /* computed checksum */ struct pim_neighbor *neigh; struct pim_msg_header *header; bool no_fwd; +#if PIM_IPV == 4 if (len < sizeof(*ip_hdr)) { if (PIM_DEBUG_PIM_PACKETS) zlog_debug( @@ -171,11 +173,16 @@ int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len) return -1; } - ip_hdr = (struct ip *)buf; ip_hlen = ip_hdr->ip_hl << 2; /* ip_hl gives length in 4-byte words */ + sg = pim_sgaddr_from_iphdr(ip_hdr); pim_msg = buf + ip_hlen; pim_msg_len = len - ip_hlen; +#else + /* NB: header is not included in IPv6 RX */ + pim_msg = buf; + pim_msg_len = len; +#endif header = (struct pim_msg_header *)pim_msg; if (pim_msg_len < PIM_PIM_MIN_LEN) { @@ -235,43 +242,29 @@ int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len) } if (PIM_DEBUG_PIM_PACKETS) { - pim_inet4_dump("<src?>", ip_hdr->ip_src, src_str, - sizeof(src_str)); - pim_inet4_dump("<dst?>", ip_hdr->ip_dst, dst_str, - sizeof(dst_str)); zlog_debug( - "Recv PIM %s packet from %s to %s on %s: ttl=%d pim_version=%d pim_msg_size=%d checksum=%x", - pim_pim_msgtype2str(header->type), src_str, dst_str, - ifp->name, ip_hdr->ip_ttl, header->ver, pim_msg_len, - checksum); - if (PIM_DEBUG_PIM_PACKETDUMP_RECV) { + "Recv PIM %s packet from %pPA to %pPA on %s: pim_version=%d pim_msg_size=%d checksum=%x", + pim_pim_msgtype2str(header->type), &sg.src, &sg.grp, + ifp->name, header->ver, pim_msg_len, checksum); + if (PIM_DEBUG_PIM_PACKETDUMP_RECV) pim_pkt_dump(__func__, pim_msg, pim_msg_len); - } } - if (!pim_pkt_dst_addr_ok(header->type, ip_hdr->ip_dst.s_addr)) { - char dst_str[INET_ADDRSTRLEN]; - char src_str[INET_ADDRSTRLEN]; - - pim_inet4_dump("<dst?>", ip_hdr->ip_dst, dst_str, - sizeof(dst_str)); - pim_inet4_dump("<src?>", ip_hdr->ip_src, src_str, - sizeof(src_str)); + if (!pim_pkt_dst_addr_ok(header->type, sg.grp)) { zlog_warn( - "%s: Ignoring Pkt. Unexpected IP destination %s for %s (Expected: all_pim_routers_addr) from %s", - __func__, dst_str, pim_pim_msgtype2str(header->type), - src_str); + "%s: Ignoring Pkt. Unexpected IP destination %pPA for %s (Expected: all_pim_routers_addr) from %pPA", + __func__, &sg.grp, pim_pim_msgtype2str(header->type), + &sg.src); return -1; } switch (header->type) { case PIM_MSG_TYPE_HELLO: - return pim_hello_recv(ifp, ip_hdr->ip_src, - pim_msg + PIM_MSG_HEADER_LEN, + return pim_hello_recv(ifp, sg.src, pim_msg + PIM_MSG_HEADER_LEN, pim_msg_len - PIM_MSG_HEADER_LEN); break; case PIM_MSG_TYPE_REGISTER: - return pim_register_recv(ifp, ip_hdr->ip_dst, ip_hdr->ip_src, + return pim_register_recv(ifp, sg.grp, sg.src, pim_msg + PIM_MSG_HEADER_LEN, pim_msg_len - PIM_MSG_HEADER_LEN); break; @@ -280,38 +273,37 @@ int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len) pim_msg_len - PIM_MSG_HEADER_LEN); break; case PIM_MSG_TYPE_JOIN_PRUNE: - neigh = pim_neighbor_find(ifp, ip_hdr->ip_src); + neigh = pim_neighbor_find(ifp, sg.src); if (!neigh) { if (PIM_DEBUG_PIM_PACKETS) zlog_debug( - "%s %s: non-hello PIM message type=%d from non-neighbor %s on %s", + "%s %s: non-hello PIM message type=%d from non-neighbor %pPA on %s", __FILE__, __func__, header->type, - src_str, ifp->name); + &sg.src, ifp->name); return -1; } pim_neighbor_timer_reset(neigh, neigh->holdtime); - return pim_joinprune_recv(ifp, neigh, ip_hdr->ip_src, + return pim_joinprune_recv(ifp, neigh, sg.src, pim_msg + PIM_MSG_HEADER_LEN, pim_msg_len - PIM_MSG_HEADER_LEN); break; case PIM_MSG_TYPE_ASSERT: - neigh = pim_neighbor_find(ifp, ip_hdr->ip_src); + neigh = pim_neighbor_find(ifp, sg.src); if (!neigh) { if (PIM_DEBUG_PIM_PACKETS) zlog_debug( - "%s %s: non-hello PIM message type=%d from non-neighbor %s on %s", + "%s %s: non-hello PIM message type=%d from non-neighbor %pPA on %s", __FILE__, __func__, header->type, - src_str, ifp->name); + &sg.src, ifp->name); return -1; } pim_neighbor_timer_reset(neigh, neigh->holdtime); - return pim_assert_recv(ifp, neigh, ip_hdr->ip_src, + return pim_assert_recv(ifp, neigh, sg.src, pim_msg + PIM_MSG_HEADER_LEN, pim_msg_len - PIM_MSG_HEADER_LEN); break; case PIM_MSG_TYPE_BOOTSTRAP: - return pim_bsm_process(ifp, ip_hdr, pim_msg, pim_msg_len, - no_fwd); + return pim_bsm_process(ifp, &sg, pim_msg, pim_msg_len, no_fwd); break; default: @@ -326,13 +318,13 @@ int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len) static void pim_sock_read_on(struct interface *ifp); -static int pim_sock_read(struct thread *t) +static void pim_sock_read(struct thread *t) { struct interface *ifp, *orig_ifp; struct pim_interface *pim_ifp; int fd; - struct sockaddr_in from; - struct sockaddr_in to; + struct sockaddr_storage from; + struct sockaddr_storage to; socklen_t fromlen = sizeof(from); socklen_t tolen = sizeof(to); uint8_t buf[PIM_PIM_BUFSIZE_READ]; @@ -348,6 +340,8 @@ static int pim_sock_read(struct thread *t) pim_ifp = ifp->info; while (cont) { + pim_sgaddr sg; + len = pim_socket_recvfromto(fd, buf, sizeof(buf), &from, &fromlen, &to, &tolen, &ifindex); if (len < 0) { @@ -377,7 +371,15 @@ static int pim_sock_read(struct thread *t) ifindex); goto done; } - int fail = pim_pim_packet(ifp, buf, len); +#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 + + int fail = pim_pim_packet(ifp, buf, len, sg); if (fail) { if (PIM_DEBUG_PIM_PACKETS) zlog_debug("%s: pim_pim_packet() return=%d", @@ -398,8 +400,6 @@ done: if (result) { ++pim_ifp->pim_ifstat_hello_recvfail; } - - return result; } static void pim_sock_read_on(struct interface *ifp) @@ -430,7 +430,7 @@ static int pim_sock_open(struct interface *ifp) return -1; if (pim_socket_join(fd, qpim_all_pim_routers_addr, - pim_ifp->primary_address, ifp->ifindex)) { + pim_ifp->primary_address, ifp->ifindex, pim_ifp)) { close(fd); return -2; } @@ -454,6 +454,24 @@ void pim_ifstat_reset(struct interface *ifp) pim_ifp->pim_ifstat_hello_sendfail = 0; pim_ifp->pim_ifstat_hello_recv = 0; pim_ifp->pim_ifstat_hello_recvfail = 0; + pim_ifp->pim_ifstat_bsm_rx = 0; + pim_ifp->pim_ifstat_bsm_tx = 0; + pim_ifp->pim_ifstat_join_recv = 0; + pim_ifp->pim_ifstat_join_send = 0; + pim_ifp->pim_ifstat_prune_recv = 0; + pim_ifp->pim_ifstat_prune_send = 0; + pim_ifp->pim_ifstat_reg_recv = 0; + pim_ifp->pim_ifstat_reg_send = 0; + pim_ifp->pim_ifstat_reg_stop_recv = 0; + pim_ifp->pim_ifstat_reg_stop_send = 0; + pim_ifp->pim_ifstat_assert_recv = 0; + pim_ifp->pim_ifstat_assert_send = 0; + pim_ifp->pim_ifstat_bsm_cfg_miss = 0; + pim_ifp->pim_ifstat_ucast_bsm_cfg_miss = 0; + pim_ifp->pim_ifstat_bsm_invalid_sz = 0; + pim_ifp->igmp_ifstat_joins_sent = 0; + pim_ifp->igmp_ifstat_joins_failed = 0; + pim_ifp->igmp_peak_group_count = 0; } void pim_sock_reset(struct interface *ifp) @@ -508,7 +526,8 @@ static uint16_t ip_id = 0; static int pim_msg_send_frame(int fd, char *buf, size_t len, - struct sockaddr *dst, size_t salen) + struct sockaddr *dst, size_t salen, + const char *ifname) { struct ip *ip = (struct ip *)buf; @@ -524,8 +543,8 @@ static int pim_msg_send_frame(int fd, char *buf, size_t len, ip->ip_len = htons(sendlen); ip->ip_off = htons(offset | IP_MF); - if (pim_msg_send_frame(fd, buf, sendlen, dst, salen) - == 0) { + if (pim_msg_send_frame(fd, buf, sendlen, dst, salen, + ifname) == 0) { struct ip *ip2 = (struct ip *)(buf + newlen1); size_t newlen2 = len - sendlen; sendlen = newlen2 + hdrsize; @@ -534,7 +553,8 @@ static int pim_msg_send_frame(int fd, char *buf, size_t len, ip2->ip_len = htons(sendlen); ip2->ip_off = htons(offset + (newlen1 >> 3)); return pim_msg_send_frame(fd, (char *)ip2, - sendlen, dst, salen); + sendlen, dst, salen, + ifname); } } @@ -544,9 +564,9 @@ static int pim_msg_send_frame(int fd, char *buf, size_t len, pim_inet4_dump("<dst?>", ip->ip_dst, dst_str, sizeof(dst_str)); zlog_warn( - "%s: sendto() failure to %s: fd=%d msg_size=%zd: errno=%d: %s", - __func__, dst_str, fd, len, errno, - safe_strerror(errno)); + "%s: sendto() failure to %s: iface=%s fd=%d msg_size=%zd: errno=%d: %s", + __func__, dst_str, ifname, fd, len, + errno, safe_strerror(errno)); } return -1; } @@ -555,8 +575,8 @@ static int pim_msg_send_frame(int fd, char *buf, size_t len, return 0; } -int pim_msg_send(int fd, struct in_addr src, struct in_addr dst, - uint8_t *pim_msg, int pim_msg_size, const char *ifname) +int pim_msg_send(int fd, pim_addr src, pim_addr dst, uint8_t *pim_msg, + int pim_msg_size, const char *ifname) { struct sockaddr_in to; socklen_t tolen; @@ -628,7 +648,7 @@ int pim_msg_send(int fd, struct in_addr src, struct in_addr dst, } pim_msg_send_frame(fd, (char *)buffer, sendlen, (struct sockaddr *)&to, - tolen); + tolen, ifname); return 0; } @@ -706,6 +726,7 @@ int pim_hello_send(struct interface *ifp, uint16_t holdtime) } ++pim_ifp->pim_ifstat_hello_sent; + PIM_IF_FLAG_SET_HELLO_SENT(pim_ifp->flags); return 0; } @@ -729,7 +750,7 @@ static void hello_resched(struct interface *ifp) /* Periodic hello timer */ -static int on_pim_hello_send(struct thread *t) +static void on_pim_hello_send(struct thread *t) { struct pim_interface *pim_ifp; struct interface *ifp; @@ -745,7 +766,7 @@ static int on_pim_hello_send(struct thread *t) /* * Send hello */ - return pim_hello_send(ifp, PIM_IF_DEFAULT_HOLDTIME(pim_ifp)); + pim_hello_send(ifp, PIM_IF_DEFAULT_HOLDTIME(pim_ifp)); } /* |
