2 * Copyright (C) 2020 VmWare
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
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
24 #include "lib/northbound_cli.h"
25 #include "pim_igmpv3.h"
26 #include "pim_neighbor.h"
30 #include "pim_static.h"
32 #include "pim_ssmpingd.h"
33 #include "pim_vxlan.h"
36 #include "lib_errors.h"
40 #define pim6_msdp_err(funcname, argtype) \
41 int funcname(struct argtype *args) \
43 snprintf(args->errmsg, args->errmsg_len, \
44 "Trying to configure MSDP in pim6d. " \
45 "MSDP does not exist for IPv6."); \
46 return NB_ERR_VALIDATION; \
48 MACRO_REQUIRE_SEMICOLON()
50 #define yang_dnode_get_pimaddr yang_dnode_get_ipv6
52 #else /* PIM_IPV != 6 */
53 #define pim6_msdp_err(funcname, argtype) \
54 MACRO_REQUIRE_SEMICOLON()
56 #define yang_dnode_get_pimaddr yang_dnode_get_ipv4
57 #endif /* PIM_IPV != 6 */
59 static void pim_if_membership_clear(struct interface
*ifp
)
61 struct pim_interface
*pim_ifp
;
66 if (PIM_IF_TEST_PIM(pim_ifp
->options
)
67 && PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
71 pim_ifchannel_membership_clear(ifp
);
75 * When PIM is disabled on interface, IGMPv3 local membership
76 * information is not injected into PIM interface state.
78 * The function pim_if_membership_refresh() fetches all IGMPv3 local
79 * membership information into PIM. It is intented to be called
80 * whenever PIM is enabled on the interface in order to collect missed
81 * local membership information.
83 static void pim_if_membership_refresh(struct interface
*ifp
)
85 struct pim_interface
*pim_ifp
;
86 struct listnode
*grpnode
;
93 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
95 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
))
99 * First clear off membership from all PIM (S,G) entries on the
103 pim_ifchannel_membership_clear(ifp
);
106 * Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
110 /* scan igmp groups */
111 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->gm_group_list
, grpnode
, grp
)) {
112 struct listnode
*srcnode
;
113 struct gm_source
*src
;
115 /* scan group sources */
116 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, srcnode
,
119 if (IGMP_SOURCE_TEST_FORWARDING(src
->source_flags
)) {
122 memset(&sg
, 0, sizeof(sg
));
123 sg
.src
= src
->source_addr
;
124 sg
.grp
= grp
->group_addr
;
125 pim_ifchannel_local_membership_add(
126 ifp
, &sg
, false /*is_vxlan*/);
129 } /* scan group sources */
130 } /* scan igmp groups */
133 * Finally delete every PIM (S,G) entry lacking all state info
136 pim_ifchannel_delete_on_noinfo(ifp
);
139 static int pim_cmd_interface_add(struct interface
*ifp
)
141 struct pim_interface
*pim_ifp
= ifp
->info
;
144 pim_ifp
= pim_if_new(ifp
, false, true, false, false);
146 PIM_IF_DO_PIM(pim_ifp
->options
);
148 pim_if_addr_add_all(ifp
);
149 pim_if_membership_refresh(ifp
);
151 pim_if_create_pimreg(pim_ifp
->pim
);
155 static int pim_cmd_interface_delete(struct interface
*ifp
)
157 struct pim_interface
*pim_ifp
= ifp
->info
;
162 PIM_IF_DONT_PIM(pim_ifp
->options
);
164 pim_if_membership_clear(ifp
);
167 * pim_sock_delete() removes all neighbors from
168 * pim_ifp->pim_neighbor_list.
170 pim_sock_delete(ifp
, "pim unconfigured on interface");
172 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
173 pim_if_addr_del_all(ifp
);
180 static int interface_pim_use_src_cmd_worker(struct interface
*ifp
,
181 pim_addr source_addr
, char *errmsg
, size_t errmsg_len
)
186 result
= pim_update_source_set(ifp
, source_addr
);
191 case PIM_IFACE_NOT_FOUND
:
193 snprintf(errmsg
, errmsg_len
,
194 "Pim not enabled on this interface %s",
197 case PIM_UPDATE_SOURCE_DUP
:
199 snprintf(errmsg
, errmsg_len
, "Source already set");
203 snprintf(errmsg
, errmsg_len
, "Source set failed");
209 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
210 enum pim_spt_switchover spt
,
213 pim
->spt
.switchover
= spt
;
215 switch (pim
->spt
.switchover
) {
216 case PIM_SPT_IMMEDIATE
:
217 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->spt
.plist
);
219 pim_upstream_add_lhr_star_pimreg(pim
);
221 case PIM_SPT_INFINITY
:
222 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
224 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->spt
.plist
);
227 pim
->spt
.plist
= XSTRDUP(MTYPE_PIM_PLIST_NAME
, plist
);
234 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, const char *plist
,
235 char *errmsg
, size_t errmsg_len
)
237 int result
= pim_ssm_range_set(pim
, pim
->vrf
->vrf_id
, plist
);
240 if (result
== PIM_SSM_ERR_NONE
)
244 case PIM_SSM_ERR_NO_VRF
:
245 snprintf(errmsg
, errmsg_len
,
246 "VRF doesn't exist");
248 case PIM_SSM_ERR_DUP
:
249 snprintf(errmsg
, errmsg_len
,
253 snprintf(errmsg
, errmsg_len
,
254 "ssm range config failed");
260 static int pim_rp_cmd_worker(struct pim_instance
*pim
, pim_addr rp_addr
,
261 struct prefix group
, const char *plist
,
262 char *errmsg
, size_t errmsg_len
)
266 result
= pim_rp_new(pim
, rp_addr
, group
, plist
, RP_SRC_STATIC
);
268 if (result
== PIM_RP_NO_PATH
) {
269 snprintfrr(errmsg
, errmsg_len
,
270 "No Path to RP address specified: %pPA", &rp_addr
);
271 return NB_ERR_INCONSISTENCY
;
274 if (result
== PIM_GROUP_OVERLAP
) {
275 snprintf(errmsg
, errmsg_len
,
276 "Group range specified cannot exact match another");
277 return NB_ERR_INCONSISTENCY
;
280 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
281 snprintf(errmsg
, errmsg_len
,
282 "This group is already covered by a RP prefix-list");
283 return NB_ERR_INCONSISTENCY
;
286 if (result
== PIM_RP_PFXLIST_IN_USE
) {
287 snprintf(errmsg
, errmsg_len
,
288 "The same prefix-list cannot be applied to multiple RPs");
289 return NB_ERR_INCONSISTENCY
;
295 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
, pim_addr rp_addr
,
296 struct prefix group
, const char *plist
,
297 char *errmsg
, size_t errmsg_len
)
299 char group_str
[PREFIX2STR_BUFFER
];
302 prefix2str(&group
, group_str
, sizeof(group_str
));
304 result
= pim_rp_del(pim
, rp_addr
, group
, plist
, RP_SRC_STATIC
);
306 if (result
== PIM_GROUP_BAD_ADDRESS
) {
307 snprintf(errmsg
, errmsg_len
,
308 "Bad group address specified: %s", group_str
);
309 return NB_ERR_INCONSISTENCY
;
312 if (result
== PIM_RP_BAD_ADDRESS
) {
313 snprintfrr(errmsg
, errmsg_len
, "Bad RP address specified: %pPA",
315 return NB_ERR_INCONSISTENCY
;
318 if (result
== PIM_RP_NOT_FOUND
) {
319 snprintf(errmsg
, errmsg_len
,
320 "Unable to find specified RP");
321 return NB_ERR_INCONSISTENCY
;
327 static bool is_pim_interface(const struct lyd_node
*dnode
)
329 char if_xpath
[XPATH_MAXLEN
];
330 const struct lyd_node
*pim_enable_dnode
;
331 const struct lyd_node
*igmp_enable_dnode
;
333 yang_dnode_get_path(dnode
, if_xpath
, sizeof(if_xpath
));
335 yang_dnode_getf(dnode
,
336 "%s/frr-pim:pim/address-family[address-family='%s']/pim-enable",
337 if_xpath
, "frr-routing:ipv4");
338 igmp_enable_dnode
= yang_dnode_getf(dnode
,
339 "%s/frr-gmp:gmp/address-family[address-family='%s']/enable",
340 if_xpath
, "frr-routing:ipv4");
342 if (((pim_enable_dnode
) &&
343 (yang_dnode_get_bool(pim_enable_dnode
, "."))) ||
344 ((igmp_enable_dnode
) &&
345 (yang_dnode_get_bool(igmp_enable_dnode
, "."))))
351 static int pim_cmd_igmp_start(struct interface
*ifp
)
353 struct pim_interface
*pim_ifp
;
354 uint8_t need_startup
= 0;
359 pim_ifp
= pim_if_new(ifp
, true, false, false, false);
362 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
363 PIM_IF_DO_IGMP(pim_ifp
->options
);
367 pim_if_create_pimreg(pim_ifp
->pim
);
369 /* 'ip igmp' executed multiple times, with need_startup
370 * avoid multiple if add all and membership refresh
373 pim_if_addr_add_all(ifp
);
374 pim_if_membership_refresh(ifp
);
381 * CLI reconfiguration affects the interface level (struct pim_interface).
382 * This function propagates the reconfiguration to every active socket
383 * for that interface.
385 static void igmp_sock_query_interval_reconfig(struct gm_sock
*igmp
)
387 struct interface
*ifp
;
388 struct pim_interface
*pim_ifp
;
391 assert(igmp
->interface
);
392 assert(igmp
->interface
->info
);
394 ifp
= igmp
->interface
;
397 if (PIM_DEBUG_IGMP_TRACE
)
398 zlog_debug("%s: Querier %pPAs on %s reconfig query_interval=%d",
399 __func__
, &igmp
->ifaddr
, ifp
->name
,
400 pim_ifp
->gm_default_query_interval
);
403 * igmp_startup_mode_on() will reset QQI:
405 * igmp->querier_query_interval = pim_ifp->gm_default_query_interval;
407 igmp_startup_mode_on(igmp
);
410 static void igmp_sock_query_reschedule(struct gm_sock
*igmp
)
412 if (igmp
->mtrace_only
)
415 if (igmp
->t_igmp_query_timer
) {
416 /* other querier present */
417 assert(igmp
->t_igmp_query_timer
);
418 assert(!igmp
->t_other_querier_timer
);
420 pim_igmp_general_query_off(igmp
);
421 pim_igmp_general_query_on(igmp
);
423 assert(igmp
->t_igmp_query_timer
);
424 assert(!igmp
->t_other_querier_timer
);
426 /* this is the querier */
428 assert(!igmp
->t_igmp_query_timer
);
429 assert(igmp
->t_other_querier_timer
);
431 pim_igmp_other_querier_timer_off(igmp
);
432 pim_igmp_other_querier_timer_on(igmp
);
434 assert(!igmp
->t_igmp_query_timer
);
435 assert(igmp
->t_other_querier_timer
);
439 static void change_query_interval(struct pim_interface
*pim_ifp
,
442 struct listnode
*sock_node
;
443 struct gm_sock
*igmp
;
445 pim_ifp
->gm_default_query_interval
= query_interval
;
447 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->gm_socket_list
, sock_node
, igmp
)) {
448 igmp_sock_query_interval_reconfig(igmp
);
449 igmp_sock_query_reschedule(igmp
);
453 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
454 int query_max_response_time_dsec
)
456 struct listnode
*sock_node
;
457 struct gm_sock
*igmp
;
458 struct listnode
*grp_node
;
459 struct gm_group
*grp
;
461 if (pim_ifp
->gm_query_max_response_time_dsec
==
462 query_max_response_time_dsec
)
465 pim_ifp
->gm_query_max_response_time_dsec
= query_max_response_time_dsec
;
468 * Below we modify socket/group/source timers in order to quickly
469 * reflect the change. Otherwise, those timers would args->eventually
473 /* scan all sockets */
474 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->gm_socket_list
, sock_node
, igmp
)) {
475 /* reschedule socket general query */
476 igmp_sock_query_reschedule(igmp
);
479 /* scan socket groups */
480 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->gm_group_list
, grp_node
, grp
)) {
481 struct listnode
*src_node
;
482 struct gm_source
*src
;
484 /* reset group timers for groups in EXCLUDE mode */
485 if (grp
->group_filtermode_isexcl
)
486 igmp_group_reset_gmi(grp
);
488 /* scan group sources */
489 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, src_node
,
492 /* reset source timers for sources with running
495 if (src
->t_source_timer
)
496 igmp_source_reset_gmi(grp
, src
);
501 int routing_control_plane_protocols_name_validate(
502 struct nb_cb_create_args
*args
)
506 name
= yang_dnode_get_string(args
->dnode
, "./name");
507 if (!strmatch(name
, "pim")) {
508 snprintf(args
->errmsg
, args
->errmsg_len
,
509 "pim supports only one instance with name pimd");
510 return NB_ERR_VALIDATION
;
516 * XPath: /frr-pim:pim/address-family
518 int pim_address_family_create(struct nb_cb_create_args
*args
)
520 switch (args
->event
) {
531 int pim_address_family_destroy(struct nb_cb_destroy_args
*args
)
533 switch (args
->event
) {
545 * XPath: /frr-pim:pim/address-family/packets
547 int pim_address_family_packets_modify(struct nb_cb_modify_args
*args
)
549 switch (args
->event
) {
555 router
->packet_process
= yang_dnode_get_uint8(args
->dnode
,
564 * XPath: /frr-pim:pim/address-family/join-prune-interval
566 int pim_address_family_join_prune_interval_modify(
567 struct nb_cb_modify_args
*args
)
569 switch (args
->event
) {
575 router
->t_periodic
= yang_dnode_get_uint16(args
->dnode
, NULL
);
583 * XPath: /frr-pim:pim/address-family/register-suppress-time
585 int pim_address_family_register_suppress_time_modify(
586 struct nb_cb_modify_args
*args
)
589 switch (args
->event
) {
591 value
= yang_dnode_get_uint16(args
->dnode
, NULL
);
593 * As soon as this is non-constant it needs to be replaced with
594 * a yang_dnode_get to lookup the candidate value, *not* the
595 * operational value. Since the code has a field assigned and
596 * used for this value it should have YANG/CLI to set it too,
597 * otherwise just use the #define!
599 /* RFC7761: 4.11. Timer Values */
600 if (value
<= router
->register_probe_time
* 2) {
602 args
->errmsg
, args
->errmsg_len
,
603 "Register suppress time (%u) must be more than "
604 "twice the register probe time (%u).",
605 value
, router
->register_probe_time
);
606 return NB_ERR_VALIDATION
;
613 pim_update_suppress_timers(
614 yang_dnode_get_uint16(args
->dnode
, NULL
));
622 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/ecmp
624 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ecmp_modify(
625 struct nb_cb_modify_args
*args
)
628 struct pim_instance
*pim
;
630 switch (args
->event
) {
636 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
638 pim
->ecmp_enable
= yang_dnode_get_bool(args
->dnode
, NULL
);
645 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/ecmp-rebalance
647 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ecmp_rebalance_modify(
648 struct nb_cb_modify_args
*args
)
651 struct pim_instance
*pim
;
653 switch (args
->event
) {
659 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
661 pim
->ecmp_rebalance_enable
=
662 yang_dnode_get_bool(args
->dnode
, NULL
);
669 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/keep-alive-timer
671 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_keep_alive_timer_modify(
672 struct nb_cb_modify_args
*args
)
675 struct pim_instance
*pim
;
677 switch (args
->event
) {
683 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
685 pim
->keep_alive_time
= yang_dnode_get_uint16(args
->dnode
, NULL
);
693 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/rp-keep-alive-timer
695 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_keep_alive_timer_modify(
696 struct nb_cb_modify_args
*args
)
699 struct pim_instance
*pim
;
701 switch (args
->event
) {
707 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
709 pim
->rp_keep_alive_time
= yang_dnode_get_uint16(args
->dnode
,
718 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family
720 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_create(
721 struct nb_cb_create_args
*args
)
723 switch (args
->event
) {
734 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_destroy(
735 struct nb_cb_destroy_args
*args
)
737 switch (args
->event
) {
749 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/send-v6-secondary
751 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_send_v6_secondary_modify(
752 struct nb_cb_modify_args
*args
)
755 struct pim_instance
*pim
;
757 switch (args
->event
) {
763 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
765 pim
->send_v6_secondary
= yang_dnode_get_bool(args
->dnode
, NULL
);
772 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_send_v6_secondary_destroy(
773 struct nb_cb_destroy_args
*args
)
775 switch (args
->event
) {
788 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/spt-switchover
790 void routing_control_plane_protocols_control_plane_protocol_pim_address_family_spt_switchover_apply_finish(
791 struct nb_cb_apply_finish_args
*args
)
794 struct pim_instance
*pim
;
795 int spt_switch_action
;
796 const char *prefix_list
= NULL
;
798 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
800 spt_switch_action
= yang_dnode_get_enum(args
->dnode
, "./spt-action");
802 switch (spt_switch_action
) {
803 case PIM_SPT_INFINITY
:
804 if (yang_dnode_exists(args
->dnode
,
805 "./spt-infinity-prefix-list"))
806 prefix_list
= yang_dnode_get_string(
807 args
->dnode
, "./spt-infinity-prefix-list");
809 pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
,
812 case PIM_SPT_IMMEDIATE
:
813 pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
818 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/spt-switchover/spt-action
820 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_spt_switchover_spt_action_modify(
821 struct nb_cb_modify_args
*args
)
823 switch (args
->event
) {
835 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/spt-switchover/spt-infinity-prefix-list
837 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_spt_switchover_spt_infinity_prefix_list_modify(
838 struct nb_cb_modify_args
*args
)
840 switch (args
->event
) {
851 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_spt_switchover_spt_infinity_prefix_list_destroy(
852 struct nb_cb_destroy_args
*args
)
854 switch (args
->event
) {
866 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/ssm-prefix-list
868 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_prefix_list_modify(
869 struct nb_cb_modify_args
*args
)
872 struct pim_instance
*pim
;
873 const char *plist_name
;
876 switch (args
->event
) {
882 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
884 plist_name
= yang_dnode_get_string(args
->dnode
, NULL
);
885 result
= pim_ssm_cmd_worker(pim
, plist_name
, args
->errmsg
,
889 return NB_ERR_INCONSISTENCY
;
897 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_prefix_list_destroy(
898 struct nb_cb_destroy_args
*args
)
901 struct pim_instance
*pim
;
904 switch (args
->event
) {
910 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
912 result
= pim_ssm_cmd_worker(pim
, NULL
, args
->errmsg
,
916 return NB_ERR_INCONSISTENCY
;
925 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/ssm-pingd-source-ip
927 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_pingd_source_ip_create(
928 struct nb_cb_create_args
*args
)
931 struct pim_instance
*pim
;
933 struct ipaddr source_addr
;
935 switch (args
->event
) {
941 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
943 yang_dnode_get_ip(&source_addr
, args
->dnode
, NULL
);
944 result
= pim_ssmpingd_start(pim
, source_addr
.ip
._v4_addr
);
946 char source_str
[INET_ADDRSTRLEN
];
948 ipaddr2str(&source_addr
, source_str
,
950 snprintf(args
->errmsg
, args
->errmsg_len
,
951 "%% Failure starting ssmpingd for source %s: %d",
953 return NB_ERR_INCONSISTENCY
;
960 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_pingd_source_ip_destroy(
961 struct nb_cb_destroy_args
*args
)
964 struct pim_instance
*pim
;
966 struct ipaddr source_addr
;
968 switch (args
->event
) {
974 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
976 yang_dnode_get_ip(&source_addr
, args
->dnode
, NULL
);
977 result
= pim_ssmpingd_stop(pim
, source_addr
.ip
._v4_addr
);
979 char source_str
[INET_ADDRSTRLEN
];
981 ipaddr2str(&source_addr
, source_str
,
983 snprintf(args
->errmsg
, args
->errmsg_len
,
984 "%% Failure stopping ssmpingd for source %s: %d",
986 return NB_ERR_INCONSISTENCY
;
997 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/hold-time
999 int pim_msdp_hold_time_modify(struct nb_cb_modify_args
*args
)
1001 struct pim_instance
*pim
;
1004 switch (args
->event
) {
1005 case NB_EV_VALIDATE
:
1010 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1012 pim
->msdp
.hold_time
= yang_dnode_get_uint16(args
->dnode
, NULL
);
1021 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/keep-alive
1023 int pim_msdp_keep_alive_modify(struct nb_cb_modify_args
*args
)
1025 struct pim_instance
*pim
;
1028 switch (args
->event
) {
1029 case NB_EV_VALIDATE
:
1034 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1036 pim
->msdp
.keep_alive
= yang_dnode_get_uint16(args
->dnode
, NULL
);
1045 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/connection-retry
1047 int pim_msdp_connection_retry_modify(struct nb_cb_modify_args
*args
)
1049 struct pim_instance
*pim
;
1052 switch (args
->event
) {
1053 case NB_EV_VALIDATE
:
1058 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1060 pim
->msdp
.connection_retry
=
1061 yang_dnode_get_uint16(args
->dnode
, NULL
);
1068 pim6_msdp_err(pim_msdp_mesh_group_destroy
, nb_cb_destroy_args
);
1069 pim6_msdp_err(pim_msdp_mesh_group_create
, nb_cb_create_args
);
1070 pim6_msdp_err(pim_msdp_mesh_group_source_modify
, nb_cb_modify_args
);
1071 pim6_msdp_err(pim_msdp_mesh_group_source_destroy
, nb_cb_destroy_args
);
1072 pim6_msdp_err(pim_msdp_mesh_group_members_create
, nb_cb_create_args
);
1073 pim6_msdp_err(pim_msdp_mesh_group_members_destroy
, nb_cb_destroy_args
);
1074 pim6_msdp_err(routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify
,
1076 pim6_msdp_err(routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_destroy
,
1077 nb_cb_destroy_args
);
1078 pim6_msdp_err(routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_create
,
1084 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups
1086 int pim_msdp_mesh_group_create(struct nb_cb_create_args
*args
)
1088 struct pim_msdp_mg
*mg
;
1091 switch (args
->event
) {
1092 case NB_EV_VALIDATE
:
1097 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1098 mg
= pim_msdp_mg_new(vrf
->info
, yang_dnode_get_string(
1099 args
->dnode
, "./name"));
1100 nb_running_set_entry(args
->dnode
, mg
);
1107 int pim_msdp_mesh_group_destroy(struct nb_cb_destroy_args
*args
)
1109 struct pim_msdp_mg
*mg
;
1112 switch (args
->event
) {
1113 case NB_EV_VALIDATE
:
1118 mg
= nb_running_unset_entry(args
->dnode
);
1119 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1120 pim_msdp_mg_free(vrf
->info
, &mg
);
1129 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups/source
1131 int pim_msdp_mesh_group_source_modify(struct nb_cb_modify_args
*args
)
1133 const struct lyd_node
*vrf_dnode
;
1134 struct pim_msdp_mg
*mg
;
1138 switch (args
->event
) {
1139 case NB_EV_VALIDATE
:
1144 mg
= nb_running_get_entry(args
->dnode
, NULL
, true);
1146 yang_dnode_get_parent(args
->dnode
, "address-family");
1147 vrf
= nb_running_get_entry(vrf_dnode
, "../../", true);
1148 yang_dnode_get_ip(&ip
, args
->dnode
, NULL
);
1150 pim_msdp_mg_src_add(vrf
->info
, mg
, &ip
.ip
._v4_addr
);
1156 int pim_msdp_mesh_group_source_destroy(struct nb_cb_destroy_args
*args
)
1158 const struct lyd_node
*vrf_dnode
;
1159 struct pim_msdp_mg
*mg
;
1161 struct in_addr addr
;
1163 switch (args
->event
) {
1164 case NB_EV_VALIDATE
:
1169 mg
= nb_running_get_entry(args
->dnode
, NULL
, true);
1171 yang_dnode_get_parent(args
->dnode
, "address-family");
1172 vrf
= nb_running_get_entry(vrf_dnode
, "../../", true);
1174 addr
.s_addr
= INADDR_ANY
;
1175 pim_msdp_mg_src_add(vrf
->info
, mg
, &addr
);
1184 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups/members
1186 int pim_msdp_mesh_group_members_create(struct nb_cb_create_args
*args
)
1188 const struct lyd_node
*vrf_dnode
;
1189 struct pim_msdp_mg_mbr
*mbr
;
1190 struct pim_msdp_mg
*mg
;
1194 switch (args
->event
) {
1195 case NB_EV_VALIDATE
:
1200 mg
= nb_running_get_entry(args
->dnode
, NULL
, true);
1202 yang_dnode_get_parent(args
->dnode
, "address-family");
1203 vrf
= nb_running_get_entry(vrf_dnode
, "../../", true);
1204 yang_dnode_get_ip(&ip
, args
->dnode
, "address");
1206 mbr
= pim_msdp_mg_mbr_add(vrf
->info
, mg
, &ip
.ip
._v4_addr
);
1207 nb_running_set_entry(args
->dnode
, mbr
);
1214 int pim_msdp_mesh_group_members_destroy(struct nb_cb_destroy_args
*args
)
1216 struct pim_msdp_mg_mbr
*mbr
;
1217 struct pim_msdp_mg
*mg
;
1218 const struct lyd_node
*mg_dnode
;
1220 switch (args
->event
) {
1221 case NB_EV_VALIDATE
:
1226 mbr
= nb_running_get_entry(args
->dnode
, NULL
, true);
1228 yang_dnode_get_parent(args
->dnode
, "msdp-mesh-groups");
1229 mg
= nb_running_get_entry(mg_dnode
, NULL
, true);
1230 pim_msdp_mg_mbr_del(mg
, mbr
);
1231 nb_running_unset_entry(args
->dnode
);
1239 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-peer
1241 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_create(
1242 struct nb_cb_create_args
*args
)
1244 struct pim_msdp_peer
*mp
;
1245 struct pim_instance
*pim
;
1247 struct ipaddr peer_ip
;
1248 struct ipaddr source_ip
;
1250 switch (args
->event
) {
1251 case NB_EV_VALIDATE
:
1256 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1258 yang_dnode_get_ip(&peer_ip
, args
->dnode
, "./peer-ip");
1259 yang_dnode_get_ip(&source_ip
, args
->dnode
, "./source-ip");
1260 mp
= pim_msdp_peer_add(pim
, &peer_ip
.ipaddr_v4
,
1261 &source_ip
.ipaddr_v4
, NULL
);
1262 nb_running_set_entry(args
->dnode
, mp
);
1269 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_destroy(
1270 struct nb_cb_destroy_args
*args
)
1272 struct pim_msdp_peer
*mp
;
1274 switch (args
->event
) {
1275 case NB_EV_VALIDATE
:
1280 mp
= nb_running_unset_entry(args
->dnode
);
1281 pim_msdp_peer_del(&mp
);
1289 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-peer/source-ip
1291 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify(
1292 struct nb_cb_modify_args
*args
)
1294 struct pim_msdp_peer
*mp
;
1295 struct ipaddr source_ip
;
1297 switch (args
->event
) {
1298 case NB_EV_VALIDATE
:
1303 mp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1304 yang_dnode_get_ip(&source_ip
, args
->dnode
, NULL
);
1305 pim_msdp_peer_change_source(mp
, &source_ip
.ipaddr_v4
);
1311 #endif /* PIM_IPV != 6 */
1314 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag
1316 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_create(
1317 struct nb_cb_create_args
*args
)
1319 switch (args
->event
) {
1320 case NB_EV_VALIDATE
:
1330 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_destroy(
1331 struct nb_cb_destroy_args
*args
)
1333 struct in_addr addr
;
1335 switch (args
->event
) {
1336 case NB_EV_VALIDATE
:
1342 pim_vxlan_mlag_update(true/*mlag_enable*/,
1343 false/*peer_state*/, MLAG_ROLE_NONE
,
1344 NULL
/*peerlink*/, &addr
);
1352 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag
1354 void routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_apply_finish(
1355 struct nb_cb_apply_finish_args
*args
)
1360 struct interface
*ifp
;
1361 struct ipaddr reg_addr
;
1363 ifname
= yang_dnode_get_string(args
->dnode
, "./peerlink-rif");
1364 ifp
= if_lookup_by_name(ifname
, VRF_DEFAULT
);
1366 snprintf(args
->errmsg
, args
->errmsg_len
,
1367 "No such interface name %s", ifname
);
1370 role
= yang_dnode_get_enum(args
->dnode
, "./my-role");
1371 peer_state
= yang_dnode_get_bool(args
->dnode
, "./peer-state");
1372 yang_dnode_get_ip(®_addr
, args
->dnode
, "./reg-address");
1374 pim_vxlan_mlag_update(true, peer_state
, role
, ifp
,
1375 ®_addr
.ip
._v4_addr
);
1380 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/peerlink-rif
1382 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_peerlink_rif_modify(
1383 struct nb_cb_modify_args
*args
)
1385 switch (args
->event
) {
1386 case NB_EV_VALIDATE
:
1396 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_peerlink_rif_destroy(
1397 struct nb_cb_destroy_args
*args
)
1399 switch (args
->event
) {
1400 case NB_EV_VALIDATE
:
1411 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/reg-address
1413 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_reg_address_modify(
1414 struct nb_cb_modify_args
*args
)
1416 switch (args
->event
) {
1417 case NB_EV_VALIDATE
:
1427 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_reg_address_destroy(
1428 struct nb_cb_destroy_args
*args
)
1430 switch (args
->event
) {
1431 case NB_EV_VALIDATE
:
1442 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/my-role
1444 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_my_role_modify(
1445 struct nb_cb_modify_args
*args
)
1447 switch (args
->event
) {
1448 case NB_EV_VALIDATE
:
1459 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/peer-state
1461 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_peer_state_modify(
1462 struct nb_cb_modify_args
*args
)
1464 switch (args
->event
) {
1465 case NB_EV_VALIDATE
:
1476 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/register-accept-list
1478 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_register_accept_list_modify(
1479 struct nb_cb_modify_args
*args
)
1482 struct pim_instance
*pim
;
1485 switch (args
->event
) {
1486 case NB_EV_VALIDATE
:
1491 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1493 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
1495 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
1496 pim
->register_plist
= XSTRDUP(MTYPE_PIM_PLIST_NAME
, plist
);
1504 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_register_accept_list_destroy(
1505 struct nb_cb_destroy_args
*args
)
1508 struct pim_instance
*pim
;
1510 switch (args
->event
) {
1511 case NB_EV_VALIDATE
:
1516 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1519 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
1527 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family
1529 int lib_interface_pim_address_family_create(struct nb_cb_create_args
*args
)
1531 switch (args
->event
) {
1532 case NB_EV_VALIDATE
:
1542 int lib_interface_pim_address_family_destroy(struct nb_cb_destroy_args
*args
)
1544 struct interface
*ifp
;
1545 struct pim_interface
*pim_ifp
;
1547 switch (args
->event
) {
1548 case NB_EV_VALIDATE
:
1553 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1554 pim_ifp
= ifp
->info
;
1558 if (!pim_cmd_interface_delete(ifp
)) {
1559 snprintf(args
->errmsg
, args
->errmsg_len
,
1560 "Unable to delete interface information %s",
1562 return NB_ERR_INCONSISTENCY
;
1570 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/pim-enable
1572 int lib_interface_pim_address_family_pim_enable_modify(struct nb_cb_modify_args
*args
)
1574 struct interface
*ifp
;
1575 struct pim_interface
*pim_ifp
;
1577 const struct lyd_node
*if_dnode
;
1579 switch (args
->event
) {
1580 case NB_EV_VALIDATE
:
1581 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
1583 yang_get_list_elements_count(if_dnode
);
1585 /* Limiting mcast interfaces to number of VIFs */
1586 if (mcast_if_count
== MAXVIFS
) {
1587 snprintf(args
->errmsg
, args
->errmsg_len
,
1588 "Max multicast interfaces(%d) reached.",
1590 return NB_ERR_VALIDATION
;
1597 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1599 if (yang_dnode_get_bool(args
->dnode
, NULL
)) {
1600 if (!pim_cmd_interface_add(ifp
)) {
1601 snprintf(args
->errmsg
, args
->errmsg_len
,
1602 "Could not enable PIM SM on interface %s",
1604 return NB_ERR_INCONSISTENCY
;
1607 pim_ifp
= ifp
->info
;
1609 return NB_ERR_INCONSISTENCY
;
1611 if (!pim_cmd_interface_delete(ifp
)) {
1612 snprintf(args
->errmsg
, args
->errmsg_len
,
1613 "Unable to delete interface information");
1614 return NB_ERR_INCONSISTENCY
;
1624 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/hello-interval
1626 int lib_interface_pim_address_family_hello_interval_modify(
1627 struct nb_cb_modify_args
*args
)
1629 struct interface
*ifp
;
1630 struct pim_interface
*pim_ifp
;
1632 switch (args
->event
) {
1633 case NB_EV_VALIDATE
:
1638 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1639 pim_ifp
= ifp
->info
;
1640 pim_ifp
->pim_hello_period
=
1641 yang_dnode_get_uint8(args
->dnode
, NULL
);
1642 pim_ifp
->pim_default_holdtime
= -1;
1650 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/hello-holdtime
1652 int lib_interface_pim_address_family_hello_holdtime_modify(
1653 struct nb_cb_modify_args
*args
)
1655 struct interface
*ifp
;
1656 struct pim_interface
*pim_ifp
;
1658 switch (args
->event
) {
1659 case NB_EV_VALIDATE
:
1664 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1665 pim_ifp
= ifp
->info
;
1666 pim_ifp
->pim_default_holdtime
=
1667 yang_dnode_get_uint16(args
->dnode
, NULL
);
1675 int lib_interface_pim_address_family_hello_holdtime_destroy(
1676 struct nb_cb_destroy_args
*args
)
1678 struct interface
*ifp
;
1679 struct pim_interface
*pim_ifp
;
1681 switch (args
->event
) {
1682 case NB_EV_VALIDATE
:
1687 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1688 pim_ifp
= ifp
->info
;
1689 pim_ifp
->pim_default_holdtime
= -1;
1696 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd
1698 int lib_interface_pim_address_family_bfd_create(struct nb_cb_create_args
*args
)
1700 struct interface
*ifp
;
1701 struct pim_interface
*pim_ifp
;
1703 switch (args
->event
) {
1704 case NB_EV_VALIDATE
:
1710 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1711 pim_ifp
= ifp
->info
;
1712 pim_ifp
->bfd_config
.enabled
= true;
1719 int lib_interface_pim_address_family_bfd_destroy(
1720 struct nb_cb_destroy_args
*args
)
1722 struct interface
*ifp
;
1723 struct pim_interface
*pim_ifp
;
1724 const struct lyd_node
*if_dnode
;
1726 switch (args
->event
) {
1727 case NB_EV_VALIDATE
:
1728 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
1729 if (!is_pim_interface(if_dnode
)) {
1730 snprintf(args
->errmsg
, args
->errmsg_len
,
1731 "Pim not enabled on this interface");
1732 return NB_ERR_VALIDATION
;
1739 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1740 pim_ifp
= ifp
->info
;
1741 pim_ifp
->bfd_config
.enabled
= false;
1742 pim_bfd_reg_dereg_all_nbr(ifp
);
1750 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd
1752 void lib_interface_pim_address_family_bfd_apply_finish(
1753 struct nb_cb_apply_finish_args
*args
)
1755 struct interface
*ifp
;
1756 struct pim_interface
*pim_ifp
;
1758 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1759 pim_ifp
= ifp
->info
;
1762 zlog_debug("Pim not enabled on this interface");
1766 pim_ifp
->bfd_config
.detection_multiplier
=
1767 yang_dnode_get_uint8(args
->dnode
, "./detect_mult");
1768 pim_ifp
->bfd_config
.min_rx
=
1769 yang_dnode_get_uint16(args
->dnode
, "./min-rx-interval");
1770 pim_ifp
->bfd_config
.min_tx
=
1771 yang_dnode_get_uint16(args
->dnode
, "./min-tx-interval");
1773 pim_bfd_reg_dereg_all_nbr(ifp
);
1777 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/min-rx-interval
1779 int lib_interface_pim_address_family_bfd_min_rx_interval_modify(
1780 struct nb_cb_modify_args
*args
)
1782 switch (args
->event
) {
1783 case NB_EV_VALIDATE
:
1794 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/min-tx-interval
1796 int lib_interface_pim_address_family_bfd_min_tx_interval_modify(
1797 struct nb_cb_modify_args
*args
)
1799 switch (args
->event
) {
1800 case NB_EV_VALIDATE
:
1811 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/detect_mult
1813 int lib_interface_pim_address_family_bfd_detect_mult_modify(
1814 struct nb_cb_modify_args
*args
)
1816 switch (args
->event
) {
1817 case NB_EV_VALIDATE
:
1828 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/profile
1830 int lib_interface_pim_address_family_bfd_profile_modify(
1831 struct nb_cb_modify_args
*args
)
1833 struct interface
*ifp
;
1834 struct pim_interface
*pim_ifp
;
1836 switch (args
->event
) {
1837 case NB_EV_VALIDATE
:
1843 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1844 pim_ifp
= ifp
->info
;
1845 XFREE(MTYPE_TMP
, pim_ifp
->bfd_config
.profile
);
1846 pim_ifp
->bfd_config
.profile
= XSTRDUP(
1847 MTYPE_TMP
, yang_dnode_get_string(args
->dnode
, NULL
));
1854 int lib_interface_pim_address_family_bfd_profile_destroy(
1855 struct nb_cb_destroy_args
*args
)
1857 struct interface
*ifp
;
1858 struct pim_interface
*pim_ifp
;
1860 switch (args
->event
) {
1861 case NB_EV_VALIDATE
:
1867 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1868 pim_ifp
= ifp
->info
;
1869 XFREE(MTYPE_TMP
, pim_ifp
->bfd_config
.profile
);
1877 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bsm
1879 int lib_interface_pim_address_family_bsm_modify(struct nb_cb_modify_args
*args
)
1881 struct interface
*ifp
;
1882 struct pim_interface
*pim_ifp
;
1884 switch (args
->event
) {
1885 case NB_EV_VALIDATE
:
1890 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1891 pim_ifp
= ifp
->info
;
1892 pim_ifp
->bsm_enable
= yang_dnode_get_bool(args
->dnode
, NULL
);
1901 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/unicast-bsm
1903 int lib_interface_pim_address_family_unicast_bsm_modify(
1904 struct nb_cb_modify_args
*args
)
1906 struct interface
*ifp
;
1907 struct pim_interface
*pim_ifp
;
1909 switch (args
->event
) {
1910 case NB_EV_VALIDATE
:
1915 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1916 pim_ifp
= ifp
->info
;
1917 pim_ifp
->ucast_bsm_accept
=
1918 yang_dnode_get_bool(args
->dnode
, NULL
);
1927 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/active-active
1929 int lib_interface_pim_address_family_active_active_modify(
1930 struct nb_cb_modify_args
*args
)
1932 struct interface
*ifp
;
1933 struct pim_interface
*pim_ifp
;
1935 switch (args
->event
) {
1936 case NB_EV_VALIDATE
:
1941 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1942 pim_ifp
= ifp
->info
;
1943 if (yang_dnode_get_bool(args
->dnode
, NULL
)) {
1946 "Configuring PIM active-active on Interface: %s",
1948 pim_if_configure_mlag_dualactive(pim_ifp
);
1952 "UnConfiguring PIM active-active on Interface: %s",
1954 pim_if_unconfigure_mlag_dualactive(pim_ifp
);
1965 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/dr-priority
1967 int lib_interface_pim_address_family_dr_priority_modify(
1968 struct nb_cb_modify_args
*args
)
1970 struct interface
*ifp
;
1971 struct pim_interface
*pim_ifp
;
1972 uint32_t old_dr_prio
;
1973 const struct lyd_node
*if_dnode
;
1975 switch (args
->event
) {
1976 case NB_EV_VALIDATE
:
1977 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
1978 if (!is_pim_interface(if_dnode
)) {
1979 snprintf(args
->errmsg
, args
->errmsg_len
,
1980 "Pim not enabled on this interface");
1981 return NB_ERR_VALIDATION
;
1988 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1989 pim_ifp
= ifp
->info
;
1990 old_dr_prio
= pim_ifp
->pim_dr_priority
;
1991 pim_ifp
->pim_dr_priority
= yang_dnode_get_uint32(args
->dnode
,
1994 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
1995 pim_if_dr_election(ifp
);
1996 pim_hello_restart_now(ifp
);
2005 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/use-source
2007 int lib_interface_pim_address_family_use_source_modify(
2008 struct nb_cb_modify_args
*args
)
2010 struct interface
*ifp
;
2011 pim_addr source_addr
;
2013 const struct lyd_node
*if_dnode
;
2015 switch (args
->event
) {
2016 case NB_EV_VALIDATE
:
2017 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2018 if (!is_pim_interface(if_dnode
)) {
2019 snprintf(args
->errmsg
, args
->errmsg_len
,
2020 "Pim not enabled on this interface");
2021 return NB_ERR_VALIDATION
;
2028 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2030 yang_dnode_get_ipv4(&source_addr
, args
->dnode
, NULL
);
2032 yang_dnode_get_ipv6(&source_addr
, args
->dnode
, NULL
);
2035 result
= interface_pim_use_src_cmd_worker(
2037 args
->errmsg
, args
->errmsg_len
);
2039 if (result
!= PIM_SUCCESS
)
2040 return NB_ERR_INCONSISTENCY
;
2048 int lib_interface_pim_address_family_use_source_destroy(
2049 struct nb_cb_destroy_args
*args
)
2051 struct interface
*ifp
;
2053 const struct lyd_node
*if_dnode
;
2055 switch (args
->event
) {
2056 case NB_EV_VALIDATE
:
2057 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2058 if (!is_pim_interface(if_dnode
)) {
2059 snprintf(args
->errmsg
, args
->errmsg_len
,
2060 "Pim not enabled on this interface");
2061 return NB_ERR_VALIDATION
;
2068 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2070 result
= interface_pim_use_src_cmd_worker(ifp
, PIMADDR_ANY
,
2074 if (result
!= PIM_SUCCESS
)
2075 return NB_ERR_INCONSISTENCY
;
2084 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/multicast-boundary-oil
2086 int lib_interface_pim_address_family_multicast_boundary_oil_modify(
2087 struct nb_cb_modify_args
*args
)
2089 struct interface
*ifp
;
2090 struct pim_interface
*pim_ifp
;
2092 const struct lyd_node
*if_dnode
;
2094 switch (args
->event
) {
2095 case NB_EV_VALIDATE
:
2096 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2097 if (!is_pim_interface(if_dnode
)) {
2098 snprintf(args
->errmsg
, args
->errmsg_len
,
2099 "Pim not enabled on this interface");
2100 return NB_ERR_VALIDATION
;
2107 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2108 pim_ifp
= ifp
->info
;
2109 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
2111 if (pim_ifp
->boundary_oil_plist
)
2112 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
2114 pim_ifp
->boundary_oil_plist
=
2115 XSTRDUP(MTYPE_PIM_INTERFACE
, plist
);
2123 int lib_interface_pim_address_family_multicast_boundary_oil_destroy(
2124 struct nb_cb_destroy_args
*args
)
2126 struct interface
*ifp
;
2127 struct pim_interface
*pim_ifp
;
2128 const struct lyd_node
*if_dnode
;
2130 switch (args
->event
) {
2131 case NB_EV_VALIDATE
:
2132 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2133 if (!is_pim_interface(if_dnode
)) {
2134 snprintf(args
->errmsg
, args
->errmsg_len
,
2135 "%% Enable PIM and/or IGMP on this interface first");
2136 return NB_ERR_VALIDATION
;
2143 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2144 pim_ifp
= ifp
->info
;
2145 if (pim_ifp
->boundary_oil_plist
)
2146 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
2154 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/mroute
2156 int lib_interface_pim_address_family_mroute_create(
2157 struct nb_cb_create_args
*args
)
2159 switch (args
->event
) {
2160 case NB_EV_VALIDATE
:
2170 int lib_interface_pim_address_family_mroute_destroy(
2171 struct nb_cb_destroy_args
*args
)
2173 struct pim_instance
*pim
;
2174 struct pim_interface
*pim_iifp
;
2175 struct interface
*iif
;
2176 struct interface
*oif
;
2177 const char *oifname
;
2178 pim_addr source_addr
;
2179 pim_addr group_addr
;
2180 const struct lyd_node
*if_dnode
;
2182 switch (args
->event
) {
2183 case NB_EV_VALIDATE
:
2184 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2185 if (!is_pim_interface(if_dnode
)) {
2186 snprintf(args
->errmsg
, args
->errmsg_len
,
2187 "%% Enable PIM and/or IGMP on this interface first");
2188 return NB_ERR_VALIDATION
;
2195 iif
= nb_running_get_entry(args
->dnode
, NULL
, true);
2196 pim_iifp
= iif
->info
;
2197 pim
= pim_iifp
->pim
;
2199 oifname
= yang_dnode_get_string(args
->dnode
, "./oif");
2200 oif
= if_lookup_by_name(oifname
, pim
->vrf
->vrf_id
);
2203 snprintf(args
->errmsg
, args
->errmsg_len
,
2204 "No such interface name %s",
2206 return NB_ERR_INCONSISTENCY
;
2209 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
, "./source-addr");
2210 yang_dnode_get_pimaddr(&group_addr
, args
->dnode
, "./group-addr");
2212 if (pim_static_del(pim
, iif
, oif
, group_addr
, source_addr
)) {
2213 snprintf(args
->errmsg
, args
->errmsg_len
,
2214 "Failed to remove static mroute");
2215 return NB_ERR_INCONSISTENCY
;
2225 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/mroute/oif
2227 int lib_interface_pim_address_family_mroute_oif_modify(
2228 struct nb_cb_modify_args
*args
)
2230 struct pim_instance
*pim
;
2231 struct pim_interface
*pim_iifp
;
2232 struct interface
*iif
;
2233 struct interface
*oif
;
2234 const char *oifname
;
2235 pim_addr source_addr
;
2236 pim_addr group_addr
;
2237 const struct lyd_node
*if_dnode
;
2239 switch (args
->event
) {
2240 case NB_EV_VALIDATE
:
2241 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2242 if (!is_pim_interface(if_dnode
)) {
2243 snprintf(args
->errmsg
, args
->errmsg_len
,
2244 "%% Enable PIM and/or IGMP on this interface first");
2245 return NB_ERR_VALIDATION
;
2248 #ifdef PIM_ENFORCE_LOOPFREE_MFC
2249 iif
= nb_running_get_entry(args
->dnode
, NULL
, false);
2254 pim_iifp
= iif
->info
;
2255 pim
= pim_iifp
->pim
;
2257 oifname
= yang_dnode_get_string(args
->dnode
, NULL
);
2258 oif
= if_lookup_by_name(oifname
, pim
->vrf
->vrf_id
);
2260 if (oif
&& (iif
->ifindex
== oif
->ifindex
)) {
2261 strlcpy(args
->errmsg
,
2262 "% IIF same as OIF and loopfree enforcement is enabled; rejecting",
2264 return NB_ERR_VALIDATION
;
2272 iif
= nb_running_get_entry(args
->dnode
, NULL
, true);
2273 pim_iifp
= iif
->info
;
2274 pim
= pim_iifp
->pim
;
2276 oifname
= yang_dnode_get_string(args
->dnode
, NULL
);
2277 oif
= if_lookup_by_name(oifname
, pim
->vrf
->vrf_id
);
2279 snprintf(args
->errmsg
, args
->errmsg_len
,
2280 "No such interface name %s",
2282 return NB_ERR_INCONSISTENCY
;
2285 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
, "../source-addr");
2286 yang_dnode_get_pimaddr(&group_addr
, args
->dnode
, "../group-addr");
2288 if (pim_static_add(pim
, iif
, oif
, group_addr
, source_addr
)) {
2289 snprintf(args
->errmsg
, args
->errmsg_len
,
2290 "Failed to add static mroute");
2291 return NB_ERR_INCONSISTENCY
;
2300 int lib_interface_pim_address_family_mroute_oif_destroy(
2301 struct nb_cb_destroy_args
*args
)
2303 switch (args
->event
) {
2304 case NB_EV_VALIDATE
:
2315 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/static-rp/rp-list
2317 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_create(
2318 struct nb_cb_create_args
*args
)
2320 switch (args
->event
) {
2321 case NB_EV_VALIDATE
:
2331 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_destroy(
2332 struct nb_cb_destroy_args
*args
)
2335 struct pim_instance
*pim
;
2336 struct prefix group
;
2341 switch (args
->event
) {
2342 case NB_EV_VALIDATE
:
2347 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2349 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "./rp-address");
2351 if (yang_dnode_get(args
->dnode
, "./group-list")) {
2352 yang_dnode_get_prefix(&group
, args
->dnode
,
2355 result
= pim_no_rp_cmd_worker(pim
, rp_addr
, group
, NULL
,
2360 else if (yang_dnode_get(args
->dnode
, "./prefix-list")) {
2361 plist
= yang_dnode_get_string(args
->dnode
,
2363 if (!pim_get_all_mcast_group(&group
)) {
2366 "Unable to convert 224.0.0.0/4 to prefix");
2367 return NB_ERR_INCONSISTENCY
;
2370 result
= pim_no_rp_cmd_worker(pim
, rp_addr
, group
,
2371 plist
, args
->errmsg
,
2376 return NB_ERR_INCONSISTENCY
;
2384 * 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
2386 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_group_list_create(
2387 struct nb_cb_create_args
*args
)
2390 struct pim_instance
*pim
;
2391 struct prefix group
;
2394 switch (args
->event
) {
2395 case NB_EV_VALIDATE
:
2400 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2402 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "../rp-address");
2403 yang_dnode_get_prefix(&group
, args
->dnode
, NULL
);
2405 return pim_rp_cmd_worker(pim
, rp_addr
, group
, NULL
,
2406 args
->errmsg
, args
->errmsg_len
);
2412 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_group_list_destroy(
2413 struct nb_cb_destroy_args
*args
)
2416 struct pim_instance
*pim
;
2417 struct prefix group
;
2420 switch (args
->event
) {
2421 case NB_EV_VALIDATE
:
2426 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2428 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "../rp-address");
2429 yang_dnode_get_prefix(&group
, args
->dnode
, NULL
);
2432 return pim_no_rp_cmd_worker(pim
, rp_addr
, group
, NULL
,
2433 args
->errmsg
, args
->errmsg_len
);
2440 * 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
2442 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_prefix_list_modify(
2443 struct nb_cb_modify_args
*args
)
2446 struct pim_instance
*pim
;
2447 struct prefix group
;
2451 switch (args
->event
) {
2452 case NB_EV_VALIDATE
:
2457 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2459 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
2460 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "../rp-address");
2461 if (!pim_get_all_mcast_group(&group
)) {
2462 flog_err(EC_LIB_DEVELOPMENT
,
2463 "Unable to convert 224.0.0.0/4 to prefix");
2464 return NB_ERR_INCONSISTENCY
;
2466 return pim_rp_cmd_worker(pim
, rp_addr
, group
, plist
,
2467 args
->errmsg
, args
->errmsg_len
);
2473 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_prefix_list_destroy(
2474 struct nb_cb_destroy_args
*args
)
2477 struct pim_instance
*pim
;
2478 struct prefix group
;
2482 switch (args
->event
) {
2483 case NB_EV_VALIDATE
:
2488 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2490 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "../rp-address");
2491 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
2492 if (!pim_get_all_mcast_group(&group
)) {
2493 flog_err(EC_LIB_DEVELOPMENT
,
2494 "Unable to convert 224.0.0.0/4 to prefix");
2495 return NB_ERR_INCONSISTENCY
;
2497 return pim_no_rp_cmd_worker(pim
, rp_addr
, group
, plist
,
2498 args
->errmsg
, args
->errmsg_len
);
2506 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family
2508 int lib_interface_gmp_address_family_create(struct nb_cb_create_args
*args
)
2510 switch (args
->event
) {
2511 case NB_EV_VALIDATE
:
2521 int lib_interface_gmp_address_family_destroy(struct nb_cb_destroy_args
*args
)
2523 struct interface
*ifp
;
2524 struct pim_interface
*pim_ifp
;
2526 switch (args
->event
) {
2527 case NB_EV_VALIDATE
:
2532 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2533 pim_ifp
= ifp
->info
;
2538 PIM_IF_DONT_IGMP(pim_ifp
->options
);
2540 pim_if_membership_clear(ifp
);
2542 pim_if_addr_del_all_igmp(ifp
);
2544 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
2552 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/enable
2554 int lib_interface_gmp_address_family_enable_modify(
2555 struct nb_cb_modify_args
*args
)
2557 struct interface
*ifp
;
2559 struct pim_interface
*pim_ifp
;
2561 const char *ifp_name
;
2562 const struct lyd_node
*if_dnode
;
2564 switch (args
->event
) {
2565 case NB_EV_VALIDATE
:
2566 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2568 yang_get_list_elements_count(if_dnode
);
2569 /* Limiting mcast interfaces to number of VIFs */
2570 if (mcast_if_count
== MAXVIFS
) {
2571 ifp_name
= yang_dnode_get_string(if_dnode
, "name");
2572 snprintf(args
->errmsg
, args
->errmsg_len
,
2573 "Max multicast interfaces(%d) Reached. Could not enable IGMP on interface %s",
2575 return NB_ERR_VALIDATION
;
2582 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2583 igmp_enable
= yang_dnode_get_bool(args
->dnode
, NULL
);
2586 return pim_cmd_igmp_start(ifp
);
2589 pim_ifp
= ifp
->info
;
2592 return NB_ERR_INCONSISTENCY
;
2594 PIM_IF_DONT_IGMP(pim_ifp
->options
);
2596 pim_if_membership_clear(ifp
);
2598 pim_if_addr_del_all_igmp(ifp
);
2600 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
2609 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/igmp-version
2611 int lib_interface_gmp_address_family_igmp_version_modify(
2612 struct nb_cb_modify_args
*args
)
2614 struct interface
*ifp
;
2615 struct pim_interface
*pim_ifp
;
2616 int igmp_version
, old_version
= 0;
2618 switch (args
->event
) {
2619 case NB_EV_VALIDATE
:
2624 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2625 pim_ifp
= ifp
->info
;
2628 return NB_ERR_INCONSISTENCY
;
2630 igmp_version
= yang_dnode_get_uint8(args
->dnode
, NULL
);
2631 old_version
= pim_ifp
->igmp_version
;
2632 pim_ifp
->igmp_version
= igmp_version
;
2634 /* Current and new version is different refresh existing
2635 * membership. Going from 3 -> 2 or 2 -> 3.
2637 if (old_version
!= igmp_version
)
2638 pim_if_membership_refresh(ifp
);
2646 int lib_interface_gmp_address_family_igmp_version_destroy(
2647 struct nb_cb_destroy_args
*args
)
2649 struct interface
*ifp
;
2650 struct pim_interface
*pim_ifp
;
2652 switch (args
->event
) {
2653 case NB_EV_VALIDATE
:
2658 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2659 pim_ifp
= ifp
->info
;
2660 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
2668 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/mld-version
2670 int lib_interface_gmp_address_family_mld_version_modify(
2671 struct nb_cb_modify_args
*args
)
2673 switch (args
->event
) {
2674 case NB_EV_VALIDATE
:
2684 int lib_interface_gmp_address_family_mld_version_destroy(
2685 struct nb_cb_destroy_args
*args
)
2687 switch (args
->event
) {
2688 case NB_EV_VALIDATE
:
2699 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/query-interval
2701 int lib_interface_gmp_address_family_query_interval_modify(
2702 struct nb_cb_modify_args
*args
)
2704 struct interface
*ifp
;
2707 switch (args
->event
) {
2708 case NB_EV_VALIDATE
:
2713 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2714 query_interval
= yang_dnode_get_uint16(args
->dnode
, NULL
);
2715 change_query_interval(ifp
->info
, query_interval
);
2722 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/query-max-response-time
2724 int lib_interface_gmp_address_family_query_max_response_time_modify(
2725 struct nb_cb_modify_args
*args
)
2727 struct interface
*ifp
;
2728 int query_max_response_time_dsec
;
2730 switch (args
->event
) {
2731 case NB_EV_VALIDATE
:
2736 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2737 query_max_response_time_dsec
=
2738 yang_dnode_get_uint16(args
->dnode
, NULL
);
2739 change_query_max_response_time(ifp
->info
,
2740 query_max_response_time_dsec
);
2747 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/last-member-query-interval
2749 int lib_interface_gmp_address_family_last_member_query_interval_modify(
2750 struct nb_cb_modify_args
*args
)
2752 struct interface
*ifp
;
2753 struct pim_interface
*pim_ifp
;
2754 int last_member_query_interval
;
2756 switch (args
->event
) {
2757 case NB_EV_VALIDATE
:
2762 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2763 pim_ifp
= ifp
->info
;
2764 last_member_query_interval
=
2765 yang_dnode_get_uint16(args
->dnode
, NULL
);
2766 pim_ifp
->gm_specific_query_max_response_time_dsec
=
2767 last_member_query_interval
;
2776 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/robustness-variable
2778 int lib_interface_gmp_address_family_robustness_variable_modify(
2779 struct nb_cb_modify_args
*args
)
2781 struct interface
*ifp
;
2782 struct pim_interface
*pim_ifp
;
2783 int last_member_query_count
;
2785 switch (args
->event
) {
2786 case NB_EV_VALIDATE
:
2791 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2792 pim_ifp
= ifp
->info
;
2793 last_member_query_count
=
2794 yang_dnode_get_uint8(args
->dnode
, NULL
);
2795 pim_ifp
->gm_last_member_query_count
= last_member_query_count
;
2804 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/static-group
2806 int lib_interface_gmp_address_family_static_group_create(
2807 struct nb_cb_create_args
*args
)
2809 struct interface
*ifp
;
2810 struct ipaddr source_addr
;
2811 struct ipaddr group_addr
;
2813 const char *ifp_name
;
2814 const struct lyd_node
*if_dnode
;
2816 switch (args
->event
) {
2817 case NB_EV_VALIDATE
:
2818 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2819 if (!is_pim_interface(if_dnode
)) {
2820 ifp_name
= yang_dnode_get_string(if_dnode
, "name");
2821 snprintf(args
->errmsg
, args
->errmsg_len
,
2822 "multicast not enabled on interface %s",
2824 return NB_ERR_VALIDATION
;
2827 yang_dnode_get_ip(&group_addr
, args
->dnode
, "./group-addr");
2828 if (pim_is_group_224_0_0_0_24(group_addr
.ip
._v4_addr
)) {
2830 args
->errmsg
, args
->errmsg_len
,
2831 "Groups within 224.0.0.0/24 are reserved and cannot be joined");
2832 return NB_ERR_VALIDATION
;
2839 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2840 yang_dnode_get_ip(&source_addr
, args
->dnode
, "./source-addr");
2841 yang_dnode_get_ip(&group_addr
, args
->dnode
, "./group-addr");
2843 result
= pim_if_igmp_join_add(ifp
, group_addr
.ip
._v4_addr
,
2844 source_addr
.ip
._v4_addr
);
2846 snprintf(args
->errmsg
, args
->errmsg_len
,
2847 "Failure joining IGMP group");
2848 return NB_ERR_INCONSISTENCY
;
2855 int lib_interface_gmp_address_family_static_group_destroy(
2856 struct nb_cb_destroy_args
*args
)
2858 struct interface
*ifp
;
2859 struct ipaddr source_addr
;
2860 struct ipaddr group_addr
;
2863 switch (args
->event
) {
2864 case NB_EV_VALIDATE
:
2869 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2870 yang_dnode_get_ip(&source_addr
, args
->dnode
, "./source-addr");
2871 yang_dnode_get_ip(&group_addr
, args
->dnode
, "./group-addr");
2873 result
= pim_if_igmp_join_del(ifp
, group_addr
.ip
._v4_addr
,
2874 source_addr
.ip
._v4_addr
);
2877 char src_str
[INET_ADDRSTRLEN
];
2878 char grp_str
[INET_ADDRSTRLEN
];
2880 ipaddr2str(&source_addr
, src_str
, sizeof(src_str
));
2881 ipaddr2str(&group_addr
, grp_str
, sizeof(grp_str
));
2883 snprintf(args
->errmsg
, args
->errmsg_len
,
2884 "%% Failure leaving IGMP group %s %s on interface %s: %d",
2885 src_str
, grp_str
, ifp
->name
, result
);
2887 return NB_ERR_INCONSISTENCY
;