diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c index a04a0afc80..5912709fe6 100644 --- a/pimd/pim_pim.c +++ b/pimd/pim_pim.c @@ -39,6 +39,7 @@ #include "pim_join.h" #include "pim_assert.h" #include "pim_msg.h" +#include "pim_register.h" static int on_pim_hello_send(struct thread *t); static int pim_hello_send(struct interface *ifp, @@ -206,8 +207,7 @@ int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len) pim_version, pim_type, pim_msg_len, checksum); } - if (pim_type == PIM_MSG_TYPE_REGISTER || - pim_type == PIM_MSG_TYPE_REG_STOP || + if (pim_type == PIM_MSG_TYPE_REG_STOP || pim_type == PIM_MSG_TYPE_BOOTSTRAP || pim_type == PIM_MSG_TYPE_GRAFT || pim_type == PIM_MSG_TYPE_GRAFT_ACK || @@ -221,11 +221,16 @@ int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len) } if (pim_type == PIM_MSG_TYPE_HELLO) { - int result = pim_hello_recv(ifp, - ip_hdr->ip_src, - pim_msg + PIM_MSG_HEADER_LEN, - pim_msg_len - PIM_MSG_HEADER_LEN); - return result; + return pim_hello_recv(ifp, + ip_hdr->ip_src, + pim_msg + PIM_MSG_HEADER_LEN, + pim_msg_len - PIM_MSG_HEADER_LEN); + } else if (pim_type == PIM_MSG_TYPE_REGISTER) { + return pim_register_recv(ifp, + ip_hdr->ip_dst, + ip_hdr->ip_src, + pim_msg + PIM_MSG_HEADER_LEN, + pim_msg_len - PIM_MSG_HEADER_LEN); } neigh = pim_neighbor_find(ifp, ip_hdr->ip_src); @@ -242,15 +247,18 @@ int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len) ip_hdr->ip_src, pim_msg + PIM_MSG_HEADER_LEN, pim_msg_len - PIM_MSG_HEADER_LEN); + break; case PIM_MSG_TYPE_ASSERT: return pim_assert_recv(ifp, neigh, ip_hdr->ip_src, pim_msg + PIM_MSG_HEADER_LEN, pim_msg_len - PIM_MSG_HEADER_LEN); + break; default: zlog_warn("%s %s: unsupported PIM message type=%d from %s on %s", __FILE__, __PRETTY_FUNCTION__, pim_type, src_str, ifp->name); + break; } return -1; diff --git a/pimd/pim_register.c b/pimd/pim_register.c index 7961f2a166..b6cda10bb8 100644 --- a/pimd/pim_register.c +++ b/pimd/pim_register.c @@ -111,13 +111,13 @@ pim_register_recv (struct interface *ifp, struct in_addr src_addr, uint8_t *tlv_buf, int tlv_buf_size) { - //int sentRegisterStop = 0; + int sentRegisterStop = 0; + struct ip *ip_hdr; + size_t hlen; struct in_addr group = { .s_addr = 0 }; struct in_addr source = { .s_addr = 0 }; - struct in_addr outer_src = { .s_addr = 0 }; - uint32_t *bits = (uint32_t *)tlv_buf; - //uint8_t *data = (tlv_buf + sizeof(uint32_t)); - uint32_t nrb; + uint8_t *msg; + uint32_t *bits; if (!pim_check_is_my_ip_address (dest_addr)) { if (PIM_DEBUG_PIM_PACKETS) { @@ -130,9 +130,34 @@ pim_register_recv (struct interface *ifp, return 0; } - nrb = (*bits && PIM_REGISTER_NR_BIT); + /* + * Please note this is not drawn to get the correct bit/data size + * + * The entirety of the REGISTER packet looks like this: + * ------------------------------------------------------------- + * | Ver | Type | Reserved | Checksum | + * |-----------------------------------------------------------| + * |B|N| Reserved 2 | + * |-----------------------------------------------------------| + * | Encap | IP HDR | + * | Mcast | | + * | Packet |--------------------------------------------------| + * | | Mcast Data | + * | | | + * ... + * + * tlv_buf when received from the caller points at the B bit + * We need to know the inner source and dest + */ + bits = (uint32_t *)tlv_buf; + ip_hdr = (struct ip *)(tlv_buf + PIM_MSG_REGISTER_LEN); + hlen = (ip_hdr->ip_hl << 2) | PIM_MSG_REGISTER_LEN; + msg = (uint8_t *)tlv_buf + hlen; + source = ip_hdr->ip_src; + group = ip_hdr->ip_dst; + if (I_am_RP (group) && (dest_addr.s_addr == (RP (group).s_addr))) { - //sentRegisterStop = 0; + sentRegisterStop = 0; if (*bits && PIM_REGISTER_BORDER_BIT) { struct in_addr pimbr = pim_br_get_pmbr (source, group); @@ -141,18 +166,48 @@ pim_register_recv (struct interface *ifp, if (pimbr.s_addr == pim_br_unknown.s_addr) pim_br_set_pmbr(source, group, outer_src); - else if (outer_src.s_addr != pimbr.s_addr) { - pim_register_stop_send(outer_src); + else if (outer.s_addr != pimbr.s_addr) { + pim_register_stop_send(outer); if (PIM_DEBUG_PIM_PACKETS) zlog_debug("%s: Sending register-Stop to %s and dropping mr. packet", __func__, "Sender"); + /* Drop Packet Silently */ + return 1; } } - } else { - nrb++; - //pim_recv_ + + struct pim_upstream *upstream = pim_upstream_find (source, group); + /* + * If we don't have a place to send ignore the packet + */ + if (!upstream) + return 1; + + if ((upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE) || + ((SwitchToSptDesired(source, group)) && + (inherited_list(source, group) == NULL))) { + pim_register_stop_send(outer); + sentRegisterStop = 1; } + if ((upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE) || + (SwitchToSptDesired(source, group))) { + if (SentRegisterStop) { + //set KeepaliveTimer(S,G) to RP_Keepalive_Period; + } else { + //set KeepaliveTimer(S,G) to Keepalive_Period; + } + } + + if (!(upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE) && + !(*bits && PIM_REGISTER_NR_BIT)) { + //decapsulate and forward the iner packet to + //inherited_olist(S,G,rpt) + } + } else { + pim_register_stop_send(outer); + } + return 1; } diff --git a/pimd/pim_register.h b/pimd/pim_register.h index b2482f7aab..76214ee1aa 100644 --- a/pimd/pim_register.h +++ b/pimd/pim_register.h @@ -28,6 +28,8 @@ #define PIM_REGISTER_BORDER_BIT 0x80000000 #define PIM_REGISTER_NR_BIT 0x40000000 +#define PIM_MSG_REGISTER_LEN (4) + void pim_register_send_test_packet_start (struct in_addr source, struct in_addr group, uint32_t pps);