diff --git a/pimd/pim_assert.c b/pimd/pim_assert.c index 4443e4459a..1add2ebb00 100644 --- a/pimd/pim_assert.c +++ b/pimd/pim_assert.c @@ -474,6 +474,7 @@ static int pim_assert_do(struct pim_ifchannel *ch, } if (pim_msg_send(pim_ifp->pim_sock_fd, + pim_ifp->primary_address, qpim_all_pim_routers_addr, pim_msg, pim_msg_size, diff --git a/pimd/pim_join.c b/pimd/pim_join.c index 80e77ecb32..c7d54d3c04 100644 --- a/pimd/pim_join.c +++ b/pimd/pim_join.c @@ -434,6 +434,7 @@ int pim_joinprune_send(struct interface *ifp, return pim_msg_size; if (pim_msg_send(pim_ifp->pim_sock_fd, + pim_ifp->primary_address, qpim_all_pim_routers_addr, pim_msg, pim_msg_size, diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index a17a8b1006..65696f6d33 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -218,7 +218,8 @@ pim_mroute_msg_wholepkt (int fd, struct interface *ifp, const char *buf) * If we've received a register suppress */ if (!up->t_rs_timer) - pim_register_send((uint8_t *)buf + sizeof(struct ip), ntohs (ip_hdr->ip_len), rpg, 0); + pim_register_send((uint8_t *)buf + sizeof(struct ip), ntohs (ip_hdr->ip_len), + pim_ifp->primary_address, rpg, 0); return 0; } @@ -357,9 +358,12 @@ pim_mroute_msg_wrvifwhole (int fd, struct interface *ifp, const char *buf) if (!up->fhr) { struct pim_nexthop source; + struct pim_rpf *rpf = RP (sg.grp); + pim_ifp = rpf->source_nexthop.interface->info; + //No if channel, but upstream we are at the RP. pim_nexthop_lookup (&source, up->upstream_register); - pim_register_stop_send(source.interface, &sg, up->upstream_register); + pim_register_stop_send(source.interface, &sg, pim_ifp->primary_address, up->upstream_register); //Send S bit down the join. up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE; } diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c index 382c9bc46d..f58e326d16 100644 --- a/pimd/pim_pim.c +++ b/pimd/pim_pim.c @@ -480,7 +480,10 @@ void pim_sock_reset(struct interface *ifp) pim_ifstat_reset(ifp); } +static uint16_t ip_id = 0; + int pim_msg_send(int fd, + struct in_addr src, struct in_addr dst, uint8_t *pim_msg, int pim_msg_size, @@ -489,6 +492,25 @@ int pim_msg_send(int fd, ssize_t sent; struct sockaddr_in to; socklen_t tolen; + unsigned char buffer[3000]; + unsigned char *msg_start; + struct ip *ip; + + memset (buffer, 0, 3000); + int sendlen = sizeof (struct ip) + pim_msg_size; + + msg_start = buffer + sizeof (struct ip); + memcpy (msg_start, pim_msg, pim_msg_size); + + ip = (struct ip *)buffer; + ip->ip_id = htons (++ip_id); + ip->ip_hl = 5; + ip->ip_v = 4; + ip->ip_p = PIM_IP_PROTO_PIM; + ip->ip_src = src; + ip->ip_dst = dst; + ip->ip_ttl = MAXTTL; + ip->ip_len = htons (sendlen); if (PIM_DEBUG_PIM_PACKETS) { char dst_str[100]; @@ -508,9 +530,9 @@ int pim_msg_send(int fd, pim_pkt_dump(__PRETTY_FUNCTION__, pim_msg, pim_msg_size); } - sent = sendto(fd, pim_msg, pim_msg_size, MSG_DONTWAIT, + sent = sendto(fd, buffer, sendlen, MSG_DONTWAIT, (struct sockaddr *)&to, tolen); - if (sent != (ssize_t) pim_msg_size) { + if (sent != (ssize_t) sendlen) { char dst_str[100]; pim_inet4_dump("", dst, dst_str, sizeof(dst_str)); if (sent < 0) { @@ -577,6 +599,7 @@ static int hello_send(struct interface *ifp, PIM_MSG_TYPE_HELLO); if (pim_msg_send(pim_ifp->pim_sock_fd, + pim_ifp->primary_address, qpim_all_pim_routers_addr, pim_msg, pim_msg_size, @@ -759,6 +782,8 @@ int pim_sock_add(struct interface *ifp) return -2; } + pim_socket_ip_hdr (pim_ifp->pim_sock_fd); + pim_ifp->t_pim_sock_read = NULL; pim_ifp->pim_sock_creation = pim_time_monotonic_sec(); diff --git a/pimd/pim_pim.h b/pimd/pim_pim.h index 01c9044a26..fad572a125 100644 --- a/pimd/pim_pim.h +++ b/pimd/pim_pim.h @@ -70,6 +70,7 @@ void pim_hello_restart_triggered(struct interface *ifp); int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len); int pim_msg_send(int fd, + struct in_addr src, struct in_addr dst, uint8_t *pim_msg, int pim_msg_size, diff --git a/pimd/pim_register.c b/pimd/pim_register.c index 4cc4a2703c..bd41f1f4f0 100644 --- a/pimd/pim_register.c +++ b/pimd/pim_register.c @@ -46,7 +46,7 @@ struct thread *send_test_packet_timer = NULL; void pim_register_stop_send (struct interface *ifp, struct prefix_sg *sg, - struct in_addr originator) + struct in_addr src, struct in_addr originator) { struct pim_interface *pinfo; unsigned char buffer[3000]; @@ -83,7 +83,7 @@ pim_register_stop_send (struct interface *ifp, struct prefix_sg *sg, zlog_debug ("%s: No pinfo!\n", __PRETTY_FUNCTION__); return; } - if (pim_msg_send (pinfo->pim_sock_fd, originator, + if (pim_msg_send (pinfo->pim_sock_fd, src, originator, buffer, b1length + PIM_MSG_REGISTER_STOP_LEN, ifp->name)) { @@ -145,7 +145,7 @@ pim_register_stop_recv (uint8_t *buf, int buf_size) } void -pim_register_send (const uint8_t *buf, int buf_size, struct pim_rpf *rpg, int null_register) +pim_register_send (const uint8_t *buf, int buf_size, struct in_addr src, struct pim_rpf *rpg, int null_register) { unsigned char buffer[3000]; unsigned char *b1; @@ -176,6 +176,7 @@ pim_register_send (const uint8_t *buf, int buf_size, struct pim_rpf *rpg, int nu pim_msg_build_header(buffer, buf_size + PIM_MSG_REGISTER_LEN, PIM_MSG_TYPE_REGISTER); if (pim_msg_send(pinfo->pim_sock_fd, + src, rpg->rpf_addr, buffer, buf_size + PIM_MSG_REGISTER_LEN, @@ -306,7 +307,7 @@ pim_register_recv (struct interface *ifp, if (pimbr.s_addr == pim_br_unknown.s_addr) pim_br_set_pmbr(&sg, src_addr); else if (src_addr.s_addr != pimbr.s_addr) { - pim_register_stop_send (ifp, &sg, src_addr); + pim_register_stop_send (ifp, &sg, dest_addr, src_addr); if (PIM_DEBUG_PIM_PACKETS) zlog_debug("%s: Sending register-Stop to %s and dropping mr. packet", __func__, "Sender"); @@ -338,7 +339,7 @@ pim_register_recv (struct interface *ifp, ((SwitchToSptDesired(&sg)) && pim_upstream_inherited_olist (upstream) == 0)) { //pim_scan_individual_oil (upstream->channel_oil); - pim_register_stop_send (ifp, &sg, src_addr); + pim_register_stop_send (ifp, &sg, dest_addr, src_addr); sentRegisterStop = 1; } @@ -359,7 +360,7 @@ pim_register_recv (struct interface *ifp, // This is taken care of by the kernel for us } } else { - pim_register_stop_send (ifp, &sg, src_addr); + pim_register_stop_send (ifp, &sg, dest_addr, src_addr); } return 1; diff --git a/pimd/pim_register.h b/pimd/pim_register.h index ce2e052104..4200c5e269 100644 --- a/pimd/pim_register.h +++ b/pimd/pim_register.h @@ -42,7 +42,7 @@ int pim_register_recv (struct interface *ifp, struct in_addr src_addr, uint8_t *tlv_buf, int tlv_buf_size); -void pim_register_send (const uint8_t *buf, int buf_size, struct pim_rpf *rpg, int null_register); -void pim_register_stop_send (struct interface *ifp, struct prefix_sg *sg, struct in_addr originator); +void pim_register_send (const uint8_t *buf, int buf_size, struct in_addr src, struct pim_rpf *rpg, int null_register); +void pim_register_stop_send (struct interface *ifp, struct prefix_sg *sg, struct in_addr src, struct in_addr originator); #endif diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 68c773d0c8..034878d20d 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -932,6 +932,7 @@ pim_upstream_state2str (enum pim_upstream_state join_state) static int pim_upstream_register_stop_timer (struct thread *t) { + struct pim_interface *pim_ifp; struct pim_upstream *up; struct pim_rpf *rpg; struct ip ip_hdr; @@ -956,6 +957,7 @@ pim_upstream_register_stop_timer (struct thread *t) case PIM_UPSTREAM_JOINED: break; case PIM_UPSTREAM_PRUNE: + pim_ifp = up->rpf.source_nexthop.interface->info; up->join_state = PIM_UPSTREAM_JOIN_PENDING; pim_upstream_start_register_stop_timer (up, 1); @@ -968,7 +970,8 @@ pim_upstream_register_stop_timer (struct thread *t) ip_hdr.ip_dst = up->sg.grp; ip_hdr.ip_len = htons (20); // checksum is broken - pim_register_send ((uint8_t *)&ip_hdr, sizeof (struct ip), rpg, 1); + pim_register_send ((uint8_t *)&ip_hdr, sizeof (struct ip), + pim_ifp->primary_address, rpg, 1); break; default: break;