mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-13 21:10:28 +00:00
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:
parent
7747bad6ac
commit
4df01a4e66
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user