From 77e390e59e924b05d40e40b60430560d0e88b426 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 20 Oct 2015 08:36:37 -0700 Subject: [PATCH] pimd: Start handling of pim REGISTER packet type This code starts the handling of the pim register type. No guarantees that it works correctly, just that it compiles and the start of the code is in there. Signed-off-by: Donald Sharp --- pimd/pim_pim.c | 22 +++++++++---- pimd/pim_register.c | 79 ++++++++++++++++++++++++++++++++++++++------- pimd/pim_register.h | 2 ++ 3 files changed, 84 insertions(+), 19 deletions(-) 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,17 +166,47 @@ 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); -- 2.39.5