diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 016ba3e451..465c368f43 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -1643,6 +1643,44 @@ json_object_pim_upstream_add (json_object *json, struct pim_upstream *up) json_object_boolean_true_add(json, "sourceMsdp"); } +static const char * +pim_upstream_state2brief_str (enum pim_upstream_state join_state, char *state_str) +{ + switch (join_state) + { + case PIM_UPSTREAM_NOTJOINED: + strcpy (state_str, "NotJ"); + break; + case PIM_UPSTREAM_JOINED: + strcpy (state_str, "J"); + break; + default: + strcpy (state_str, "Unk"); + } + return state_str; +} + +static const char * +pim_reg_state2brief_str (enum pim_reg_state reg_state, char *state_str) +{ + switch (reg_state) + { + case PIM_REG_NOINFO: + strcpy (state_str, "RegNI"); + break; + case PIM_REG_JOIN: + strcpy (state_str, "RegJ"); + break; + case PIM_REG_JOIN_PENDING: + case PIM_REG_PRUNE: + strcpy (state_str, "RegP"); + break; + default: + strcpy (state_str, "Unk"); + } + return state_str; +} + static void pim_show_upstream(struct vty *vty, u_char uj) { struct listnode *upnode; @@ -1667,6 +1705,7 @@ static void pim_show_upstream(struct vty *vty, u_char uj) char rs_timer[10]; char ka_timer[10]; char msdp_reg_timer[10]; + char state_str[PIM_REG_STATE_STR_LEN]; pim_inet4_dump("", up->sg.src, src_str, sizeof(src_str)); pim_inet4_dump("", up->sg.grp, grp_str, sizeof(grp_str)); @@ -1690,6 +1729,14 @@ static void pim_show_upstream(struct vty *vty, u_char uj) pim_time_timer_to_hhmmss (ka_timer, sizeof (ka_timer), up->t_ka_timer); pim_time_timer_to_hhmmss (msdp_reg_timer, sizeof (msdp_reg_timer), up->t_msdp_reg_timer); + pim_upstream_state2brief_str (up->join_state, state_str); + if (up->reg_state != PIM_REG_NOINFO) { + char tmp_str[PIM_REG_STATE_STR_LEN]; + + sprintf (state_str + strlen (state_str), ",%s", + pim_reg_state2brief_str (up->reg_state, tmp_str)); + } + if (uj) { json_object_object_get_ex(json, grp_str, &json_group); @@ -1703,7 +1750,9 @@ static void pim_show_upstream(struct vty *vty, u_char uj) json_object_string_add(json_row, "inboundInterface", up->rpf.source_nexthop.interface->name); json_object_string_add(json_row, "source", src_str); json_object_string_add(json_row, "group", grp_str); - json_object_string_add(json_row, "state", pim_upstream_state2str (up->join_state)); + json_object_string_add(json_row, "state", state_str); + json_object_string_add(json_row, "joinState", pim_upstream_state2str (up->join_state)); + json_object_string_add(json_row, "regState", pim_reg_state2str (up->reg_state, state_str)); json_object_string_add(json_row, "upTime", uptime); json_object_string_add(json_row, "joinTimer", join_timer); json_object_string_add(json_row, "resetTimer", rs_timer); @@ -1717,7 +1766,7 @@ static void pim_show_upstream(struct vty *vty, u_char uj) up->rpf.source_nexthop.interface->name, src_str, grp_str, - pim_upstream_state2str (up->join_state), + state_str, uptime, join_timer, rs_timer, diff --git a/pimd/pim_jp_agg.c b/pimd/pim_jp_agg.c index 67ddf05d06..8d4510324c 100644 --- a/pimd/pim_jp_agg.c +++ b/pimd/pim_jp_agg.c @@ -249,6 +249,10 @@ pim_jp_agg_single_upstream_send (struct pim_rpf *rpf, static bool first = true; + /* skip JP upstream messages if source is directly connected */ + if (pim_if_connected_to_source (rpf->source_nexthop.interface, up->sg.src)) + return; + if (first) { groups = list_new(); diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index 334e0ce06e..9401475813 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -189,7 +189,7 @@ pim_mroute_msg_nocache (int fd, struct interface *ifp, const struct igmpmsg *msg up->channel_oil->cc.pktcnt++; PIM_UPSTREAM_FLAG_SET_FHR(up->flags); pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM); - up->join_state = PIM_UPSTREAM_JOINED; + up->reg_state = PIM_REG_JOIN; return 0; } @@ -453,7 +453,7 @@ pim_mroute_msg_wrvifwhole (int fd, struct interface *ifp, const char *buf) up->channel_oil = oil; up->channel_oil->cc.pktcnt++; pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM); - up->join_state = PIM_UPSTREAM_JOINED; + up->reg_state = PIM_REG_JOIN; pim_upstream_inherited_olist (up); // Send the packet to the RP diff --git a/pimd/pim_register.c b/pimd/pim_register.c index 29b4e8a63b..46d8e3ec2e 100644 --- a/pimd/pim_register.c +++ b/pimd/pim_register.c @@ -122,19 +122,19 @@ pim_register_stop_recv (uint8_t *buf, int buf_size) zlog_debug ("Received Register stop for %s", upstream->sg_str); - switch (upstream->join_state) + switch (upstream->reg_state) { - case PIM_UPSTREAM_NOTJOINED: - case PIM_UPSTREAM_PRUNE: + case PIM_REG_NOINFO: + case PIM_REG_PRUNE: return 0; break; - case PIM_UPSTREAM_JOINED: - upstream->join_state = PIM_UPSTREAM_PRUNE; + case PIM_REG_JOIN: + upstream->reg_state = PIM_REG_PRUNE; pim_channel_del_oif (upstream->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM); pim_upstream_start_register_stop_timer (upstream, 0); break; - case PIM_UPSTREAM_JOIN_PENDING: - upstream->join_state = PIM_UPSTREAM_PRUNE; + case PIM_REG_JOIN_PENDING: + upstream->reg_state = PIM_REG_PRUNE; pim_upstream_start_register_stop_timer (upstream, 0); return 0; break; @@ -358,7 +358,7 @@ pim_register_recv (struct interface *ifp, upstream->sg.src = sg.src; upstream->rpf.rpf_addr = upstream->rpf.source_nexthop.mrib_nexthop_addr; - upstream->join_state = PIM_UPSTREAM_PRUNE; + upstream->join_state = PIM_UPSTREAM_NOTJOINED; } diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 4187635b19..19f7d3336c 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -473,28 +473,9 @@ pim_upstream_switch(struct pim_upstream *up, pim_upstream_state2str (new_state)); } - /* - * This code still needs work. - */ - switch (up->join_state) - { - case PIM_UPSTREAM_PRUNE: - if (!PIM_UPSTREAM_FLAG_TEST_FHR(up->flags)) - { - up->join_state = new_state; - up->state_transition = pim_time_monotonic_sec (); - } - break; - case PIM_UPSTREAM_JOIN_PENDING: - break; - case PIM_UPSTREAM_NOTJOINED: - case PIM_UPSTREAM_JOINED: - up->join_state = new_state; - if (old_state != new_state) - up->state_transition = pim_time_monotonic_sec(); - - break; - } + up->join_state = new_state; + if (old_state != new_state) + up->state_transition = pim_time_monotonic_sec(); pim_upstream_update_assert_tracking_desired(up); @@ -509,6 +490,7 @@ pim_upstream_switch(struct pim_upstream *up, PIM_UPSTREAM_FLAG_SET_FHR(up->flags); if (!old_fhr && PIM_UPSTREAM_FLAG_TEST_SRC_STREAM(up->flags)) { + up->reg_state = PIM_REG_JOIN; pim_upstream_keep_alive_timer_start (up, qpim_keep_alive_time); pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM); } @@ -601,7 +583,8 @@ pim_upstream_new (struct prefix_sg *sg, up->t_ka_timer = NULL; up->t_rs_timer = NULL; up->t_msdp_reg_timer = NULL; - up->join_state = 0; + up->join_state = PIM_UPSTREAM_NOTJOINED; + up->reg_state = PIM_REG_NOINFO; up->state_transition = pim_time_monotonic_sec(); up->channel_oil = NULL; up->sptbit = PIM_UPSTREAM_SPTBIT_FALSE; @@ -957,8 +940,8 @@ static void pim_upstream_fhr_kat_expiry(struct pim_upstream *up) THREAD_OFF(up->t_rs_timer); /* remove regiface from the OIL if it is there*/ pim_channel_del_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM); - /* move to "not-joined" */ - up->join_state = PIM_UPSTREAM_NOTJOINED; + /* clear the register state */ + up->reg_state = PIM_REG_NOINFO; PIM_UPSTREAM_FLAG_UNSET_FHR(up->flags); } @@ -972,9 +955,9 @@ static void pim_upstream_fhr_kat_start(struct pim_upstream *up) zlog_debug ("kat started on %s; set fhr reg state to joined", up->sg_str); PIM_UPSTREAM_FLAG_SET_FHR(up->flags); - if (up->join_state == PIM_UPSTREAM_NOTJOINED) { + if (up->reg_state == PIM_REG_NOINFO) { pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM); - up->join_state = PIM_UPSTREAM_JOINED; + up->reg_state = PIM_REG_JOIN; } } } @@ -1201,16 +1184,33 @@ pim_upstream_state2str (enum pim_upstream_state join_state) case PIM_UPSTREAM_JOINED: return "Joined"; break; - case PIM_UPSTREAM_JOIN_PENDING: - return "JoinPending"; - break; - case PIM_UPSTREAM_PRUNE: - return "Prune"; - break; } return "Unknown"; } +const char * +pim_reg_state2str (enum pim_reg_state reg_state, char *state_str) +{ + switch (reg_state) + { + case PIM_REG_NOINFO: + strcpy (state_str, "RegNoInfo"); + break; + case PIM_REG_JOIN: + strcpy (state_str, "RegJoined"); + break; + case PIM_REG_JOIN_PENDING: + strcpy (state_str, "RegJoinPend"); + break; + case PIM_REG_PRUNE: + strcpy (state_str, "RegPrune"); + break; + default: + strcpy (state_str, "RegUnknown"); + } + return state_str; +} + static int pim_upstream_register_stop_timer (struct thread *t) { @@ -1224,20 +1224,21 @@ pim_upstream_register_stop_timer (struct thread *t) if (PIM_DEBUG_TRACE) { + char state_str[PIM_REG_STATE_STR_LEN]; zlog_debug ("%s: (S,G)=%s upstream register stop timer %s", __PRETTY_FUNCTION__, up->sg_str, - pim_upstream_state2str(up->join_state)); + pim_reg_state2str(up->reg_state, state_str)); } - switch (up->join_state) + switch (up->reg_state) { - case PIM_UPSTREAM_JOIN_PENDING: - up->join_state = PIM_UPSTREAM_JOINED; + case PIM_REG_JOIN_PENDING: + up->reg_state = PIM_REG_JOIN; pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM); break; - case PIM_UPSTREAM_JOINED: + case PIM_REG_JOIN: break; - case PIM_UPSTREAM_PRUNE: + case PIM_REG_PRUNE: pim_ifp = up->rpf.source_nexthop.interface->info; if (!pim_ifp) { @@ -1246,7 +1247,7 @@ pim_upstream_register_stop_timer (struct thread *t) __PRETTY_FUNCTION__, up->rpf.source_nexthop.interface->name); return 0; } - up->join_state = PIM_UPSTREAM_JOIN_PENDING; + up->reg_state = PIM_REG_JOIN_PENDING; pim_upstream_start_register_stop_timer (up, 1); if (((up->channel_oil->cc.lastused/100) > PIM_KEEPALIVE_PERIOD) && diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h index 7cdf73759d..b191fe9404 100644 --- a/pimd/pim_upstream.h +++ b/pimd/pim_upstream.h @@ -61,8 +61,13 @@ enum pim_upstream_state { PIM_UPSTREAM_NOTJOINED, PIM_UPSTREAM_JOINED, - PIM_UPSTREAM_JOIN_PENDING, - PIM_UPSTREAM_PRUNE, +}; + +enum pim_reg_state { + PIM_REG_NOINFO, + PIM_REG_JOIN, + PIM_REG_JOIN_PENDING, + PIM_REG_PRUNE, }; enum pim_upstream_sptbit { @@ -88,6 +93,7 @@ struct pim_upstream { struct list *sources; enum pim_upstream_state join_state; + enum pim_reg_state reg_state; enum pim_upstream_sptbit sptbit; int ref_count; @@ -163,6 +169,8 @@ void pim_upstream_send_join (struct pim_upstream *up); void pim_upstream_switch (struct pim_upstream *up, enum pim_upstream_state new_state); const char *pim_upstream_state2str (enum pim_upstream_state join_state); +#define PIM_REG_STATE_STR_LEN 12 +const char *pim_reg_state2str (enum pim_reg_state state, char *state_str); int pim_upstream_inherited_olist_decide (struct pim_upstream *up); int pim_upstream_inherited_olist (struct pim_upstream *up);