]> git.proxmox.com Git - mirror_frr.git/blame - pimd/pim_mlag.c
Merge pull request #5288 from SumitAgarwal123/bfd_docs
[mirror_frr.git] / pimd / pim_mlag.c
CommitLineData
36b5b98f
SK
1/*
2 * This is an implementation of PIM MLAG Functionality
3 *
4 * Module name: PIM MLAG
5 *
6 * Author: sathesh Kumar karra <sathk@cumulusnetworks.com>
7 *
8 * Copyright (C) 2019 Cumulus Networks http://www.cumulusnetworks.com
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 2 of the License, or (at your option)
13 * any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 * more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with this program; see the file COPYING; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24#include <zebra.h>
25
26#include "pimd.h"
27#include "pim_mlag.h"
28
29extern struct zclient *zclient;
30
46c2687c
SK
31
32/********************API to process PIM MLAG Data ************************/
33
34static void pim_mlag_process_mlagd_state_change(struct mlag_status msg)
35{
36 char buf[MLAG_ROLE_STRSIZE];
37
38 if (PIM_DEBUG_MLAG)
39 zlog_debug("%s: msg dump: my_role: %s, peer_state: %s",
40 __func__,
41 mlag_role2str(msg.my_role, buf, sizeof(buf)),
42 (msg.peer_state == MLAG_STATE_RUNNING ? "RUNNING"
43 : "DOWN"));
44}
45
46static void pim_mlag_process_peer_frr_state_change(struct mlag_frr_status msg)
47{
48 if (PIM_DEBUG_MLAG)
49 zlog_debug(
50 "%s: msg dump: peer_frr_state: %s", __func__,
51 (msg.frr_state == MLAG_FRR_STATE_UP ? "UP" : "DOWN"));
52}
53
54static void pim_mlag_process_vxlan_update(struct mlag_vxlan *msg)
55{
56}
57
58static void pim_mlag_process_mroute_add(struct mlag_mroute_add msg)
59{
60 if (PIM_DEBUG_MLAG) {
61 zlog_debug(
62 "%s: msg dump: vrf_name: %s, s.ip: 0x%x, g.ip: 0x%x cost: %u",
63 __func__, msg.vrf_name, msg.source_ip, msg.group_ip,
64 msg.cost_to_rp);
65 zlog_debug(
66 "owner_id: %d, DR: %d, Dual active: %d, vrf_id: 0x%x intf_name: %s",
67 msg.owner_id, msg.am_i_dr, msg.am_i_dual_active,
68 msg.vrf_id, msg.intf_name);
69 }
70}
71
72static void pim_mlag_process_mroute_del(struct mlag_mroute_del msg)
73{
74 if (PIM_DEBUG_MLAG) {
75 zlog_debug(
76 "%s: msg dump: vrf_name: %s, s.ip: 0x%x, g.ip: 0x%x ",
77 __func__, msg.vrf_name, msg.source_ip, msg.group_ip);
78 zlog_debug("owner_id: %d, vrf_id: 0x%x intf_name: %s",
79 msg.owner_id, msg.vrf_id, msg.intf_name);
80 }
81}
82
83
84int pim_zebra_mlag_handle_msg(struct stream *s, int len)
85{
86 struct mlag_msg mlag_msg;
87 char buf[ZLOG_FILTER_LENGTH_MAX];
88 int rc = 0;
89
1e76492b 90 rc = mlag_lib_decode_mlag_hdr(s, &mlag_msg);
46c2687c
SK
91 if (rc)
92 return (rc);
93
94 if (PIM_DEBUG_MLAG)
95 zlog_debug("%s: Received msg type: %s length: %d, bulk_cnt: %d",
96 __func__,
1e76492b
SK
97 mlag_lib_msgid_to_str(mlag_msg.msg_type, buf,
98 sizeof(buf)),
46c2687c
SK
99 mlag_msg.data_len, mlag_msg.msg_cnt);
100
101 switch (mlag_msg.msg_type) {
102 case MLAG_STATUS_UPDATE: {
103 struct mlag_status msg;
104
1e76492b 105 rc = mlag_lib_decode_mlag_status(s, &msg);
46c2687c
SK
106 if (rc)
107 return (rc);
108 pim_mlag_process_mlagd_state_change(msg);
109 } break;
110 case MLAG_PEER_FRR_STATUS: {
111 struct mlag_frr_status msg;
112
1e76492b 113 rc = mlag_lib_decode_frr_status(s, &msg);
46c2687c
SK
114 if (rc)
115 return (rc);
116 pim_mlag_process_peer_frr_state_change(msg);
117 } break;
118 case MLAG_VXLAN_UPDATE: {
119 struct mlag_vxlan msg;
120
1e76492b 121 rc = mlag_lib_decode_vxlan_update(s, &msg);
46c2687c
SK
122 if (rc)
123 return rc;
124 pim_mlag_process_vxlan_update(&msg);
125 } break;
126 case MLAG_MROUTE_ADD: {
127 struct mlag_mroute_add msg;
128
1e76492b 129 rc = mlag_lib_decode_mroute_add(s, &msg);
46c2687c
SK
130 if (rc)
131 return (rc);
132 pim_mlag_process_mroute_add(msg);
133 } break;
134 case MLAG_MROUTE_DEL: {
135 struct mlag_mroute_del msg;
136
1e76492b 137 rc = mlag_lib_decode_mroute_del(s, &msg);
46c2687c
SK
138 if (rc)
139 return (rc);
140 pim_mlag_process_mroute_del(msg);
141 } break;
142 case MLAG_MROUTE_ADD_BULK: {
143 struct mlag_mroute_add msg;
67fa73f2 144 int i;
46c2687c
SK
145
146 for (i = 0; i < mlag_msg.msg_cnt; i++) {
147
1e76492b 148 rc = mlag_lib_decode_mroute_add(s, &msg);
46c2687c
SK
149 if (rc)
150 return (rc);
151 pim_mlag_process_mroute_add(msg);
152 }
153 } break;
154 case MLAG_MROUTE_DEL_BULK: {
155 struct mlag_mroute_del msg;
67fa73f2 156 int i;
46c2687c
SK
157
158 for (i = 0; i < mlag_msg.msg_cnt; i++) {
159
1e76492b 160 rc = mlag_lib_decode_mroute_del(s, &msg);
46c2687c
SK
161 if (rc)
162 return (rc);
163 pim_mlag_process_mroute_del(msg);
164 }
165 } break;
166 default:
167 break;
168 }
169 return 0;
170}
171
172/****************End of PIM Mesasge processing handler********************/
173
174int pim_zebra_mlag_process_up(void)
175{
176 if (PIM_DEBUG_MLAG)
177 zlog_debug("%s: Received Process-Up from Mlag", __func__);
178
179 return 0;
180}
181
182int pim_zebra_mlag_process_down(void)
183{
184 if (PIM_DEBUG_MLAG)
185 zlog_debug("%s: Received Process-Down from Mlag", __func__);
186
187 return 0;
188}
189
36b5b98f
SK
190static int pim_mlag_register_handler(struct thread *thread)
191{
192 uint32_t bit_mask = 0;
193
194 if (!zclient)
195 return -1;
196
197 SET_FLAG(bit_mask, (1 << MLAG_STATUS_UPDATE));
198 SET_FLAG(bit_mask, (1 << MLAG_MROUTE_ADD));
199 SET_FLAG(bit_mask, (1 << MLAG_MROUTE_DEL));
200 SET_FLAG(bit_mask, (1 << MLAG_DUMP));
201 SET_FLAG(bit_mask, (1 << MLAG_MROUTE_ADD_BULK));
202 SET_FLAG(bit_mask, (1 << MLAG_MROUTE_DEL_BULK));
203 SET_FLAG(bit_mask, (1 << MLAG_PIM_CFG_DUMP));
204 SET_FLAG(bit_mask, (1 << MLAG_VXLAN_UPDATE));
205 SET_FLAG(bit_mask, (1 << MLAG_PEER_FRR_STATUS));
206
207 if (PIM_DEBUG_MLAG)
208 zlog_debug("%s: Posting Client Register to MLAG mask: 0x%x",
209 __func__, bit_mask);
210
211 zclient_send_mlag_register(zclient, bit_mask);
212 return 0;
213}
214
215void pim_mlag_register(void)
216{
217 if (router->mlag_process_register)
218 return;
219
220 router->mlag_process_register = true;
221
222 thread_add_event(router->master, pim_mlag_register_handler, NULL, 0,
223 NULL);
224}
225
226static int pim_mlag_deregister_handler(struct thread *thread)
227{
228 if (!zclient)
229 return -1;
230
231 if (PIM_DEBUG_MLAG)
232 zlog_debug("%s: Posting Client De-Register to MLAG from PIM",
233 __func__);
234 router->connected_to_mlag = false;
235 zclient_send_mlag_deregister(zclient);
236 return 0;
237}
238
239void pim_mlag_deregister(void)
240{
241 /* if somebody still interested in the MLAG channel skip de-reg */
242 if (router->pim_mlag_intf_cnt)
243 return;
244
245 /* not registered; nothing do */
246 if (!router->mlag_process_register)
247 return;
248
249 router->mlag_process_register = false;
250
251 thread_add_event(router->master, pim_mlag_deregister_handler, NULL, 0,
252 NULL);
253}
254
255void pim_if_configure_mlag_dualactive(struct pim_interface *pim_ifp)
256{
257 if (!pim_ifp || !pim_ifp->pim || pim_ifp->activeactive == true)
258 return;
259
260 if (PIM_DEBUG_MLAG)
261 zlog_debug("%s: Configuring active-active on Interface: %s",
262 __func__, "NULL");
263
264 pim_ifp->activeactive = true;
265 if (pim_ifp->pim)
266 pim_ifp->pim->inst_mlag_intf_cnt++;
267
268 router->pim_mlag_intf_cnt++;
269 if (PIM_DEBUG_MLAG)
270 zlog_debug(
271 "%s: Total MLAG configured Interfaces on router: %d, Inst: %d",
272 __func__, router->pim_mlag_intf_cnt,
273 pim_ifp->pim->inst_mlag_intf_cnt);
274
275 if (router->pim_mlag_intf_cnt == 1) {
276 /*
277 * atleast one Interface is configured for MLAG, send register
278 * to Zebra for receiving MLAG Updates
279 */
280 pim_mlag_register();
281 }
282}
283
284void pim_if_unconfigure_mlag_dualactive(struct pim_interface *pim_ifp)
285{
286 if (!pim_ifp || !pim_ifp->pim || pim_ifp->activeactive == false)
287 return;
288
289 if (PIM_DEBUG_MLAG)
290 zlog_debug("%s: UnConfiguring active-active on Interface: %s",
291 __func__, "NULL");
292
293 pim_ifp->activeactive = false;
46c2687c 294 pim_ifp->pim->inst_mlag_intf_cnt--;
36b5b98f
SK
295
296 router->pim_mlag_intf_cnt--;
297 if (PIM_DEBUG_MLAG)
298 zlog_debug(
299 "%s: Total MLAG configured Interfaces on router: %d, Inst: %d",
300 __func__, router->pim_mlag_intf_cnt,
301 pim_ifp->pim->inst_mlag_intf_cnt);
302
303 if (router->pim_mlag_intf_cnt == 0) {
304 /*
305 * all the Interfaces are MLAG un-configured, post MLAG
306 * De-register to Zebra
307 */
308 pim_mlag_deregister();
309 }
310}
311
312
313void pim_instance_mlag_init(struct pim_instance *pim)
314{
315 if (!pim)
316 return;
317
318 pim->inst_mlag_intf_cnt = 0;
319}
320
321
322void pim_instance_mlag_terminate(struct pim_instance *pim)
323{
324 struct interface *ifp;
325
326 if (!pim)
327 return;
328
329 FOR_ALL_INTERFACES (pim->vrf, ifp) {
330 struct pim_interface *pim_ifp = ifp->info;
331
332 if (!pim_ifp || pim_ifp->activeactive == false)
333 continue;
334
335 pim_if_unconfigure_mlag_dualactive(pim_ifp);
336 }
337 pim->inst_mlag_intf_cnt = 0;
338}
339
340void pim_mlag_init(void)
341{
342 router->pim_mlag_intf_cnt = 0;
343 router->connected_to_mlag = false;
344 router->mlag_fifo = stream_fifo_new();
345 router->zpthread_mlag_write = NULL;
346 router->mlag_stream = stream_new(MLAG_BUF_LIMIT);
347}