Line data Source code
1 : /*
2 : * PIM for Quagga
3 : * Copyright (C) 2008 Everton da Silva Marques
4 : *
5 : * This program is free software; you can redistribute it and/or modify
6 : * it under the terms of the GNU General Public License as published by
7 : * the Free Software Foundation; either version 2 of the License, or
8 : * (at your option) any later version.
9 : *
10 : * This program is distributed in the hope that it will be useful, but
11 : * WITHOUT ANY WARRANTY; without even the implied warranty of
12 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 : * General Public License for more details.
14 : *
15 : * You should have received a copy of the GNU General Public License along
16 : * with this program; see the file COPYING; if not, write to the Free Software
17 : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 : */
19 :
20 : #include <zebra.h>
21 :
22 : #include "if.h"
23 : #include "linklist.h"
24 : #include "prefix.h"
25 : #include "vty.h"
26 : #include "vrf.h"
27 : #include "plist.h"
28 :
29 : #include "pimd.h"
30 : #include "pim_vty.h"
31 : #include "pim_iface.h"
32 : #include "pim_str.h"
33 : #include "pim_ssmpingd.h"
34 : #include "pim_pim.h"
35 : #include "pim_oil.h"
36 : #include "pim_static.h"
37 : #include "pim_rp.h"
38 : #include "pim_msdp.h"
39 : #include "pim_ssm.h"
40 : #include "pim_bfd.h"
41 : #include "pim_bsm.h"
42 : #include "pim_vxlan.h"
43 : #include "pim6_mld.h"
44 :
45 0 : int pim_debug_config_write(struct vty *vty)
46 : {
47 0 : int writes = 0;
48 :
49 0 : if (PIM_DEBUG_MSDP_EVENTS) {
50 0 : vty_out(vty, "debug msdp events\n");
51 0 : ++writes;
52 : }
53 0 : if (PIM_DEBUG_MSDP_PACKETS) {
54 0 : vty_out(vty, "debug msdp packets\n");
55 0 : ++writes;
56 : }
57 0 : if (PIM_DEBUG_MSDP_INTERNAL) {
58 0 : vty_out(vty, "debug msdp internal\n");
59 0 : ++writes;
60 : }
61 0 : if (PIM_DEBUG_GM_EVENTS) {
62 0 : vty_out(vty, "debug " GM_AF_DBG " events\n");
63 0 : ++writes;
64 : }
65 0 : if (PIM_DEBUG_GM_PACKETS) {
66 0 : vty_out(vty, "debug " GM_AF_DBG " packets\n");
67 0 : ++writes;
68 : }
69 : /* PIM_DEBUG_GM_TRACE catches _DETAIL too */
70 0 : if (router->debugs & PIM_MASK_GM_TRACE) {
71 0 : vty_out(vty, "debug " GM_AF_DBG " trace\n");
72 0 : ++writes;
73 : }
74 0 : if (PIM_DEBUG_GM_TRACE_DETAIL) {
75 0 : vty_out(vty, "debug " GM_AF_DBG " trace detail\n");
76 0 : ++writes;
77 : }
78 :
79 : /* PIM_DEBUG_MROUTE catches _DETAIL too */
80 0 : if (router->debugs & PIM_MASK_MROUTE) {
81 0 : vty_out(vty, "debug " PIM_MROUTE_DBG "\n");
82 0 : ++writes;
83 : }
84 0 : if (PIM_DEBUG_MROUTE_DETAIL) {
85 0 : vty_out(vty, "debug " PIM_MROUTE_DBG " detail\n");
86 0 : ++writes;
87 : }
88 :
89 0 : if (PIM_DEBUG_MTRACE) {
90 0 : vty_out(vty, "debug mtrace\n");
91 0 : ++writes;
92 : }
93 :
94 0 : if (PIM_DEBUG_PIM_EVENTS) {
95 0 : vty_out(vty, "debug " PIM_AF_DBG " events\n");
96 0 : ++writes;
97 : }
98 0 : if (PIM_DEBUG_PIM_PACKETS) {
99 0 : vty_out(vty, "debug " PIM_AF_DBG " packets\n");
100 0 : ++writes;
101 : }
102 0 : if (PIM_DEBUG_PIM_PACKETDUMP_SEND) {
103 0 : vty_out(vty, "debug " PIM_AF_DBG " packet-dump send\n");
104 0 : ++writes;
105 : }
106 0 : if (PIM_DEBUG_PIM_PACKETDUMP_RECV) {
107 0 : vty_out(vty, "debug " PIM_AF_DBG " packet-dump receive\n");
108 0 : ++writes;
109 : }
110 :
111 : /* PIM_DEBUG_PIM_TRACE catches _DETAIL too */
112 0 : if (router->debugs & PIM_MASK_PIM_TRACE) {
113 0 : vty_out(vty, "debug " PIM_AF_DBG " trace\n");
114 0 : ++writes;
115 : }
116 0 : if (PIM_DEBUG_PIM_TRACE_DETAIL) {
117 0 : vty_out(vty, "debug " PIM_AF_DBG " trace detail\n");
118 0 : ++writes;
119 : }
120 :
121 0 : if (PIM_DEBUG_ZEBRA) {
122 0 : vty_out(vty, "debug " PIM_AF_DBG " zebra\n");
123 0 : ++writes;
124 : }
125 :
126 0 : if (PIM_DEBUG_MLAG) {
127 0 : vty_out(vty, "debug pim mlag\n");
128 0 : ++writes;
129 : }
130 :
131 0 : if (PIM_DEBUG_BSM) {
132 0 : vty_out(vty, "debug " PIM_AF_DBG " bsm\n");
133 0 : ++writes;
134 : }
135 :
136 0 : if (PIM_DEBUG_VXLAN) {
137 0 : vty_out(vty, "debug " PIM_AF_DBG " vxlan\n");
138 0 : ++writes;
139 : }
140 :
141 0 : if (PIM_DEBUG_SSMPINGD) {
142 0 : vty_out(vty, "debug ssmpingd\n");
143 0 : ++writes;
144 : }
145 :
146 0 : if (PIM_DEBUG_PIM_HELLO) {
147 0 : vty_out(vty, "debug " PIM_AF_DBG " packets hello\n");
148 0 : ++writes;
149 : }
150 :
151 0 : if (PIM_DEBUG_PIM_J_P) {
152 0 : vty_out(vty, "debug " PIM_AF_DBG " packets joins\n");
153 0 : ++writes;
154 : }
155 :
156 0 : if (PIM_DEBUG_PIM_REG) {
157 0 : vty_out(vty, "debug " PIM_AF_DBG " packets register\n");
158 0 : ++writes;
159 : }
160 :
161 0 : if (PIM_DEBUG_STATIC) {
162 0 : vty_out(vty, "debug pim static\n");
163 0 : ++writes;
164 : }
165 :
166 0 : if (PIM_DEBUG_PIM_NHT) {
167 0 : vty_out(vty, "debug " PIM_AF_DBG " nht\n");
168 0 : ++writes;
169 : }
170 :
171 0 : if (PIM_DEBUG_PIM_NHT_RP) {
172 0 : vty_out(vty, "debug pim nht rp\n");
173 0 : ++writes;
174 : }
175 :
176 0 : if (PIM_DEBUG_PIM_NHT_DETAIL) {
177 0 : vty_out(vty, "debug " PIM_AF_DBG " nht detail\n");
178 0 : ++writes;
179 : }
180 :
181 0 : return writes;
182 : }
183 :
184 0 : int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty)
185 : {
186 0 : int writes = 0;
187 0 : struct pim_ssm *ssm = pim->ssm_info;
188 0 : char spaces[10];
189 :
190 0 : if (pim->vrf->vrf_id == VRF_DEFAULT)
191 0 : snprintf(spaces, sizeof(spaces), "%s", "");
192 : else
193 0 : snprintf(spaces, sizeof(spaces), "%s", " ");
194 :
195 0 : writes += pim_msdp_peer_config_write(vty, pim, spaces);
196 0 : writes += pim_msdp_config_write(pim, vty, spaces);
197 :
198 0 : if (!pim->send_v6_secondary) {
199 0 : vty_out(vty, "%sno ip pim send-v6-secondary\n", spaces);
200 0 : ++writes;
201 : }
202 :
203 0 : writes += pim_rp_config_write(pim, vty, spaces);
204 :
205 0 : if (pim->vrf->vrf_id == VRF_DEFAULT) {
206 0 : if (router->register_suppress_time
207 : != PIM_REGISTER_SUPPRESSION_TIME_DEFAULT) {
208 0 : vty_out(vty, "%s" PIM_AF_NAME " pim register-suppress-time %d\n",
209 : spaces, router->register_suppress_time);
210 0 : ++writes;
211 : }
212 0 : if (router->t_periodic != PIM_DEFAULT_T_PERIODIC) {
213 0 : vty_out(vty, "%s" PIM_AF_NAME " pim join-prune-interval %d\n",
214 : spaces, router->t_periodic);
215 0 : ++writes;
216 : }
217 :
218 0 : if (router->packet_process != PIM_DEFAULT_PACKET_PROCESS) {
219 0 : vty_out(vty, "%s" PIM_AF_NAME " pim packets %d\n", spaces,
220 : router->packet_process);
221 0 : ++writes;
222 : }
223 : }
224 0 : if (pim->keep_alive_time != PIM_KEEPALIVE_PERIOD) {
225 0 : vty_out(vty, "%s" PIM_AF_NAME " pim keep-alive-timer %d\n",
226 : spaces, pim->keep_alive_time);
227 0 : ++writes;
228 : }
229 0 : if (pim->rp_keep_alive_time != (unsigned int)PIM_RP_KEEPALIVE_PERIOD) {
230 0 : vty_out(vty, "%s" PIM_AF_NAME " pim rp keep-alive-timer %d\n",
231 : spaces, pim->rp_keep_alive_time);
232 0 : ++writes;
233 : }
234 0 : if (ssm->plist_name) {
235 0 : vty_out(vty, "%sip pim ssm prefix-list %s\n", spaces,
236 : ssm->plist_name);
237 0 : ++writes;
238 : }
239 0 : if (pim->register_plist) {
240 0 : vty_out(vty, "%sip pim register-accept-list %s\n", spaces,
241 : pim->register_plist);
242 0 : ++writes;
243 : }
244 0 : if (pim->spt.switchover == PIM_SPT_INFINITY) {
245 0 : if (pim->spt.plist)
246 0 : vty_out(vty,
247 : "%s" PIM_AF_NAME " pim spt-switchover infinity-and-beyond prefix-list %s\n",
248 : spaces, pim->spt.plist);
249 : else
250 0 : vty_out(vty,
251 : "%s" PIM_AF_NAME " pim spt-switchover infinity-and-beyond\n",
252 : spaces);
253 0 : ++writes;
254 : }
255 0 : if (pim->ecmp_rebalance_enable) {
256 0 : vty_out(vty, "%sip pim ecmp rebalance\n", spaces);
257 0 : ++writes;
258 0 : } else if (pim->ecmp_enable) {
259 0 : vty_out(vty, "%sip pim ecmp\n", spaces);
260 0 : ++writes;
261 : }
262 :
263 0 : if (pim->gm_watermark_limit != 0) {
264 : #if PIM_IPV == 4
265 0 : vty_out(vty, "%s" PIM_AF_NAME " igmp watermark-warn %u\n",
266 : spaces, pim->gm_watermark_limit);
267 : #else
268 : vty_out(vty, "%s" PIM_AF_NAME " mld watermark-warn %u\n",
269 : spaces, pim->gm_watermark_limit);
270 : #endif
271 0 : ++writes;
272 : }
273 :
274 0 : if (pim->ssmpingd_list) {
275 0 : struct listnode *node;
276 0 : struct ssmpingd_sock *ss;
277 0 : ++writes;
278 0 : for (ALL_LIST_ELEMENTS_RO(pim->ssmpingd_list, node, ss)) {
279 0 : vty_out(vty, "%s" PIM_AF_NAME " ssmpingd %pPA\n",
280 : spaces, &ss->source_addr);
281 0 : ++writes;
282 : }
283 : }
284 :
285 0 : if (pim->msdp.hold_time != PIM_MSDP_PEER_HOLD_TIME
286 0 : || pim->msdp.keep_alive != PIM_MSDP_PEER_KA_TIME
287 0 : || pim->msdp.connection_retry != PIM_MSDP_PEER_CONNECT_RETRY_TIME) {
288 0 : vty_out(vty, "%sip msdp timers %u %u", spaces,
289 : pim->msdp.hold_time, pim->msdp.keep_alive);
290 0 : if (pim->msdp.connection_retry
291 : != PIM_MSDP_PEER_CONNECT_RETRY_TIME)
292 0 : vty_out(vty, " %u", pim->msdp.connection_retry);
293 0 : vty_out(vty, "\n");
294 : }
295 :
296 0 : return writes;
297 : }
298 :
299 : #if PIM_IPV == 4
300 0 : static int gm_config_write(struct vty *vty, int writes,
301 : struct pim_interface *pim_ifp)
302 : {
303 : /* IF ip igmp */
304 0 : if (pim_ifp->gm_enable) {
305 0 : vty_out(vty, " ip igmp\n");
306 0 : ++writes;
307 : }
308 :
309 : /* ip igmp version */
310 0 : if (pim_ifp->igmp_version != IGMP_DEFAULT_VERSION) {
311 0 : vty_out(vty, " ip igmp version %d\n", pim_ifp->igmp_version);
312 0 : ++writes;
313 : }
314 :
315 : /* IF ip igmp query-max-response-time */
316 0 : if (pim_ifp->gm_query_max_response_time_dsec !=
317 : GM_QUERY_MAX_RESPONSE_TIME_DSEC) {
318 0 : vty_out(vty, " ip igmp query-max-response-time %d\n",
319 : pim_ifp->gm_query_max_response_time_dsec);
320 0 : ++writes;
321 : }
322 :
323 : /* IF ip igmp query-interval */
324 0 : if (pim_ifp->gm_default_query_interval != GM_GENERAL_QUERY_INTERVAL) {
325 0 : vty_out(vty, " ip igmp query-interval %d\n",
326 : pim_ifp->gm_default_query_interval);
327 0 : ++writes;
328 : }
329 :
330 : /* IF ip igmp last-member_query-count */
331 0 : if (pim_ifp->gm_last_member_query_count !=
332 : GM_DEFAULT_ROBUSTNESS_VARIABLE) {
333 0 : vty_out(vty, " ip igmp last-member-query-count %d\n",
334 : pim_ifp->gm_last_member_query_count);
335 0 : ++writes;
336 : }
337 :
338 : /* IF ip igmp last-member_query-interval */
339 0 : if (pim_ifp->gm_specific_query_max_response_time_dsec !=
340 : GM_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC) {
341 0 : vty_out(vty, " ip igmp last-member-query-interval %d\n",
342 : pim_ifp->gm_specific_query_max_response_time_dsec);
343 0 : ++writes;
344 : }
345 :
346 : /* IF ip igmp join */
347 0 : if (pim_ifp->gm_join_list) {
348 0 : struct listnode *node;
349 0 : struct gm_join *ij;
350 0 : for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_join_list, node, ij)) {
351 0 : char group_str[INET_ADDRSTRLEN];
352 0 : char source_str[INET_ADDRSTRLEN];
353 0 : pim_inet4_dump("<grp?>", ij->group_addr, group_str,
354 : sizeof(group_str));
355 0 : if (ij->source_addr.s_addr == INADDR_ANY) {
356 0 : vty_out(vty, " ip igmp join %s\n", group_str);
357 : } else {
358 0 : inet_ntop(AF_INET, &ij->source_addr, source_str,
359 : sizeof(source_str));
360 0 : vty_out(vty, " ip igmp join %s %s\n", group_str,
361 : source_str);
362 : }
363 0 : ++writes;
364 : }
365 : }
366 :
367 0 : return writes;
368 : }
369 : #else
370 : static int gm_config_write(struct vty *vty, int writes,
371 : struct pim_interface *pim_ifp)
372 : {
373 : /* IF ipv6 mld */
374 : if (pim_ifp->gm_enable) {
375 : vty_out(vty, " ipv6 mld\n");
376 : ++writes;
377 : }
378 :
379 : if (pim_ifp->mld_version != MLD_DEFAULT_VERSION)
380 : vty_out(vty, " ipv6 mld version %d\n", pim_ifp->mld_version);
381 :
382 : /* IF ipv6 mld query-max-response-time */
383 : if (pim_ifp->gm_query_max_response_time_dsec !=
384 : GM_QUERY_MAX_RESPONSE_TIME_DSEC)
385 : vty_out(vty, " ipv6 mld query-max-response-time %d\n",
386 : pim_ifp->gm_query_max_response_time_dsec);
387 :
388 : if (pim_ifp->gm_default_query_interval != GM_GENERAL_QUERY_INTERVAL)
389 : vty_out(vty, " ipv6 mld query-interval %d\n",
390 : pim_ifp->gm_default_query_interval);
391 :
392 : /* IF ipv6 mld last-member_query-count */
393 : if (pim_ifp->gm_last_member_query_count !=
394 : GM_DEFAULT_ROBUSTNESS_VARIABLE)
395 : vty_out(vty, " ipv6 mld last-member-query-count %d\n",
396 : pim_ifp->gm_last_member_query_count);
397 :
398 : /* IF ipv6 mld last-member_query-interval */
399 : if (pim_ifp->gm_specific_query_max_response_time_dsec !=
400 : GM_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC)
401 : vty_out(vty, " ipv6 mld last-member-query-interval %d\n",
402 : pim_ifp->gm_specific_query_max_response_time_dsec);
403 :
404 : return writes;
405 : }
406 : #endif
407 :
408 0 : int pim_config_write(struct vty *vty, int writes, struct interface *ifp,
409 : struct pim_instance *pim)
410 : {
411 0 : struct pim_interface *pim_ifp = ifp->info;
412 :
413 0 : if (pim_ifp->pim_enable) {
414 0 : vty_out(vty, " " PIM_AF_NAME " pim\n");
415 0 : ++writes;
416 : }
417 :
418 : /* IF ip pim drpriority */
419 0 : if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) {
420 0 : vty_out(vty, " " PIM_AF_NAME " pim drpriority %u\n",
421 : pim_ifp->pim_dr_priority);
422 0 : ++writes;
423 : }
424 :
425 : /* IF ip pim hello */
426 0 : if (pim_ifp->pim_hello_period != PIM_DEFAULT_HELLO_PERIOD) {
427 0 : vty_out(vty, " " PIM_AF_NAME " pim hello %d", pim_ifp->pim_hello_period);
428 0 : if (pim_ifp->pim_default_holdtime != -1)
429 0 : vty_out(vty, " %d", pim_ifp->pim_default_holdtime);
430 0 : vty_out(vty, "\n");
431 0 : ++writes;
432 : }
433 :
434 0 : writes += gm_config_write(vty, writes, pim_ifp);
435 :
436 : /* update source */
437 0 : if (!pim_addr_is_any(pim_ifp->update_source)) {
438 0 : vty_out(vty, " " PIM_AF_NAME " pim use-source %pPA\n",
439 : &pim_ifp->update_source);
440 0 : ++writes;
441 : }
442 :
443 0 : if (pim_ifp->activeactive)
444 0 : vty_out(vty, " " PIM_AF_NAME " pim active-active\n");
445 :
446 : /* boundary */
447 0 : if (pim_ifp->boundary_oil_plist) {
448 0 : vty_out(vty, " " PIM_AF_NAME " multicast boundary oil %s\n",
449 : pim_ifp->boundary_oil_plist);
450 0 : ++writes;
451 : }
452 :
453 0 : if (pim_ifp->pim_passive_enable) {
454 0 : vty_out(vty, " " PIM_AF_NAME " pim passive\n");
455 0 : ++writes;
456 : }
457 :
458 0 : writes += pim_static_write_mroute(pim, vty, ifp);
459 0 : pim_bsm_write_config(vty, ifp);
460 0 : ++writes;
461 0 : pim_bfd_write_config(vty, ifp);
462 0 : ++writes;
463 :
464 0 : return writes;
465 : }
466 :
467 0 : int pim_interface_config_write(struct vty *vty)
468 : {
469 0 : struct pim_instance *pim;
470 0 : struct interface *ifp;
471 0 : struct vrf *vrf;
472 0 : int writes = 0;
473 :
474 0 : RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
475 0 : pim = vrf->info;
476 0 : if (!pim)
477 0 : continue;
478 :
479 0 : FOR_ALL_INTERFACES (pim->vrf, ifp) {
480 : /* pim is enabled internally/implicitly on the vxlan
481 : * termination device ipmr-lo. skip displaying that
482 : * config to avoid confusion
483 : */
484 0 : if (pim_vxlan_is_term_dev_cfg(pim, ifp))
485 0 : continue;
486 :
487 : /* IF name */
488 0 : if_vty_config_start(vty, ifp);
489 :
490 0 : ++writes;
491 :
492 0 : if (ifp->desc) {
493 0 : vty_out(vty, " description %s\n", ifp->desc);
494 0 : ++writes;
495 : }
496 :
497 0 : if (ifp->info) {
498 0 : pim_config_write(vty, writes, ifp, pim);
499 : }
500 0 : if_vty_config_end(vty);
501 :
502 0 : ++writes;
503 : }
504 : }
505 :
506 0 : return writes;
507 : }
|