Skip to content

Commit

Permalink
pimd: When DR becomes non DR, couldreg state events not handled.
Browse files Browse the repository at this point in the history
RCA: Upstreams which are in register state other than noinfo, doesnt remove
register tunnel from oif after it becomes nonDR

Fix: scan upstreams with iif as the old dr and check if couldReg becomes false.
If couldreg becomes false from true, remove regiface and stop reg timer.
Do not disturb the entry. Later the entry shall be removed by kat expiry.

Signed-off-by: Saravanan K <[email protected]>
  • Loading branch information
sarav511 committed Mar 20, 2020
1 parent 7f2ccbe commit 46a9ea8
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 1 deletion.
1 change: 1 addition & 0 deletions pimd/pim_iface.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ struct pim_interface *pim_if_new(struct interface *ifp, bool igmp, bool pim,
/* BSM config on interface: true by default */
pim_ifp->bsm_enable = true;
pim_ifp->ucast_bsm_accept = true;
pim_ifp->am_i_dr = false;

/*
RFC 3376: 8.3. Query Response Interval
Expand Down
1 change: 1 addition & 0 deletions pimd/pim_iface.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ struct pim_interface {

/* Turn on Active-Active for this interface */
bool activeactive;
bool am_i_dr;

int64_t pim_ifstat_start; /* start timestamp for stats */
uint64_t pim_ifstat_bsm_rx;
Expand Down
11 changes: 11 additions & 0 deletions pimd/pim_neighbor.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "pim_join.h"
#include "pim_jp_agg.h"
#include "pim_bfd.h"
#include "pim_register.h"

static void dr_election_by_addr(struct interface *ifp)
{
Expand Down Expand Up @@ -141,6 +142,16 @@ int pim_if_dr_election(struct interface *ifp)
pim_if_update_join_desired(pim_ifp);
pim_if_update_could_assert(ifp);
pim_if_update_assert_tracking_desired(ifp);

if (PIM_I_am_DR(pim_ifp))
pim_ifp->am_i_dr = true;
else {
if (pim_ifp->am_i_dr == true) {
pim_reg_del_on_couldreg_fail(ifp);
pim_ifp->am_i_dr = false;
}
}

return 1;
}

Expand Down
1 change: 1 addition & 0 deletions pimd/pim_pim.c
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,7 @@ void pim_sock_reset(struct interface *ifp)
pim_ifp->pim_dr_num_nondrpri_neighbors =
0; /* neighbors without dr_pri */
pim_ifp->pim_dr_addr = pim_ifp->primary_address;
pim_ifp->am_i_dr = true;

pim_ifstat_reset(ifp);
}
Expand Down
29 changes: 29 additions & 0 deletions pimd/pim_register.c
Original file line number Diff line number Diff line change
Expand Up @@ -498,3 +498,32 @@ int pim_register_recv(struct interface *ifp, struct in_addr dest_addr,

return 0;
}

/*
* This routine scan all upstream and update register state and remove pimreg
* when couldreg becomes false.
*/
void pim_reg_del_on_couldreg_fail(struct interface *ifp)
{
struct pim_interface *pim_ifp = ifp->info;
struct pim_instance *pim;
struct pim_upstream *up;

if (!pim_ifp)
return;

pim = pim_ifp->pim;

frr_each (rb_pim_upstream, &pim->upstream_head, up) {
if (ifp != up->rpf.source_nexthop.interface)
continue;

if (!pim_upstream_could_register(up)
&& (up->reg_state != PIM_REG_NOINFO)) {
pim_channel_del_oif(up->channel_oil, pim->regiface,
PIM_OIF_FLAG_PROTO_PIM, __func__);
THREAD_OFF(up->t_rs_timer);
up->reg_state = PIM_REG_NOINFO;
}
}
}
1 change: 1 addition & 0 deletions pimd/pim_register.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,6 @@ void pim_register_stop_send(struct interface *ifp, struct prefix_sg *sg,
struct in_addr src, struct in_addr originator);
void pim_register_join(struct pim_upstream *up);
void pim_null_register_send(struct pim_upstream *up);
void pim_reg_del_on_couldreg_fail(struct interface *ifp);

#endif
2 changes: 1 addition & 1 deletion pimd/pim_upstream.c
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ static void forward_off(struct pim_upstream *up)
} /* scan iface channel list */
}

static int pim_upstream_could_register(struct pim_upstream *up)
int pim_upstream_could_register(struct pim_upstream *up)
{
struct pim_interface *pim_ifp = NULL;

Expand Down
1 change: 1 addition & 0 deletions pimd/pim_upstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -394,4 +394,5 @@ void pim_upstream_update_use_rpt(struct pim_upstream *up,
uint32_t pim_up_mlag_local_cost(struct pim_upstream *up);
uint32_t pim_up_mlag_peer_cost(struct pim_upstream *up);
void pim_upstream_reeval_use_rpt(struct pim_instance *pim);
int pim_upstream_could_register(struct pim_upstream *up);
#endif /* PIM_UPSTREAM_H */

0 comments on commit 46a9ea8

Please sign in to comment.