pimd: Fix pim to use correct src address for packets

When sending register packets to the RP from the FHR
we should be using the ip address of the incoming interface
that received the mcast packet.

Ticket: CM-12445
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2016-08-22 09:10:05 -04:00 committed by Donald Sharp
parent 7747bad6ac
commit 4df01a4e66
8 changed files with 49 additions and 13 deletions

View File

@ -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,

View File

@ -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,

View File

@ -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;
}

View File

@ -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, 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();

View File

@ -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,

View File

@ -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;

View File

@ -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

View File

@ -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;