summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pimd/pim_assert.c1
-rw-r--r--pimd/pim_join.c1
-rw-r--r--pimd/pim_mroute.c8
-rw-r--r--pimd/pim_pim.c29
-rw-r--r--pimd/pim_pim.h1
-rw-r--r--pimd/pim_register.c13
-rw-r--r--pimd/pim_register.h4
-rw-r--r--pimd/pim_upstream.c5
8 files changed, 49 insertions, 13 deletions
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, 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;