From 566387390f7d9eaf29c7ec103101e3397d8758ac Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 15 Jul 2016 15:42:09 -0400 Subject: [PATCH] pimd: First Schwag at pim_register_stop Implement the pim_register_stop state machine. There are still a few bugs still but this is enough to get us rolling a bit more. Signed-off-by: Donald Sharp --- pimd/pim_ifchannel.c | 4 ++++ pimd/pim_ifchannel.h | 3 ++- pimd/pim_mroute.c | 8 ++++++-- pimd/pim_pim.c | 3 ++- pimd/pim_register.c | 42 +++++++++++++++++++++++++++++++++++------- pimd/pim_register.h | 3 ++- pimd/pim_upstream.c | 39 ++++++++++++++++++++++++--------------- pimd/pim_upstream.h | 3 +++ 8 files changed, 78 insertions(+), 27 deletions(-) diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index d3855d5d76..15dd682a50 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -148,6 +148,7 @@ const char *pim_ifchannel_ifjoin_name(enum pim_ifjoin_state ifjoin_state) { switch (ifjoin_state) { case PIM_IFJOIN_NOINFO: return "NOINFO"; + case PIM_IFJOIN_JOIN_PIMREG: return "REGT"; case PIM_IFJOIN_JOIN: return "JOIN"; case PIM_IFJOIN_PRUNE_PENDING: return "PRUNEP"; } @@ -627,6 +628,8 @@ void pim_ifchannel_join_add(struct interface *ifp, THREAD_OFF(ch->t_ifjoin_prune_pending_timer); pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_JOIN); break; + case PIM_IFJOIN_JOIN_PIMREG: + zlog_warn("Received Incorrect new state"); } zassert(!IFCHANNEL_NOINFO(ch)); @@ -660,6 +663,7 @@ void pim_ifchannel_prune(struct interface *ifp, switch (ch->ifjoin_state) { case PIM_IFJOIN_NOINFO: case PIM_IFJOIN_PRUNE_PENDING: + case PIM_IFJOIN_JOIN_PIMREG: /* nothing to do */ break; case PIM_IFJOIN_JOIN: diff --git a/pimd/pim_ifchannel.h b/pimd/pim_ifchannel.h index e6f1c2947c..5f488ddc0f 100644 --- a/pimd/pim_ifchannel.h +++ b/pimd/pim_ifchannel.h @@ -37,7 +37,8 @@ enum pim_ifmembership { enum pim_ifjoin_state { PIM_IFJOIN_NOINFO, PIM_IFJOIN_JOIN, - PIM_IFJOIN_PRUNE_PENDING + PIM_IFJOIN_PRUNE_PENDING, + PIM_IFJOIN_JOIN_PIMREG, }; enum pim_ifassert_state { diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index 83a3b1045d..c13f2cbba4 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -36,6 +36,7 @@ #include "pim_rp.h" #include "pim_oil.h" #include "pim_register.h" +#include "pim_ifchannel.h" /* GLOBAL VARS */ extern struct zebra_privs_t pimd_privs; @@ -93,6 +94,7 @@ pim_mroute_msg_nocache (int fd, struct interface *ifp, const struct igmpmsg *msg const char *src_str, const char *grp_str) { struct pim_interface *pim_ifp = ifp->info; + struct pim_ifchannel *ch; struct pim_upstream *up; struct pim_rpf *rpg; @@ -149,8 +151,10 @@ pim_mroute_msg_nocache (int fd, struct interface *ifp, const struct igmpmsg *msg return 0; } up->channel_oil->cc.pktcnt++; - - pim_channel_add_oif(up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_SOURCE); + up->fhr = 1; + ch = pim_ifchannel_add (pim_regiface, msg->im_src, msg->im_dst); + pim_ifchannel_ifjoin_switch (__PRETTY_FUNCTION__, ch, PIM_IFJOIN_JOIN_PIMREG); + up->join_state = PIM_UPSTREAM_JOINED; return 0; } diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c index 60bba9e9ba..5f5b2dd5ec 100644 --- a/pimd/pim_pim.c +++ b/pimd/pim_pim.c @@ -224,7 +224,8 @@ int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len) pim_msg_len - PIM_MSG_HEADER_LEN); break; case PIM_MSG_TYPE_REG_STOP: - return pim_register_stop_recv (); + return pim_register_stop_recv (pim_msg + PIM_MSG_HEADER_LEN, + pim_msg_len - PIM_MSG_HEADER_LEN); break; case PIM_MSG_TYPE_JOIN_PRUNE: neigh = pim_neighbor_find(ifp, ip_hdr->ip_src); diff --git a/pimd/pim_register.c b/pimd/pim_register.c index 2876dec83f..c8d0174116 100644 --- a/pimd/pim_register.c +++ b/pimd/pim_register.c @@ -112,9 +112,41 @@ pim_register_stop_send (struct interface *ifp, struct in_addr source, } int -pim_register_stop_recv (void) +pim_register_stop_recv (uint8_t *buf, int buf_size) { - zlog_debug ("Received Register Stop"); + struct pim_upstream *upstream = NULL; + struct prefix source; + struct prefix group; + int l; + + if (PIM_DEBUG_PACKETS) + pim_pkt_dump ("Received Register Stop", buf, buf_size); + + l = pim_parse_addr_group (&group, buf, buf_size); + buf += l; + buf_size -= l; + l = pim_parse_addr_ucast (&source, buf, buf_size); + upstream = pim_upstream_find (source.u.prefix4, group.u.prefix4); + if (!upstream) + { + return 0; + } + + switch (upstream->join_state) + { + case PIM_UPSTREAM_NOTJOINED: + case PIM_UPSTREAM_PRUNE: + return 0; + break; + case PIM_UPSTREAM_JOINED: + case PIM_UPSTREAM_JOIN_PENDING: + upstream->join_state = PIM_UPSTREAM_PRUNE; + pim_upstream_start_register_stop_timer (upstream, 0); + pim_channel_del_oif (upstream->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM); + return 0; + break; + } + return 0; } @@ -313,11 +345,7 @@ pim_register_recv (struct interface *ifp, upstream->rpf.rpf_addr.s_addr = source.s_addr; upstream->channel_oil->oil.mfcc_origin = source; pim_scan_individual_oil (upstream->channel_oil); - pim_joinprune_send(upstream->rpf.source_nexthop.interface, - upstream->rpf.source_nexthop.mrib_nexthop_addr, - upstream->source_addr, - upstream->group_addr, - 1); + pim_upstream_send_join (upstream); //decapsulate and forward the iner packet to //inherited_olist(S,G,rpt) diff --git a/pimd/pim_register.h b/pimd/pim_register.h index 3de1557966..8ab24b7137 100644 --- a/pimd/pim_register.h +++ b/pimd/pim_register.h @@ -35,7 +35,8 @@ void pim_register_send_test_packet_start (struct in_addr source, struct in_addr group, uint32_t pps); -int pim_register_stop_recv (void); +int pim_register_stop_recv (uint8_t *buf, int buf_size); + int pim_register_recv (struct interface *ifp, struct in_addr dest_addr, struct in_addr src_addr, diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 87f6089b28..4f2c2d0eaa 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -82,25 +82,34 @@ void pim_upstream_delete(struct pim_upstream *up) pim_upstream_free(up); } -static void send_join(struct pim_upstream *up) +void +pim_upstream_send_join (struct pim_upstream *up) { - zassert(up->join_state == PIM_UPSTREAM_JOINED); - - if (PIM_DEBUG_PIM_TRACE) { + char src_str[100]; + char grp_str[100]; + char rpf_str[100]; + pim_inet4_dump("", up->source_addr, src_str, sizeof(src_str)); + pim_inet4_dump("", up->group_addr, grp_str, sizeof(grp_str)); + pim_inet4_dump("", up->rpf.rpf_addr, rpf_str, sizeof(rpf_str)); + zlog_debug ("%s: RPF'(%s,%s)=%s(%s) for Interface %s", __PRETTY_FUNCTION__, + src_str, grp_str, rpf_str, pim_upstream_state2str (up), + up->rpf.source_nexthop.interface->name); if (PIM_INADDR_IS_ANY(up->rpf.rpf_addr)) { - char src_str[100]; - char grp_str[100]; - char rpf_str[100]; - pim_inet4_dump("", up->source_addr, src_str, sizeof(src_str)); - pim_inet4_dump("", up->group_addr, grp_str, sizeof(grp_str)); - pim_inet4_dump("", up->rpf.rpf_addr, rpf_str, sizeof(rpf_str)); - zlog_warn("%s: can't send join upstream: RPF'(%s,%s)=%s", - __PRETTY_FUNCTION__, - src_str, grp_str, rpf_str); + zlog_debug("%s: can't send join upstream: RPF'(%s,%s)=%s", + __PRETTY_FUNCTION__, + src_str, grp_str, rpf_str); /* warning only */ } } + + /* + * In the case of a FHR we will not have anyone to send this to. + */ + if (up->fhr) + return; + + zassert(up->join_state == PIM_UPSTREAM_JOINED); /* send Join(S,G) to the current upstream neighbor */ pim_joinprune_send(up->rpf.source_nexthop.interface, @@ -118,7 +127,7 @@ static int on_join_timer(struct thread *t) up = THREAD_ARG(t); zassert(up); - send_join(up); + pim_upstream_send_join (up); up->t_join_timer = NULL; join_timer_start(up); @@ -334,7 +343,7 @@ static void pim_upstream_switch(struct pim_upstream *up, if (new_state == PIM_UPSTREAM_JOINED) { forward_on(up); - send_join(up); + pim_upstream_send_join (up); join_timer_start(up); } else { diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h index 222e30b4ba..5e7d6114df 100644 --- a/pimd/pim_upstream.h +++ b/pimd/pim_upstream.h @@ -87,6 +87,7 @@ enum pim_upstream_sptbit { See RFC 4601: 4.5.7. Sending (S,G) Join/Prune Message */ struct pim_upstream { + int fhr; struct in_addr upstream_addr;/* Who we are talking to */ struct in_addr source_addr; /* (S,G) source key */ struct in_addr group_addr; /* (S,G) group key */ @@ -152,5 +153,7 @@ int pim_upstream_switch_to_spt_desired (struct in_addr source, struct in_addr gr void pim_upstream_start_register_stop_timer (struct pim_upstream *up, int null_register); +void pim_upstream_send_join (struct pim_upstream *up); + const char *pim_upstream_state2str (struct pim_upstream *up); #endif /* PIM_UPSTREAM_H */ -- 2.39.5