}
if (pim_msg_send(pim_ifp->pim_sock_fd,
+ pim_ifp->primary_address,
qpim_all_pim_routers_addr,
pim_msg,
pim_msg_size,
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,
* 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;
}
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;
}
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,
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];
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) {
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,
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();
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,
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];
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))
{
}
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;
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,
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");
((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;
}
// 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;
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
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;
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);
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;