1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Copyright (C) 2008 Everton da Silva Marques
18 #include "pim_iface.h"
20 #include "pim_ssmpingd.h"
23 #include "pim_static.h"
29 #include "pim_vxlan.h"
32 int pim_debug_config_write(struct vty
*vty
)
36 if (PIM_DEBUG_MSDP_EVENTS
) {
37 vty_out(vty
, "debug msdp events\n");
40 if (PIM_DEBUG_MSDP_PACKETS
) {
41 vty_out(vty
, "debug msdp packets\n");
44 if (PIM_DEBUG_MSDP_INTERNAL
) {
45 vty_out(vty
, "debug msdp internal\n");
48 if (PIM_DEBUG_GM_EVENTS
) {
49 vty_out(vty
, "debug " GM_AF_DBG
" events\n");
52 if (PIM_DEBUG_GM_PACKETS
) {
53 vty_out(vty
, "debug " GM_AF_DBG
" packets\n");
56 /* PIM_DEBUG_GM_TRACE catches _DETAIL too */
57 if (router
->debugs
& PIM_MASK_GM_TRACE
) {
58 vty_out(vty
, "debug " GM_AF_DBG
" trace\n");
61 if (PIM_DEBUG_GM_TRACE_DETAIL
) {
62 vty_out(vty
, "debug " GM_AF_DBG
" trace detail\n");
66 /* PIM_DEBUG_MROUTE catches _DETAIL too */
67 if (router
->debugs
& PIM_MASK_MROUTE
) {
68 vty_out(vty
, "debug " PIM_MROUTE_DBG
"\n");
71 if (PIM_DEBUG_MROUTE_DETAIL
) {
72 vty_out(vty
, "debug " PIM_MROUTE_DBG
" detail\n");
76 if (PIM_DEBUG_MTRACE
) {
77 vty_out(vty
, "debug mtrace\n");
81 if (PIM_DEBUG_PIM_EVENTS
) {
82 vty_out(vty
, "debug " PIM_AF_DBG
" events\n");
85 if (PIM_DEBUG_PIM_PACKETS
) {
86 vty_out(vty
, "debug " PIM_AF_DBG
" packets\n");
89 if (PIM_DEBUG_PIM_PACKETDUMP_SEND
) {
90 vty_out(vty
, "debug " PIM_AF_DBG
" packet-dump send\n");
93 if (PIM_DEBUG_PIM_PACKETDUMP_RECV
) {
94 vty_out(vty
, "debug " PIM_AF_DBG
" packet-dump receive\n");
98 /* PIM_DEBUG_PIM_TRACE catches _DETAIL too */
99 if (router
->debugs
& PIM_MASK_PIM_TRACE
) {
100 vty_out(vty
, "debug " PIM_AF_DBG
" trace\n");
103 if (PIM_DEBUG_PIM_TRACE_DETAIL
) {
104 vty_out(vty
, "debug " PIM_AF_DBG
" trace detail\n");
108 if (PIM_DEBUG_ZEBRA
) {
109 vty_out(vty
, "debug " PIM_AF_DBG
" zebra\n");
113 if (PIM_DEBUG_MLAG
) {
114 vty_out(vty
, "debug pim mlag\n");
119 vty_out(vty
, "debug " PIM_AF_DBG
" bsm\n");
123 if (PIM_DEBUG_VXLAN
) {
124 vty_out(vty
, "debug " PIM_AF_DBG
" vxlan\n");
128 if (PIM_DEBUG_SSMPINGD
) {
129 vty_out(vty
, "debug ssmpingd\n");
133 if (PIM_DEBUG_PIM_HELLO
) {
134 vty_out(vty
, "debug " PIM_AF_DBG
" packets hello\n");
138 if (PIM_DEBUG_PIM_J_P
) {
139 vty_out(vty
, "debug " PIM_AF_DBG
" packets joins\n");
143 if (PIM_DEBUG_PIM_REG
) {
144 vty_out(vty
, "debug " PIM_AF_DBG
" packets register\n");
148 if (PIM_DEBUG_STATIC
) {
149 vty_out(vty
, "debug pim static\n");
153 if (PIM_DEBUG_PIM_NHT
) {
154 vty_out(vty
, "debug " PIM_AF_DBG
" nht\n");
158 if (PIM_DEBUG_PIM_NHT_RP
) {
159 vty_out(vty
, "debug pim nht rp\n");
163 if (PIM_DEBUG_PIM_NHT_DETAIL
) {
164 vty_out(vty
, "debug " PIM_AF_DBG
" nht detail\n");
171 int pim_global_config_write_worker(struct pim_instance
*pim
, struct vty
*vty
)
174 struct pim_ssm
*ssm
= pim
->ssm_info
;
177 if (pim
->vrf
->vrf_id
== VRF_DEFAULT
)
178 snprintf(spaces
, sizeof(spaces
), "%s", "");
180 snprintf(spaces
, sizeof(spaces
), "%s", " ");
182 writes
+= pim_msdp_peer_config_write(vty
, pim
, spaces
);
183 writes
+= pim_msdp_config_write(pim
, vty
, spaces
);
185 if (!pim
->send_v6_secondary
) {
186 vty_out(vty
, "%sno ip pim send-v6-secondary\n", spaces
);
190 writes
+= pim_rp_config_write(pim
, vty
, spaces
);
192 if (pim
->vrf
->vrf_id
== VRF_DEFAULT
) {
193 if (router
->register_suppress_time
194 != PIM_REGISTER_SUPPRESSION_TIME_DEFAULT
) {
195 vty_out(vty
, "%s" PIM_AF_NAME
" pim register-suppress-time %d\n",
196 spaces
, router
->register_suppress_time
);
199 if (router
->t_periodic
!= PIM_DEFAULT_T_PERIODIC
) {
200 vty_out(vty
, "%s" PIM_AF_NAME
" pim join-prune-interval %d\n",
201 spaces
, router
->t_periodic
);
205 if (router
->packet_process
!= PIM_DEFAULT_PACKET_PROCESS
) {
206 vty_out(vty
, "%s" PIM_AF_NAME
" pim packets %d\n", spaces
,
207 router
->packet_process
);
211 if (pim
->keep_alive_time
!= PIM_KEEPALIVE_PERIOD
) {
212 vty_out(vty
, "%s" PIM_AF_NAME
" pim keep-alive-timer %d\n",
213 spaces
, pim
->keep_alive_time
);
216 if (pim
->rp_keep_alive_time
!= (unsigned int)PIM_RP_KEEPALIVE_PERIOD
) {
217 vty_out(vty
, "%s" PIM_AF_NAME
" pim rp keep-alive-timer %d\n",
218 spaces
, pim
->rp_keep_alive_time
);
221 if (ssm
->plist_name
) {
222 vty_out(vty
, "%sip pim ssm prefix-list %s\n", spaces
,
226 if (pim
->register_plist
) {
227 vty_out(vty
, "%sip pim register-accept-list %s\n", spaces
,
228 pim
->register_plist
);
231 if (pim
->spt
.switchover
== PIM_SPT_INFINITY
) {
234 "%s" PIM_AF_NAME
" pim spt-switchover infinity-and-beyond prefix-list %s\n",
235 spaces
, pim
->spt
.plist
);
238 "%s" PIM_AF_NAME
" pim spt-switchover infinity-and-beyond\n",
242 if (pim
->ecmp_rebalance_enable
) {
243 vty_out(vty
, "%sip pim ecmp rebalance\n", spaces
);
245 } else if (pim
->ecmp_enable
) {
246 vty_out(vty
, "%sip pim ecmp\n", spaces
);
250 if (pim
->gm_watermark_limit
!= 0) {
252 vty_out(vty
, "%s" PIM_AF_NAME
" igmp watermark-warn %u\n",
253 spaces
, pim
->gm_watermark_limit
);
255 vty_out(vty
, "%s" PIM_AF_NAME
" mld watermark-warn %u\n",
256 spaces
, pim
->gm_watermark_limit
);
261 if (pim
->ssmpingd_list
) {
262 struct listnode
*node
;
263 struct ssmpingd_sock
*ss
;
265 for (ALL_LIST_ELEMENTS_RO(pim
->ssmpingd_list
, node
, ss
)) {
266 vty_out(vty
, "%s" PIM_AF_NAME
" ssmpingd %pPA\n",
267 spaces
, &ss
->source_addr
);
272 if (pim
->msdp
.hold_time
!= PIM_MSDP_PEER_HOLD_TIME
273 || pim
->msdp
.keep_alive
!= PIM_MSDP_PEER_KA_TIME
274 || pim
->msdp
.connection_retry
!= PIM_MSDP_PEER_CONNECT_RETRY_TIME
) {
275 vty_out(vty
, "%sip msdp timers %u %u", spaces
,
276 pim
->msdp
.hold_time
, pim
->msdp
.keep_alive
);
277 if (pim
->msdp
.connection_retry
278 != PIM_MSDP_PEER_CONNECT_RETRY_TIME
)
279 vty_out(vty
, " %u", pim
->msdp
.connection_retry
);
287 static int gm_config_write(struct vty
*vty
, int writes
,
288 struct pim_interface
*pim_ifp
)
291 if (pim_ifp
->gm_enable
) {
292 vty_out(vty
, " ip igmp\n");
296 /* ip igmp version */
297 if (pim_ifp
->igmp_version
!= IGMP_DEFAULT_VERSION
) {
298 vty_out(vty
, " ip igmp version %d\n", pim_ifp
->igmp_version
);
302 /* IF ip igmp query-max-response-time */
303 if (pim_ifp
->gm_query_max_response_time_dsec
!=
304 GM_QUERY_MAX_RESPONSE_TIME_DSEC
) {
305 vty_out(vty
, " ip igmp query-max-response-time %d\n",
306 pim_ifp
->gm_query_max_response_time_dsec
);
310 /* IF ip igmp query-interval */
311 if (pim_ifp
->gm_default_query_interval
!= GM_GENERAL_QUERY_INTERVAL
) {
312 vty_out(vty
, " ip igmp query-interval %d\n",
313 pim_ifp
->gm_default_query_interval
);
317 /* IF ip igmp last-member_query-count */
318 if (pim_ifp
->gm_last_member_query_count
!=
319 GM_DEFAULT_ROBUSTNESS_VARIABLE
) {
320 vty_out(vty
, " ip igmp last-member-query-count %d\n",
321 pim_ifp
->gm_last_member_query_count
);
325 /* IF ip igmp last-member_query-interval */
326 if (pim_ifp
->gm_specific_query_max_response_time_dsec
!=
327 GM_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC
) {
328 vty_out(vty
, " ip igmp last-member-query-interval %d\n",
329 pim_ifp
->gm_specific_query_max_response_time_dsec
);
333 /* IF ip igmp join */
334 if (pim_ifp
->gm_join_list
) {
335 struct listnode
*node
;
337 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->gm_join_list
, node
, ij
)) {
338 char group_str
[INET_ADDRSTRLEN
];
339 char source_str
[INET_ADDRSTRLEN
];
340 pim_inet4_dump("<grp?>", ij
->group_addr
, group_str
,
342 if (ij
->source_addr
.s_addr
== INADDR_ANY
) {
343 vty_out(vty
, " ip igmp join %s\n", group_str
);
345 inet_ntop(AF_INET
, &ij
->source_addr
, source_str
,
347 vty_out(vty
, " ip igmp join %s %s\n", group_str
,
357 static int gm_config_write(struct vty
*vty
, int writes
,
358 struct pim_interface
*pim_ifp
)
361 if (pim_ifp
->gm_enable
) {
362 vty_out(vty
, " ipv6 mld\n");
366 if (pim_ifp
->mld_version
!= MLD_DEFAULT_VERSION
)
367 vty_out(vty
, " ipv6 mld version %d\n", pim_ifp
->mld_version
);
369 /* IF ipv6 mld query-max-response-time */
370 if (pim_ifp
->gm_query_max_response_time_dsec
!=
371 GM_QUERY_MAX_RESPONSE_TIME_DSEC
)
372 vty_out(vty
, " ipv6 mld query-max-response-time %d\n",
373 pim_ifp
->gm_query_max_response_time_dsec
);
375 if (pim_ifp
->gm_default_query_interval
!= GM_GENERAL_QUERY_INTERVAL
)
376 vty_out(vty
, " ipv6 mld query-interval %d\n",
377 pim_ifp
->gm_default_query_interval
);
379 /* IF ipv6 mld last-member_query-count */
380 if (pim_ifp
->gm_last_member_query_count
!=
381 GM_DEFAULT_ROBUSTNESS_VARIABLE
)
382 vty_out(vty
, " ipv6 mld last-member-query-count %d\n",
383 pim_ifp
->gm_last_member_query_count
);
385 /* IF ipv6 mld last-member_query-interval */
386 if (pim_ifp
->gm_specific_query_max_response_time_dsec
!=
387 GM_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC
)
388 vty_out(vty
, " ipv6 mld last-member-query-interval %d\n",
389 pim_ifp
->gm_specific_query_max_response_time_dsec
);
395 int pim_config_write(struct vty
*vty
, int writes
, struct interface
*ifp
,
396 struct pim_instance
*pim
)
398 struct pim_interface
*pim_ifp
= ifp
->info
;
400 if (pim_ifp
->pim_enable
) {
401 vty_out(vty
, " " PIM_AF_NAME
" pim\n");
405 /* IF ip pim drpriority */
406 if (pim_ifp
->pim_dr_priority
!= PIM_DEFAULT_DR_PRIORITY
) {
407 vty_out(vty
, " " PIM_AF_NAME
" pim drpriority %u\n",
408 pim_ifp
->pim_dr_priority
);
412 /* IF ip pim hello */
413 if (pim_ifp
->pim_hello_period
!= PIM_DEFAULT_HELLO_PERIOD
) {
414 vty_out(vty
, " " PIM_AF_NAME
" pim hello %d", pim_ifp
->pim_hello_period
);
415 if (pim_ifp
->pim_default_holdtime
!= -1)
416 vty_out(vty
, " %d", pim_ifp
->pim_default_holdtime
);
421 writes
+= gm_config_write(vty
, writes
, pim_ifp
);
424 if (!pim_addr_is_any(pim_ifp
->update_source
)) {
425 vty_out(vty
, " " PIM_AF_NAME
" pim use-source %pPA\n",
426 &pim_ifp
->update_source
);
430 if (pim_ifp
->activeactive
)
431 vty_out(vty
, " " PIM_AF_NAME
" pim active-active\n");
434 if (pim_ifp
->boundary_oil_plist
) {
435 vty_out(vty
, " " PIM_AF_NAME
" multicast boundary oil %s\n",
436 pim_ifp
->boundary_oil_plist
);
440 if (pim_ifp
->pim_passive_enable
) {
441 vty_out(vty
, " " PIM_AF_NAME
" pim passive\n");
445 writes
+= pim_static_write_mroute(pim
, vty
, ifp
);
446 pim_bsm_write_config(vty
, ifp
);
448 pim_bfd_write_config(vty
, ifp
);
454 int pim_interface_config_write(struct vty
*vty
)
456 struct pim_instance
*pim
;
457 struct interface
*ifp
;
461 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
466 FOR_ALL_INTERFACES (pim
->vrf
, ifp
) {
467 /* pim is enabled internally/implicitly on the vxlan
468 * termination device ipmr-lo. skip displaying that
469 * config to avoid confusion
471 if (pim_vxlan_is_term_dev_cfg(pim
, ifp
))
475 if_vty_config_start(vty
, ifp
);
480 vty_out(vty
, " description %s\n", ifp
->desc
);
485 pim_config_write(vty
, writes
, ifp
, pim
);
487 if_vty_config_end(vty
);