]> git.proxmox.com Git - mirror_frr.git/blob - pimd/pim_bsm.c
pimd: rp_new & rp_del split into 2 tier functions & implement rp_change
[mirror_frr.git] / pimd / pim_bsm.c
1 /*
2 * pim_bsm.c: PIM BSM handling routines
3 *
4 * Copyright (C) 2018-19 Vmware, Inc.
5 * Saravanan K
6 *
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.
11 *
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.
16 *
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,
20 * MA 02110-1301 USA
21 */
22 #include "if.h"
23 #include "pimd.h"
24 #include "pim_iface.h"
25 #include "pim_instance.h"
26 #include "pim_rpf.h"
27 #include "pim_hello.h"
28 #include "pim_pim.h"
29 #include "pim_nht.h"
30 #include "pim_bsm.h"
31 #include "pim_time.h"
32
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);
37
38 /* pim_bsm_write_config - Write the interface pim bsm configuration.*/
39 void pim_bsm_write_config(struct vty *vty, struct interface *ifp)
40 {
41 struct pim_interface *pim_ifp = ifp->info;
42
43 if (pim_ifp) {
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");
48 }
49 }
50
51 static void pim_free_bsgrp_data(struct bsgrp_node *bsgrp_node)
52 {
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);
57
58 XFREE(MTYPE_PIM_BSGRP_NODE, bsgrp_node);
59 }
60
61 static void pim_bsm_node_free(struct bsm_info *bsm)
62 {
63 if (bsm->bsm)
64 XFREE(MTYPE_PIM_BSM_PKT_VAR_MEM, bsm->bsm);
65 XFREE(MTYPE_PIM_BSM_INFO, bsm);
66 }
67
68 void pim_bsm_proc_init(struct pim_instance *pim)
69 {
70 memset(&pim->global_scope, 0, sizeof(struct bsm_scope));
71
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);
80 }
81
82 void pim_bsm_proc_free(struct pim_instance *pim)
83 {
84 struct route_node *rn;
85 struct bsgrp_node *bsgrp;
86
87 pim_bs_timer_stop(&pim->global_scope);
88
89 if (pim->global_scope.bsm_list)
90 list_delete(&pim->global_scope.bsm_list);
91
92 for (rn = route_top(pim->global_scope.bsrp_table); rn;
93 rn = route_next(rn)) {
94 bsgrp = rn->info;
95 if (!bsgrp)
96 continue;
97 pim_free_bsgrp_data(bsgrp);
98 }
99
100 if (pim->global_scope.bsrp_table)
101 route_table_finish(pim->global_scope.bsrp_table);
102 }
103
104 static int pim_on_bs_timer(struct thread *t)
105 {
106 return 0;
107 }
108
109 static void pim_bs_timer_stop(struct bsm_scope *scope)
110 {
111 if (PIM_DEBUG_BSM)
112 zlog_debug("%s : BS timer being stopped of sz: %d",
113 __PRETTY_FUNCTION__, scope->sz_id);
114 THREAD_OFF(scope->bs_timer);
115 }
116
117 static void pim_bs_timer_start(struct bsm_scope *scope, int bs_timeout)
118 {
119 if (!scope) {
120 if (PIM_DEBUG_BSM)
121 zlog_debug("%s : Invalid scope(NULL).",
122 __PRETTY_FUNCTION__);
123 }
124
125 THREAD_OFF(scope->bs_timer);
126
127 if (PIM_DEBUG_BSM)
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,
131 &scope->bs_timer);
132 }
133
134 struct bsgrp_node *pim_bsm_get_bsgrp_node(struct bsm_scope *scope,
135 struct prefix *grp)
136 {
137 struct route_node *rn;
138 struct bsgrp_node *bsgrp;
139
140 rn = route_node_lookup(scope->bsrp_table, grp);
141 if (!rn) {
142 if (PIM_DEBUG_BSM)
143 zlog_debug("%s: Route node doesn't exist for the group",
144 __PRETTY_FUNCTION__);
145 return NULL;
146 }
147 bsgrp = rn->info;
148 route_unlock_node(rn);
149
150 return bsgrp;
151 }