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 pim_addr source_addr
;
935 switch (args
->event
) {
941 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
943 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
,
945 result
= pim_ssmpingd_start(pim
, source_addr
);
948 args
->errmsg
, args
->errmsg_len
,
949 "%% Failure starting ssmpingd for source %pPA: %d",
950 &source_addr
, result
);
951 return NB_ERR_INCONSISTENCY
;
958 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_pingd_source_ip_destroy(
959 struct nb_cb_destroy_args
*args
)
962 struct pim_instance
*pim
;
964 pim_addr source_addr
;
966 switch (args
->event
) {
972 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
974 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
,
976 result
= pim_ssmpingd_stop(pim
, source_addr
);
979 args
->errmsg
, args
->errmsg_len
,
980 "%% Failure stopping ssmpingd for source %pPA: %d",
981 &source_addr
, result
);
982 return NB_ERR_INCONSISTENCY
;
993 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/hold-time
995 int pim_msdp_hold_time_modify(struct nb_cb_modify_args
*args
)
997 struct pim_instance
*pim
;
1000 switch (args
->event
) {
1001 case NB_EV_VALIDATE
:
1006 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1008 pim
->msdp
.hold_time
= yang_dnode_get_uint16(args
->dnode
, NULL
);
1017 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/keep-alive
1019 int pim_msdp_keep_alive_modify(struct nb_cb_modify_args
*args
)
1021 struct pim_instance
*pim
;
1024 switch (args
->event
) {
1025 case NB_EV_VALIDATE
:
1030 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1032 pim
->msdp
.keep_alive
= yang_dnode_get_uint16(args
->dnode
, NULL
);
1041 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/connection-retry
1043 int pim_msdp_connection_retry_modify(struct nb_cb_modify_args
*args
)
1045 struct pim_instance
*pim
;
1048 switch (args
->event
) {
1049 case NB_EV_VALIDATE
:
1054 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1056 pim
->msdp
.connection_retry
=
1057 yang_dnode_get_uint16(args
->dnode
, NULL
);
1064 pim6_msdp_err(pim_msdp_mesh_group_destroy
, nb_cb_destroy_args
);
1065 pim6_msdp_err(pim_msdp_mesh_group_create
, nb_cb_create_args
);
1066 pim6_msdp_err(pim_msdp_mesh_group_source_modify
, nb_cb_modify_args
);
1067 pim6_msdp_err(pim_msdp_mesh_group_source_destroy
, nb_cb_destroy_args
);
1068 pim6_msdp_err(pim_msdp_mesh_group_members_create
, nb_cb_create_args
);
1069 pim6_msdp_err(pim_msdp_mesh_group_members_destroy
, nb_cb_destroy_args
);
1070 pim6_msdp_err(routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify
,
1072 pim6_msdp_err(routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_destroy
,
1073 nb_cb_destroy_args
);
1074 pim6_msdp_err(routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_create
,
1080 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups
1082 int pim_msdp_mesh_group_create(struct nb_cb_create_args
*args
)
1084 struct pim_msdp_mg
*mg
;
1087 switch (args
->event
) {
1088 case NB_EV_VALIDATE
:
1093 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1094 mg
= pim_msdp_mg_new(vrf
->info
, yang_dnode_get_string(
1095 args
->dnode
, "./name"));
1096 nb_running_set_entry(args
->dnode
, mg
);
1103 int pim_msdp_mesh_group_destroy(struct nb_cb_destroy_args
*args
)
1105 struct pim_msdp_mg
*mg
;
1108 switch (args
->event
) {
1109 case NB_EV_VALIDATE
:
1114 mg
= nb_running_unset_entry(args
->dnode
);
1115 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1116 pim_msdp_mg_free(vrf
->info
, &mg
);
1125 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups/source
1127 int pim_msdp_mesh_group_source_modify(struct nb_cb_modify_args
*args
)
1129 const struct lyd_node
*vrf_dnode
;
1130 struct pim_msdp_mg
*mg
;
1134 switch (args
->event
) {
1135 case NB_EV_VALIDATE
:
1140 mg
= nb_running_get_entry(args
->dnode
, NULL
, true);
1142 yang_dnode_get_parent(args
->dnode
, "address-family");
1143 vrf
= nb_running_get_entry(vrf_dnode
, "../../", true);
1144 yang_dnode_get_ip(&ip
, args
->dnode
, NULL
);
1146 pim_msdp_mg_src_add(vrf
->info
, mg
, &ip
.ip
._v4_addr
);
1152 int pim_msdp_mesh_group_source_destroy(struct nb_cb_destroy_args
*args
)
1154 const struct lyd_node
*vrf_dnode
;
1155 struct pim_msdp_mg
*mg
;
1157 struct in_addr addr
;
1159 switch (args
->event
) {
1160 case NB_EV_VALIDATE
:
1165 mg
= nb_running_get_entry(args
->dnode
, NULL
, true);
1167 yang_dnode_get_parent(args
->dnode
, "address-family");
1168 vrf
= nb_running_get_entry(vrf_dnode
, "../../", true);
1170 addr
.s_addr
= INADDR_ANY
;
1171 pim_msdp_mg_src_add(vrf
->info
, mg
, &addr
);
1180 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups/members
1182 int pim_msdp_mesh_group_members_create(struct nb_cb_create_args
*args
)
1184 const struct lyd_node
*vrf_dnode
;
1185 struct pim_msdp_mg_mbr
*mbr
;
1186 struct pim_msdp_mg
*mg
;
1190 switch (args
->event
) {
1191 case NB_EV_VALIDATE
:
1196 mg
= nb_running_get_entry(args
->dnode
, NULL
, true);
1198 yang_dnode_get_parent(args
->dnode
, "address-family");
1199 vrf
= nb_running_get_entry(vrf_dnode
, "../../", true);
1200 yang_dnode_get_ip(&ip
, args
->dnode
, "address");
1202 mbr
= pim_msdp_mg_mbr_add(vrf
->info
, mg
, &ip
.ip
._v4_addr
);
1203 nb_running_set_entry(args
->dnode
, mbr
);
1210 int pim_msdp_mesh_group_members_destroy(struct nb_cb_destroy_args
*args
)
1212 struct pim_msdp_mg_mbr
*mbr
;
1213 struct pim_msdp_mg
*mg
;
1214 const struct lyd_node
*mg_dnode
;
1216 switch (args
->event
) {
1217 case NB_EV_VALIDATE
:
1222 mbr
= nb_running_get_entry(args
->dnode
, NULL
, true);
1224 yang_dnode_get_parent(args
->dnode
, "msdp-mesh-groups");
1225 mg
= nb_running_get_entry(mg_dnode
, NULL
, true);
1226 pim_msdp_mg_mbr_del(mg
, mbr
);
1227 nb_running_unset_entry(args
->dnode
);
1235 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-peer
1237 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_create(
1238 struct nb_cb_create_args
*args
)
1240 struct pim_msdp_peer
*mp
;
1241 struct pim_instance
*pim
;
1243 struct ipaddr peer_ip
;
1244 struct ipaddr source_ip
;
1246 switch (args
->event
) {
1247 case NB_EV_VALIDATE
:
1252 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1254 yang_dnode_get_ip(&peer_ip
, args
->dnode
, "./peer-ip");
1255 yang_dnode_get_ip(&source_ip
, args
->dnode
, "./source-ip");
1256 mp
= pim_msdp_peer_add(pim
, &peer_ip
.ipaddr_v4
,
1257 &source_ip
.ipaddr_v4
, NULL
);
1258 nb_running_set_entry(args
->dnode
, mp
);
1265 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_destroy(
1266 struct nb_cb_destroy_args
*args
)
1268 struct pim_msdp_peer
*mp
;
1270 switch (args
->event
) {
1271 case NB_EV_VALIDATE
:
1276 mp
= nb_running_unset_entry(args
->dnode
);
1277 pim_msdp_peer_del(&mp
);
1285 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-peer/source-ip
1287 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify(
1288 struct nb_cb_modify_args
*args
)
1290 struct pim_msdp_peer
*mp
;
1291 struct ipaddr source_ip
;
1293 switch (args
->event
) {
1294 case NB_EV_VALIDATE
:
1299 mp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1300 yang_dnode_get_ip(&source_ip
, args
->dnode
, NULL
);
1301 pim_msdp_peer_change_source(mp
, &source_ip
.ipaddr_v4
);
1307 #endif /* PIM_IPV != 6 */
1310 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag
1312 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_create(
1313 struct nb_cb_create_args
*args
)
1315 switch (args
->event
) {
1316 case NB_EV_VALIDATE
:
1326 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_destroy(
1327 struct nb_cb_destroy_args
*args
)
1329 struct in_addr addr
;
1331 switch (args
->event
) {
1332 case NB_EV_VALIDATE
:
1338 pim_vxlan_mlag_update(true/*mlag_enable*/,
1339 false/*peer_state*/, MLAG_ROLE_NONE
,
1340 NULL
/*peerlink*/, &addr
);
1348 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag
1350 void routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_apply_finish(
1351 struct nb_cb_apply_finish_args
*args
)
1356 struct interface
*ifp
;
1357 struct ipaddr reg_addr
;
1359 ifname
= yang_dnode_get_string(args
->dnode
, "./peerlink-rif");
1360 ifp
= if_lookup_by_name(ifname
, VRF_DEFAULT
);
1362 snprintf(args
->errmsg
, args
->errmsg_len
,
1363 "No such interface name %s", ifname
);
1366 role
= yang_dnode_get_enum(args
->dnode
, "./my-role");
1367 peer_state
= yang_dnode_get_bool(args
->dnode
, "./peer-state");
1368 yang_dnode_get_ip(®_addr
, args
->dnode
, "./reg-address");
1370 pim_vxlan_mlag_update(true, peer_state
, role
, ifp
,
1371 ®_addr
.ip
._v4_addr
);
1376 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/peerlink-rif
1378 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_peerlink_rif_modify(
1379 struct nb_cb_modify_args
*args
)
1381 switch (args
->event
) {
1382 case NB_EV_VALIDATE
:
1392 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_peerlink_rif_destroy(
1393 struct nb_cb_destroy_args
*args
)
1395 switch (args
->event
) {
1396 case NB_EV_VALIDATE
:
1407 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/reg-address
1409 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_reg_address_modify(
1410 struct nb_cb_modify_args
*args
)
1412 switch (args
->event
) {
1413 case NB_EV_VALIDATE
:
1423 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_reg_address_destroy(
1424 struct nb_cb_destroy_args
*args
)
1426 switch (args
->event
) {
1427 case NB_EV_VALIDATE
:
1438 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/my-role
1440 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_my_role_modify(
1441 struct nb_cb_modify_args
*args
)
1443 switch (args
->event
) {
1444 case NB_EV_VALIDATE
:
1455 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/peer-state
1457 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_peer_state_modify(
1458 struct nb_cb_modify_args
*args
)
1460 switch (args
->event
) {
1461 case NB_EV_VALIDATE
:
1472 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/register-accept-list
1474 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_register_accept_list_modify(
1475 struct nb_cb_modify_args
*args
)
1478 struct pim_instance
*pim
;
1481 switch (args
->event
) {
1482 case NB_EV_VALIDATE
:
1487 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1489 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
1491 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
1492 pim
->register_plist
= XSTRDUP(MTYPE_PIM_PLIST_NAME
, plist
);
1500 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_register_accept_list_destroy(
1501 struct nb_cb_destroy_args
*args
)
1504 struct pim_instance
*pim
;
1506 switch (args
->event
) {
1507 case NB_EV_VALIDATE
:
1512 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1515 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
1523 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family
1525 int lib_interface_pim_address_family_create(struct nb_cb_create_args
*args
)
1527 switch (args
->event
) {
1528 case NB_EV_VALIDATE
:
1538 int lib_interface_pim_address_family_destroy(struct nb_cb_destroy_args
*args
)
1540 struct interface
*ifp
;
1541 struct pim_interface
*pim_ifp
;
1543 switch (args
->event
) {
1544 case NB_EV_VALIDATE
:
1549 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1550 pim_ifp
= ifp
->info
;
1554 if (!pim_cmd_interface_delete(ifp
)) {
1555 snprintf(args
->errmsg
, args
->errmsg_len
,
1556 "Unable to delete interface information %s",
1558 return NB_ERR_INCONSISTENCY
;
1566 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/pim-enable
1568 int lib_interface_pim_address_family_pim_enable_modify(struct nb_cb_modify_args
*args
)
1570 struct interface
*ifp
;
1571 struct pim_interface
*pim_ifp
;
1573 const struct lyd_node
*if_dnode
;
1575 switch (args
->event
) {
1576 case NB_EV_VALIDATE
:
1577 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
1579 yang_get_list_elements_count(if_dnode
);
1581 /* Limiting mcast interfaces to number of VIFs */
1582 if (mcast_if_count
== MAXVIFS
) {
1583 snprintf(args
->errmsg
, args
->errmsg_len
,
1584 "Max multicast interfaces(%d) reached.",
1586 return NB_ERR_VALIDATION
;
1593 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1595 if (yang_dnode_get_bool(args
->dnode
, NULL
)) {
1596 if (!pim_cmd_interface_add(ifp
)) {
1597 snprintf(args
->errmsg
, args
->errmsg_len
,
1598 "Could not enable PIM SM on interface %s",
1600 return NB_ERR_INCONSISTENCY
;
1603 pim_ifp
= ifp
->info
;
1605 return NB_ERR_INCONSISTENCY
;
1607 if (!pim_cmd_interface_delete(ifp
)) {
1608 snprintf(args
->errmsg
, args
->errmsg_len
,
1609 "Unable to delete interface information");
1610 return NB_ERR_INCONSISTENCY
;
1620 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/hello-interval
1622 int lib_interface_pim_address_family_hello_interval_modify(
1623 struct nb_cb_modify_args
*args
)
1625 struct interface
*ifp
;
1626 struct pim_interface
*pim_ifp
;
1628 switch (args
->event
) {
1629 case NB_EV_VALIDATE
:
1634 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1635 pim_ifp
= ifp
->info
;
1636 pim_ifp
->pim_hello_period
=
1637 yang_dnode_get_uint8(args
->dnode
, NULL
);
1638 pim_ifp
->pim_default_holdtime
= -1;
1646 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/hello-holdtime
1648 int lib_interface_pim_address_family_hello_holdtime_modify(
1649 struct nb_cb_modify_args
*args
)
1651 struct interface
*ifp
;
1652 struct pim_interface
*pim_ifp
;
1654 switch (args
->event
) {
1655 case NB_EV_VALIDATE
:
1660 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1661 pim_ifp
= ifp
->info
;
1662 pim_ifp
->pim_default_holdtime
=
1663 yang_dnode_get_uint16(args
->dnode
, NULL
);
1671 int lib_interface_pim_address_family_hello_holdtime_destroy(
1672 struct nb_cb_destroy_args
*args
)
1674 struct interface
*ifp
;
1675 struct pim_interface
*pim_ifp
;
1677 switch (args
->event
) {
1678 case NB_EV_VALIDATE
:
1683 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1684 pim_ifp
= ifp
->info
;
1685 pim_ifp
->pim_default_holdtime
= -1;
1692 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd
1694 int lib_interface_pim_address_family_bfd_create(struct nb_cb_create_args
*args
)
1696 struct interface
*ifp
;
1697 struct pim_interface
*pim_ifp
;
1699 switch (args
->event
) {
1700 case NB_EV_VALIDATE
:
1706 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1707 pim_ifp
= ifp
->info
;
1708 pim_ifp
->bfd_config
.enabled
= true;
1715 int lib_interface_pim_address_family_bfd_destroy(
1716 struct nb_cb_destroy_args
*args
)
1718 struct interface
*ifp
;
1719 struct pim_interface
*pim_ifp
;
1720 const struct lyd_node
*if_dnode
;
1722 switch (args
->event
) {
1723 case NB_EV_VALIDATE
:
1724 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
1725 if (!is_pim_interface(if_dnode
)) {
1726 snprintf(args
->errmsg
, args
->errmsg_len
,
1727 "Pim not enabled on this interface");
1728 return NB_ERR_VALIDATION
;
1735 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1736 pim_ifp
= ifp
->info
;
1737 pim_ifp
->bfd_config
.enabled
= false;
1738 pim_bfd_reg_dereg_all_nbr(ifp
);
1746 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd
1748 void lib_interface_pim_address_family_bfd_apply_finish(
1749 struct nb_cb_apply_finish_args
*args
)
1751 struct interface
*ifp
;
1752 struct pim_interface
*pim_ifp
;
1754 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1755 pim_ifp
= ifp
->info
;
1758 zlog_debug("Pim not enabled on this interface");
1762 pim_ifp
->bfd_config
.detection_multiplier
=
1763 yang_dnode_get_uint8(args
->dnode
, "./detect_mult");
1764 pim_ifp
->bfd_config
.min_rx
=
1765 yang_dnode_get_uint16(args
->dnode
, "./min-rx-interval");
1766 pim_ifp
->bfd_config
.min_tx
=
1767 yang_dnode_get_uint16(args
->dnode
, "./min-tx-interval");
1769 pim_bfd_reg_dereg_all_nbr(ifp
);
1773 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/min-rx-interval
1775 int lib_interface_pim_address_family_bfd_min_rx_interval_modify(
1776 struct nb_cb_modify_args
*args
)
1778 switch (args
->event
) {
1779 case NB_EV_VALIDATE
:
1790 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/min-tx-interval
1792 int lib_interface_pim_address_family_bfd_min_tx_interval_modify(
1793 struct nb_cb_modify_args
*args
)
1795 switch (args
->event
) {
1796 case NB_EV_VALIDATE
:
1807 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/detect_mult
1809 int lib_interface_pim_address_family_bfd_detect_mult_modify(
1810 struct nb_cb_modify_args
*args
)
1812 switch (args
->event
) {
1813 case NB_EV_VALIDATE
:
1824 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/profile
1826 int lib_interface_pim_address_family_bfd_profile_modify(
1827 struct nb_cb_modify_args
*args
)
1829 struct interface
*ifp
;
1830 struct pim_interface
*pim_ifp
;
1832 switch (args
->event
) {
1833 case NB_EV_VALIDATE
:
1839 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1840 pim_ifp
= ifp
->info
;
1841 XFREE(MTYPE_TMP
, pim_ifp
->bfd_config
.profile
);
1842 pim_ifp
->bfd_config
.profile
= XSTRDUP(
1843 MTYPE_TMP
, yang_dnode_get_string(args
->dnode
, NULL
));
1850 int lib_interface_pim_address_family_bfd_profile_destroy(
1851 struct nb_cb_destroy_args
*args
)
1853 struct interface
*ifp
;
1854 struct pim_interface
*pim_ifp
;
1856 switch (args
->event
) {
1857 case NB_EV_VALIDATE
:
1863 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1864 pim_ifp
= ifp
->info
;
1865 XFREE(MTYPE_TMP
, pim_ifp
->bfd_config
.profile
);
1873 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bsm
1875 int lib_interface_pim_address_family_bsm_modify(struct nb_cb_modify_args
*args
)
1877 struct interface
*ifp
;
1878 struct pim_interface
*pim_ifp
;
1880 switch (args
->event
) {
1881 case NB_EV_VALIDATE
:
1886 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1887 pim_ifp
= ifp
->info
;
1888 pim_ifp
->bsm_enable
= yang_dnode_get_bool(args
->dnode
, NULL
);
1897 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/unicast-bsm
1899 int lib_interface_pim_address_family_unicast_bsm_modify(
1900 struct nb_cb_modify_args
*args
)
1902 struct interface
*ifp
;
1903 struct pim_interface
*pim_ifp
;
1905 switch (args
->event
) {
1906 case NB_EV_VALIDATE
:
1911 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1912 pim_ifp
= ifp
->info
;
1913 pim_ifp
->ucast_bsm_accept
=
1914 yang_dnode_get_bool(args
->dnode
, NULL
);
1923 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/active-active
1925 int lib_interface_pim_address_family_active_active_modify(
1926 struct nb_cb_modify_args
*args
)
1928 struct interface
*ifp
;
1929 struct pim_interface
*pim_ifp
;
1931 switch (args
->event
) {
1932 case NB_EV_VALIDATE
:
1937 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1938 pim_ifp
= ifp
->info
;
1939 if (yang_dnode_get_bool(args
->dnode
, NULL
)) {
1942 "Configuring PIM active-active on Interface: %s",
1944 pim_if_configure_mlag_dualactive(pim_ifp
);
1948 "UnConfiguring PIM active-active on Interface: %s",
1950 pim_if_unconfigure_mlag_dualactive(pim_ifp
);
1961 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/dr-priority
1963 int lib_interface_pim_address_family_dr_priority_modify(
1964 struct nb_cb_modify_args
*args
)
1966 struct interface
*ifp
;
1967 struct pim_interface
*pim_ifp
;
1968 uint32_t old_dr_prio
;
1969 const struct lyd_node
*if_dnode
;
1971 switch (args
->event
) {
1972 case NB_EV_VALIDATE
:
1973 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
1974 if (!is_pim_interface(if_dnode
)) {
1975 snprintf(args
->errmsg
, args
->errmsg_len
,
1976 "Pim not enabled on this interface");
1977 return NB_ERR_VALIDATION
;
1984 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1985 pim_ifp
= ifp
->info
;
1986 old_dr_prio
= pim_ifp
->pim_dr_priority
;
1987 pim_ifp
->pim_dr_priority
= yang_dnode_get_uint32(args
->dnode
,
1990 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
1991 pim_if_dr_election(ifp
);
1992 pim_hello_restart_now(ifp
);
2001 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/use-source
2003 int lib_interface_pim_address_family_use_source_modify(
2004 struct nb_cb_modify_args
*args
)
2006 struct interface
*ifp
;
2007 pim_addr source_addr
;
2009 const struct lyd_node
*if_dnode
;
2011 switch (args
->event
) {
2012 case NB_EV_VALIDATE
:
2013 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2014 if (!is_pim_interface(if_dnode
)) {
2015 snprintf(args
->errmsg
, args
->errmsg_len
,
2016 "Pim not enabled on this interface");
2017 return NB_ERR_VALIDATION
;
2024 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2026 yang_dnode_get_ipv4(&source_addr
, args
->dnode
, NULL
);
2028 yang_dnode_get_ipv6(&source_addr
, args
->dnode
, NULL
);
2031 result
= interface_pim_use_src_cmd_worker(
2033 args
->errmsg
, args
->errmsg_len
);
2035 if (result
!= PIM_SUCCESS
)
2036 return NB_ERR_INCONSISTENCY
;
2044 int lib_interface_pim_address_family_use_source_destroy(
2045 struct nb_cb_destroy_args
*args
)
2047 struct interface
*ifp
;
2049 const struct lyd_node
*if_dnode
;
2051 switch (args
->event
) {
2052 case NB_EV_VALIDATE
:
2053 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2054 if (!is_pim_interface(if_dnode
)) {
2055 snprintf(args
->errmsg
, args
->errmsg_len
,
2056 "Pim not enabled on this interface");
2057 return NB_ERR_VALIDATION
;
2064 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2066 result
= interface_pim_use_src_cmd_worker(ifp
, PIMADDR_ANY
,
2070 if (result
!= PIM_SUCCESS
)
2071 return NB_ERR_INCONSISTENCY
;
2080 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/multicast-boundary-oil
2082 int lib_interface_pim_address_family_multicast_boundary_oil_modify(
2083 struct nb_cb_modify_args
*args
)
2085 struct interface
*ifp
;
2086 struct pim_interface
*pim_ifp
;
2088 const struct lyd_node
*if_dnode
;
2090 switch (args
->event
) {
2091 case NB_EV_VALIDATE
:
2092 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2093 if (!is_pim_interface(if_dnode
)) {
2094 snprintf(args
->errmsg
, args
->errmsg_len
,
2095 "Pim not enabled on this interface");
2096 return NB_ERR_VALIDATION
;
2103 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2104 pim_ifp
= ifp
->info
;
2105 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
2107 if (pim_ifp
->boundary_oil_plist
)
2108 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
2110 pim_ifp
->boundary_oil_plist
=
2111 XSTRDUP(MTYPE_PIM_INTERFACE
, plist
);
2119 int lib_interface_pim_address_family_multicast_boundary_oil_destroy(
2120 struct nb_cb_destroy_args
*args
)
2122 struct interface
*ifp
;
2123 struct pim_interface
*pim_ifp
;
2124 const struct lyd_node
*if_dnode
;
2126 switch (args
->event
) {
2127 case NB_EV_VALIDATE
:
2128 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2129 if (!is_pim_interface(if_dnode
)) {
2130 snprintf(args
->errmsg
, args
->errmsg_len
,
2131 "%% Enable PIM and/or IGMP on this interface first");
2132 return NB_ERR_VALIDATION
;
2139 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2140 pim_ifp
= ifp
->info
;
2141 if (pim_ifp
->boundary_oil_plist
)
2142 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
2150 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/mroute
2152 int lib_interface_pim_address_family_mroute_create(
2153 struct nb_cb_create_args
*args
)
2155 switch (args
->event
) {
2156 case NB_EV_VALIDATE
:
2166 int lib_interface_pim_address_family_mroute_destroy(
2167 struct nb_cb_destroy_args
*args
)
2169 struct pim_instance
*pim
;
2170 struct pim_interface
*pim_iifp
;
2171 struct interface
*iif
;
2172 struct interface
*oif
;
2173 const char *oifname
;
2174 pim_addr source_addr
;
2175 pim_addr group_addr
;
2176 const struct lyd_node
*if_dnode
;
2178 switch (args
->event
) {
2179 case NB_EV_VALIDATE
:
2180 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2181 if (!is_pim_interface(if_dnode
)) {
2182 snprintf(args
->errmsg
, args
->errmsg_len
,
2183 "%% Enable PIM and/or IGMP on this interface first");
2184 return NB_ERR_VALIDATION
;
2191 iif
= nb_running_get_entry(args
->dnode
, NULL
, true);
2192 pim_iifp
= iif
->info
;
2193 pim
= pim_iifp
->pim
;
2195 oifname
= yang_dnode_get_string(args
->dnode
, "./oif");
2196 oif
= if_lookup_by_name(oifname
, pim
->vrf
->vrf_id
);
2199 snprintf(args
->errmsg
, args
->errmsg_len
,
2200 "No such interface name %s",
2202 return NB_ERR_INCONSISTENCY
;
2205 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
, "./source-addr");
2206 yang_dnode_get_pimaddr(&group_addr
, args
->dnode
, "./group-addr");
2208 if (pim_static_del(pim
, iif
, oif
, group_addr
, source_addr
)) {
2209 snprintf(args
->errmsg
, args
->errmsg_len
,
2210 "Failed to remove static mroute");
2211 return NB_ERR_INCONSISTENCY
;
2221 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/mroute/oif
2223 int lib_interface_pim_address_family_mroute_oif_modify(
2224 struct nb_cb_modify_args
*args
)
2226 struct pim_instance
*pim
;
2227 struct pim_interface
*pim_iifp
;
2228 struct interface
*iif
;
2229 struct interface
*oif
;
2230 const char *oifname
;
2231 pim_addr source_addr
;
2232 pim_addr group_addr
;
2233 const struct lyd_node
*if_dnode
;
2235 switch (args
->event
) {
2236 case NB_EV_VALIDATE
:
2237 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2238 if (!is_pim_interface(if_dnode
)) {
2239 snprintf(args
->errmsg
, args
->errmsg_len
,
2240 "%% Enable PIM and/or IGMP on this interface first");
2241 return NB_ERR_VALIDATION
;
2244 #ifdef PIM_ENFORCE_LOOPFREE_MFC
2245 iif
= nb_running_get_entry(args
->dnode
, NULL
, false);
2250 pim_iifp
= iif
->info
;
2251 pim
= pim_iifp
->pim
;
2253 oifname
= yang_dnode_get_string(args
->dnode
, NULL
);
2254 oif
= if_lookup_by_name(oifname
, pim
->vrf
->vrf_id
);
2256 if (oif
&& (iif
->ifindex
== oif
->ifindex
)) {
2257 strlcpy(args
->errmsg
,
2258 "% IIF same as OIF and loopfree enforcement is enabled; rejecting",
2260 return NB_ERR_VALIDATION
;
2268 iif
= nb_running_get_entry(args
->dnode
, NULL
, true);
2269 pim_iifp
= iif
->info
;
2270 pim
= pim_iifp
->pim
;
2272 oifname
= yang_dnode_get_string(args
->dnode
, NULL
);
2273 oif
= if_lookup_by_name(oifname
, pim
->vrf
->vrf_id
);
2275 snprintf(args
->errmsg
, args
->errmsg_len
,
2276 "No such interface name %s",
2278 return NB_ERR_INCONSISTENCY
;
2281 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
, "../source-addr");
2282 yang_dnode_get_pimaddr(&group_addr
, args
->dnode
, "../group-addr");
2284 if (pim_static_add(pim
, iif
, oif
, group_addr
, source_addr
)) {
2285 snprintf(args
->errmsg
, args
->errmsg_len
,
2286 "Failed to add static mroute");
2287 return NB_ERR_INCONSISTENCY
;
2296 int lib_interface_pim_address_family_mroute_oif_destroy(
2297 struct nb_cb_destroy_args
*args
)
2299 switch (args
->event
) {
2300 case NB_EV_VALIDATE
:
2311 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/static-rp/rp-list
2313 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_create(
2314 struct nb_cb_create_args
*args
)
2316 switch (args
->event
) {
2317 case NB_EV_VALIDATE
:
2327 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_destroy(
2328 struct nb_cb_destroy_args
*args
)
2331 struct pim_instance
*pim
;
2332 struct prefix group
;
2337 switch (args
->event
) {
2338 case NB_EV_VALIDATE
:
2343 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2345 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "./rp-address");
2347 if (yang_dnode_get(args
->dnode
, "./group-list")) {
2348 yang_dnode_get_prefix(&group
, args
->dnode
,
2351 result
= pim_no_rp_cmd_worker(pim
, rp_addr
, group
, NULL
,
2356 else if (yang_dnode_get(args
->dnode
, "./prefix-list")) {
2357 plist
= yang_dnode_get_string(args
->dnode
,
2359 if (!pim_get_all_mcast_group(&group
)) {
2362 "Unable to convert 224.0.0.0/4 to prefix");
2363 return NB_ERR_INCONSISTENCY
;
2366 result
= pim_no_rp_cmd_worker(pim
, rp_addr
, group
,
2367 plist
, args
->errmsg
,
2372 return NB_ERR_INCONSISTENCY
;
2380 * 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
2382 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_group_list_create(
2383 struct nb_cb_create_args
*args
)
2386 struct pim_instance
*pim
;
2387 struct prefix group
;
2390 switch (args
->event
) {
2391 case NB_EV_VALIDATE
:
2396 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2398 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "../rp-address");
2399 yang_dnode_get_prefix(&group
, args
->dnode
, NULL
);
2401 return pim_rp_cmd_worker(pim
, rp_addr
, group
, NULL
,
2402 args
->errmsg
, args
->errmsg_len
);
2408 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_group_list_destroy(
2409 struct nb_cb_destroy_args
*args
)
2412 struct pim_instance
*pim
;
2413 struct prefix group
;
2416 switch (args
->event
) {
2417 case NB_EV_VALIDATE
:
2422 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2424 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "../rp-address");
2425 yang_dnode_get_prefix(&group
, args
->dnode
, NULL
);
2428 return pim_no_rp_cmd_worker(pim
, rp_addr
, group
, NULL
,
2429 args
->errmsg
, args
->errmsg_len
);
2436 * 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
2438 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_prefix_list_modify(
2439 struct nb_cb_modify_args
*args
)
2442 struct pim_instance
*pim
;
2443 struct prefix group
;
2447 switch (args
->event
) {
2448 case NB_EV_VALIDATE
:
2453 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2455 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
2456 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "../rp-address");
2457 if (!pim_get_all_mcast_group(&group
)) {
2458 flog_err(EC_LIB_DEVELOPMENT
,
2459 "Unable to convert 224.0.0.0/4 to prefix");
2460 return NB_ERR_INCONSISTENCY
;
2462 return pim_rp_cmd_worker(pim
, rp_addr
, group
, plist
,
2463 args
->errmsg
, args
->errmsg_len
);
2469 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_prefix_list_destroy(
2470 struct nb_cb_destroy_args
*args
)
2473 struct pim_instance
*pim
;
2474 struct prefix group
;
2478 switch (args
->event
) {
2479 case NB_EV_VALIDATE
:
2484 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2486 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "../rp-address");
2487 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
2488 if (!pim_get_all_mcast_group(&group
)) {
2489 flog_err(EC_LIB_DEVELOPMENT
,
2490 "Unable to convert 224.0.0.0/4 to prefix");
2491 return NB_ERR_INCONSISTENCY
;
2493 return pim_no_rp_cmd_worker(pim
, rp_addr
, group
, plist
,
2494 args
->errmsg
, args
->errmsg_len
);
2502 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family
2504 int lib_interface_gmp_address_family_create(struct nb_cb_create_args
*args
)
2506 switch (args
->event
) {
2507 case NB_EV_VALIDATE
:
2517 int lib_interface_gmp_address_family_destroy(struct nb_cb_destroy_args
*args
)
2519 struct interface
*ifp
;
2520 struct pim_interface
*pim_ifp
;
2522 switch (args
->event
) {
2523 case NB_EV_VALIDATE
:
2528 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2529 pim_ifp
= ifp
->info
;
2534 PIM_IF_DONT_IGMP(pim_ifp
->options
);
2536 pim_if_membership_clear(ifp
);
2538 pim_if_addr_del_all_igmp(ifp
);
2540 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
2548 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/enable
2550 int lib_interface_gmp_address_family_enable_modify(
2551 struct nb_cb_modify_args
*args
)
2553 struct interface
*ifp
;
2555 struct pim_interface
*pim_ifp
;
2557 const char *ifp_name
;
2558 const struct lyd_node
*if_dnode
;
2560 switch (args
->event
) {
2561 case NB_EV_VALIDATE
:
2562 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2564 yang_get_list_elements_count(if_dnode
);
2565 /* Limiting mcast interfaces to number of VIFs */
2566 if (mcast_if_count
== MAXVIFS
) {
2567 ifp_name
= yang_dnode_get_string(if_dnode
, "name");
2568 snprintf(args
->errmsg
, args
->errmsg_len
,
2569 "Max multicast interfaces(%d) Reached. Could not enable IGMP on interface %s",
2571 return NB_ERR_VALIDATION
;
2578 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2579 igmp_enable
= yang_dnode_get_bool(args
->dnode
, NULL
);
2582 return pim_cmd_igmp_start(ifp
);
2585 pim_ifp
= ifp
->info
;
2588 return NB_ERR_INCONSISTENCY
;
2590 PIM_IF_DONT_IGMP(pim_ifp
->options
);
2592 pim_if_membership_clear(ifp
);
2594 pim_if_addr_del_all_igmp(ifp
);
2596 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
2605 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/igmp-version
2607 int lib_interface_gmp_address_family_igmp_version_modify(
2608 struct nb_cb_modify_args
*args
)
2610 struct interface
*ifp
;
2611 struct pim_interface
*pim_ifp
;
2612 int igmp_version
, old_version
= 0;
2614 switch (args
->event
) {
2615 case NB_EV_VALIDATE
:
2620 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2621 pim_ifp
= ifp
->info
;
2624 return NB_ERR_INCONSISTENCY
;
2626 igmp_version
= yang_dnode_get_uint8(args
->dnode
, NULL
);
2627 old_version
= pim_ifp
->igmp_version
;
2628 pim_ifp
->igmp_version
= igmp_version
;
2630 /* Current and new version is different refresh existing
2631 * membership. Going from 3 -> 2 or 2 -> 3.
2633 if (old_version
!= igmp_version
)
2634 pim_if_membership_refresh(ifp
);
2642 int lib_interface_gmp_address_family_igmp_version_destroy(
2643 struct nb_cb_destroy_args
*args
)
2645 struct interface
*ifp
;
2646 struct pim_interface
*pim_ifp
;
2648 switch (args
->event
) {
2649 case NB_EV_VALIDATE
:
2654 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2655 pim_ifp
= ifp
->info
;
2656 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
2664 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/mld-version
2666 int lib_interface_gmp_address_family_mld_version_modify(
2667 struct nb_cb_modify_args
*args
)
2669 switch (args
->event
) {
2670 case NB_EV_VALIDATE
:
2680 int lib_interface_gmp_address_family_mld_version_destroy(
2681 struct nb_cb_destroy_args
*args
)
2683 switch (args
->event
) {
2684 case NB_EV_VALIDATE
:
2695 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/query-interval
2697 int lib_interface_gmp_address_family_query_interval_modify(
2698 struct nb_cb_modify_args
*args
)
2700 struct interface
*ifp
;
2703 switch (args
->event
) {
2704 case NB_EV_VALIDATE
:
2709 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2710 query_interval
= yang_dnode_get_uint16(args
->dnode
, NULL
);
2711 change_query_interval(ifp
->info
, query_interval
);
2718 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/query-max-response-time
2720 int lib_interface_gmp_address_family_query_max_response_time_modify(
2721 struct nb_cb_modify_args
*args
)
2723 struct interface
*ifp
;
2724 int query_max_response_time_dsec
;
2726 switch (args
->event
) {
2727 case NB_EV_VALIDATE
:
2732 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2733 query_max_response_time_dsec
=
2734 yang_dnode_get_uint16(args
->dnode
, NULL
);
2735 change_query_max_response_time(ifp
->info
,
2736 query_max_response_time_dsec
);
2743 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/last-member-query-interval
2745 int lib_interface_gmp_address_family_last_member_query_interval_modify(
2746 struct nb_cb_modify_args
*args
)
2748 struct interface
*ifp
;
2749 struct pim_interface
*pim_ifp
;
2750 int last_member_query_interval
;
2752 switch (args
->event
) {
2753 case NB_EV_VALIDATE
:
2758 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2759 pim_ifp
= ifp
->info
;
2760 last_member_query_interval
=
2761 yang_dnode_get_uint16(args
->dnode
, NULL
);
2762 pim_ifp
->gm_specific_query_max_response_time_dsec
=
2763 last_member_query_interval
;
2772 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/robustness-variable
2774 int lib_interface_gmp_address_family_robustness_variable_modify(
2775 struct nb_cb_modify_args
*args
)
2777 struct interface
*ifp
;
2778 struct pim_interface
*pim_ifp
;
2779 int last_member_query_count
;
2781 switch (args
->event
) {
2782 case NB_EV_VALIDATE
:
2787 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2788 pim_ifp
= ifp
->info
;
2789 last_member_query_count
=
2790 yang_dnode_get_uint8(args
->dnode
, NULL
);
2791 pim_ifp
->gm_last_member_query_count
= last_member_query_count
;
2800 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/static-group
2802 int lib_interface_gmp_address_family_static_group_create(
2803 struct nb_cb_create_args
*args
)
2805 struct interface
*ifp
;
2806 struct ipaddr source_addr
;
2807 struct ipaddr group_addr
;
2809 const char *ifp_name
;
2810 const struct lyd_node
*if_dnode
;
2812 switch (args
->event
) {
2813 case NB_EV_VALIDATE
:
2814 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2815 if (!is_pim_interface(if_dnode
)) {
2816 ifp_name
= yang_dnode_get_string(if_dnode
, "name");
2817 snprintf(args
->errmsg
, args
->errmsg_len
,
2818 "multicast not enabled on interface %s",
2820 return NB_ERR_VALIDATION
;
2823 yang_dnode_get_ip(&group_addr
, args
->dnode
, "./group-addr");
2824 if (pim_is_group_224_0_0_0_24(group_addr
.ip
._v4_addr
)) {
2826 args
->errmsg
, args
->errmsg_len
,
2827 "Groups within 224.0.0.0/24 are reserved and cannot be joined");
2828 return NB_ERR_VALIDATION
;
2835 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2836 yang_dnode_get_ip(&source_addr
, args
->dnode
, "./source-addr");
2837 yang_dnode_get_ip(&group_addr
, args
->dnode
, "./group-addr");
2839 result
= pim_if_igmp_join_add(ifp
, group_addr
.ip
._v4_addr
,
2840 source_addr
.ip
._v4_addr
);
2842 snprintf(args
->errmsg
, args
->errmsg_len
,
2843 "Failure joining IGMP group");
2844 return NB_ERR_INCONSISTENCY
;
2851 int lib_interface_gmp_address_family_static_group_destroy(
2852 struct nb_cb_destroy_args
*args
)
2854 struct interface
*ifp
;
2855 struct ipaddr source_addr
;
2856 struct ipaddr group_addr
;
2859 switch (args
->event
) {
2860 case NB_EV_VALIDATE
:
2865 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2866 yang_dnode_get_ip(&source_addr
, args
->dnode
, "./source-addr");
2867 yang_dnode_get_ip(&group_addr
, args
->dnode
, "./group-addr");
2869 result
= pim_if_igmp_join_del(ifp
, group_addr
.ip
._v4_addr
,
2870 source_addr
.ip
._v4_addr
);
2873 char src_str
[INET_ADDRSTRLEN
];
2874 char grp_str
[INET_ADDRSTRLEN
];
2876 ipaddr2str(&source_addr
, src_str
, sizeof(src_str
));
2877 ipaddr2str(&group_addr
, grp_str
, sizeof(grp_str
));
2879 snprintf(args
->errmsg
, args
->errmsg_len
,
2880 "%% Failure leaving IGMP group %s %s on interface %s: %d",
2881 src_str
, grp_str
, ifp
->name
, result
);
2883 return NB_ERR_INCONSISTENCY
;