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"
41 #define pim6_msdp_err(funcname, argtype) \
42 int funcname(struct argtype *args) \
44 snprintf(args->errmsg, args->errmsg_len, \
45 "Trying to configure MSDP in pim6d. " \
46 "MSDP does not exist for IPv6."); \
47 return NB_ERR_VALIDATION; \
49 MACRO_REQUIRE_SEMICOLON()
51 #define yang_dnode_get_pimaddr yang_dnode_get_ipv6
53 #else /* PIM_IPV != 6 */
54 #define pim6_msdp_err(funcname, argtype) \
55 MACRO_REQUIRE_SEMICOLON()
57 #define yang_dnode_get_pimaddr yang_dnode_get_ipv4
58 #endif /* PIM_IPV != 6 */
60 static void pim_if_membership_clear(struct interface
*ifp
)
62 struct pim_interface
*pim_ifp
;
67 if (pim_ifp
->pim_enable
&& pim_ifp
->gm_enable
) {
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_ifp
->pim_enable
)
95 if (!pim_ifp
->gm_enable
)
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_ifp
->pim_enable
= true;
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_ifp
->pim_enable
= false;
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_ifp
->gm_enable
) {
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
, "."))))
352 static int pim_cmd_igmp_start(struct interface
*ifp
)
354 struct pim_interface
*pim_ifp
;
355 uint8_t need_startup
= 0;
360 pim_ifp
= pim_if_new(ifp
, true, false, false, false);
363 if (!pim_ifp
->gm_enable
) {
364 pim_ifp
->gm_enable
= true;
368 pim_if_create_pimreg(pim_ifp
->pim
);
370 /* 'ip igmp' executed multiple times, with need_startup
371 * avoid multiple if add all and membership refresh
374 pim_if_addr_add_all(ifp
);
375 pim_if_membership_refresh(ifp
);
380 #endif /* PIM_IPV == 4 */
383 * CLI reconfiguration affects the interface level (struct pim_interface).
384 * This function propagates the reconfiguration to every active socket
385 * for that interface.
388 static void igmp_sock_query_interval_reconfig(struct gm_sock
*igmp
)
390 struct interface
*ifp
;
391 struct pim_interface
*pim_ifp
;
394 assert(igmp
->interface
);
395 assert(igmp
->interface
->info
);
397 ifp
= igmp
->interface
;
400 if (PIM_DEBUG_IGMP_TRACE
)
401 zlog_debug("%s: Querier %pPAs on %s reconfig query_interval=%d",
402 __func__
, &igmp
->ifaddr
, ifp
->name
,
403 pim_ifp
->gm_default_query_interval
);
406 * igmp_startup_mode_on() will reset QQI:
408 * igmp->querier_query_interval = pim_ifp->gm_default_query_interval;
410 igmp_startup_mode_on(igmp
);
413 static void igmp_sock_query_reschedule(struct gm_sock
*igmp
)
415 if (igmp
->mtrace_only
)
418 if (igmp
->t_igmp_query_timer
) {
419 /* other querier present */
420 assert(igmp
->t_igmp_query_timer
);
421 assert(!igmp
->t_other_querier_timer
);
423 pim_igmp_general_query_off(igmp
);
424 pim_igmp_general_query_on(igmp
);
426 assert(igmp
->t_igmp_query_timer
);
427 assert(!igmp
->t_other_querier_timer
);
429 /* this is the querier */
431 assert(!igmp
->t_igmp_query_timer
);
432 assert(igmp
->t_other_querier_timer
);
434 pim_igmp_other_querier_timer_off(igmp
);
435 pim_igmp_other_querier_timer_on(igmp
);
437 assert(!igmp
->t_igmp_query_timer
);
438 assert(igmp
->t_other_querier_timer
);
441 #endif /* PIM_IPV == 4 */
444 static void change_query_interval(struct pim_interface
*pim_ifp
,
447 struct listnode
*sock_node
;
448 struct gm_sock
*igmp
;
450 pim_ifp
->gm_default_query_interval
= query_interval
;
452 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->gm_socket_list
, sock_node
, igmp
)) {
453 igmp_sock_query_interval_reconfig(igmp
);
454 igmp_sock_query_reschedule(igmp
);
460 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
461 int query_max_response_time_dsec
)
463 struct listnode
*sock_node
;
464 struct gm_sock
*igmp
;
465 struct listnode
*grp_node
;
466 struct gm_group
*grp
;
468 if (pim_ifp
->gm_query_max_response_time_dsec
==
469 query_max_response_time_dsec
)
472 pim_ifp
->gm_query_max_response_time_dsec
= query_max_response_time_dsec
;
475 * Below we modify socket/group/source timers in order to quickly
476 * reflect the change. Otherwise, those timers would args->eventually
480 /* scan all sockets */
481 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->gm_socket_list
, sock_node
, igmp
)) {
482 /* reschedule socket general query */
483 igmp_sock_query_reschedule(igmp
);
486 /* scan socket groups */
487 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->gm_group_list
, grp_node
, grp
)) {
488 struct listnode
*src_node
;
489 struct gm_source
*src
;
491 /* reset group timers for groups in EXCLUDE mode */
492 if (grp
->group_filtermode_isexcl
)
493 igmp_group_reset_gmi(grp
);
495 /* scan group sources */
496 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, src_node
,
499 /* reset source timers for sources with running
502 if (src
->t_source_timer
)
503 igmp_source_reset_gmi(grp
, src
);
509 int routing_control_plane_protocols_name_validate(
510 struct nb_cb_create_args
*args
)
514 name
= yang_dnode_get_string(args
->dnode
, "./name");
515 if (!strmatch(name
, "pim")) {
516 snprintf(args
->errmsg
, args
->errmsg_len
,
517 "pim supports only one instance with name pimd");
518 return NB_ERR_VALIDATION
;
524 * XPath: /frr-pim:pim/address-family
526 int pim_address_family_create(struct nb_cb_create_args
*args
)
528 switch (args
->event
) {
539 int pim_address_family_destroy(struct nb_cb_destroy_args
*args
)
541 switch (args
->event
) {
553 * XPath: /frr-pim:pim/address-family/packets
555 int pim_address_family_packets_modify(struct nb_cb_modify_args
*args
)
557 switch (args
->event
) {
563 router
->packet_process
= yang_dnode_get_uint8(args
->dnode
,
572 * XPath: /frr-pim:pim/address-family/join-prune-interval
574 int pim_address_family_join_prune_interval_modify(
575 struct nb_cb_modify_args
*args
)
577 switch (args
->event
) {
583 router
->t_periodic
= yang_dnode_get_uint16(args
->dnode
, NULL
);
591 * XPath: /frr-pim:pim/address-family/register-suppress-time
593 int pim_address_family_register_suppress_time_modify(
594 struct nb_cb_modify_args
*args
)
597 switch (args
->event
) {
599 value
= yang_dnode_get_uint16(args
->dnode
, NULL
);
601 * As soon as this is non-constant it needs to be replaced with
602 * a yang_dnode_get to lookup the candidate value, *not* the
603 * operational value. Since the code has a field assigned and
604 * used for this value it should have YANG/CLI to set it too,
605 * otherwise just use the #define!
607 /* RFC7761: 4.11. Timer Values */
608 if (value
<= router
->register_probe_time
* 2) {
610 args
->errmsg
, args
->errmsg_len
,
611 "Register suppress time (%u) must be more than "
612 "twice the register probe time (%u).",
613 value
, router
->register_probe_time
);
614 return NB_ERR_VALIDATION
;
621 pim_update_suppress_timers(
622 yang_dnode_get_uint16(args
->dnode
, NULL
));
630 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/ecmp
632 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ecmp_modify(
633 struct nb_cb_modify_args
*args
)
636 struct pim_instance
*pim
;
638 switch (args
->event
) {
644 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
646 pim
->ecmp_enable
= yang_dnode_get_bool(args
->dnode
, NULL
);
653 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/ecmp-rebalance
655 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ecmp_rebalance_modify(
656 struct nb_cb_modify_args
*args
)
659 struct pim_instance
*pim
;
661 switch (args
->event
) {
667 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
669 pim
->ecmp_rebalance_enable
=
670 yang_dnode_get_bool(args
->dnode
, NULL
);
677 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/keep-alive-timer
679 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_keep_alive_timer_modify(
680 struct nb_cb_modify_args
*args
)
683 struct pim_instance
*pim
;
685 switch (args
->event
) {
691 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
693 pim
->keep_alive_time
= yang_dnode_get_uint16(args
->dnode
, NULL
);
701 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/rp-keep-alive-timer
703 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_keep_alive_timer_modify(
704 struct nb_cb_modify_args
*args
)
707 struct pim_instance
*pim
;
709 switch (args
->event
) {
715 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
717 pim
->rp_keep_alive_time
= yang_dnode_get_uint16(args
->dnode
,
726 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family
728 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_create(
729 struct nb_cb_create_args
*args
)
731 switch (args
->event
) {
742 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_destroy(
743 struct nb_cb_destroy_args
*args
)
745 switch (args
->event
) {
757 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/send-v6-secondary
759 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_send_v6_secondary_modify(
760 struct nb_cb_modify_args
*args
)
763 struct pim_instance
*pim
;
765 switch (args
->event
) {
771 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
773 pim
->send_v6_secondary
= yang_dnode_get_bool(args
->dnode
, NULL
);
780 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_send_v6_secondary_destroy(
781 struct nb_cb_destroy_args
*args
)
783 switch (args
->event
) {
796 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/spt-switchover
798 void routing_control_plane_protocols_control_plane_protocol_pim_address_family_spt_switchover_apply_finish(
799 struct nb_cb_apply_finish_args
*args
)
802 struct pim_instance
*pim
;
803 int spt_switch_action
;
804 const char *prefix_list
= NULL
;
806 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
808 spt_switch_action
= yang_dnode_get_enum(args
->dnode
, "./spt-action");
810 switch (spt_switch_action
) {
811 case PIM_SPT_INFINITY
:
812 if (yang_dnode_exists(args
->dnode
,
813 "./spt-infinity-prefix-list"))
814 prefix_list
= yang_dnode_get_string(
815 args
->dnode
, "./spt-infinity-prefix-list");
817 pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
,
820 case PIM_SPT_IMMEDIATE
:
821 pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
826 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/spt-switchover/spt-action
828 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_spt_switchover_spt_action_modify(
829 struct nb_cb_modify_args
*args
)
831 switch (args
->event
) {
843 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/spt-switchover/spt-infinity-prefix-list
845 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_spt_switchover_spt_infinity_prefix_list_modify(
846 struct nb_cb_modify_args
*args
)
848 switch (args
->event
) {
859 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_spt_switchover_spt_infinity_prefix_list_destroy(
860 struct nb_cb_destroy_args
*args
)
862 switch (args
->event
) {
874 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/ssm-prefix-list
876 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_prefix_list_modify(
877 struct nb_cb_modify_args
*args
)
880 struct pim_instance
*pim
;
881 const char *plist_name
;
884 switch (args
->event
) {
890 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
892 plist_name
= yang_dnode_get_string(args
->dnode
, NULL
);
893 result
= pim_ssm_cmd_worker(pim
, plist_name
, args
->errmsg
,
897 return NB_ERR_INCONSISTENCY
;
905 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_prefix_list_destroy(
906 struct nb_cb_destroy_args
*args
)
909 struct pim_instance
*pim
;
912 switch (args
->event
) {
918 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
920 result
= pim_ssm_cmd_worker(pim
, NULL
, args
->errmsg
,
924 return NB_ERR_INCONSISTENCY
;
933 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/ssm-pingd-source-ip
935 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_pingd_source_ip_create(
936 struct nb_cb_create_args
*args
)
939 struct pim_instance
*pim
;
941 pim_addr source_addr
;
943 switch (args
->event
) {
949 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
951 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
,
953 result
= pim_ssmpingd_start(pim
, source_addr
);
956 args
->errmsg
, args
->errmsg_len
,
957 "%% Failure starting ssmpingd for source %pPA: %d",
958 &source_addr
, result
);
959 return NB_ERR_INCONSISTENCY
;
966 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_pingd_source_ip_destroy(
967 struct nb_cb_destroy_args
*args
)
970 struct pim_instance
*pim
;
972 pim_addr source_addr
;
974 switch (args
->event
) {
980 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
982 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
,
984 result
= pim_ssmpingd_stop(pim
, source_addr
);
987 args
->errmsg
, args
->errmsg_len
,
988 "%% Failure stopping ssmpingd for source %pPA: %d",
989 &source_addr
, result
);
990 return NB_ERR_INCONSISTENCY
;
1001 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/hold-time
1003 int pim_msdp_hold_time_modify(struct nb_cb_modify_args
*args
)
1005 struct pim_instance
*pim
;
1008 switch (args
->event
) {
1009 case NB_EV_VALIDATE
:
1014 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1016 pim
->msdp
.hold_time
= yang_dnode_get_uint16(args
->dnode
, NULL
);
1025 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/keep-alive
1027 int pim_msdp_keep_alive_modify(struct nb_cb_modify_args
*args
)
1029 struct pim_instance
*pim
;
1032 switch (args
->event
) {
1033 case NB_EV_VALIDATE
:
1038 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1040 pim
->msdp
.keep_alive
= yang_dnode_get_uint16(args
->dnode
, NULL
);
1049 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/connection-retry
1051 int pim_msdp_connection_retry_modify(struct nb_cb_modify_args
*args
)
1053 struct pim_instance
*pim
;
1056 switch (args
->event
) {
1057 case NB_EV_VALIDATE
:
1062 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1064 pim
->msdp
.connection_retry
=
1065 yang_dnode_get_uint16(args
->dnode
, NULL
);
1072 pim6_msdp_err(pim_msdp_mesh_group_destroy
, nb_cb_destroy_args
);
1073 pim6_msdp_err(pim_msdp_mesh_group_create
, nb_cb_create_args
);
1074 pim6_msdp_err(pim_msdp_mesh_group_source_modify
, nb_cb_modify_args
);
1075 pim6_msdp_err(pim_msdp_mesh_group_source_destroy
, nb_cb_destroy_args
);
1076 pim6_msdp_err(pim_msdp_mesh_group_members_create
, nb_cb_create_args
);
1077 pim6_msdp_err(pim_msdp_mesh_group_members_destroy
, nb_cb_destroy_args
);
1078 pim6_msdp_err(routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify
,
1080 pim6_msdp_err(routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_destroy
,
1081 nb_cb_destroy_args
);
1082 pim6_msdp_err(routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_create
,
1088 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups
1090 int pim_msdp_mesh_group_create(struct nb_cb_create_args
*args
)
1092 struct pim_msdp_mg
*mg
;
1095 switch (args
->event
) {
1096 case NB_EV_VALIDATE
:
1101 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1102 mg
= pim_msdp_mg_new(vrf
->info
, yang_dnode_get_string(
1103 args
->dnode
, "./name"));
1104 nb_running_set_entry(args
->dnode
, mg
);
1111 int pim_msdp_mesh_group_destroy(struct nb_cb_destroy_args
*args
)
1113 struct pim_msdp_mg
*mg
;
1116 switch (args
->event
) {
1117 case NB_EV_VALIDATE
:
1122 mg
= nb_running_unset_entry(args
->dnode
);
1123 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1124 pim_msdp_mg_free(vrf
->info
, &mg
);
1133 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups/source
1135 int pim_msdp_mesh_group_source_modify(struct nb_cb_modify_args
*args
)
1137 const struct lyd_node
*vrf_dnode
;
1138 struct pim_msdp_mg
*mg
;
1142 switch (args
->event
) {
1143 case NB_EV_VALIDATE
:
1148 mg
= nb_running_get_entry(args
->dnode
, NULL
, true);
1150 yang_dnode_get_parent(args
->dnode
, "address-family");
1151 vrf
= nb_running_get_entry(vrf_dnode
, "../../", true);
1152 yang_dnode_get_ip(&ip
, args
->dnode
, NULL
);
1154 pim_msdp_mg_src_add(vrf
->info
, mg
, &ip
.ip
._v4_addr
);
1160 int pim_msdp_mesh_group_source_destroy(struct nb_cb_destroy_args
*args
)
1162 const struct lyd_node
*vrf_dnode
;
1163 struct pim_msdp_mg
*mg
;
1165 struct in_addr addr
;
1167 switch (args
->event
) {
1168 case NB_EV_VALIDATE
:
1173 mg
= nb_running_get_entry(args
->dnode
, NULL
, true);
1175 yang_dnode_get_parent(args
->dnode
, "address-family");
1176 vrf
= nb_running_get_entry(vrf_dnode
, "../../", true);
1178 addr
.s_addr
= INADDR_ANY
;
1179 pim_msdp_mg_src_add(vrf
->info
, mg
, &addr
);
1188 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups/members
1190 int pim_msdp_mesh_group_members_create(struct nb_cb_create_args
*args
)
1192 const struct lyd_node
*vrf_dnode
;
1193 struct pim_msdp_mg_mbr
*mbr
;
1194 struct pim_msdp_mg
*mg
;
1198 switch (args
->event
) {
1199 case NB_EV_VALIDATE
:
1204 mg
= nb_running_get_entry(args
->dnode
, NULL
, true);
1206 yang_dnode_get_parent(args
->dnode
, "address-family");
1207 vrf
= nb_running_get_entry(vrf_dnode
, "../../", true);
1208 yang_dnode_get_ip(&ip
, args
->dnode
, "address");
1210 mbr
= pim_msdp_mg_mbr_add(vrf
->info
, mg
, &ip
.ip
._v4_addr
);
1211 nb_running_set_entry(args
->dnode
, mbr
);
1218 int pim_msdp_mesh_group_members_destroy(struct nb_cb_destroy_args
*args
)
1220 struct pim_msdp_mg_mbr
*mbr
;
1221 struct pim_msdp_mg
*mg
;
1222 const struct lyd_node
*mg_dnode
;
1224 switch (args
->event
) {
1225 case NB_EV_VALIDATE
:
1230 mbr
= nb_running_get_entry(args
->dnode
, NULL
, true);
1232 yang_dnode_get_parent(args
->dnode
, "msdp-mesh-groups");
1233 mg
= nb_running_get_entry(mg_dnode
, NULL
, true);
1234 pim_msdp_mg_mbr_del(mg
, mbr
);
1235 nb_running_unset_entry(args
->dnode
);
1243 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-peer
1245 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_create(
1246 struct nb_cb_create_args
*args
)
1248 struct pim_msdp_peer
*mp
;
1249 struct pim_instance
*pim
;
1251 struct ipaddr peer_ip
;
1252 struct ipaddr source_ip
;
1254 switch (args
->event
) {
1255 case NB_EV_VALIDATE
:
1260 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1262 yang_dnode_get_ip(&peer_ip
, args
->dnode
, "./peer-ip");
1263 yang_dnode_get_ip(&source_ip
, args
->dnode
, "./source-ip");
1264 mp
= pim_msdp_peer_add(pim
, &peer_ip
.ipaddr_v4
,
1265 &source_ip
.ipaddr_v4
, NULL
);
1266 nb_running_set_entry(args
->dnode
, mp
);
1273 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_destroy(
1274 struct nb_cb_destroy_args
*args
)
1276 struct pim_msdp_peer
*mp
;
1278 switch (args
->event
) {
1279 case NB_EV_VALIDATE
:
1284 mp
= nb_running_unset_entry(args
->dnode
);
1285 pim_msdp_peer_del(&mp
);
1293 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-peer/source-ip
1295 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify(
1296 struct nb_cb_modify_args
*args
)
1298 struct pim_msdp_peer
*mp
;
1299 struct ipaddr source_ip
;
1301 switch (args
->event
) {
1302 case NB_EV_VALIDATE
:
1307 mp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1308 yang_dnode_get_ip(&source_ip
, args
->dnode
, NULL
);
1309 pim_msdp_peer_change_source(mp
, &source_ip
.ipaddr_v4
);
1315 #endif /* PIM_IPV != 6 */
1318 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag
1320 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_create(
1321 struct nb_cb_create_args
*args
)
1323 switch (args
->event
) {
1324 case NB_EV_VALIDATE
:
1334 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_destroy(
1335 struct nb_cb_destroy_args
*args
)
1337 struct in_addr addr
;
1339 switch (args
->event
) {
1340 case NB_EV_VALIDATE
:
1346 pim_vxlan_mlag_update(true/*mlag_enable*/,
1347 false/*peer_state*/, MLAG_ROLE_NONE
,
1348 NULL
/*peerlink*/, &addr
);
1356 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag
1358 void routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_apply_finish(
1359 struct nb_cb_apply_finish_args
*args
)
1364 struct interface
*ifp
;
1365 struct ipaddr reg_addr
;
1367 ifname
= yang_dnode_get_string(args
->dnode
, "./peerlink-rif");
1368 ifp
= if_lookup_by_name(ifname
, VRF_DEFAULT
);
1370 snprintf(args
->errmsg
, args
->errmsg_len
,
1371 "No such interface name %s", ifname
);
1374 role
= yang_dnode_get_enum(args
->dnode
, "./my-role");
1375 peer_state
= yang_dnode_get_bool(args
->dnode
, "./peer-state");
1376 yang_dnode_get_ip(®_addr
, args
->dnode
, "./reg-address");
1378 pim_vxlan_mlag_update(true, peer_state
, role
, ifp
,
1379 ®_addr
.ip
._v4_addr
);
1384 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/peerlink-rif
1386 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_peerlink_rif_modify(
1387 struct nb_cb_modify_args
*args
)
1389 switch (args
->event
) {
1390 case NB_EV_VALIDATE
:
1400 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_peerlink_rif_destroy(
1401 struct nb_cb_destroy_args
*args
)
1403 switch (args
->event
) {
1404 case NB_EV_VALIDATE
:
1415 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/reg-address
1417 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_reg_address_modify(
1418 struct nb_cb_modify_args
*args
)
1420 switch (args
->event
) {
1421 case NB_EV_VALIDATE
:
1431 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_reg_address_destroy(
1432 struct nb_cb_destroy_args
*args
)
1434 switch (args
->event
) {
1435 case NB_EV_VALIDATE
:
1446 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/my-role
1448 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_my_role_modify(
1449 struct nb_cb_modify_args
*args
)
1451 switch (args
->event
) {
1452 case NB_EV_VALIDATE
:
1463 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/peer-state
1465 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_peer_state_modify(
1466 struct nb_cb_modify_args
*args
)
1468 switch (args
->event
) {
1469 case NB_EV_VALIDATE
:
1480 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/register-accept-list
1482 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_register_accept_list_modify(
1483 struct nb_cb_modify_args
*args
)
1486 struct pim_instance
*pim
;
1489 switch (args
->event
) {
1490 case NB_EV_VALIDATE
:
1495 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1497 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
1499 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
1500 pim
->register_plist
= XSTRDUP(MTYPE_PIM_PLIST_NAME
, plist
);
1508 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_register_accept_list_destroy(
1509 struct nb_cb_destroy_args
*args
)
1512 struct pim_instance
*pim
;
1514 switch (args
->event
) {
1515 case NB_EV_VALIDATE
:
1520 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1523 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
1531 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family
1533 int lib_interface_pim_address_family_create(struct nb_cb_create_args
*args
)
1535 switch (args
->event
) {
1536 case NB_EV_VALIDATE
:
1546 int lib_interface_pim_address_family_destroy(struct nb_cb_destroy_args
*args
)
1548 struct interface
*ifp
;
1549 struct pim_interface
*pim_ifp
;
1551 switch (args
->event
) {
1552 case NB_EV_VALIDATE
:
1557 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1558 pim_ifp
= ifp
->info
;
1562 if (!pim_cmd_interface_delete(ifp
)) {
1563 snprintf(args
->errmsg
, args
->errmsg_len
,
1564 "Unable to delete interface information %s",
1566 return NB_ERR_INCONSISTENCY
;
1574 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/pim-enable
1576 int lib_interface_pim_address_family_pim_enable_modify(struct nb_cb_modify_args
*args
)
1578 struct interface
*ifp
;
1579 struct pim_interface
*pim_ifp
;
1581 const struct lyd_node
*if_dnode
;
1583 switch (args
->event
) {
1584 case NB_EV_VALIDATE
:
1585 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
1587 yang_get_list_elements_count(if_dnode
);
1589 /* Limiting mcast interfaces to number of VIFs */
1590 if (mcast_if_count
== MAXVIFS
) {
1591 snprintf(args
->errmsg
, args
->errmsg_len
,
1592 "Max multicast interfaces(%d) reached.",
1594 return NB_ERR_VALIDATION
;
1601 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1603 if (yang_dnode_get_bool(args
->dnode
, NULL
)) {
1604 if (!pim_cmd_interface_add(ifp
)) {
1605 snprintf(args
->errmsg
, args
->errmsg_len
,
1606 "Could not enable PIM SM on interface %s",
1608 return NB_ERR_INCONSISTENCY
;
1611 pim_ifp
= ifp
->info
;
1613 return NB_ERR_INCONSISTENCY
;
1615 if (!pim_cmd_interface_delete(ifp
)) {
1616 snprintf(args
->errmsg
, args
->errmsg_len
,
1617 "Unable to delete interface information");
1618 return NB_ERR_INCONSISTENCY
;
1629 * /frr-interface:lib/interface/frr-pim:pim/address-family/pim-passive-enable
1631 int lib_interface_pim_address_family_pim_passive_enable_modify(
1632 struct nb_cb_modify_args
*args
)
1634 struct interface
*ifp
;
1635 struct pim_interface
*pim_ifp
;
1637 switch (args
->event
) {
1638 case NB_EV_VALIDATE
:
1643 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1644 pim_ifp
= ifp
->info
;
1645 pim_ifp
->pim_passive_enable
=
1646 yang_dnode_get_bool(args
->dnode
, NULL
);
1654 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/hello-interval
1656 int lib_interface_pim_address_family_hello_interval_modify(
1657 struct nb_cb_modify_args
*args
)
1659 struct interface
*ifp
;
1660 struct pim_interface
*pim_ifp
;
1662 switch (args
->event
) {
1663 case NB_EV_VALIDATE
:
1668 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1669 pim_ifp
= ifp
->info
;
1670 pim_ifp
->pim_hello_period
=
1671 yang_dnode_get_uint8(args
->dnode
, NULL
);
1672 pim_ifp
->pim_default_holdtime
= -1;
1680 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/hello-holdtime
1682 int lib_interface_pim_address_family_hello_holdtime_modify(
1683 struct nb_cb_modify_args
*args
)
1685 struct interface
*ifp
;
1686 struct pim_interface
*pim_ifp
;
1688 switch (args
->event
) {
1689 case NB_EV_VALIDATE
:
1694 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1695 pim_ifp
= ifp
->info
;
1696 pim_ifp
->pim_default_holdtime
=
1697 yang_dnode_get_uint16(args
->dnode
, NULL
);
1705 int lib_interface_pim_address_family_hello_holdtime_destroy(
1706 struct nb_cb_destroy_args
*args
)
1708 struct interface
*ifp
;
1709 struct pim_interface
*pim_ifp
;
1711 switch (args
->event
) {
1712 case NB_EV_VALIDATE
:
1717 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1718 pim_ifp
= ifp
->info
;
1719 pim_ifp
->pim_default_holdtime
= -1;
1726 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd
1728 int lib_interface_pim_address_family_bfd_create(struct nb_cb_create_args
*args
)
1730 struct interface
*ifp
;
1731 struct pim_interface
*pim_ifp
;
1733 switch (args
->event
) {
1734 case NB_EV_VALIDATE
:
1740 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1741 pim_ifp
= ifp
->info
;
1742 pim_ifp
->bfd_config
.enabled
= true;
1749 int lib_interface_pim_address_family_bfd_destroy(
1750 struct nb_cb_destroy_args
*args
)
1752 struct interface
*ifp
;
1753 struct pim_interface
*pim_ifp
;
1754 const struct lyd_node
*if_dnode
;
1756 switch (args
->event
) {
1757 case NB_EV_VALIDATE
:
1758 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
1759 if (!is_pim_interface(if_dnode
)) {
1760 snprintf(args
->errmsg
, args
->errmsg_len
,
1761 "Pim not enabled on this interface");
1762 return NB_ERR_VALIDATION
;
1769 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1770 pim_ifp
= ifp
->info
;
1771 pim_ifp
->bfd_config
.enabled
= false;
1772 pim_bfd_reg_dereg_all_nbr(ifp
);
1780 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd
1782 void lib_interface_pim_address_family_bfd_apply_finish(
1783 struct nb_cb_apply_finish_args
*args
)
1785 struct interface
*ifp
;
1786 struct pim_interface
*pim_ifp
;
1788 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1789 pim_ifp
= ifp
->info
;
1792 zlog_debug("Pim not enabled on this interface");
1796 pim_ifp
->bfd_config
.detection_multiplier
=
1797 yang_dnode_get_uint8(args
->dnode
, "./detect_mult");
1798 pim_ifp
->bfd_config
.min_rx
=
1799 yang_dnode_get_uint16(args
->dnode
, "./min-rx-interval");
1800 pim_ifp
->bfd_config
.min_tx
=
1801 yang_dnode_get_uint16(args
->dnode
, "./min-tx-interval");
1803 pim_bfd_reg_dereg_all_nbr(ifp
);
1807 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/min-rx-interval
1809 int lib_interface_pim_address_family_bfd_min_rx_interval_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/min-tx-interval
1826 int lib_interface_pim_address_family_bfd_min_tx_interval_modify(
1827 struct nb_cb_modify_args
*args
)
1829 switch (args
->event
) {
1830 case NB_EV_VALIDATE
:
1841 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/detect_mult
1843 int lib_interface_pim_address_family_bfd_detect_mult_modify(
1844 struct nb_cb_modify_args
*args
)
1846 switch (args
->event
) {
1847 case NB_EV_VALIDATE
:
1858 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/profile
1860 int lib_interface_pim_address_family_bfd_profile_modify(
1861 struct nb_cb_modify_args
*args
)
1863 struct interface
*ifp
;
1864 struct pim_interface
*pim_ifp
;
1866 switch (args
->event
) {
1867 case NB_EV_VALIDATE
:
1873 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1874 pim_ifp
= ifp
->info
;
1875 XFREE(MTYPE_TMP
, pim_ifp
->bfd_config
.profile
);
1876 pim_ifp
->bfd_config
.profile
= XSTRDUP(
1877 MTYPE_TMP
, yang_dnode_get_string(args
->dnode
, NULL
));
1884 int lib_interface_pim_address_family_bfd_profile_destroy(
1885 struct nb_cb_destroy_args
*args
)
1887 struct interface
*ifp
;
1888 struct pim_interface
*pim_ifp
;
1890 switch (args
->event
) {
1891 case NB_EV_VALIDATE
:
1897 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1898 pim_ifp
= ifp
->info
;
1899 XFREE(MTYPE_TMP
, pim_ifp
->bfd_config
.profile
);
1907 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bsm
1909 int lib_interface_pim_address_family_bsm_modify(struct nb_cb_modify_args
*args
)
1911 struct interface
*ifp
;
1912 struct pim_interface
*pim_ifp
;
1914 switch (args
->event
) {
1915 case NB_EV_VALIDATE
:
1920 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1921 pim_ifp
= ifp
->info
;
1922 pim_ifp
->bsm_enable
= yang_dnode_get_bool(args
->dnode
, NULL
);
1931 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/unicast-bsm
1933 int lib_interface_pim_address_family_unicast_bsm_modify(
1934 struct nb_cb_modify_args
*args
)
1936 struct interface
*ifp
;
1937 struct pim_interface
*pim_ifp
;
1939 switch (args
->event
) {
1940 case NB_EV_VALIDATE
:
1945 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1946 pim_ifp
= ifp
->info
;
1947 pim_ifp
->ucast_bsm_accept
=
1948 yang_dnode_get_bool(args
->dnode
, NULL
);
1957 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/active-active
1959 int lib_interface_pim_address_family_active_active_modify(
1960 struct nb_cb_modify_args
*args
)
1962 struct interface
*ifp
;
1963 struct pim_interface
*pim_ifp
;
1965 switch (args
->event
) {
1966 case NB_EV_VALIDATE
:
1971 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1972 pim_ifp
= ifp
->info
;
1973 if (yang_dnode_get_bool(args
->dnode
, NULL
)) {
1976 "Configuring PIM active-active on Interface: %s",
1978 pim_if_configure_mlag_dualactive(pim_ifp
);
1982 "UnConfiguring PIM active-active on Interface: %s",
1984 pim_if_unconfigure_mlag_dualactive(pim_ifp
);
1995 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/dr-priority
1997 int lib_interface_pim_address_family_dr_priority_modify(
1998 struct nb_cb_modify_args
*args
)
2000 struct interface
*ifp
;
2001 struct pim_interface
*pim_ifp
;
2002 uint32_t old_dr_prio
;
2003 const struct lyd_node
*if_dnode
;
2005 switch (args
->event
) {
2006 case NB_EV_VALIDATE
:
2007 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2008 if (!is_pim_interface(if_dnode
)) {
2009 snprintf(args
->errmsg
, args
->errmsg_len
,
2010 "Pim not enabled on this interface");
2011 return NB_ERR_VALIDATION
;
2018 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2019 pim_ifp
= ifp
->info
;
2020 old_dr_prio
= pim_ifp
->pim_dr_priority
;
2021 pim_ifp
->pim_dr_priority
= yang_dnode_get_uint32(args
->dnode
,
2024 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
2025 pim_if_dr_election(ifp
);
2026 pim_hello_restart_now(ifp
);
2035 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/use-source
2037 int lib_interface_pim_address_family_use_source_modify(
2038 struct nb_cb_modify_args
*args
)
2040 struct interface
*ifp
;
2041 pim_addr source_addr
;
2043 const struct lyd_node
*if_dnode
;
2045 switch (args
->event
) {
2046 case NB_EV_VALIDATE
:
2047 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2048 if (!is_pim_interface(if_dnode
)) {
2049 snprintf(args
->errmsg
, args
->errmsg_len
,
2050 "Pim not enabled on this interface");
2051 return NB_ERR_VALIDATION
;
2058 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2060 yang_dnode_get_ipv4(&source_addr
, args
->dnode
, NULL
);
2062 yang_dnode_get_ipv6(&source_addr
, args
->dnode
, NULL
);
2065 result
= interface_pim_use_src_cmd_worker(
2067 args
->errmsg
, args
->errmsg_len
);
2069 if (result
!= PIM_SUCCESS
)
2070 return NB_ERR_INCONSISTENCY
;
2078 int lib_interface_pim_address_family_use_source_destroy(
2079 struct nb_cb_destroy_args
*args
)
2081 struct interface
*ifp
;
2083 const struct lyd_node
*if_dnode
;
2085 switch (args
->event
) {
2086 case NB_EV_VALIDATE
:
2087 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2088 if (!is_pim_interface(if_dnode
)) {
2089 snprintf(args
->errmsg
, args
->errmsg_len
,
2090 "Pim not enabled on this interface");
2091 return NB_ERR_VALIDATION
;
2098 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2100 result
= interface_pim_use_src_cmd_worker(ifp
, PIMADDR_ANY
,
2104 if (result
!= PIM_SUCCESS
)
2105 return NB_ERR_INCONSISTENCY
;
2114 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/multicast-boundary-oil
2116 int lib_interface_pim_address_family_multicast_boundary_oil_modify(
2117 struct nb_cb_modify_args
*args
)
2119 struct interface
*ifp
;
2120 struct pim_interface
*pim_ifp
;
2122 const struct lyd_node
*if_dnode
;
2124 switch (args
->event
) {
2125 case NB_EV_VALIDATE
:
2126 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2127 if (!is_pim_interface(if_dnode
)) {
2128 snprintf(args
->errmsg
, args
->errmsg_len
,
2129 "Pim not enabled on this interface");
2130 return NB_ERR_VALIDATION
;
2137 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2138 pim_ifp
= ifp
->info
;
2139 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
2141 if (pim_ifp
->boundary_oil_plist
)
2142 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
2144 pim_ifp
->boundary_oil_plist
=
2145 XSTRDUP(MTYPE_PIM_INTERFACE
, plist
);
2153 int lib_interface_pim_address_family_multicast_boundary_oil_destroy(
2154 struct nb_cb_destroy_args
*args
)
2156 struct interface
*ifp
;
2157 struct pim_interface
*pim_ifp
;
2158 const struct lyd_node
*if_dnode
;
2160 switch (args
->event
) {
2161 case NB_EV_VALIDATE
:
2162 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2163 if (!is_pim_interface(if_dnode
)) {
2164 snprintf(args
->errmsg
, args
->errmsg_len
,
2165 "%% Enable PIM and/or IGMP on this interface first");
2166 return NB_ERR_VALIDATION
;
2173 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2174 pim_ifp
= ifp
->info
;
2175 if (pim_ifp
->boundary_oil_plist
)
2176 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
2184 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/mroute
2186 int lib_interface_pim_address_family_mroute_create(
2187 struct nb_cb_create_args
*args
)
2189 switch (args
->event
) {
2190 case NB_EV_VALIDATE
:
2200 int lib_interface_pim_address_family_mroute_destroy(
2201 struct nb_cb_destroy_args
*args
)
2203 struct pim_instance
*pim
;
2204 struct pim_interface
*pim_iifp
;
2205 struct interface
*iif
;
2206 struct interface
*oif
;
2207 const char *oifname
;
2208 pim_addr source_addr
;
2209 pim_addr group_addr
;
2210 const struct lyd_node
*if_dnode
;
2212 switch (args
->event
) {
2213 case NB_EV_VALIDATE
:
2214 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2215 if (!is_pim_interface(if_dnode
)) {
2216 snprintf(args
->errmsg
, args
->errmsg_len
,
2217 "%% Enable PIM and/or IGMP on this interface first");
2218 return NB_ERR_VALIDATION
;
2225 iif
= nb_running_get_entry(args
->dnode
, NULL
, true);
2226 pim_iifp
= iif
->info
;
2227 pim
= pim_iifp
->pim
;
2229 oifname
= yang_dnode_get_string(args
->dnode
, "./oif");
2230 oif
= if_lookup_by_name(oifname
, pim
->vrf
->vrf_id
);
2233 snprintf(args
->errmsg
, args
->errmsg_len
,
2234 "No such interface name %s",
2236 return NB_ERR_INCONSISTENCY
;
2239 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
, "./source-addr");
2240 yang_dnode_get_pimaddr(&group_addr
, args
->dnode
, "./group-addr");
2242 if (pim_static_del(pim
, iif
, oif
, group_addr
, source_addr
)) {
2243 snprintf(args
->errmsg
, args
->errmsg_len
,
2244 "Failed to remove static mroute");
2245 return NB_ERR_INCONSISTENCY
;
2255 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/mroute/oif
2257 int lib_interface_pim_address_family_mroute_oif_modify(
2258 struct nb_cb_modify_args
*args
)
2260 struct pim_instance
*pim
;
2261 struct pim_interface
*pim_iifp
;
2262 struct interface
*iif
;
2263 struct interface
*oif
;
2264 const char *oifname
;
2265 pim_addr source_addr
;
2266 pim_addr group_addr
;
2267 const struct lyd_node
*if_dnode
;
2269 switch (args
->event
) {
2270 case NB_EV_VALIDATE
:
2271 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2272 if (!is_pim_interface(if_dnode
)) {
2273 snprintf(args
->errmsg
, args
->errmsg_len
,
2274 "%% Enable PIM and/or IGMP on this interface first");
2275 return NB_ERR_VALIDATION
;
2278 #ifdef PIM_ENFORCE_LOOPFREE_MFC
2279 iif
= nb_running_get_entry(args
->dnode
, NULL
, false);
2284 pim_iifp
= iif
->info
;
2285 pim
= pim_iifp
->pim
;
2287 oifname
= yang_dnode_get_string(args
->dnode
, NULL
);
2288 oif
= if_lookup_by_name(oifname
, pim
->vrf
->vrf_id
);
2290 if (oif
&& (iif
->ifindex
== oif
->ifindex
)) {
2291 strlcpy(args
->errmsg
,
2292 "% IIF same as OIF and loopfree enforcement is enabled; rejecting",
2294 return NB_ERR_VALIDATION
;
2302 iif
= nb_running_get_entry(args
->dnode
, NULL
, true);
2303 pim_iifp
= iif
->info
;
2304 pim
= pim_iifp
->pim
;
2306 oifname
= yang_dnode_get_string(args
->dnode
, NULL
);
2307 oif
= if_lookup_by_name(oifname
, pim
->vrf
->vrf_id
);
2309 snprintf(args
->errmsg
, args
->errmsg_len
,
2310 "No such interface name %s",
2312 return NB_ERR_INCONSISTENCY
;
2315 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
, "../source-addr");
2316 yang_dnode_get_pimaddr(&group_addr
, args
->dnode
, "../group-addr");
2318 if (pim_static_add(pim
, iif
, oif
, group_addr
, source_addr
)) {
2319 snprintf(args
->errmsg
, args
->errmsg_len
,
2320 "Failed to add static mroute");
2321 return NB_ERR_INCONSISTENCY
;
2330 int lib_interface_pim_address_family_mroute_oif_destroy(
2331 struct nb_cb_destroy_args
*args
)
2333 switch (args
->event
) {
2334 case NB_EV_VALIDATE
:
2345 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/static-rp/rp-list
2347 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_create(
2348 struct nb_cb_create_args
*args
)
2350 switch (args
->event
) {
2351 case NB_EV_VALIDATE
:
2361 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_destroy(
2362 struct nb_cb_destroy_args
*args
)
2365 struct pim_instance
*pim
;
2366 struct prefix group
;
2371 switch (args
->event
) {
2372 case NB_EV_VALIDATE
:
2377 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2379 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "./rp-address");
2381 if (yang_dnode_get(args
->dnode
, "./group-list")) {
2382 yang_dnode_get_prefix(&group
, args
->dnode
,
2385 result
= pim_no_rp_cmd_worker(pim
, rp_addr
, group
, NULL
,
2390 else if (yang_dnode_get(args
->dnode
, "./prefix-list")) {
2391 plist
= yang_dnode_get_string(args
->dnode
,
2393 if (!pim_get_all_mcast_group(&group
)) {
2396 "Unable to convert 224.0.0.0/4 to prefix");
2397 return NB_ERR_INCONSISTENCY
;
2400 result
= pim_no_rp_cmd_worker(pim
, rp_addr
, group
,
2401 plist
, args
->errmsg
,
2406 return NB_ERR_INCONSISTENCY
;
2414 * 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
2416 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_group_list_create(
2417 struct nb_cb_create_args
*args
)
2420 struct pim_instance
*pim
;
2421 struct prefix group
;
2424 switch (args
->event
) {
2425 case NB_EV_VALIDATE
:
2430 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2432 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "../rp-address");
2433 yang_dnode_get_prefix(&group
, args
->dnode
, NULL
);
2435 return pim_rp_cmd_worker(pim
, rp_addr
, group
, NULL
,
2436 args
->errmsg
, args
->errmsg_len
);
2442 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_group_list_destroy(
2443 struct nb_cb_destroy_args
*args
)
2446 struct pim_instance
*pim
;
2447 struct prefix group
;
2450 switch (args
->event
) {
2451 case NB_EV_VALIDATE
:
2456 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2458 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "../rp-address");
2459 yang_dnode_get_prefix(&group
, args
->dnode
, NULL
);
2462 return pim_no_rp_cmd_worker(pim
, rp_addr
, group
, NULL
,
2463 args
->errmsg
, args
->errmsg_len
);
2470 * 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
2472 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_prefix_list_modify(
2473 struct nb_cb_modify_args
*args
)
2476 struct pim_instance
*pim
;
2477 struct prefix group
;
2481 switch (args
->event
) {
2482 case NB_EV_VALIDATE
:
2487 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2489 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
2490 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "../rp-address");
2491 if (!pim_get_all_mcast_group(&group
)) {
2492 flog_err(EC_LIB_DEVELOPMENT
,
2493 "Unable to convert 224.0.0.0/4 to prefix");
2494 return NB_ERR_INCONSISTENCY
;
2496 return pim_rp_cmd_worker(pim
, rp_addr
, group
, plist
,
2497 args
->errmsg
, args
->errmsg_len
);
2503 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_prefix_list_destroy(
2504 struct nb_cb_destroy_args
*args
)
2507 struct pim_instance
*pim
;
2508 struct prefix group
;
2512 switch (args
->event
) {
2513 case NB_EV_VALIDATE
:
2518 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2520 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "../rp-address");
2521 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
2522 if (!pim_get_all_mcast_group(&group
)) {
2523 flog_err(EC_LIB_DEVELOPMENT
,
2524 "Unable to convert 224.0.0.0/4 to prefix");
2525 return NB_ERR_INCONSISTENCY
;
2527 return pim_no_rp_cmd_worker(pim
, rp_addr
, group
, plist
,
2528 args
->errmsg
, args
->errmsg_len
);
2536 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family
2538 int lib_interface_gmp_address_family_create(struct nb_cb_create_args
*args
)
2540 switch (args
->event
) {
2541 case NB_EV_VALIDATE
:
2551 int lib_interface_gmp_address_family_destroy(struct nb_cb_destroy_args
*args
)
2553 struct interface
*ifp
;
2554 struct pim_interface
*pim_ifp
;
2556 switch (args
->event
) {
2557 case NB_EV_VALIDATE
:
2562 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2563 pim_ifp
= ifp
->info
;
2568 pim_ifp
->gm_enable
= false;
2570 pim_if_membership_clear(ifp
);
2572 pim_if_addr_del_all_igmp(ifp
);
2574 if (!pim_ifp
->pim_enable
)
2582 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/enable
2584 int lib_interface_gmp_address_family_enable_modify(
2585 struct nb_cb_modify_args
*args
)
2588 struct interface
*ifp
;
2590 struct pim_interface
*pim_ifp
;
2592 const char *ifp_name
;
2593 const struct lyd_node
*if_dnode
;
2595 switch (args
->event
) {
2596 case NB_EV_VALIDATE
:
2597 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2599 yang_get_list_elements_count(if_dnode
);
2600 /* Limiting mcast interfaces to number of VIFs */
2601 if (mcast_if_count
== MAXVIFS
) {
2602 ifp_name
= yang_dnode_get_string(if_dnode
, "name");
2603 snprintf(args
->errmsg
, args
->errmsg_len
,
2604 "Max multicast interfaces(%d) Reached. Could not enable IGMP on interface %s",
2606 return NB_ERR_VALIDATION
;
2613 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2614 gm_enable
= yang_dnode_get_bool(args
->dnode
, NULL
);
2617 return pim_cmd_igmp_start(ifp
);
2620 pim_ifp
= ifp
->info
;
2623 return NB_ERR_INCONSISTENCY
;
2625 pim_ifp
->gm_enable
= false;
2627 pim_if_membership_clear(ifp
);
2629 pim_if_addr_del_all_igmp(ifp
);
2631 if (!pim_ifp
->pim_enable
)
2636 /* TBD Depends on MLD data structure changes */
2637 #endif /* PIM_IPV == 4 */
2642 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/igmp-version
2644 int lib_interface_gmp_address_family_igmp_version_modify(
2645 struct nb_cb_modify_args
*args
)
2647 struct interface
*ifp
;
2648 struct pim_interface
*pim_ifp
;
2649 int igmp_version
, old_version
= 0;
2651 switch (args
->event
) {
2652 case NB_EV_VALIDATE
:
2657 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2658 pim_ifp
= ifp
->info
;
2661 return NB_ERR_INCONSISTENCY
;
2663 igmp_version
= yang_dnode_get_uint8(args
->dnode
, NULL
);
2664 old_version
= pim_ifp
->igmp_version
;
2665 pim_ifp
->igmp_version
= igmp_version
;
2667 /* Current and new version is different refresh existing
2668 * membership. Going from 3 -> 2 or 2 -> 3.
2670 if (old_version
!= igmp_version
)
2671 pim_if_membership_refresh(ifp
);
2679 int lib_interface_gmp_address_family_igmp_version_destroy(
2680 struct nb_cb_destroy_args
*args
)
2682 struct interface
*ifp
;
2683 struct pim_interface
*pim_ifp
;
2685 switch (args
->event
) {
2686 case NB_EV_VALIDATE
:
2691 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2692 pim_ifp
= ifp
->info
;
2693 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
2701 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/mld-version
2703 int lib_interface_gmp_address_family_mld_version_modify(
2704 struct nb_cb_modify_args
*args
)
2706 struct interface
*ifp
;
2707 struct pim_interface
*pim_ifp
;
2709 switch (args
->event
) {
2710 case NB_EV_VALIDATE
:
2715 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2716 pim_ifp
= ifp
->info
;
2718 return NB_ERR_INCONSISTENCY
;
2720 pim_ifp
->mld_version
= yang_dnode_get_uint8(args
->dnode
, NULL
);
2728 int lib_interface_gmp_address_family_mld_version_destroy(
2729 struct nb_cb_destroy_args
*args
)
2731 struct interface
*ifp
;
2732 struct pim_interface
*pim_ifp
;
2734 switch (args
->event
) {
2735 case NB_EV_VALIDATE
:
2740 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2741 pim_ifp
= ifp
->info
;
2743 return NB_ERR_INCONSISTENCY
;
2745 pim_ifp
->mld_version
= 2;
2754 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/query-interval
2756 int lib_interface_gmp_address_family_query_interval_modify(
2757 struct nb_cb_modify_args
*args
)
2759 struct interface
*ifp
;
2763 switch (args
->event
) {
2764 case NB_EV_VALIDATE
:
2769 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2770 query_interval
= yang_dnode_get_uint16(args
->dnode
, NULL
);
2771 change_query_interval(ifp
->info
, query_interval
);
2774 struct pim_interface
*pim_ifp
;
2776 switch (args
->event
) {
2777 case NB_EV_VALIDATE
:
2782 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2783 pim_ifp
= ifp
->info
;
2785 return NB_ERR_INCONSISTENCY
;
2787 query_interval
= yang_dnode_get_uint16(args
->dnode
, NULL
);
2788 pim_ifp
->gm_default_query_interval
= query_interval
;
2796 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/query-max-response-time
2798 int lib_interface_gmp_address_family_query_max_response_time_modify(
2799 struct nb_cb_modify_args
*args
)
2802 struct interface
*ifp
;
2803 int query_max_response_time_dsec
;
2805 switch (args
->event
) {
2806 case NB_EV_VALIDATE
:
2811 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2812 query_max_response_time_dsec
=
2813 yang_dnode_get_uint16(args
->dnode
, NULL
);
2814 change_query_max_response_time(ifp
->info
,
2815 query_max_response_time_dsec
);
2818 /* TBD Depends on MLD data structure changes */
2826 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/last-member-query-interval
2828 int lib_interface_gmp_address_family_last_member_query_interval_modify(
2829 struct nb_cb_modify_args
*args
)
2832 struct interface
*ifp
;
2833 struct pim_interface
*pim_ifp
;
2834 int last_member_query_interval
;
2836 switch (args
->event
) {
2837 case NB_EV_VALIDATE
:
2842 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2843 pim_ifp
= ifp
->info
;
2844 last_member_query_interval
=
2845 yang_dnode_get_uint16(args
->dnode
, NULL
);
2846 pim_ifp
->gm_specific_query_max_response_time_dsec
=
2847 last_member_query_interval
;
2852 /* TBD Depends on MLD data structure changes */
2859 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/robustness-variable
2861 int lib_interface_gmp_address_family_robustness_variable_modify(
2862 struct nb_cb_modify_args
*args
)
2865 struct interface
*ifp
;
2866 struct pim_interface
*pim_ifp
;
2867 int last_member_query_count
;
2869 switch (args
->event
) {
2870 case NB_EV_VALIDATE
:
2875 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2876 pim_ifp
= ifp
->info
;
2877 last_member_query_count
=
2878 yang_dnode_get_uint8(args
->dnode
, NULL
);
2879 pim_ifp
->gm_last_member_query_count
= last_member_query_count
;
2884 /* TBD Depends on MLD data structure changes */
2891 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/static-group
2893 int lib_interface_gmp_address_family_static_group_create(
2894 struct nb_cb_create_args
*args
)
2897 struct interface
*ifp
;
2898 struct ipaddr source_addr
;
2899 struct ipaddr group_addr
;
2901 const char *ifp_name
;
2902 const struct lyd_node
*if_dnode
;
2904 switch (args
->event
) {
2905 case NB_EV_VALIDATE
:
2906 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2907 if (!is_pim_interface(if_dnode
)) {
2908 ifp_name
= yang_dnode_get_string(if_dnode
, "name");
2909 snprintf(args
->errmsg
, args
->errmsg_len
,
2910 "multicast not enabled on interface %s",
2912 return NB_ERR_VALIDATION
;
2915 yang_dnode_get_ip(&group_addr
, args
->dnode
, "./group-addr");
2916 if (pim_is_group_224_0_0_0_24(group_addr
.ip
._v4_addr
)) {
2918 args
->errmsg
, args
->errmsg_len
,
2919 "Groups within 224.0.0.0/24 are reserved and cannot be joined");
2920 return NB_ERR_VALIDATION
;
2927 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2928 yang_dnode_get_ip(&source_addr
, args
->dnode
, "./source-addr");
2929 yang_dnode_get_ip(&group_addr
, args
->dnode
, "./group-addr");
2931 result
= pim_if_igmp_join_add(ifp
, group_addr
.ip
._v4_addr
,
2932 source_addr
.ip
._v4_addr
);
2934 snprintf(args
->errmsg
, args
->errmsg_len
,
2935 "Failure joining IGMP group");
2936 return NB_ERR_INCONSISTENCY
;
2940 /* TBD Depends on MLD data structure changes */
2941 #endif /* PIM_IPV == 4 */
2945 int lib_interface_gmp_address_family_static_group_destroy(
2946 struct nb_cb_destroy_args
*args
)
2948 struct interface
*ifp
;
2949 struct ipaddr source_addr
;
2950 struct ipaddr group_addr
;
2953 switch (args
->event
) {
2954 case NB_EV_VALIDATE
:
2959 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2960 yang_dnode_get_ip(&source_addr
, args
->dnode
, "./source-addr");
2961 yang_dnode_get_ip(&group_addr
, args
->dnode
, "./group-addr");
2963 result
= pim_if_igmp_join_del(ifp
, group_addr
.ip
._v4_addr
,
2964 source_addr
.ip
._v4_addr
);
2967 char src_str
[INET_ADDRSTRLEN
];
2968 char grp_str
[INET_ADDRSTRLEN
];
2970 ipaddr2str(&source_addr
, src_str
, sizeof(src_str
));
2971 ipaddr2str(&group_addr
, grp_str
, sizeof(grp_str
));
2973 snprintf(args
->errmsg
, args
->errmsg_len
,
2974 "%% Failure leaving IGMP group %s %s on interface %s: %d",
2975 src_str
, grp_str
, ifp
->name
, result
);
2977 return NB_ERR_INCONSISTENCY
;