1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2020 VmWare
11 #include "lib/northbound_cli.h"
12 #include "pim_igmpv3.h"
13 #include "pim_neighbor.h"
18 #include "pim_static.h"
20 #include "pim_ssmpingd.h"
21 #include "pim_vxlan.h"
24 #include "lib_errors.h"
29 #define pim6_msdp_err(funcname, argtype) \
30 int funcname(struct argtype *args) \
32 snprintf(args->errmsg, args->errmsg_len, \
33 "Trying to configure MSDP in pim6d. " \
34 "MSDP does not exist for IPv6."); \
35 return NB_ERR_VALIDATION; \
37 MACRO_REQUIRE_SEMICOLON()
39 #define yang_dnode_get_pimaddr yang_dnode_get_ipv6
41 #else /* PIM_IPV != 6 */
42 #define pim6_msdp_err(funcname, argtype) \
43 MACRO_REQUIRE_SEMICOLON()
45 #define yang_dnode_get_pimaddr yang_dnode_get_ipv4
46 #endif /* PIM_IPV != 6 */
48 static void pim_if_membership_clear(struct interface
*ifp
)
50 struct pim_interface
*pim_ifp
;
55 if (pim_ifp
->pim_enable
&& pim_ifp
->gm_enable
) {
59 pim_ifchannel_membership_clear(ifp
);
63 * When PIM is disabled on interface, IGMPv3 local membership
64 * information is not injected into PIM interface state.
66 * The function pim_if_membership_refresh() fetches all IGMPv3 local
67 * membership information into PIM. It is intented to be called
68 * whenever PIM is enabled on the interface in order to collect missed
69 * local membership information.
71 static void pim_if_membership_refresh(struct interface
*ifp
)
73 struct pim_interface
*pim_ifp
;
75 struct listnode
*grpnode
;
79 struct gm_sg
*sg
, *sg_start
;
85 gm_ifp
= pim_ifp
->mld
;
88 if (!pim_ifp
->pim_enable
)
90 if (!pim_ifp
->gm_enable
)
94 * First clear off membership from all PIM (S,G) entries on the
98 pim_ifchannel_membership_clear(ifp
);
102 * Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
106 /* scan igmp groups */
107 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->gm_group_list
, grpnode
, grp
)) {
108 struct listnode
*srcnode
;
109 struct gm_source
*src
;
111 /* scan group sources */
112 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, srcnode
,
115 if (IGMP_SOURCE_TEST_FORWARDING(src
->source_flags
)) {
118 memset(&sg
, 0, sizeof(sg
));
119 sg
.src
= src
->source_addr
;
120 sg
.grp
= grp
->group_addr
;
121 pim_ifchannel_local_membership_add(
122 ifp
, &sg
, false /*is_vxlan*/);
125 } /* scan group sources */
126 } /* scan igmp groups */
128 sg_start
= gm_sgs_first(gm_ifp
->sgs
);
130 frr_each_from (gm_sgs
, gm_ifp
->sgs
, sg
, sg_start
) {
131 if (!in6_multicast_nofwd(&sg
->sgaddr
.grp
)) {
132 pim_ifchannel_local_membership_add(
133 ifp
, &sg
->sgaddr
, false /*is_vxlan*/);
139 * Finally delete every PIM (S,G) entry lacking all state info
142 pim_ifchannel_delete_on_noinfo(ifp
);
145 static int pim_cmd_interface_add(struct interface
*ifp
)
147 struct pim_interface
*pim_ifp
= ifp
->info
;
150 pim_ifp
= pim_if_new(ifp
, false, true, false, false);
152 pim_ifp
->pim_enable
= true;
154 pim_if_addr_add_all(ifp
);
155 pim_upstream_nh_if_update(pim_ifp
->pim
, ifp
);
156 pim_if_membership_refresh(ifp
);
158 pim_if_create_pimreg(pim_ifp
->pim
);
162 static int pim_cmd_interface_delete(struct interface
*ifp
)
164 struct pim_interface
*pim_ifp
= ifp
->info
;
169 pim_ifp
->pim_enable
= false;
171 pim_if_membership_clear(ifp
);
174 * pim_sock_delete() removes all neighbors from
175 * pim_ifp->pim_neighbor_list.
177 pim_sock_delete(ifp
, "pim unconfigured on interface");
178 pim_upstream_nh_if_update(pim_ifp
->pim
, ifp
);
180 if (!pim_ifp
->gm_enable
) {
181 pim_if_addr_del_all(ifp
);
188 static int interface_pim_use_src_cmd_worker(struct interface
*ifp
,
189 pim_addr source_addr
, char *errmsg
, size_t errmsg_len
)
194 result
= pim_update_source_set(ifp
, source_addr
);
199 case PIM_IFACE_NOT_FOUND
:
201 snprintf(errmsg
, errmsg_len
,
202 "Pim not enabled on this interface %s",
205 case PIM_UPDATE_SOURCE_DUP
:
207 snprintf(errmsg
, errmsg_len
, "Source already set");
211 snprintf(errmsg
, errmsg_len
, "Source set failed");
217 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
218 enum pim_spt_switchover spt
,
221 pim
->spt
.switchover
= spt
;
223 switch (pim
->spt
.switchover
) {
224 case PIM_SPT_IMMEDIATE
:
225 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->spt
.plist
);
227 pim_upstream_add_lhr_star_pimreg(pim
);
229 case PIM_SPT_INFINITY
:
230 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
232 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->spt
.plist
);
235 pim
->spt
.plist
= XSTRDUP(MTYPE_PIM_PLIST_NAME
, plist
);
242 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, const char *plist
,
243 char *errmsg
, size_t errmsg_len
)
245 int result
= pim_ssm_range_set(pim
, pim
->vrf
->vrf_id
, plist
);
248 if (result
== PIM_SSM_ERR_NONE
)
252 case PIM_SSM_ERR_NO_VRF
:
253 snprintf(errmsg
, errmsg_len
,
254 "VRF doesn't exist");
256 case PIM_SSM_ERR_DUP
:
257 snprintf(errmsg
, errmsg_len
,
261 snprintf(errmsg
, errmsg_len
,
262 "ssm range config failed");
268 static int pim_rp_cmd_worker(struct pim_instance
*pim
, pim_addr rp_addr
,
269 struct prefix group
, const char *plist
,
270 char *errmsg
, size_t errmsg_len
)
274 result
= pim_rp_new(pim
, rp_addr
, group
, plist
, RP_SRC_STATIC
);
276 if (result
== PIM_RP_NO_PATH
) {
277 snprintfrr(errmsg
, errmsg_len
,
278 "No Path to RP address specified: %pPA", &rp_addr
);
279 return NB_ERR_INCONSISTENCY
;
282 if (result
== PIM_GROUP_OVERLAP
) {
283 snprintf(errmsg
, errmsg_len
,
284 "Group range specified cannot exact match another");
285 return NB_ERR_INCONSISTENCY
;
288 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
289 snprintf(errmsg
, errmsg_len
,
290 "This group is already covered by a RP prefix-list");
291 return NB_ERR_INCONSISTENCY
;
294 if (result
== PIM_RP_PFXLIST_IN_USE
) {
295 snprintf(errmsg
, errmsg_len
,
296 "The same prefix-list cannot be applied to multiple RPs");
297 return NB_ERR_INCONSISTENCY
;
303 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, pim_addr rp_addr
,
304 struct prefix group
, const char *plist
,
305 char *errmsg
, size_t errmsg_len
)
307 char group_str
[PREFIX2STR_BUFFER
];
310 prefix2str(&group
, group_str
, sizeof(group_str
));
312 result
= pim_rp_del(pim
, rp_addr
, group
, plist
, RP_SRC_STATIC
);
314 if (result
== PIM_GROUP_BAD_ADDRESS
) {
315 snprintf(errmsg
, errmsg_len
,
316 "Bad group address specified: %s", group_str
);
317 return NB_ERR_INCONSISTENCY
;
320 if (result
== PIM_RP_BAD_ADDRESS
) {
321 snprintfrr(errmsg
, errmsg_len
, "Bad RP address specified: %pPA",
323 return NB_ERR_INCONSISTENCY
;
326 if (result
== PIM_RP_NOT_FOUND
) {
327 snprintf(errmsg
, errmsg_len
,
328 "Unable to find specified RP");
329 return NB_ERR_INCONSISTENCY
;
335 static bool is_pim_interface(const struct lyd_node
*dnode
)
337 char if_xpath
[XPATH_MAXLEN
];
338 const struct lyd_node
*pim_enable_dnode
;
339 const struct lyd_node
*igmp_enable_dnode
;
341 yang_dnode_get_path(dnode
, if_xpath
, sizeof(if_xpath
));
343 yang_dnode_getf(dnode
,
344 "%s/frr-pim:pim/address-family[address-family='%s']/pim-enable",
345 if_xpath
, FRR_PIM_AF_XPATH_VAL
);
346 igmp_enable_dnode
= yang_dnode_getf(dnode
,
347 "%s/frr-gmp:gmp/address-family[address-family='%s']/enable",
348 if_xpath
, FRR_PIM_AF_XPATH_VAL
);
350 if (((pim_enable_dnode
) &&
351 (yang_dnode_get_bool(pim_enable_dnode
, "."))) ||
352 ((igmp_enable_dnode
) &&
353 (yang_dnode_get_bool(igmp_enable_dnode
, "."))))
359 static int pim_cmd_gm_start(struct interface
*ifp
)
361 struct pim_interface
*pim_ifp
;
362 uint8_t need_startup
= 0;
367 pim_ifp
= pim_if_new(ifp
, true, false, false, false);
370 if (!pim_ifp
->gm_enable
) {
371 pim_ifp
->gm_enable
= true;
375 pim_if_create_pimreg(pim_ifp
->pim
);
377 /* 'ip igmp' executed multiple times, with need_startup
378 * avoid multiple if add all and membership refresh
381 pim_if_addr_add_all(ifp
);
382 pim_if_membership_refresh(ifp
);
389 * CLI reconfiguration affects the interface level (struct pim_interface).
390 * This function propagates the reconfiguration to every active socket
391 * for that interface.
394 static void igmp_sock_query_interval_reconfig(struct gm_sock
*igmp
)
396 struct interface
*ifp
;
397 struct pim_interface
*pim_ifp
;
400 assert(igmp
->interface
);
401 assert(igmp
->interface
->info
);
403 ifp
= igmp
->interface
;
406 if (PIM_DEBUG_GM_TRACE
)
407 zlog_debug("%s: Querier %pPAs on %s reconfig query_interval=%d",
408 __func__
, &igmp
->ifaddr
, ifp
->name
,
409 pim_ifp
->gm_default_query_interval
);
412 * igmp_startup_mode_on() will reset QQI:
414 * igmp->querier_query_interval = pim_ifp->gm_default_query_interval;
416 igmp_startup_mode_on(igmp
);
419 static void igmp_sock_query_reschedule(struct gm_sock
*igmp
)
421 if (igmp
->mtrace_only
)
424 if (igmp
->t_igmp_query_timer
) {
425 /* other querier present */
426 assert(igmp
->t_igmp_query_timer
);
427 assert(!igmp
->t_other_querier_timer
);
429 pim_igmp_general_query_off(igmp
);
430 pim_igmp_general_query_on(igmp
);
432 assert(igmp
->t_igmp_query_timer
);
433 assert(!igmp
->t_other_querier_timer
);
435 /* this is the querier */
437 assert(!igmp
->t_igmp_query_timer
);
438 assert(igmp
->t_other_querier_timer
);
440 pim_igmp_other_querier_timer_off(igmp
);
441 pim_igmp_other_querier_timer_on(igmp
);
443 assert(!igmp
->t_igmp_query_timer
);
444 assert(igmp
->t_other_querier_timer
);
447 #endif /* PIM_IPV == 4 */
450 static void change_query_interval(struct pim_interface
*pim_ifp
,
453 struct listnode
*sock_node
;
454 struct gm_sock
*igmp
;
456 pim_ifp
->gm_default_query_interval
= query_interval
;
458 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->gm_socket_list
, sock_node
, igmp
)) {
459 igmp_sock_query_interval_reconfig(igmp
);
460 igmp_sock_query_reschedule(igmp
);
465 static void change_query_max_response_time(struct interface
*ifp
,
466 int query_max_response_time_dsec
)
469 struct listnode
*sock_node
;
470 struct gm_sock
*igmp
;
471 struct listnode
*grp_node
;
472 struct gm_group
*grp
;
475 struct pim_interface
*pim_ifp
= ifp
->info
;
477 if (pim_ifp
->gm_query_max_response_time_dsec
==
478 query_max_response_time_dsec
)
481 pim_ifp
->gm_query_max_response_time_dsec
= query_max_response_time_dsec
;
487 * Below we modify socket/group/source timers in order to quickly
488 * reflect the change. Otherwise, those timers would args->eventually
492 /* scan all sockets */
493 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->gm_socket_list
, sock_node
, igmp
)) {
494 /* reschedule socket general query */
495 igmp_sock_query_reschedule(igmp
);
498 /* scan socket groups */
499 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->gm_group_list
, grp_node
, grp
)) {
500 struct listnode
*src_node
;
501 struct gm_source
*src
;
503 /* reset group timers for groups in EXCLUDE mode */
504 if (grp
->group_filtermode_isexcl
)
505 igmp_group_reset_gmi(grp
);
507 /* scan group sources */
508 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, src_node
,
511 /* reset source timers for sources with running
514 if (src
->t_source_timer
)
515 igmp_source_reset_gmi(grp
, src
);
518 #endif /* PIM_IPV == 4 */
521 int routing_control_plane_protocols_name_validate(
522 struct nb_cb_create_args
*args
)
526 name
= yang_dnode_get_string(args
->dnode
, "./name");
527 if (!strmatch(name
, "pim")) {
528 snprintf(args
->errmsg
, args
->errmsg_len
,
529 "pim supports only one instance with name pimd");
530 return NB_ERR_VALIDATION
;
536 * XPath: /frr-pim:pim/address-family
538 int pim_address_family_create(struct nb_cb_create_args
*args
)
540 switch (args
->event
) {
551 int pim_address_family_destroy(struct nb_cb_destroy_args
*args
)
553 switch (args
->event
) {
565 * XPath: /frr-pim:pim/address-family/packets
567 int pim_address_family_packets_modify(struct nb_cb_modify_args
*args
)
569 switch (args
->event
) {
575 router
->packet_process
= yang_dnode_get_uint8(args
->dnode
,
584 * XPath: /frr-pim:pim/address-family/join-prune-interval
586 int pim_address_family_join_prune_interval_modify(
587 struct nb_cb_modify_args
*args
)
589 switch (args
->event
) {
595 router
->t_periodic
= yang_dnode_get_uint16(args
->dnode
, NULL
);
603 * XPath: /frr-pim:pim/address-family/register-suppress-time
605 int pim_address_family_register_suppress_time_modify(
606 struct nb_cb_modify_args
*args
)
609 switch (args
->event
) {
611 value
= yang_dnode_get_uint16(args
->dnode
, NULL
);
613 * As soon as this is non-constant it needs to be replaced with
614 * a yang_dnode_get to lookup the candidate value, *not* the
615 * operational value. Since the code has a field assigned and
616 * used for this value it should have YANG/CLI to set it too,
617 * otherwise just use the #define!
619 /* RFC7761: 4.11. Timer Values */
620 if (value
<= router
->register_probe_time
* 2) {
622 args
->errmsg
, args
->errmsg_len
,
623 "Register suppress time (%u) must be more than "
624 "twice the register probe time (%u).",
625 value
, router
->register_probe_time
);
626 return NB_ERR_VALIDATION
;
633 pim_update_suppress_timers(
634 yang_dnode_get_uint16(args
->dnode
, NULL
));
642 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/ecmp
644 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ecmp_modify(
645 struct nb_cb_modify_args
*args
)
648 struct pim_instance
*pim
;
650 switch (args
->event
) {
656 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
658 pim
->ecmp_enable
= yang_dnode_get_bool(args
->dnode
, NULL
);
665 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/ecmp-rebalance
667 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ecmp_rebalance_modify(
668 struct nb_cb_modify_args
*args
)
671 struct pim_instance
*pim
;
673 switch (args
->event
) {
679 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
681 pim
->ecmp_rebalance_enable
=
682 yang_dnode_get_bool(args
->dnode
, NULL
);
689 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/keep-alive-timer
691 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_keep_alive_timer_modify(
692 struct nb_cb_modify_args
*args
)
695 struct pim_instance
*pim
;
697 switch (args
->event
) {
703 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
705 pim
->keep_alive_time
= yang_dnode_get_uint16(args
->dnode
, NULL
);
713 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/rp-keep-alive-timer
715 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_keep_alive_timer_modify(
716 struct nb_cb_modify_args
*args
)
719 struct pim_instance
*pim
;
721 switch (args
->event
) {
727 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
729 pim
->rp_keep_alive_time
= yang_dnode_get_uint16(args
->dnode
,
738 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family
740 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_create(
741 struct nb_cb_create_args
*args
)
743 switch (args
->event
) {
754 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_destroy(
755 struct nb_cb_destroy_args
*args
)
757 switch (args
->event
) {
769 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/send-v6-secondary
771 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_send_v6_secondary_modify(
772 struct nb_cb_modify_args
*args
)
775 struct pim_instance
*pim
;
777 switch (args
->event
) {
783 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
785 pim
->send_v6_secondary
= yang_dnode_get_bool(args
->dnode
, NULL
);
792 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_send_v6_secondary_destroy(
793 struct nb_cb_destroy_args
*args
)
795 switch (args
->event
) {
808 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/spt-switchover
810 void routing_control_plane_protocols_control_plane_protocol_pim_address_family_spt_switchover_apply_finish(
811 struct nb_cb_apply_finish_args
*args
)
814 struct pim_instance
*pim
;
815 int spt_switch_action
;
816 const char *prefix_list
= NULL
;
818 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
820 spt_switch_action
= yang_dnode_get_enum(args
->dnode
, "./spt-action");
822 switch (spt_switch_action
) {
823 case PIM_SPT_INFINITY
:
824 if (yang_dnode_exists(args
->dnode
,
825 "./spt-infinity-prefix-list"))
826 prefix_list
= yang_dnode_get_string(
827 args
->dnode
, "./spt-infinity-prefix-list");
829 pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
,
832 case PIM_SPT_IMMEDIATE
:
833 pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
838 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/spt-switchover/spt-action
840 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_spt_switchover_spt_action_modify(
841 struct nb_cb_modify_args
*args
)
843 switch (args
->event
) {
855 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/spt-switchover/spt-infinity-prefix-list
857 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_spt_switchover_spt_infinity_prefix_list_modify(
858 struct nb_cb_modify_args
*args
)
860 switch (args
->event
) {
871 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_spt_switchover_spt_infinity_prefix_list_destroy(
872 struct nb_cb_destroy_args
*args
)
874 switch (args
->event
) {
886 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/ssm-prefix-list
888 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_prefix_list_modify(
889 struct nb_cb_modify_args
*args
)
892 struct pim_instance
*pim
;
893 const char *plist_name
;
896 switch (args
->event
) {
902 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
904 plist_name
= yang_dnode_get_string(args
->dnode
, NULL
);
905 result
= pim_ssm_cmd_worker(pim
, plist_name
, args
->errmsg
,
909 return NB_ERR_INCONSISTENCY
;
917 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_prefix_list_destroy(
918 struct nb_cb_destroy_args
*args
)
921 struct pim_instance
*pim
;
924 switch (args
->event
) {
930 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
932 result
= pim_ssm_cmd_worker(pim
, NULL
, args
->errmsg
,
936 return NB_ERR_INCONSISTENCY
;
945 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/ssm-pingd-source-ip
947 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_pingd_source_ip_create(
948 struct nb_cb_create_args
*args
)
951 struct pim_instance
*pim
;
953 pim_addr source_addr
;
955 switch (args
->event
) {
961 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
963 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
,
965 result
= pim_ssmpingd_start(pim
, source_addr
);
968 args
->errmsg
, args
->errmsg_len
,
969 "%% Failure starting ssmpingd for source %pPA: %d",
970 &source_addr
, result
);
971 return NB_ERR_INCONSISTENCY
;
978 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_pingd_source_ip_destroy(
979 struct nb_cb_destroy_args
*args
)
982 struct pim_instance
*pim
;
984 pim_addr source_addr
;
986 switch (args
->event
) {
992 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
994 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
,
996 result
= pim_ssmpingd_stop(pim
, source_addr
);
999 args
->errmsg
, args
->errmsg_len
,
1000 "%% Failure stopping ssmpingd for source %pPA: %d",
1001 &source_addr
, result
);
1002 return NB_ERR_INCONSISTENCY
;
1013 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/hold-time
1015 int pim_msdp_hold_time_modify(struct nb_cb_modify_args
*args
)
1017 struct pim_instance
*pim
;
1020 switch (args
->event
) {
1021 case NB_EV_VALIDATE
:
1026 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1028 pim
->msdp
.hold_time
= yang_dnode_get_uint16(args
->dnode
, NULL
);
1037 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/keep-alive
1039 int pim_msdp_keep_alive_modify(struct nb_cb_modify_args
*args
)
1041 struct pim_instance
*pim
;
1044 switch (args
->event
) {
1045 case NB_EV_VALIDATE
:
1050 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1052 pim
->msdp
.keep_alive
= yang_dnode_get_uint16(args
->dnode
, NULL
);
1061 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/connection-retry
1063 int pim_msdp_connection_retry_modify(struct nb_cb_modify_args
*args
)
1065 struct pim_instance
*pim
;
1068 switch (args
->event
) {
1069 case NB_EV_VALIDATE
:
1074 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1076 pim
->msdp
.connection_retry
=
1077 yang_dnode_get_uint16(args
->dnode
, NULL
);
1084 pim6_msdp_err(pim_msdp_mesh_group_destroy
, nb_cb_destroy_args
);
1085 pim6_msdp_err(pim_msdp_mesh_group_create
, nb_cb_create_args
);
1086 pim6_msdp_err(pim_msdp_mesh_group_source_modify
, nb_cb_modify_args
);
1087 pim6_msdp_err(pim_msdp_mesh_group_source_destroy
, nb_cb_destroy_args
);
1088 pim6_msdp_err(pim_msdp_mesh_group_members_create
, nb_cb_create_args
);
1089 pim6_msdp_err(pim_msdp_mesh_group_members_destroy
, nb_cb_destroy_args
);
1090 pim6_msdp_err(routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify
,
1092 pim6_msdp_err(routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_destroy
,
1093 nb_cb_destroy_args
);
1094 pim6_msdp_err(routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_create
,
1100 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups
1102 int pim_msdp_mesh_group_create(struct nb_cb_create_args
*args
)
1104 struct pim_msdp_mg
*mg
;
1107 switch (args
->event
) {
1108 case NB_EV_VALIDATE
:
1113 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1114 mg
= pim_msdp_mg_new(vrf
->info
, yang_dnode_get_string(
1115 args
->dnode
, "./name"));
1116 nb_running_set_entry(args
->dnode
, mg
);
1123 int pim_msdp_mesh_group_destroy(struct nb_cb_destroy_args
*args
)
1125 struct pim_msdp_mg
*mg
;
1128 switch (args
->event
) {
1129 case NB_EV_VALIDATE
:
1134 mg
= nb_running_unset_entry(args
->dnode
);
1135 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1136 pim_msdp_mg_free(vrf
->info
, &mg
);
1145 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups/source
1147 int pim_msdp_mesh_group_source_modify(struct nb_cb_modify_args
*args
)
1149 const struct lyd_node
*vrf_dnode
;
1150 struct pim_msdp_mg
*mg
;
1154 switch (args
->event
) {
1155 case NB_EV_VALIDATE
:
1160 mg
= nb_running_get_entry(args
->dnode
, NULL
, true);
1162 yang_dnode_get_parent(args
->dnode
, "address-family");
1163 vrf
= nb_running_get_entry(vrf_dnode
, "../../", true);
1164 yang_dnode_get_ip(&ip
, args
->dnode
, NULL
);
1166 pim_msdp_mg_src_add(vrf
->info
, mg
, &ip
.ip
._v4_addr
);
1172 int pim_msdp_mesh_group_source_destroy(struct nb_cb_destroy_args
*args
)
1174 const struct lyd_node
*vrf_dnode
;
1175 struct pim_msdp_mg
*mg
;
1177 struct in_addr addr
;
1179 switch (args
->event
) {
1180 case NB_EV_VALIDATE
:
1185 mg
= nb_running_get_entry(args
->dnode
, NULL
, true);
1187 yang_dnode_get_parent(args
->dnode
, "address-family");
1188 vrf
= nb_running_get_entry(vrf_dnode
, "../../", true);
1190 addr
.s_addr
= INADDR_ANY
;
1191 pim_msdp_mg_src_add(vrf
->info
, mg
, &addr
);
1200 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups/members
1202 int pim_msdp_mesh_group_members_create(struct nb_cb_create_args
*args
)
1204 const struct lyd_node
*vrf_dnode
;
1205 struct pim_msdp_mg_mbr
*mbr
;
1206 struct pim_msdp_mg
*mg
;
1210 switch (args
->event
) {
1211 case NB_EV_VALIDATE
:
1216 mg
= nb_running_get_entry(args
->dnode
, NULL
, true);
1218 yang_dnode_get_parent(args
->dnode
, "address-family");
1219 vrf
= nb_running_get_entry(vrf_dnode
, "../../", true);
1220 yang_dnode_get_ip(&ip
, args
->dnode
, "address");
1222 mbr
= pim_msdp_mg_mbr_add(vrf
->info
, mg
, &ip
.ip
._v4_addr
);
1223 nb_running_set_entry(args
->dnode
, mbr
);
1230 int pim_msdp_mesh_group_members_destroy(struct nb_cb_destroy_args
*args
)
1232 struct pim_msdp_mg_mbr
*mbr
;
1233 struct pim_msdp_mg
*mg
;
1234 const struct lyd_node
*mg_dnode
;
1236 switch (args
->event
) {
1237 case NB_EV_VALIDATE
:
1242 mbr
= nb_running_get_entry(args
->dnode
, NULL
, true);
1244 yang_dnode_get_parent(args
->dnode
, "msdp-mesh-groups");
1245 mg
= nb_running_get_entry(mg_dnode
, NULL
, true);
1246 pim_msdp_mg_mbr_del(mg
, mbr
);
1247 nb_running_unset_entry(args
->dnode
);
1255 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-peer
1257 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_create(
1258 struct nb_cb_create_args
*args
)
1260 struct pim_msdp_peer
*mp
;
1261 struct pim_instance
*pim
;
1263 struct ipaddr peer_ip
;
1264 struct ipaddr source_ip
;
1266 switch (args
->event
) {
1267 case NB_EV_VALIDATE
:
1272 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1274 yang_dnode_get_ip(&peer_ip
, args
->dnode
, "./peer-ip");
1275 yang_dnode_get_ip(&source_ip
, args
->dnode
, "./source-ip");
1276 mp
= pim_msdp_peer_add(pim
, &peer_ip
.ipaddr_v4
,
1277 &source_ip
.ipaddr_v4
, NULL
);
1278 nb_running_set_entry(args
->dnode
, mp
);
1285 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_destroy(
1286 struct nb_cb_destroy_args
*args
)
1288 struct pim_msdp_peer
*mp
;
1290 switch (args
->event
) {
1291 case NB_EV_VALIDATE
:
1296 mp
= nb_running_unset_entry(args
->dnode
);
1297 pim_msdp_peer_del(&mp
);
1305 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-peer/source-ip
1307 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify(
1308 struct nb_cb_modify_args
*args
)
1310 struct pim_msdp_peer
*mp
;
1311 struct ipaddr source_ip
;
1313 switch (args
->event
) {
1314 case NB_EV_VALIDATE
:
1319 mp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1320 yang_dnode_get_ip(&source_ip
, args
->dnode
, NULL
);
1321 pim_msdp_peer_change_source(mp
, &source_ip
.ipaddr_v4
);
1327 #endif /* PIM_IPV != 6 */
1330 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag
1332 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_create(
1333 struct nb_cb_create_args
*args
)
1335 switch (args
->event
) {
1336 case NB_EV_VALIDATE
:
1346 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_destroy(
1347 struct nb_cb_destroy_args
*args
)
1349 struct in_addr addr
;
1351 switch (args
->event
) {
1352 case NB_EV_VALIDATE
:
1358 pim_vxlan_mlag_update(true/*mlag_enable*/,
1359 false/*peer_state*/, MLAG_ROLE_NONE
,
1360 NULL
/*peerlink*/, &addr
);
1368 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag
1370 void routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_apply_finish(
1371 struct nb_cb_apply_finish_args
*args
)
1376 struct interface
*ifp
;
1377 struct ipaddr reg_addr
;
1379 ifname
= yang_dnode_get_string(args
->dnode
, "./peerlink-rif");
1380 ifp
= if_lookup_by_name(ifname
, VRF_DEFAULT
);
1382 snprintf(args
->errmsg
, args
->errmsg_len
,
1383 "No such interface name %s", ifname
);
1386 role
= yang_dnode_get_enum(args
->dnode
, "./my-role");
1387 peer_state
= yang_dnode_get_bool(args
->dnode
, "./peer-state");
1388 yang_dnode_get_ip(®_addr
, args
->dnode
, "./reg-address");
1390 pim_vxlan_mlag_update(true, peer_state
, role
, ifp
,
1391 ®_addr
.ip
._v4_addr
);
1396 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/peerlink-rif
1398 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_peerlink_rif_modify(
1399 struct nb_cb_modify_args
*args
)
1401 switch (args
->event
) {
1402 case NB_EV_VALIDATE
:
1412 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_peerlink_rif_destroy(
1413 struct nb_cb_destroy_args
*args
)
1415 switch (args
->event
) {
1416 case NB_EV_VALIDATE
:
1427 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/reg-address
1429 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_reg_address_modify(
1430 struct nb_cb_modify_args
*args
)
1432 switch (args
->event
) {
1433 case NB_EV_VALIDATE
:
1443 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_reg_address_destroy(
1444 struct nb_cb_destroy_args
*args
)
1446 switch (args
->event
) {
1447 case NB_EV_VALIDATE
:
1458 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/my-role
1460 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_my_role_modify(
1461 struct nb_cb_modify_args
*args
)
1463 switch (args
->event
) {
1464 case NB_EV_VALIDATE
:
1475 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/peer-state
1477 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_peer_state_modify(
1478 struct nb_cb_modify_args
*args
)
1480 switch (args
->event
) {
1481 case NB_EV_VALIDATE
:
1492 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/register-accept-list
1494 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_register_accept_list_modify(
1495 struct nb_cb_modify_args
*args
)
1498 struct pim_instance
*pim
;
1501 switch (args
->event
) {
1502 case NB_EV_VALIDATE
:
1507 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1509 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
1511 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
1512 pim
->register_plist
= XSTRDUP(MTYPE_PIM_PLIST_NAME
, plist
);
1520 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_register_accept_list_destroy(
1521 struct nb_cb_destroy_args
*args
)
1524 struct pim_instance
*pim
;
1526 switch (args
->event
) {
1527 case NB_EV_VALIDATE
:
1532 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1535 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
1543 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family
1545 int lib_interface_pim_address_family_create(struct nb_cb_create_args
*args
)
1547 switch (args
->event
) {
1548 case NB_EV_VALIDATE
:
1558 int lib_interface_pim_address_family_destroy(struct nb_cb_destroy_args
*args
)
1560 struct interface
*ifp
;
1561 struct pim_interface
*pim_ifp
;
1563 switch (args
->event
) {
1564 case NB_EV_VALIDATE
:
1569 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1570 pim_ifp
= ifp
->info
;
1574 if (!pim_cmd_interface_delete(ifp
)) {
1575 snprintf(args
->errmsg
, args
->errmsg_len
,
1576 "Unable to delete interface information %s",
1578 return NB_ERR_INCONSISTENCY
;
1586 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/pim-enable
1588 int lib_interface_pim_address_family_pim_enable_modify(struct nb_cb_modify_args
*args
)
1590 struct interface
*ifp
;
1591 struct pim_interface
*pim_ifp
;
1593 const struct lyd_node
*if_dnode
;
1595 switch (args
->event
) {
1596 case NB_EV_VALIDATE
:
1597 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
1599 yang_get_list_elements_count(if_dnode
);
1601 /* Limiting mcast interfaces to number of VIFs */
1602 if (mcast_if_count
== MAXVIFS
) {
1603 snprintf(args
->errmsg
, args
->errmsg_len
,
1604 "Max multicast interfaces(%d) reached.",
1606 return NB_ERR_VALIDATION
;
1613 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1615 if (yang_dnode_get_bool(args
->dnode
, NULL
)) {
1616 if (!pim_cmd_interface_add(ifp
)) {
1617 snprintf(args
->errmsg
, args
->errmsg_len
,
1618 "Could not enable PIM SM on interface %s",
1620 return NB_ERR_INCONSISTENCY
;
1623 pim_ifp
= ifp
->info
;
1625 return NB_ERR_INCONSISTENCY
;
1627 if (!pim_cmd_interface_delete(ifp
)) {
1628 snprintf(args
->errmsg
, args
->errmsg_len
,
1629 "Unable to delete interface information");
1630 return NB_ERR_INCONSISTENCY
;
1641 * /frr-interface:lib/interface/frr-pim:pim/address-family/pim-passive-enable
1643 int lib_interface_pim_address_family_pim_passive_enable_modify(
1644 struct nb_cb_modify_args
*args
)
1646 struct interface
*ifp
;
1647 struct pim_interface
*pim_ifp
;
1649 switch (args
->event
) {
1650 case NB_EV_VALIDATE
:
1655 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1656 pim_ifp
= ifp
->info
;
1657 pim_ifp
->pim_passive_enable
=
1658 yang_dnode_get_bool(args
->dnode
, NULL
);
1666 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/hello-interval
1668 int lib_interface_pim_address_family_hello_interval_modify(
1669 struct nb_cb_modify_args
*args
)
1671 struct interface
*ifp
;
1672 struct pim_interface
*pim_ifp
;
1674 switch (args
->event
) {
1675 case NB_EV_VALIDATE
:
1680 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1681 pim_ifp
= ifp
->info
;
1682 pim_ifp
->pim_hello_period
=
1683 yang_dnode_get_uint8(args
->dnode
, NULL
);
1684 pim_ifp
->pim_default_holdtime
= -1;
1692 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/hello-holdtime
1694 int lib_interface_pim_address_family_hello_holdtime_modify(
1695 struct nb_cb_modify_args
*args
)
1697 struct interface
*ifp
;
1698 struct pim_interface
*pim_ifp
;
1700 switch (args
->event
) {
1701 case NB_EV_VALIDATE
:
1706 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1707 pim_ifp
= ifp
->info
;
1708 pim_ifp
->pim_default_holdtime
=
1709 yang_dnode_get_uint16(args
->dnode
, NULL
);
1717 int lib_interface_pim_address_family_hello_holdtime_destroy(
1718 struct nb_cb_destroy_args
*args
)
1720 struct interface
*ifp
;
1721 struct pim_interface
*pim_ifp
;
1723 switch (args
->event
) {
1724 case NB_EV_VALIDATE
:
1729 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1730 pim_ifp
= ifp
->info
;
1731 pim_ifp
->pim_default_holdtime
= -1;
1738 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd
1740 int lib_interface_pim_address_family_bfd_create(struct nb_cb_create_args
*args
)
1742 struct interface
*ifp
;
1743 struct pim_interface
*pim_ifp
;
1745 switch (args
->event
) {
1746 case NB_EV_VALIDATE
:
1752 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1753 pim_ifp
= ifp
->info
;
1754 pim_ifp
->bfd_config
.enabled
= true;
1761 int lib_interface_pim_address_family_bfd_destroy(
1762 struct nb_cb_destroy_args
*args
)
1764 struct interface
*ifp
;
1765 struct pim_interface
*pim_ifp
;
1766 const struct lyd_node
*if_dnode
;
1768 switch (args
->event
) {
1769 case NB_EV_VALIDATE
:
1770 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
1771 if (!is_pim_interface(if_dnode
)) {
1772 snprintf(args
->errmsg
, args
->errmsg_len
,
1773 "Pim not enabled on this interface");
1774 return NB_ERR_VALIDATION
;
1781 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1782 pim_ifp
= ifp
->info
;
1783 pim_ifp
->bfd_config
.enabled
= false;
1784 pim_bfd_reg_dereg_all_nbr(ifp
);
1792 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd
1794 void lib_interface_pim_address_family_bfd_apply_finish(
1795 struct nb_cb_apply_finish_args
*args
)
1797 struct interface
*ifp
;
1798 struct pim_interface
*pim_ifp
;
1800 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1801 pim_ifp
= ifp
->info
;
1804 zlog_debug("Pim not enabled on this interface");
1808 pim_ifp
->bfd_config
.detection_multiplier
=
1809 yang_dnode_get_uint8(args
->dnode
, "./detect_mult");
1810 pim_ifp
->bfd_config
.min_rx
=
1811 yang_dnode_get_uint16(args
->dnode
, "./min-rx-interval");
1812 pim_ifp
->bfd_config
.min_tx
=
1813 yang_dnode_get_uint16(args
->dnode
, "./min-tx-interval");
1815 pim_bfd_reg_dereg_all_nbr(ifp
);
1819 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/min-rx-interval
1821 int lib_interface_pim_address_family_bfd_min_rx_interval_modify(
1822 struct nb_cb_modify_args
*args
)
1824 switch (args
->event
) {
1825 case NB_EV_VALIDATE
:
1836 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/min-tx-interval
1838 int lib_interface_pim_address_family_bfd_min_tx_interval_modify(
1839 struct nb_cb_modify_args
*args
)
1841 switch (args
->event
) {
1842 case NB_EV_VALIDATE
:
1853 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/detect_mult
1855 int lib_interface_pim_address_family_bfd_detect_mult_modify(
1856 struct nb_cb_modify_args
*args
)
1858 switch (args
->event
) {
1859 case NB_EV_VALIDATE
:
1870 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/profile
1872 int lib_interface_pim_address_family_bfd_profile_modify(
1873 struct nb_cb_modify_args
*args
)
1875 struct interface
*ifp
;
1876 struct pim_interface
*pim_ifp
;
1878 switch (args
->event
) {
1879 case NB_EV_VALIDATE
:
1885 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1886 pim_ifp
= ifp
->info
;
1887 XFREE(MTYPE_TMP
, pim_ifp
->bfd_config
.profile
);
1888 pim_ifp
->bfd_config
.profile
= XSTRDUP(
1889 MTYPE_TMP
, yang_dnode_get_string(args
->dnode
, NULL
));
1896 int lib_interface_pim_address_family_bfd_profile_destroy(
1897 struct nb_cb_destroy_args
*args
)
1899 struct interface
*ifp
;
1900 struct pim_interface
*pim_ifp
;
1902 switch (args
->event
) {
1903 case NB_EV_VALIDATE
:
1909 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1910 pim_ifp
= ifp
->info
;
1911 XFREE(MTYPE_TMP
, pim_ifp
->bfd_config
.profile
);
1919 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bsm
1921 int lib_interface_pim_address_family_bsm_modify(struct nb_cb_modify_args
*args
)
1923 struct interface
*ifp
;
1924 struct pim_interface
*pim_ifp
;
1926 switch (args
->event
) {
1927 case NB_EV_VALIDATE
:
1932 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1933 pim_ifp
= ifp
->info
;
1934 pim_ifp
->bsm_enable
= yang_dnode_get_bool(args
->dnode
, NULL
);
1943 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/unicast-bsm
1945 int lib_interface_pim_address_family_unicast_bsm_modify(
1946 struct nb_cb_modify_args
*args
)
1948 struct interface
*ifp
;
1949 struct pim_interface
*pim_ifp
;
1951 switch (args
->event
) {
1952 case NB_EV_VALIDATE
:
1957 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1958 pim_ifp
= ifp
->info
;
1959 pim_ifp
->ucast_bsm_accept
=
1960 yang_dnode_get_bool(args
->dnode
, NULL
);
1969 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/active-active
1971 int lib_interface_pim_address_family_active_active_modify(
1972 struct nb_cb_modify_args
*args
)
1974 struct interface
*ifp
;
1975 struct pim_interface
*pim_ifp
;
1977 switch (args
->event
) {
1978 case NB_EV_VALIDATE
:
1983 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1984 pim_ifp
= ifp
->info
;
1985 if (yang_dnode_get_bool(args
->dnode
, NULL
)) {
1988 "Configuring PIM active-active on Interface: %s",
1990 pim_if_configure_mlag_dualactive(pim_ifp
);
1994 "UnConfiguring PIM active-active on Interface: %s",
1996 pim_if_unconfigure_mlag_dualactive(pim_ifp
);
2007 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/dr-priority
2009 int lib_interface_pim_address_family_dr_priority_modify(
2010 struct nb_cb_modify_args
*args
)
2012 struct interface
*ifp
;
2013 struct pim_interface
*pim_ifp
;
2014 uint32_t old_dr_prio
;
2015 const struct lyd_node
*if_dnode
;
2017 switch (args
->event
) {
2018 case NB_EV_VALIDATE
:
2019 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2020 if (!is_pim_interface(if_dnode
)) {
2021 snprintf(args
->errmsg
, args
->errmsg_len
,
2022 "Pim not enabled on this interface");
2023 return NB_ERR_VALIDATION
;
2030 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2031 pim_ifp
= ifp
->info
;
2032 old_dr_prio
= pim_ifp
->pim_dr_priority
;
2033 pim_ifp
->pim_dr_priority
= yang_dnode_get_uint32(args
->dnode
,
2036 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
2037 pim_if_dr_election(ifp
);
2038 pim_hello_restart_now(ifp
);
2047 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/use-source
2049 int lib_interface_pim_address_family_use_source_modify(
2050 struct nb_cb_modify_args
*args
)
2052 struct interface
*ifp
;
2053 pim_addr source_addr
;
2055 const struct lyd_node
*if_dnode
;
2057 switch (args
->event
) {
2058 case NB_EV_VALIDATE
:
2059 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2060 if (!is_pim_interface(if_dnode
)) {
2061 snprintf(args
->errmsg
, args
->errmsg_len
,
2062 "Pim not enabled on this interface");
2063 return NB_ERR_VALIDATION
;
2070 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2072 yang_dnode_get_ipv4(&source_addr
, args
->dnode
, NULL
);
2074 yang_dnode_get_ipv6(&source_addr
, args
->dnode
, NULL
);
2077 result
= interface_pim_use_src_cmd_worker(
2079 args
->errmsg
, args
->errmsg_len
);
2081 if (result
!= PIM_SUCCESS
)
2082 return NB_ERR_INCONSISTENCY
;
2090 int lib_interface_pim_address_family_use_source_destroy(
2091 struct nb_cb_destroy_args
*args
)
2093 struct interface
*ifp
;
2095 const struct lyd_node
*if_dnode
;
2097 switch (args
->event
) {
2098 case NB_EV_VALIDATE
:
2099 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2100 if (!is_pim_interface(if_dnode
)) {
2101 snprintf(args
->errmsg
, args
->errmsg_len
,
2102 "Pim not enabled on this interface");
2103 return NB_ERR_VALIDATION
;
2110 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2112 result
= interface_pim_use_src_cmd_worker(ifp
, PIMADDR_ANY
,
2116 if (result
!= PIM_SUCCESS
)
2117 return NB_ERR_INCONSISTENCY
;
2126 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/multicast-boundary-oil
2128 int lib_interface_pim_address_family_multicast_boundary_oil_modify(
2129 struct nb_cb_modify_args
*args
)
2131 struct interface
*ifp
;
2132 struct pim_interface
*pim_ifp
;
2134 const struct lyd_node
*if_dnode
;
2136 switch (args
->event
) {
2137 case NB_EV_VALIDATE
:
2138 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2139 if (!is_pim_interface(if_dnode
)) {
2140 snprintf(args
->errmsg
, args
->errmsg_len
,
2141 "Pim not enabled on this interface");
2142 return NB_ERR_VALIDATION
;
2149 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2150 pim_ifp
= ifp
->info
;
2151 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
2153 if (pim_ifp
->boundary_oil_plist
)
2154 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
2156 pim_ifp
->boundary_oil_plist
=
2157 XSTRDUP(MTYPE_PIM_INTERFACE
, plist
);
2165 int lib_interface_pim_address_family_multicast_boundary_oil_destroy(
2166 struct nb_cb_destroy_args
*args
)
2168 struct interface
*ifp
;
2169 struct pim_interface
*pim_ifp
;
2170 const struct lyd_node
*if_dnode
;
2172 switch (args
->event
) {
2173 case NB_EV_VALIDATE
:
2174 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2175 if (!is_pim_interface(if_dnode
)) {
2176 snprintf(args
->errmsg
, args
->errmsg_len
,
2177 "%% Enable PIM and/or IGMP on this interface first");
2178 return NB_ERR_VALIDATION
;
2185 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2186 pim_ifp
= ifp
->info
;
2187 if (pim_ifp
->boundary_oil_plist
)
2188 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
2196 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/mroute
2198 int lib_interface_pim_address_family_mroute_create(
2199 struct nb_cb_create_args
*args
)
2201 switch (args
->event
) {
2202 case NB_EV_VALIDATE
:
2212 int lib_interface_pim_address_family_mroute_destroy(
2213 struct nb_cb_destroy_args
*args
)
2215 struct pim_instance
*pim
;
2216 struct pim_interface
*pim_iifp
;
2217 struct interface
*iif
;
2218 struct interface
*oif
;
2219 const char *oifname
;
2220 pim_addr source_addr
;
2221 pim_addr group_addr
;
2222 const struct lyd_node
*if_dnode
;
2224 switch (args
->event
) {
2225 case NB_EV_VALIDATE
:
2226 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2227 if (!is_pim_interface(if_dnode
)) {
2228 snprintf(args
->errmsg
, args
->errmsg_len
,
2229 "%% Enable PIM and/or IGMP on this interface first");
2230 return NB_ERR_VALIDATION
;
2237 iif
= nb_running_get_entry(args
->dnode
, NULL
, true);
2238 pim_iifp
= iif
->info
;
2239 pim
= pim_iifp
->pim
;
2241 oifname
= yang_dnode_get_string(args
->dnode
, "./oif");
2242 oif
= if_lookup_by_name(oifname
, pim
->vrf
->vrf_id
);
2245 snprintf(args
->errmsg
, args
->errmsg_len
,
2246 "No such interface name %s",
2248 return NB_ERR_INCONSISTENCY
;
2251 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
, "./source-addr");
2252 yang_dnode_get_pimaddr(&group_addr
, args
->dnode
, "./group-addr");
2254 if (pim_static_del(pim
, iif
, oif
, group_addr
, source_addr
)) {
2255 snprintf(args
->errmsg
, args
->errmsg_len
,
2256 "Failed to remove static mroute");
2257 return NB_ERR_INCONSISTENCY
;
2267 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/mroute/oif
2269 int lib_interface_pim_address_family_mroute_oif_modify(
2270 struct nb_cb_modify_args
*args
)
2272 struct pim_instance
*pim
;
2273 struct pim_interface
*pim_iifp
;
2274 struct interface
*iif
;
2275 struct interface
*oif
;
2276 const char *oifname
;
2277 pim_addr source_addr
;
2278 pim_addr group_addr
;
2279 const struct lyd_node
*if_dnode
;
2281 switch (args
->event
) {
2282 case NB_EV_VALIDATE
:
2283 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2284 if (!is_pim_interface(if_dnode
)) {
2285 snprintf(args
->errmsg
, args
->errmsg_len
,
2286 "%% Enable PIM and/or IGMP on this interface first");
2287 return NB_ERR_VALIDATION
;
2290 #ifdef PIM_ENFORCE_LOOPFREE_MFC
2291 iif
= nb_running_get_entry(args
->dnode
, NULL
, false);
2296 pim_iifp
= iif
->info
;
2297 pim
= pim_iifp
->pim
;
2299 oifname
= yang_dnode_get_string(args
->dnode
, NULL
);
2300 oif
= if_lookup_by_name(oifname
, pim
->vrf
->vrf_id
);
2302 if (oif
&& (iif
->ifindex
== oif
->ifindex
)) {
2303 strlcpy(args
->errmsg
,
2304 "% IIF same as OIF and loopfree enforcement is enabled; rejecting",
2306 return NB_ERR_VALIDATION
;
2314 iif
= nb_running_get_entry(args
->dnode
, NULL
, true);
2315 pim_iifp
= iif
->info
;
2316 pim
= pim_iifp
->pim
;
2318 oifname
= yang_dnode_get_string(args
->dnode
, NULL
);
2319 oif
= if_lookup_by_name(oifname
, pim
->vrf
->vrf_id
);
2321 snprintf(args
->errmsg
, args
->errmsg_len
,
2322 "No such interface name %s",
2324 return NB_ERR_INCONSISTENCY
;
2327 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
, "../source-addr");
2328 yang_dnode_get_pimaddr(&group_addr
, args
->dnode
, "../group-addr");
2330 if (pim_static_add(pim
, iif
, oif
, group_addr
, source_addr
)) {
2331 snprintf(args
->errmsg
, args
->errmsg_len
,
2332 "Failed to add static mroute");
2333 return NB_ERR_INCONSISTENCY
;
2342 int lib_interface_pim_address_family_mroute_oif_destroy(
2343 struct nb_cb_destroy_args
*args
)
2345 switch (args
->event
) {
2346 case NB_EV_VALIDATE
:
2357 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/static-rp/rp-list
2359 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_create(
2360 struct nb_cb_create_args
*args
)
2362 switch (args
->event
) {
2363 case NB_EV_VALIDATE
:
2373 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_destroy(
2374 struct nb_cb_destroy_args
*args
)
2377 struct pim_instance
*pim
;
2378 struct prefix group
;
2383 switch (args
->event
) {
2384 case NB_EV_VALIDATE
:
2389 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2391 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "./rp-address");
2393 if (yang_dnode_get(args
->dnode
, "./group-list")) {
2394 yang_dnode_get_prefix(&group
, args
->dnode
,
2397 result
= pim_no_rp_cmd_worker(pim
, rp_addr
, group
, NULL
,
2402 else if (yang_dnode_get(args
->dnode
, "./prefix-list")) {
2403 plist
= yang_dnode_get_string(args
->dnode
,
2405 if (!pim_get_all_mcast_group(&group
)) {
2408 "Unable to convert 224.0.0.0/4 to prefix");
2409 return NB_ERR_INCONSISTENCY
;
2412 result
= pim_no_rp_cmd_worker(pim
, rp_addr
, group
,
2413 plist
, args
->errmsg
,
2418 return NB_ERR_INCONSISTENCY
;
2426 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/static-rp/rp-list/group-list
2428 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_group_list_create(
2429 struct nb_cb_create_args
*args
)
2432 struct pim_instance
*pim
;
2433 struct prefix group
;
2436 switch (args
->event
) {
2437 case NB_EV_VALIDATE
:
2442 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2444 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "../rp-address");
2445 yang_dnode_get_prefix(&group
, args
->dnode
, NULL
);
2447 return pim_rp_cmd_worker(pim
, rp_addr
, group
, NULL
,
2448 args
->errmsg
, args
->errmsg_len
);
2454 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_group_list_destroy(
2455 struct nb_cb_destroy_args
*args
)
2458 struct pim_instance
*pim
;
2459 struct prefix group
;
2462 switch (args
->event
) {
2463 case NB_EV_VALIDATE
:
2468 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2470 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "../rp-address");
2471 yang_dnode_get_prefix(&group
, args
->dnode
, NULL
);
2474 return pim_no_rp_cmd_worker(pim
, rp_addr
, group
, NULL
,
2475 args
->errmsg
, args
->errmsg_len
);
2482 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/static-rp/rp-list/prefix-list
2484 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_prefix_list_modify(
2485 struct nb_cb_modify_args
*args
)
2488 struct pim_instance
*pim
;
2489 struct prefix group
;
2493 switch (args
->event
) {
2494 case NB_EV_VALIDATE
:
2499 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2501 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
2502 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "../rp-address");
2503 if (!pim_get_all_mcast_group(&group
)) {
2504 flog_err(EC_LIB_DEVELOPMENT
,
2505 "Unable to convert 224.0.0.0/4 to prefix");
2506 return NB_ERR_INCONSISTENCY
;
2508 return pim_rp_cmd_worker(pim
, rp_addr
, group
, plist
,
2509 args
->errmsg
, args
->errmsg_len
);
2515 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_prefix_list_destroy(
2516 struct nb_cb_destroy_args
*args
)
2519 struct pim_instance
*pim
;
2520 struct prefix group
;
2524 switch (args
->event
) {
2525 case NB_EV_VALIDATE
:
2530 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2532 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "../rp-address");
2533 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
2534 if (!pim_get_all_mcast_group(&group
)) {
2535 flog_err(EC_LIB_DEVELOPMENT
,
2536 "Unable to convert 224.0.0.0/4 to prefix");
2537 return NB_ERR_INCONSISTENCY
;
2539 return pim_no_rp_cmd_worker(pim
, rp_addr
, group
, plist
,
2540 args
->errmsg
, args
->errmsg_len
);
2548 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family
2550 int lib_interface_gmp_address_family_create(struct nb_cb_create_args
*args
)
2552 switch (args
->event
) {
2553 case NB_EV_VALIDATE
:
2563 int lib_interface_gmp_address_family_destroy(struct nb_cb_destroy_args
*args
)
2565 struct interface
*ifp
;
2566 struct pim_interface
*pim_ifp
;
2568 switch (args
->event
) {
2569 case NB_EV_VALIDATE
:
2574 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2575 pim_ifp
= ifp
->info
;
2580 pim_ifp
->gm_enable
= false;
2582 pim_if_membership_clear(ifp
);
2584 pim_if_addr_del_all_igmp(ifp
);
2586 if (!pim_ifp
->pim_enable
)
2594 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/enable
2596 int lib_interface_gmp_address_family_enable_modify(
2597 struct nb_cb_modify_args
*args
)
2599 struct interface
*ifp
;
2601 struct pim_interface
*pim_ifp
;
2603 const char *ifp_name
;
2604 const struct lyd_node
*if_dnode
;
2606 switch (args
->event
) {
2607 case NB_EV_VALIDATE
:
2608 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2610 yang_get_list_elements_count(if_dnode
);
2611 /* Limiting mcast interfaces to number of VIFs */
2612 if (mcast_if_count
== MAXVIFS
) {
2613 ifp_name
= yang_dnode_get_string(if_dnode
, "name");
2615 args
->errmsg
, args
->errmsg_len
,
2616 "Max multicast interfaces(%d) Reached. Could not enable %s on interface %s",
2617 MAXVIFS
, GM
, ifp_name
);
2618 return NB_ERR_VALIDATION
;
2625 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2626 gm_enable
= yang_dnode_get_bool(args
->dnode
, NULL
);
2629 return pim_cmd_gm_start(ifp
);
2632 pim_ifp
= ifp
->info
;
2635 return NB_ERR_INCONSISTENCY
;
2637 pim_ifp
->gm_enable
= false;
2639 pim_if_membership_clear(ifp
);
2642 pim_if_addr_del_all_igmp(ifp
);
2644 gm_ifp_teardown(ifp
);
2647 if (!pim_ifp
->pim_enable
)
2655 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/igmp-version
2657 int lib_interface_gmp_address_family_igmp_version_modify(
2658 struct nb_cb_modify_args
*args
)
2660 struct interface
*ifp
;
2661 struct pim_interface
*pim_ifp
;
2662 int igmp_version
, old_version
= 0;
2664 switch (args
->event
) {
2665 case NB_EV_VALIDATE
:
2670 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2671 pim_ifp
= ifp
->info
;
2674 return NB_ERR_INCONSISTENCY
;
2676 igmp_version
= yang_dnode_get_uint8(args
->dnode
, NULL
);
2677 old_version
= pim_ifp
->igmp_version
;
2678 pim_ifp
->igmp_version
= igmp_version
;
2680 /* Current and new version is different refresh existing
2681 * membership. Going from 3 -> 2 or 2 -> 3.
2683 if (old_version
!= igmp_version
)
2684 pim_if_membership_refresh(ifp
);
2692 int lib_interface_gmp_address_family_igmp_version_destroy(
2693 struct nb_cb_destroy_args
*args
)
2695 struct interface
*ifp
;
2696 struct pim_interface
*pim_ifp
;
2698 switch (args
->event
) {
2699 case NB_EV_VALIDATE
:
2704 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2705 pim_ifp
= ifp
->info
;
2706 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
2714 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/mld-version
2716 int lib_interface_gmp_address_family_mld_version_modify(
2717 struct nb_cb_modify_args
*args
)
2719 struct interface
*ifp
;
2720 struct pim_interface
*pim_ifp
;
2722 switch (args
->event
) {
2723 case NB_EV_VALIDATE
:
2728 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2729 pim_ifp
= ifp
->info
;
2731 return NB_ERR_INCONSISTENCY
;
2733 pim_ifp
->mld_version
= yang_dnode_get_uint8(args
->dnode
, NULL
);
2741 int lib_interface_gmp_address_family_mld_version_destroy(
2742 struct nb_cb_destroy_args
*args
)
2744 struct interface
*ifp
;
2745 struct pim_interface
*pim_ifp
;
2747 switch (args
->event
) {
2748 case NB_EV_VALIDATE
:
2753 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2754 pim_ifp
= ifp
->info
;
2756 return NB_ERR_INCONSISTENCY
;
2758 pim_ifp
->mld_version
= 2;
2767 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/query-interval
2769 int lib_interface_gmp_address_family_query_interval_modify(
2770 struct nb_cb_modify_args
*args
)
2772 struct interface
*ifp
;
2776 switch (args
->event
) {
2777 case NB_EV_VALIDATE
:
2782 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2783 query_interval
= yang_dnode_get_uint16(args
->dnode
, NULL
);
2784 change_query_interval(ifp
->info
, query_interval
);
2787 struct pim_interface
*pim_ifp
;
2789 switch (args
->event
) {
2790 case NB_EV_VALIDATE
:
2795 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2796 pim_ifp
= ifp
->info
;
2798 return NB_ERR_INCONSISTENCY
;
2800 query_interval
= yang_dnode_get_uint16(args
->dnode
, NULL
);
2801 pim_ifp
->gm_default_query_interval
= query_interval
;
2809 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/query-max-response-time
2811 int lib_interface_gmp_address_family_query_max_response_time_modify(
2812 struct nb_cb_modify_args
*args
)
2814 struct interface
*ifp
;
2815 int query_max_response_time_dsec
;
2817 switch (args
->event
) {
2818 case NB_EV_VALIDATE
:
2823 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2824 query_max_response_time_dsec
=
2825 yang_dnode_get_uint16(args
->dnode
, NULL
);
2826 change_query_max_response_time(ifp
,
2827 query_max_response_time_dsec
);
2834 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/last-member-query-interval
2836 int lib_interface_gmp_address_family_last_member_query_interval_modify(
2837 struct nb_cb_modify_args
*args
)
2839 struct interface
*ifp
;
2840 struct pim_interface
*pim_ifp
;
2841 int last_member_query_interval
;
2843 switch (args
->event
) {
2844 case NB_EV_VALIDATE
:
2849 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2850 pim_ifp
= ifp
->info
;
2851 last_member_query_interval
=
2852 yang_dnode_get_uint16(args
->dnode
, NULL
);
2853 pim_ifp
->gm_specific_query_max_response_time_dsec
=
2854 last_member_query_interval
;
2866 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/robustness-variable
2868 int lib_interface_gmp_address_family_robustness_variable_modify(
2869 struct nb_cb_modify_args
*args
)
2871 struct interface
*ifp
;
2872 struct pim_interface
*pim_ifp
;
2873 int last_member_query_count
;
2875 switch (args
->event
) {
2876 case NB_EV_VALIDATE
:
2881 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2882 pim_ifp
= ifp
->info
;
2883 last_member_query_count
=
2884 yang_dnode_get_uint8(args
->dnode
, NULL
);
2885 pim_ifp
->gm_last_member_query_count
= last_member_query_count
;
2896 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/static-group
2898 int lib_interface_gmp_address_family_static_group_create(
2899 struct nb_cb_create_args
*args
)
2901 struct interface
*ifp
;
2902 pim_addr source_addr
;
2903 pim_addr group_addr
;
2905 const char *ifp_name
;
2906 const struct lyd_node
*if_dnode
;
2908 switch (args
->event
) {
2909 case NB_EV_VALIDATE
:
2910 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2911 if (!is_pim_interface(if_dnode
)) {
2912 ifp_name
= yang_dnode_get_string(if_dnode
, "name");
2913 snprintf(args
->errmsg
, args
->errmsg_len
,
2914 "multicast not enabled on interface %s",
2916 return NB_ERR_VALIDATION
;
2919 yang_dnode_get_pimaddr(&group_addr
, args
->dnode
,
2922 if (pim_is_group_224_0_0_0_24(group_addr
)) {
2924 args
->errmsg
, args
->errmsg_len
,
2925 "Groups within 224.0.0.0/24 are reserved and cannot be joined");
2926 return NB_ERR_VALIDATION
;
2929 if (ipv6_mcast_reserved(&group_addr
)) {
2931 args
->errmsg
, args
->errmsg_len
,
2932 "Groups within ffx2::/16 are reserved and cannot be joined");
2933 return NB_ERR_VALIDATION
;
2941 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2942 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
,
2944 yang_dnode_get_pimaddr(&group_addr
, args
->dnode
,
2946 result
= pim_if_gm_join_add(ifp
, group_addr
, source_addr
);
2948 snprintf(args
->errmsg
, args
->errmsg_len
,
2949 "Failure joining " GM
" group");
2950 return NB_ERR_INCONSISTENCY
;
2956 int lib_interface_gmp_address_family_static_group_destroy(
2957 struct nb_cb_destroy_args
*args
)
2959 struct interface
*ifp
;
2960 pim_addr source_addr
;
2961 pim_addr group_addr
;
2964 switch (args
->event
) {
2965 case NB_EV_VALIDATE
:
2970 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2971 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
,
2973 yang_dnode_get_pimaddr(&group_addr
, args
->dnode
,
2975 result
= pim_if_gm_join_del(ifp
, group_addr
, source_addr
);
2978 snprintf(args
->errmsg
, args
->errmsg_len
,
2979 "%% Failure leaving " GM
2980 " group %pPAs %pPAs on interface %s: %d",
2981 &source_addr
, &group_addr
, ifp
->name
, result
);
2983 return NB_ERR_INCONSISTENCY
;