2 * pim_bsm.c: PIM BSM handling routines
4 * Copyright (C) 2018-19 Vmware, Inc.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; see the file COPYING; if not, write to the
19 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
24 #include "pim_iface.h"
25 #include "pim_instance.h"
27 #include "pim_hello.h"
33 /* Functions forward declaration */
34 static void pim_bs_timer_start(struct bsm_scope
*scope
, int bs_timeout
);
35 static int pim_on_bs_timer(struct thread
*t
);
36 static void pim_bs_timer_stop(struct bsm_scope
*scope
);
38 /* pim_bsm_write_config - Write the interface pim bsm configuration.*/
39 void pim_bsm_write_config(struct vty
*vty
, struct interface
*ifp
)
41 struct pim_interface
*pim_ifp
= ifp
->info
;
44 if (!pim_ifp
->bsm_enable
)
45 vty_out(vty
, " no ip pim bsm\n");
46 if (!pim_ifp
->ucast_bsm_accept
)
47 vty_out(vty
, " no ip pim unicast-bsm\n");
51 static void pim_free_bsgrp_data(struct bsgrp_node
*bsgrp_node
)
53 if (bsgrp_node
->bsrp_list
)
54 list_delete(&bsgrp_node
->bsrp_list
);
55 if (bsgrp_node
->partial_bsrp_list
)
56 list_delete(&bsgrp_node
->partial_bsrp_list
);
58 XFREE(MTYPE_PIM_BSGRP_NODE
, bsgrp_node
);
61 static void pim_bsm_node_free(struct bsm_info
*bsm
)
64 XFREE(MTYPE_PIM_BSM_PKT_VAR_MEM
, bsm
->bsm
);
65 XFREE(MTYPE_PIM_BSM_INFO
, bsm
);
68 void pim_bsm_proc_init(struct pim_instance
*pim
)
70 memset(&pim
->global_scope
, 0, sizeof(struct bsm_scope
));
72 pim
->global_scope
.sz_id
= PIM_GBL_SZ_ID
;
73 pim
->global_scope
.bsrp_table
= route_table_init();
74 pim
->global_scope
.accept_nofwd_bsm
= true;
75 pim
->global_scope
.state
= NO_INFO
;
76 pim
->global_scope
.pim
= pim
;
77 pim
->global_scope
.bsm_list
= list_new();
78 pim
->global_scope
.bsm_list
->del
= (void (*)(void *))pim_bsm_node_free
;
79 pim_bs_timer_start(&pim
->global_scope
, PIM_BS_TIME
);
82 void pim_bsm_proc_free(struct pim_instance
*pim
)
84 struct route_node
*rn
;
85 struct bsgrp_node
*bsgrp
;
87 pim_bs_timer_stop(&pim
->global_scope
);
89 if (pim
->global_scope
.bsm_list
)
90 list_delete(&pim
->global_scope
.bsm_list
);
92 for (rn
= route_top(pim
->global_scope
.bsrp_table
); rn
;
93 rn
= route_next(rn
)) {
97 pim_free_bsgrp_data(bsgrp
);
100 if (pim
->global_scope
.bsrp_table
)
101 route_table_finish(pim
->global_scope
.bsrp_table
);
104 static int pim_on_bs_timer(struct thread
*t
)
109 static void pim_bs_timer_stop(struct bsm_scope
*scope
)
112 zlog_debug("%s : BS timer being stopped of sz: %d",
113 __PRETTY_FUNCTION__
, scope
->sz_id
);
114 THREAD_OFF(scope
->bs_timer
);
117 static void pim_bs_timer_start(struct bsm_scope
*scope
, int bs_timeout
)
121 zlog_debug("%s : Invalid scope(NULL).",
122 __PRETTY_FUNCTION__
);
125 THREAD_OFF(scope
->bs_timer
);
128 zlog_debug("%s : starting bs timer for scope %d with timeout %d secs",
129 __PRETTY_FUNCTION__
, scope
->sz_id
, bs_timeout
);
130 thread_add_timer(router
->master
, pim_on_bs_timer
, scope
, bs_timeout
,
134 struct bsgrp_node
*pim_bsm_get_bsgrp_node(struct bsm_scope
*scope
,
137 struct route_node
*rn
;
138 struct bsgrp_node
*bsgrp
;
140 rn
= route_node_lookup(scope
->bsrp_table
, grp
);
143 zlog_debug("%s: Route node doesn't exist for the group",
144 __PRETTY_FUNCTION__
);
148 route_unlock_node(rn
);