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_PIM_AF_XPATH_VAL
);
338 igmp_enable_dnode
= yang_dnode_getf(dnode
,
339 "%s/frr-gmp:gmp/address-family[address-family='%s']/enable",
340 if_xpath
, FRR_PIM_AF_XPATH_VAL
);
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_gm_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_ifp
->gm_enable
) {
363 pim_ifp
->gm_enable
= true;
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.
386 static void igmp_sock_query_interval_reconfig(struct gm_sock
*igmp
)
388 struct interface
*ifp
;
389 struct pim_interface
*pim_ifp
;
392 assert(igmp
->interface
);
393 assert(igmp
->interface
->info
);
395 ifp
= igmp
->interface
;
398 if (PIM_DEBUG_IGMP_TRACE
)
399 zlog_debug("%s: Querier %pPAs on %s reconfig query_interval=%d",
400 __func__
, &igmp
->ifaddr
, ifp
->name
,
401 pim_ifp
->gm_default_query_interval
);
404 * igmp_startup_mode_on() will reset QQI:
406 * igmp->querier_query_interval = pim_ifp->gm_default_query_interval;
408 igmp_startup_mode_on(igmp
);
411 static void igmp_sock_query_reschedule(struct gm_sock
*igmp
)
413 if (igmp
->mtrace_only
)
416 if (igmp
->t_igmp_query_timer
) {
417 /* other querier present */
418 assert(igmp
->t_igmp_query_timer
);
419 assert(!igmp
->t_other_querier_timer
);
421 pim_igmp_general_query_off(igmp
);
422 pim_igmp_general_query_on(igmp
);
424 assert(igmp
->t_igmp_query_timer
);
425 assert(!igmp
->t_other_querier_timer
);
427 /* this is the querier */
429 assert(!igmp
->t_igmp_query_timer
);
430 assert(igmp
->t_other_querier_timer
);
432 pim_igmp_other_querier_timer_off(igmp
);
433 pim_igmp_other_querier_timer_on(igmp
);
435 assert(!igmp
->t_igmp_query_timer
);
436 assert(igmp
->t_other_querier_timer
);
439 #endif /* PIM_IPV == 4 */
442 static void change_query_interval(struct pim_interface
*pim_ifp
,
445 struct listnode
*sock_node
;
446 struct gm_sock
*igmp
;
448 pim_ifp
->gm_default_query_interval
= query_interval
;
450 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->gm_socket_list
, sock_node
, igmp
)) {
451 igmp_sock_query_interval_reconfig(igmp
);
452 igmp_sock_query_reschedule(igmp
);
458 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
459 int query_max_response_time_dsec
)
461 struct listnode
*sock_node
;
462 struct gm_sock
*igmp
;
463 struct listnode
*grp_node
;
464 struct gm_group
*grp
;
466 if (pim_ifp
->gm_query_max_response_time_dsec
==
467 query_max_response_time_dsec
)
470 pim_ifp
->gm_query_max_response_time_dsec
= query_max_response_time_dsec
;
473 * Below we modify socket/group/source timers in order to quickly
474 * reflect the change. Otherwise, those timers would args->eventually
478 /* scan all sockets */
479 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->gm_socket_list
, sock_node
, igmp
)) {
480 /* reschedule socket general query */
481 igmp_sock_query_reschedule(igmp
);
484 /* scan socket groups */
485 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->gm_group_list
, grp_node
, grp
)) {
486 struct listnode
*src_node
;
487 struct gm_source
*src
;
489 /* reset group timers for groups in EXCLUDE mode */
490 if (grp
->group_filtermode_isexcl
)
491 igmp_group_reset_gmi(grp
);
493 /* scan group sources */
494 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, src_node
,
497 /* reset source timers for sources with running
500 if (src
->t_source_timer
)
501 igmp_source_reset_gmi(grp
, src
);
507 int routing_control_plane_protocols_name_validate(
508 struct nb_cb_create_args
*args
)
512 name
= yang_dnode_get_string(args
->dnode
, "./name");
513 if (!strmatch(name
, "pim")) {
514 snprintf(args
->errmsg
, args
->errmsg_len
,
515 "pim supports only one instance with name pimd");
516 return NB_ERR_VALIDATION
;
522 * XPath: /frr-pim:pim/address-family
524 int pim_address_family_create(struct nb_cb_create_args
*args
)
526 switch (args
->event
) {
537 int pim_address_family_destroy(struct nb_cb_destroy_args
*args
)
539 switch (args
->event
) {
551 * XPath: /frr-pim:pim/address-family/packets
553 int pim_address_family_packets_modify(struct nb_cb_modify_args
*args
)
555 switch (args
->event
) {
561 router
->packet_process
= yang_dnode_get_uint8(args
->dnode
,
570 * XPath: /frr-pim:pim/address-family/join-prune-interval
572 int pim_address_family_join_prune_interval_modify(
573 struct nb_cb_modify_args
*args
)
575 switch (args
->event
) {
581 router
->t_periodic
= yang_dnode_get_uint16(args
->dnode
, NULL
);
589 * XPath: /frr-pim:pim/address-family/register-suppress-time
591 int pim_address_family_register_suppress_time_modify(
592 struct nb_cb_modify_args
*args
)
595 switch (args
->event
) {
597 value
= yang_dnode_get_uint16(args
->dnode
, NULL
);
599 * As soon as this is non-constant it needs to be replaced with
600 * a yang_dnode_get to lookup the candidate value, *not* the
601 * operational value. Since the code has a field assigned and
602 * used for this value it should have YANG/CLI to set it too,
603 * otherwise just use the #define!
605 /* RFC7761: 4.11. Timer Values */
606 if (value
<= router
->register_probe_time
* 2) {
608 args
->errmsg
, args
->errmsg_len
,
609 "Register suppress time (%u) must be more than "
610 "twice the register probe time (%u).",
611 value
, router
->register_probe_time
);
612 return NB_ERR_VALIDATION
;
619 pim_update_suppress_timers(
620 yang_dnode_get_uint16(args
->dnode
, NULL
));
628 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/ecmp
630 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ecmp_modify(
631 struct nb_cb_modify_args
*args
)
634 struct pim_instance
*pim
;
636 switch (args
->event
) {
642 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
644 pim
->ecmp_enable
= yang_dnode_get_bool(args
->dnode
, NULL
);
651 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/ecmp-rebalance
653 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ecmp_rebalance_modify(
654 struct nb_cb_modify_args
*args
)
657 struct pim_instance
*pim
;
659 switch (args
->event
) {
665 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
667 pim
->ecmp_rebalance_enable
=
668 yang_dnode_get_bool(args
->dnode
, NULL
);
675 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/keep-alive-timer
677 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_keep_alive_timer_modify(
678 struct nb_cb_modify_args
*args
)
681 struct pim_instance
*pim
;
683 switch (args
->event
) {
689 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
691 pim
->keep_alive_time
= yang_dnode_get_uint16(args
->dnode
, NULL
);
699 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/rp-keep-alive-timer
701 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_keep_alive_timer_modify(
702 struct nb_cb_modify_args
*args
)
705 struct pim_instance
*pim
;
707 switch (args
->event
) {
713 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
715 pim
->rp_keep_alive_time
= yang_dnode_get_uint16(args
->dnode
,
724 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family
726 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_create(
727 struct nb_cb_create_args
*args
)
729 switch (args
->event
) {
740 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_destroy(
741 struct nb_cb_destroy_args
*args
)
743 switch (args
->event
) {
755 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/send-v6-secondary
757 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_send_v6_secondary_modify(
758 struct nb_cb_modify_args
*args
)
761 struct pim_instance
*pim
;
763 switch (args
->event
) {
769 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
771 pim
->send_v6_secondary
= yang_dnode_get_bool(args
->dnode
, NULL
);
778 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_send_v6_secondary_destroy(
779 struct nb_cb_destroy_args
*args
)
781 switch (args
->event
) {
794 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/spt-switchover
796 void routing_control_plane_protocols_control_plane_protocol_pim_address_family_spt_switchover_apply_finish(
797 struct nb_cb_apply_finish_args
*args
)
800 struct pim_instance
*pim
;
801 int spt_switch_action
;
802 const char *prefix_list
= NULL
;
804 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
806 spt_switch_action
= yang_dnode_get_enum(args
->dnode
, "./spt-action");
808 switch (spt_switch_action
) {
809 case PIM_SPT_INFINITY
:
810 if (yang_dnode_exists(args
->dnode
,
811 "./spt-infinity-prefix-list"))
812 prefix_list
= yang_dnode_get_string(
813 args
->dnode
, "./spt-infinity-prefix-list");
815 pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
,
818 case PIM_SPT_IMMEDIATE
:
819 pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
824 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/spt-switchover/spt-action
826 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_spt_switchover_spt_action_modify(
827 struct nb_cb_modify_args
*args
)
829 switch (args
->event
) {
841 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/spt-switchover/spt-infinity-prefix-list
843 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_spt_switchover_spt_infinity_prefix_list_modify(
844 struct nb_cb_modify_args
*args
)
846 switch (args
->event
) {
857 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_spt_switchover_spt_infinity_prefix_list_destroy(
858 struct nb_cb_destroy_args
*args
)
860 switch (args
->event
) {
872 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/ssm-prefix-list
874 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_prefix_list_modify(
875 struct nb_cb_modify_args
*args
)
878 struct pim_instance
*pim
;
879 const char *plist_name
;
882 switch (args
->event
) {
888 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
890 plist_name
= yang_dnode_get_string(args
->dnode
, NULL
);
891 result
= pim_ssm_cmd_worker(pim
, plist_name
, args
->errmsg
,
895 return NB_ERR_INCONSISTENCY
;
903 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_prefix_list_destroy(
904 struct nb_cb_destroy_args
*args
)
907 struct pim_instance
*pim
;
910 switch (args
->event
) {
916 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
918 result
= pim_ssm_cmd_worker(pim
, NULL
, args
->errmsg
,
922 return NB_ERR_INCONSISTENCY
;
931 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/ssm-pingd-source-ip
933 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_pingd_source_ip_create(
934 struct nb_cb_create_args
*args
)
937 struct pim_instance
*pim
;
939 pim_addr source_addr
;
941 switch (args
->event
) {
947 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
949 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
,
951 result
= pim_ssmpingd_start(pim
, source_addr
);
954 args
->errmsg
, args
->errmsg_len
,
955 "%% Failure starting ssmpingd for source %pPA: %d",
956 &source_addr
, result
);
957 return NB_ERR_INCONSISTENCY
;
964 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_pingd_source_ip_destroy(
965 struct nb_cb_destroy_args
*args
)
968 struct pim_instance
*pim
;
970 pim_addr source_addr
;
972 switch (args
->event
) {
978 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
980 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
,
982 result
= pim_ssmpingd_stop(pim
, source_addr
);
985 args
->errmsg
, args
->errmsg_len
,
986 "%% Failure stopping ssmpingd for source %pPA: %d",
987 &source_addr
, result
);
988 return NB_ERR_INCONSISTENCY
;
999 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/hold-time
1001 int pim_msdp_hold_time_modify(struct nb_cb_modify_args
*args
)
1003 struct pim_instance
*pim
;
1006 switch (args
->event
) {
1007 case NB_EV_VALIDATE
:
1012 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1014 pim
->msdp
.hold_time
= yang_dnode_get_uint16(args
->dnode
, NULL
);
1023 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/keep-alive
1025 int pim_msdp_keep_alive_modify(struct nb_cb_modify_args
*args
)
1027 struct pim_instance
*pim
;
1030 switch (args
->event
) {
1031 case NB_EV_VALIDATE
:
1036 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1038 pim
->msdp
.keep_alive
= yang_dnode_get_uint16(args
->dnode
, NULL
);
1047 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/connection-retry
1049 int pim_msdp_connection_retry_modify(struct nb_cb_modify_args
*args
)
1051 struct pim_instance
*pim
;
1054 switch (args
->event
) {
1055 case NB_EV_VALIDATE
:
1060 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1062 pim
->msdp
.connection_retry
=
1063 yang_dnode_get_uint16(args
->dnode
, NULL
);
1070 pim6_msdp_err(pim_msdp_mesh_group_destroy
, nb_cb_destroy_args
);
1071 pim6_msdp_err(pim_msdp_mesh_group_create
, nb_cb_create_args
);
1072 pim6_msdp_err(pim_msdp_mesh_group_source_modify
, nb_cb_modify_args
);
1073 pim6_msdp_err(pim_msdp_mesh_group_source_destroy
, nb_cb_destroy_args
);
1074 pim6_msdp_err(pim_msdp_mesh_group_members_create
, nb_cb_create_args
);
1075 pim6_msdp_err(pim_msdp_mesh_group_members_destroy
, nb_cb_destroy_args
);
1076 pim6_msdp_err(routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify
,
1078 pim6_msdp_err(routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_destroy
,
1079 nb_cb_destroy_args
);
1080 pim6_msdp_err(routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_create
,
1086 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups
1088 int pim_msdp_mesh_group_create(struct nb_cb_create_args
*args
)
1090 struct pim_msdp_mg
*mg
;
1093 switch (args
->event
) {
1094 case NB_EV_VALIDATE
:
1099 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1100 mg
= pim_msdp_mg_new(vrf
->info
, yang_dnode_get_string(
1101 args
->dnode
, "./name"));
1102 nb_running_set_entry(args
->dnode
, mg
);
1109 int pim_msdp_mesh_group_destroy(struct nb_cb_destroy_args
*args
)
1111 struct pim_msdp_mg
*mg
;
1114 switch (args
->event
) {
1115 case NB_EV_VALIDATE
:
1120 mg
= nb_running_unset_entry(args
->dnode
);
1121 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1122 pim_msdp_mg_free(vrf
->info
, &mg
);
1131 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups/source
1133 int pim_msdp_mesh_group_source_modify(struct nb_cb_modify_args
*args
)
1135 const struct lyd_node
*vrf_dnode
;
1136 struct pim_msdp_mg
*mg
;
1140 switch (args
->event
) {
1141 case NB_EV_VALIDATE
:
1146 mg
= nb_running_get_entry(args
->dnode
, NULL
, true);
1148 yang_dnode_get_parent(args
->dnode
, "address-family");
1149 vrf
= nb_running_get_entry(vrf_dnode
, "../../", true);
1150 yang_dnode_get_ip(&ip
, args
->dnode
, NULL
);
1152 pim_msdp_mg_src_add(vrf
->info
, mg
, &ip
.ip
._v4_addr
);
1158 int pim_msdp_mesh_group_source_destroy(struct nb_cb_destroy_args
*args
)
1160 const struct lyd_node
*vrf_dnode
;
1161 struct pim_msdp_mg
*mg
;
1163 struct in_addr addr
;
1165 switch (args
->event
) {
1166 case NB_EV_VALIDATE
:
1171 mg
= nb_running_get_entry(args
->dnode
, NULL
, true);
1173 yang_dnode_get_parent(args
->dnode
, "address-family");
1174 vrf
= nb_running_get_entry(vrf_dnode
, "../../", true);
1176 addr
.s_addr
= INADDR_ANY
;
1177 pim_msdp_mg_src_add(vrf
->info
, mg
, &addr
);
1186 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups/members
1188 int pim_msdp_mesh_group_members_create(struct nb_cb_create_args
*args
)
1190 const struct lyd_node
*vrf_dnode
;
1191 struct pim_msdp_mg_mbr
*mbr
;
1192 struct pim_msdp_mg
*mg
;
1196 switch (args
->event
) {
1197 case NB_EV_VALIDATE
:
1202 mg
= nb_running_get_entry(args
->dnode
, NULL
, true);
1204 yang_dnode_get_parent(args
->dnode
, "address-family");
1205 vrf
= nb_running_get_entry(vrf_dnode
, "../../", true);
1206 yang_dnode_get_ip(&ip
, args
->dnode
, "address");
1208 mbr
= pim_msdp_mg_mbr_add(vrf
->info
, mg
, &ip
.ip
._v4_addr
);
1209 nb_running_set_entry(args
->dnode
, mbr
);
1216 int pim_msdp_mesh_group_members_destroy(struct nb_cb_destroy_args
*args
)
1218 struct pim_msdp_mg_mbr
*mbr
;
1219 struct pim_msdp_mg
*mg
;
1220 const struct lyd_node
*mg_dnode
;
1222 switch (args
->event
) {
1223 case NB_EV_VALIDATE
:
1228 mbr
= nb_running_get_entry(args
->dnode
, NULL
, true);
1230 yang_dnode_get_parent(args
->dnode
, "msdp-mesh-groups");
1231 mg
= nb_running_get_entry(mg_dnode
, NULL
, true);
1232 pim_msdp_mg_mbr_del(mg
, mbr
);
1233 nb_running_unset_entry(args
->dnode
);
1241 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-peer
1243 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_create(
1244 struct nb_cb_create_args
*args
)
1246 struct pim_msdp_peer
*mp
;
1247 struct pim_instance
*pim
;
1249 struct ipaddr peer_ip
;
1250 struct ipaddr source_ip
;
1252 switch (args
->event
) {
1253 case NB_EV_VALIDATE
:
1258 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1260 yang_dnode_get_ip(&peer_ip
, args
->dnode
, "./peer-ip");
1261 yang_dnode_get_ip(&source_ip
, args
->dnode
, "./source-ip");
1262 mp
= pim_msdp_peer_add(pim
, &peer_ip
.ipaddr_v4
,
1263 &source_ip
.ipaddr_v4
, NULL
);
1264 nb_running_set_entry(args
->dnode
, mp
);
1271 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_destroy(
1272 struct nb_cb_destroy_args
*args
)
1274 struct pim_msdp_peer
*mp
;
1276 switch (args
->event
) {
1277 case NB_EV_VALIDATE
:
1282 mp
= nb_running_unset_entry(args
->dnode
);
1283 pim_msdp_peer_del(&mp
);
1291 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-peer/source-ip
1293 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify(
1294 struct nb_cb_modify_args
*args
)
1296 struct pim_msdp_peer
*mp
;
1297 struct ipaddr source_ip
;
1299 switch (args
->event
) {
1300 case NB_EV_VALIDATE
:
1305 mp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1306 yang_dnode_get_ip(&source_ip
, args
->dnode
, NULL
);
1307 pim_msdp_peer_change_source(mp
, &source_ip
.ipaddr_v4
);
1313 #endif /* PIM_IPV != 6 */
1316 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag
1318 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_create(
1319 struct nb_cb_create_args
*args
)
1321 switch (args
->event
) {
1322 case NB_EV_VALIDATE
:
1332 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_destroy(
1333 struct nb_cb_destroy_args
*args
)
1335 struct in_addr addr
;
1337 switch (args
->event
) {
1338 case NB_EV_VALIDATE
:
1344 pim_vxlan_mlag_update(true/*mlag_enable*/,
1345 false/*peer_state*/, MLAG_ROLE_NONE
,
1346 NULL
/*peerlink*/, &addr
);
1354 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag
1356 void routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_apply_finish(
1357 struct nb_cb_apply_finish_args
*args
)
1362 struct interface
*ifp
;
1363 struct ipaddr reg_addr
;
1365 ifname
= yang_dnode_get_string(args
->dnode
, "./peerlink-rif");
1366 ifp
= if_lookup_by_name(ifname
, VRF_DEFAULT
);
1368 snprintf(args
->errmsg
, args
->errmsg_len
,
1369 "No such interface name %s", ifname
);
1372 role
= yang_dnode_get_enum(args
->dnode
, "./my-role");
1373 peer_state
= yang_dnode_get_bool(args
->dnode
, "./peer-state");
1374 yang_dnode_get_ip(®_addr
, args
->dnode
, "./reg-address");
1376 pim_vxlan_mlag_update(true, peer_state
, role
, ifp
,
1377 ®_addr
.ip
._v4_addr
);
1382 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/peerlink-rif
1384 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_peerlink_rif_modify(
1385 struct nb_cb_modify_args
*args
)
1387 switch (args
->event
) {
1388 case NB_EV_VALIDATE
:
1398 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_peerlink_rif_destroy(
1399 struct nb_cb_destroy_args
*args
)
1401 switch (args
->event
) {
1402 case NB_EV_VALIDATE
:
1413 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/reg-address
1415 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_reg_address_modify(
1416 struct nb_cb_modify_args
*args
)
1418 switch (args
->event
) {
1419 case NB_EV_VALIDATE
:
1429 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_reg_address_destroy(
1430 struct nb_cb_destroy_args
*args
)
1432 switch (args
->event
) {
1433 case NB_EV_VALIDATE
:
1444 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/my-role
1446 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_my_role_modify(
1447 struct nb_cb_modify_args
*args
)
1449 switch (args
->event
) {
1450 case NB_EV_VALIDATE
:
1461 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/peer-state
1463 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_peer_state_modify(
1464 struct nb_cb_modify_args
*args
)
1466 switch (args
->event
) {
1467 case NB_EV_VALIDATE
:
1478 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/register-accept-list
1480 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_register_accept_list_modify(
1481 struct nb_cb_modify_args
*args
)
1484 struct pim_instance
*pim
;
1487 switch (args
->event
) {
1488 case NB_EV_VALIDATE
:
1493 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1495 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
1497 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
1498 pim
->register_plist
= XSTRDUP(MTYPE_PIM_PLIST_NAME
, plist
);
1506 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_register_accept_list_destroy(
1507 struct nb_cb_destroy_args
*args
)
1510 struct pim_instance
*pim
;
1512 switch (args
->event
) {
1513 case NB_EV_VALIDATE
:
1518 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1521 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
1529 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family
1531 int lib_interface_pim_address_family_create(struct nb_cb_create_args
*args
)
1533 switch (args
->event
) {
1534 case NB_EV_VALIDATE
:
1544 int lib_interface_pim_address_family_destroy(struct nb_cb_destroy_args
*args
)
1546 struct interface
*ifp
;
1547 struct pim_interface
*pim_ifp
;
1549 switch (args
->event
) {
1550 case NB_EV_VALIDATE
:
1555 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1556 pim_ifp
= ifp
->info
;
1560 if (!pim_cmd_interface_delete(ifp
)) {
1561 snprintf(args
->errmsg
, args
->errmsg_len
,
1562 "Unable to delete interface information %s",
1564 return NB_ERR_INCONSISTENCY
;
1572 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/pim-enable
1574 int lib_interface_pim_address_family_pim_enable_modify(struct nb_cb_modify_args
*args
)
1576 struct interface
*ifp
;
1577 struct pim_interface
*pim_ifp
;
1579 const struct lyd_node
*if_dnode
;
1581 switch (args
->event
) {
1582 case NB_EV_VALIDATE
:
1583 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
1585 yang_get_list_elements_count(if_dnode
);
1587 /* Limiting mcast interfaces to number of VIFs */
1588 if (mcast_if_count
== MAXVIFS
) {
1589 snprintf(args
->errmsg
, args
->errmsg_len
,
1590 "Max multicast interfaces(%d) reached.",
1592 return NB_ERR_VALIDATION
;
1599 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1601 if (yang_dnode_get_bool(args
->dnode
, NULL
)) {
1602 if (!pim_cmd_interface_add(ifp
)) {
1603 snprintf(args
->errmsg
, args
->errmsg_len
,
1604 "Could not enable PIM SM on interface %s",
1606 return NB_ERR_INCONSISTENCY
;
1609 pim_ifp
= ifp
->info
;
1611 return NB_ERR_INCONSISTENCY
;
1613 if (!pim_cmd_interface_delete(ifp
)) {
1614 snprintf(args
->errmsg
, args
->errmsg_len
,
1615 "Unable to delete interface information");
1616 return NB_ERR_INCONSISTENCY
;
1627 * /frr-interface:lib/interface/frr-pim:pim/address-family/pim-passive-enable
1629 int lib_interface_pim_address_family_pim_passive_enable_modify(
1630 struct nb_cb_modify_args
*args
)
1632 struct interface
*ifp
;
1633 struct pim_interface
*pim_ifp
;
1635 switch (args
->event
) {
1636 case NB_EV_VALIDATE
:
1641 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1642 pim_ifp
= ifp
->info
;
1643 pim_ifp
->pim_passive_enable
=
1644 yang_dnode_get_bool(args
->dnode
, NULL
);
1652 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/hello-interval
1654 int lib_interface_pim_address_family_hello_interval_modify(
1655 struct nb_cb_modify_args
*args
)
1657 struct interface
*ifp
;
1658 struct pim_interface
*pim_ifp
;
1660 switch (args
->event
) {
1661 case NB_EV_VALIDATE
:
1666 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1667 pim_ifp
= ifp
->info
;
1668 pim_ifp
->pim_hello_period
=
1669 yang_dnode_get_uint8(args
->dnode
, NULL
);
1670 pim_ifp
->pim_default_holdtime
= -1;
1678 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/hello-holdtime
1680 int lib_interface_pim_address_family_hello_holdtime_modify(
1681 struct nb_cb_modify_args
*args
)
1683 struct interface
*ifp
;
1684 struct pim_interface
*pim_ifp
;
1686 switch (args
->event
) {
1687 case NB_EV_VALIDATE
:
1692 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1693 pim_ifp
= ifp
->info
;
1694 pim_ifp
->pim_default_holdtime
=
1695 yang_dnode_get_uint16(args
->dnode
, NULL
);
1703 int lib_interface_pim_address_family_hello_holdtime_destroy(
1704 struct nb_cb_destroy_args
*args
)
1706 struct interface
*ifp
;
1707 struct pim_interface
*pim_ifp
;
1709 switch (args
->event
) {
1710 case NB_EV_VALIDATE
:
1715 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1716 pim_ifp
= ifp
->info
;
1717 pim_ifp
->pim_default_holdtime
= -1;
1724 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd
1726 int lib_interface_pim_address_family_bfd_create(struct nb_cb_create_args
*args
)
1728 struct interface
*ifp
;
1729 struct pim_interface
*pim_ifp
;
1731 switch (args
->event
) {
1732 case NB_EV_VALIDATE
:
1738 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1739 pim_ifp
= ifp
->info
;
1740 pim_ifp
->bfd_config
.enabled
= true;
1747 int lib_interface_pim_address_family_bfd_destroy(
1748 struct nb_cb_destroy_args
*args
)
1750 struct interface
*ifp
;
1751 struct pim_interface
*pim_ifp
;
1752 const struct lyd_node
*if_dnode
;
1754 switch (args
->event
) {
1755 case NB_EV_VALIDATE
:
1756 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
1757 if (!is_pim_interface(if_dnode
)) {
1758 snprintf(args
->errmsg
, args
->errmsg_len
,
1759 "Pim not enabled on this interface");
1760 return NB_ERR_VALIDATION
;
1767 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1768 pim_ifp
= ifp
->info
;
1769 pim_ifp
->bfd_config
.enabled
= false;
1770 pim_bfd_reg_dereg_all_nbr(ifp
);
1778 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd
1780 void lib_interface_pim_address_family_bfd_apply_finish(
1781 struct nb_cb_apply_finish_args
*args
)
1783 struct interface
*ifp
;
1784 struct pim_interface
*pim_ifp
;
1786 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1787 pim_ifp
= ifp
->info
;
1790 zlog_debug("Pim not enabled on this interface");
1794 pim_ifp
->bfd_config
.detection_multiplier
=
1795 yang_dnode_get_uint8(args
->dnode
, "./detect_mult");
1796 pim_ifp
->bfd_config
.min_rx
=
1797 yang_dnode_get_uint16(args
->dnode
, "./min-rx-interval");
1798 pim_ifp
->bfd_config
.min_tx
=
1799 yang_dnode_get_uint16(args
->dnode
, "./min-tx-interval");
1801 pim_bfd_reg_dereg_all_nbr(ifp
);
1805 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/min-rx-interval
1807 int lib_interface_pim_address_family_bfd_min_rx_interval_modify(
1808 struct nb_cb_modify_args
*args
)
1810 switch (args
->event
) {
1811 case NB_EV_VALIDATE
:
1822 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/min-tx-interval
1824 int lib_interface_pim_address_family_bfd_min_tx_interval_modify(
1825 struct nb_cb_modify_args
*args
)
1827 switch (args
->event
) {
1828 case NB_EV_VALIDATE
:
1839 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/detect_mult
1841 int lib_interface_pim_address_family_bfd_detect_mult_modify(
1842 struct nb_cb_modify_args
*args
)
1844 switch (args
->event
) {
1845 case NB_EV_VALIDATE
:
1856 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/profile
1858 int lib_interface_pim_address_family_bfd_profile_modify(
1859 struct nb_cb_modify_args
*args
)
1861 struct interface
*ifp
;
1862 struct pim_interface
*pim_ifp
;
1864 switch (args
->event
) {
1865 case NB_EV_VALIDATE
:
1871 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1872 pim_ifp
= ifp
->info
;
1873 XFREE(MTYPE_TMP
, pim_ifp
->bfd_config
.profile
);
1874 pim_ifp
->bfd_config
.profile
= XSTRDUP(
1875 MTYPE_TMP
, yang_dnode_get_string(args
->dnode
, NULL
));
1882 int lib_interface_pim_address_family_bfd_profile_destroy(
1883 struct nb_cb_destroy_args
*args
)
1885 struct interface
*ifp
;
1886 struct pim_interface
*pim_ifp
;
1888 switch (args
->event
) {
1889 case NB_EV_VALIDATE
:
1895 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1896 pim_ifp
= ifp
->info
;
1897 XFREE(MTYPE_TMP
, pim_ifp
->bfd_config
.profile
);
1905 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bsm
1907 int lib_interface_pim_address_family_bsm_modify(struct nb_cb_modify_args
*args
)
1909 struct interface
*ifp
;
1910 struct pim_interface
*pim_ifp
;
1912 switch (args
->event
) {
1913 case NB_EV_VALIDATE
:
1918 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1919 pim_ifp
= ifp
->info
;
1920 pim_ifp
->bsm_enable
= yang_dnode_get_bool(args
->dnode
, NULL
);
1929 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/unicast-bsm
1931 int lib_interface_pim_address_family_unicast_bsm_modify(
1932 struct nb_cb_modify_args
*args
)
1934 struct interface
*ifp
;
1935 struct pim_interface
*pim_ifp
;
1937 switch (args
->event
) {
1938 case NB_EV_VALIDATE
:
1943 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1944 pim_ifp
= ifp
->info
;
1945 pim_ifp
->ucast_bsm_accept
=
1946 yang_dnode_get_bool(args
->dnode
, NULL
);
1955 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/active-active
1957 int lib_interface_pim_address_family_active_active_modify(
1958 struct nb_cb_modify_args
*args
)
1960 struct interface
*ifp
;
1961 struct pim_interface
*pim_ifp
;
1963 switch (args
->event
) {
1964 case NB_EV_VALIDATE
:
1969 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1970 pim_ifp
= ifp
->info
;
1971 if (yang_dnode_get_bool(args
->dnode
, NULL
)) {
1974 "Configuring PIM active-active on Interface: %s",
1976 pim_if_configure_mlag_dualactive(pim_ifp
);
1980 "UnConfiguring PIM active-active on Interface: %s",
1982 pim_if_unconfigure_mlag_dualactive(pim_ifp
);
1993 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/dr-priority
1995 int lib_interface_pim_address_family_dr_priority_modify(
1996 struct nb_cb_modify_args
*args
)
1998 struct interface
*ifp
;
1999 struct pim_interface
*pim_ifp
;
2000 uint32_t old_dr_prio
;
2001 const struct lyd_node
*if_dnode
;
2003 switch (args
->event
) {
2004 case NB_EV_VALIDATE
:
2005 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2006 if (!is_pim_interface(if_dnode
)) {
2007 snprintf(args
->errmsg
, args
->errmsg_len
,
2008 "Pim not enabled on this interface");
2009 return NB_ERR_VALIDATION
;
2016 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2017 pim_ifp
= ifp
->info
;
2018 old_dr_prio
= pim_ifp
->pim_dr_priority
;
2019 pim_ifp
->pim_dr_priority
= yang_dnode_get_uint32(args
->dnode
,
2022 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
2023 pim_if_dr_election(ifp
);
2024 pim_hello_restart_now(ifp
);
2033 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/use-source
2035 int lib_interface_pim_address_family_use_source_modify(
2036 struct nb_cb_modify_args
*args
)
2038 struct interface
*ifp
;
2039 pim_addr source_addr
;
2041 const struct lyd_node
*if_dnode
;
2043 switch (args
->event
) {
2044 case NB_EV_VALIDATE
:
2045 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2046 if (!is_pim_interface(if_dnode
)) {
2047 snprintf(args
->errmsg
, args
->errmsg_len
,
2048 "Pim not enabled on this interface");
2049 return NB_ERR_VALIDATION
;
2056 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2058 yang_dnode_get_ipv4(&source_addr
, args
->dnode
, NULL
);
2060 yang_dnode_get_ipv6(&source_addr
, args
->dnode
, NULL
);
2063 result
= interface_pim_use_src_cmd_worker(
2065 args
->errmsg
, args
->errmsg_len
);
2067 if (result
!= PIM_SUCCESS
)
2068 return NB_ERR_INCONSISTENCY
;
2076 int lib_interface_pim_address_family_use_source_destroy(
2077 struct nb_cb_destroy_args
*args
)
2079 struct interface
*ifp
;
2081 const struct lyd_node
*if_dnode
;
2083 switch (args
->event
) {
2084 case NB_EV_VALIDATE
:
2085 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2086 if (!is_pim_interface(if_dnode
)) {
2087 snprintf(args
->errmsg
, args
->errmsg_len
,
2088 "Pim not enabled on this interface");
2089 return NB_ERR_VALIDATION
;
2096 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2098 result
= interface_pim_use_src_cmd_worker(ifp
, PIMADDR_ANY
,
2102 if (result
!= PIM_SUCCESS
)
2103 return NB_ERR_INCONSISTENCY
;
2112 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/multicast-boundary-oil
2114 int lib_interface_pim_address_family_multicast_boundary_oil_modify(
2115 struct nb_cb_modify_args
*args
)
2117 struct interface
*ifp
;
2118 struct pim_interface
*pim_ifp
;
2120 const struct lyd_node
*if_dnode
;
2122 switch (args
->event
) {
2123 case NB_EV_VALIDATE
:
2124 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2125 if (!is_pim_interface(if_dnode
)) {
2126 snprintf(args
->errmsg
, args
->errmsg_len
,
2127 "Pim not enabled on this interface");
2128 return NB_ERR_VALIDATION
;
2135 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2136 pim_ifp
= ifp
->info
;
2137 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
2139 if (pim_ifp
->boundary_oil_plist
)
2140 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
2142 pim_ifp
->boundary_oil_plist
=
2143 XSTRDUP(MTYPE_PIM_INTERFACE
, plist
);
2151 int lib_interface_pim_address_family_multicast_boundary_oil_destroy(
2152 struct nb_cb_destroy_args
*args
)
2154 struct interface
*ifp
;
2155 struct pim_interface
*pim_ifp
;
2156 const struct lyd_node
*if_dnode
;
2158 switch (args
->event
) {
2159 case NB_EV_VALIDATE
:
2160 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2161 if (!is_pim_interface(if_dnode
)) {
2162 snprintf(args
->errmsg
, args
->errmsg_len
,
2163 "%% Enable PIM and/or IGMP on this interface first");
2164 return NB_ERR_VALIDATION
;
2171 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2172 pim_ifp
= ifp
->info
;
2173 if (pim_ifp
->boundary_oil_plist
)
2174 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
2182 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/mroute
2184 int lib_interface_pim_address_family_mroute_create(
2185 struct nb_cb_create_args
*args
)
2187 switch (args
->event
) {
2188 case NB_EV_VALIDATE
:
2198 int lib_interface_pim_address_family_mroute_destroy(
2199 struct nb_cb_destroy_args
*args
)
2201 struct pim_instance
*pim
;
2202 struct pim_interface
*pim_iifp
;
2203 struct interface
*iif
;
2204 struct interface
*oif
;
2205 const char *oifname
;
2206 pim_addr source_addr
;
2207 pim_addr group_addr
;
2208 const struct lyd_node
*if_dnode
;
2210 switch (args
->event
) {
2211 case NB_EV_VALIDATE
:
2212 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2213 if (!is_pim_interface(if_dnode
)) {
2214 snprintf(args
->errmsg
, args
->errmsg_len
,
2215 "%% Enable PIM and/or IGMP on this interface first");
2216 return NB_ERR_VALIDATION
;
2223 iif
= nb_running_get_entry(args
->dnode
, NULL
, true);
2224 pim_iifp
= iif
->info
;
2225 pim
= pim_iifp
->pim
;
2227 oifname
= yang_dnode_get_string(args
->dnode
, "./oif");
2228 oif
= if_lookup_by_name(oifname
, pim
->vrf
->vrf_id
);
2231 snprintf(args
->errmsg
, args
->errmsg_len
,
2232 "No such interface name %s",
2234 return NB_ERR_INCONSISTENCY
;
2237 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
, "./source-addr");
2238 yang_dnode_get_pimaddr(&group_addr
, args
->dnode
, "./group-addr");
2240 if (pim_static_del(pim
, iif
, oif
, group_addr
, source_addr
)) {
2241 snprintf(args
->errmsg
, args
->errmsg_len
,
2242 "Failed to remove static mroute");
2243 return NB_ERR_INCONSISTENCY
;
2253 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/mroute/oif
2255 int lib_interface_pim_address_family_mroute_oif_modify(
2256 struct nb_cb_modify_args
*args
)
2258 struct pim_instance
*pim
;
2259 struct pim_interface
*pim_iifp
;
2260 struct interface
*iif
;
2261 struct interface
*oif
;
2262 const char *oifname
;
2263 pim_addr source_addr
;
2264 pim_addr group_addr
;
2265 const struct lyd_node
*if_dnode
;
2267 switch (args
->event
) {
2268 case NB_EV_VALIDATE
:
2269 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2270 if (!is_pim_interface(if_dnode
)) {
2271 snprintf(args
->errmsg
, args
->errmsg_len
,
2272 "%% Enable PIM and/or IGMP on this interface first");
2273 return NB_ERR_VALIDATION
;
2276 #ifdef PIM_ENFORCE_LOOPFREE_MFC
2277 iif
= nb_running_get_entry(args
->dnode
, NULL
, false);
2282 pim_iifp
= iif
->info
;
2283 pim
= pim_iifp
->pim
;
2285 oifname
= yang_dnode_get_string(args
->dnode
, NULL
);
2286 oif
= if_lookup_by_name(oifname
, pim
->vrf
->vrf_id
);
2288 if (oif
&& (iif
->ifindex
== oif
->ifindex
)) {
2289 strlcpy(args
->errmsg
,
2290 "% IIF same as OIF and loopfree enforcement is enabled; rejecting",
2292 return NB_ERR_VALIDATION
;
2300 iif
= nb_running_get_entry(args
->dnode
, NULL
, true);
2301 pim_iifp
= iif
->info
;
2302 pim
= pim_iifp
->pim
;
2304 oifname
= yang_dnode_get_string(args
->dnode
, NULL
);
2305 oif
= if_lookup_by_name(oifname
, pim
->vrf
->vrf_id
);
2307 snprintf(args
->errmsg
, args
->errmsg_len
,
2308 "No such interface name %s",
2310 return NB_ERR_INCONSISTENCY
;
2313 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
, "../source-addr");
2314 yang_dnode_get_pimaddr(&group_addr
, args
->dnode
, "../group-addr");
2316 if (pim_static_add(pim
, iif
, oif
, group_addr
, source_addr
)) {
2317 snprintf(args
->errmsg
, args
->errmsg_len
,
2318 "Failed to add static mroute");
2319 return NB_ERR_INCONSISTENCY
;
2328 int lib_interface_pim_address_family_mroute_oif_destroy(
2329 struct nb_cb_destroy_args
*args
)
2331 switch (args
->event
) {
2332 case NB_EV_VALIDATE
:
2343 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/static-rp/rp-list
2345 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_create(
2346 struct nb_cb_create_args
*args
)
2348 switch (args
->event
) {
2349 case NB_EV_VALIDATE
:
2359 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_destroy(
2360 struct nb_cb_destroy_args
*args
)
2363 struct pim_instance
*pim
;
2364 struct prefix group
;
2369 switch (args
->event
) {
2370 case NB_EV_VALIDATE
:
2375 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2377 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "./rp-address");
2379 if (yang_dnode_get(args
->dnode
, "./group-list")) {
2380 yang_dnode_get_prefix(&group
, args
->dnode
,
2383 result
= pim_no_rp_cmd_worker(pim
, rp_addr
, group
, NULL
,
2388 else if (yang_dnode_get(args
->dnode
, "./prefix-list")) {
2389 plist
= yang_dnode_get_string(args
->dnode
,
2391 if (!pim_get_all_mcast_group(&group
)) {
2394 "Unable to convert 224.0.0.0/4 to prefix");
2395 return NB_ERR_INCONSISTENCY
;
2398 result
= pim_no_rp_cmd_worker(pim
, rp_addr
, group
,
2399 plist
, args
->errmsg
,
2404 return NB_ERR_INCONSISTENCY
;
2412 * 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
2414 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_group_list_create(
2415 struct nb_cb_create_args
*args
)
2418 struct pim_instance
*pim
;
2419 struct prefix group
;
2422 switch (args
->event
) {
2423 case NB_EV_VALIDATE
:
2428 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2430 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "../rp-address");
2431 yang_dnode_get_prefix(&group
, args
->dnode
, NULL
);
2433 return pim_rp_cmd_worker(pim
, rp_addr
, group
, NULL
,
2434 args
->errmsg
, args
->errmsg_len
);
2440 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_group_list_destroy(
2441 struct nb_cb_destroy_args
*args
)
2444 struct pim_instance
*pim
;
2445 struct prefix group
;
2448 switch (args
->event
) {
2449 case NB_EV_VALIDATE
:
2454 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2456 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "../rp-address");
2457 yang_dnode_get_prefix(&group
, args
->dnode
, NULL
);
2460 return pim_no_rp_cmd_worker(pim
, rp_addr
, group
, NULL
,
2461 args
->errmsg
, args
->errmsg_len
);
2468 * 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
2470 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_prefix_list_modify(
2471 struct nb_cb_modify_args
*args
)
2474 struct pim_instance
*pim
;
2475 struct prefix group
;
2479 switch (args
->event
) {
2480 case NB_EV_VALIDATE
:
2485 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2487 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
2488 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "../rp-address");
2489 if (!pim_get_all_mcast_group(&group
)) {
2490 flog_err(EC_LIB_DEVELOPMENT
,
2491 "Unable to convert 224.0.0.0/4 to prefix");
2492 return NB_ERR_INCONSISTENCY
;
2494 return pim_rp_cmd_worker(pim
, rp_addr
, group
, plist
,
2495 args
->errmsg
, args
->errmsg_len
);
2501 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_prefix_list_destroy(
2502 struct nb_cb_destroy_args
*args
)
2505 struct pim_instance
*pim
;
2506 struct prefix group
;
2510 switch (args
->event
) {
2511 case NB_EV_VALIDATE
:
2516 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2518 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "../rp-address");
2519 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
2520 if (!pim_get_all_mcast_group(&group
)) {
2521 flog_err(EC_LIB_DEVELOPMENT
,
2522 "Unable to convert 224.0.0.0/4 to prefix");
2523 return NB_ERR_INCONSISTENCY
;
2525 return pim_no_rp_cmd_worker(pim
, rp_addr
, group
, plist
,
2526 args
->errmsg
, args
->errmsg_len
);
2534 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family
2536 int lib_interface_gmp_address_family_create(struct nb_cb_create_args
*args
)
2538 switch (args
->event
) {
2539 case NB_EV_VALIDATE
:
2549 int lib_interface_gmp_address_family_destroy(struct nb_cb_destroy_args
*args
)
2551 struct interface
*ifp
;
2552 struct pim_interface
*pim_ifp
;
2554 switch (args
->event
) {
2555 case NB_EV_VALIDATE
:
2560 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2561 pim_ifp
= ifp
->info
;
2566 pim_ifp
->gm_enable
= false;
2568 pim_if_membership_clear(ifp
);
2570 pim_if_addr_del_all_igmp(ifp
);
2572 if (!pim_ifp
->pim_enable
)
2580 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/enable
2582 int lib_interface_gmp_address_family_enable_modify(
2583 struct nb_cb_modify_args
*args
)
2585 struct interface
*ifp
;
2587 struct pim_interface
*pim_ifp
;
2589 const char *ifp_name
;
2590 const struct lyd_node
*if_dnode
;
2592 switch (args
->event
) {
2593 case NB_EV_VALIDATE
:
2594 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2596 yang_get_list_elements_count(if_dnode
);
2597 /* Limiting mcast interfaces to number of VIFs */
2598 if (mcast_if_count
== MAXVIFS
) {
2599 ifp_name
= yang_dnode_get_string(if_dnode
, "name");
2601 args
->errmsg
, args
->errmsg_len
,
2602 "Max multicast interfaces(%d) Reached. Could not enable %s on interface %s",
2603 MAXVIFS
, GM
, ifp_name
);
2604 return NB_ERR_VALIDATION
;
2611 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2612 gm_enable
= yang_dnode_get_bool(args
->dnode
, NULL
);
2615 return pim_cmd_gm_start(ifp
);
2618 pim_ifp
= ifp
->info
;
2621 return NB_ERR_INCONSISTENCY
;
2623 pim_ifp
->gm_enable
= false;
2625 pim_if_membership_clear(ifp
);
2628 pim_if_addr_del_all_igmp(ifp
);
2630 gm_ifp_teardown(ifp
);
2633 if (!pim_ifp
->pim_enable
)
2641 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/igmp-version
2643 int lib_interface_gmp_address_family_igmp_version_modify(
2644 struct nb_cb_modify_args
*args
)
2646 struct interface
*ifp
;
2647 struct pim_interface
*pim_ifp
;
2648 int igmp_version
, old_version
= 0;
2650 switch (args
->event
) {
2651 case NB_EV_VALIDATE
:
2656 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2657 pim_ifp
= ifp
->info
;
2660 return NB_ERR_INCONSISTENCY
;
2662 igmp_version
= yang_dnode_get_uint8(args
->dnode
, NULL
);
2663 old_version
= pim_ifp
->igmp_version
;
2664 pim_ifp
->igmp_version
= igmp_version
;
2666 /* Current and new version is different refresh existing
2667 * membership. Going from 3 -> 2 or 2 -> 3.
2669 if (old_version
!= igmp_version
)
2670 pim_if_membership_refresh(ifp
);
2678 int lib_interface_gmp_address_family_igmp_version_destroy(
2679 struct nb_cb_destroy_args
*args
)
2681 struct interface
*ifp
;
2682 struct pim_interface
*pim_ifp
;
2684 switch (args
->event
) {
2685 case NB_EV_VALIDATE
:
2690 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2691 pim_ifp
= ifp
->info
;
2692 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
2700 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/mld-version
2702 int lib_interface_gmp_address_family_mld_version_modify(
2703 struct nb_cb_modify_args
*args
)
2705 struct interface
*ifp
;
2706 struct pim_interface
*pim_ifp
;
2708 switch (args
->event
) {
2709 case NB_EV_VALIDATE
:
2714 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2715 pim_ifp
= ifp
->info
;
2717 return NB_ERR_INCONSISTENCY
;
2719 pim_ifp
->mld_version
= yang_dnode_get_uint8(args
->dnode
, NULL
);
2727 int lib_interface_gmp_address_family_mld_version_destroy(
2728 struct nb_cb_destroy_args
*args
)
2730 struct interface
*ifp
;
2731 struct pim_interface
*pim_ifp
;
2733 switch (args
->event
) {
2734 case NB_EV_VALIDATE
:
2739 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2740 pim_ifp
= ifp
->info
;
2742 return NB_ERR_INCONSISTENCY
;
2744 pim_ifp
->mld_version
= 2;
2753 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/query-interval
2755 int lib_interface_gmp_address_family_query_interval_modify(
2756 struct nb_cb_modify_args
*args
)
2758 struct interface
*ifp
;
2762 switch (args
->event
) {
2763 case NB_EV_VALIDATE
:
2768 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2769 query_interval
= yang_dnode_get_uint16(args
->dnode
, NULL
);
2770 change_query_interval(ifp
->info
, query_interval
);
2773 struct pim_interface
*pim_ifp
;
2775 switch (args
->event
) {
2776 case NB_EV_VALIDATE
:
2781 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2782 pim_ifp
= ifp
->info
;
2784 return NB_ERR_INCONSISTENCY
;
2786 query_interval
= yang_dnode_get_uint16(args
->dnode
, NULL
);
2787 pim_ifp
->gm_default_query_interval
= query_interval
;
2795 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/query-max-response-time
2797 int lib_interface_gmp_address_family_query_max_response_time_modify(
2798 struct nb_cb_modify_args
*args
)
2801 struct interface
*ifp
;
2802 int query_max_response_time_dsec
;
2804 switch (args
->event
) {
2805 case NB_EV_VALIDATE
:
2810 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2811 query_max_response_time_dsec
=
2812 yang_dnode_get_uint16(args
->dnode
, NULL
);
2813 change_query_max_response_time(ifp
->info
,
2814 query_max_response_time_dsec
);
2817 /* TBD Depends on MLD data structure changes */
2825 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/last-member-query-interval
2827 int lib_interface_gmp_address_family_last_member_query_interval_modify(
2828 struct nb_cb_modify_args
*args
)
2831 struct interface
*ifp
;
2832 struct pim_interface
*pim_ifp
;
2833 int last_member_query_interval
;
2835 switch (args
->event
) {
2836 case NB_EV_VALIDATE
:
2841 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2842 pim_ifp
= ifp
->info
;
2843 last_member_query_interval
=
2844 yang_dnode_get_uint16(args
->dnode
, NULL
);
2845 pim_ifp
->gm_specific_query_max_response_time_dsec
=
2846 last_member_query_interval
;
2851 /* TBD Depends on MLD data structure changes */
2858 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/robustness-variable
2860 int lib_interface_gmp_address_family_robustness_variable_modify(
2861 struct nb_cb_modify_args
*args
)
2864 struct interface
*ifp
;
2865 struct pim_interface
*pim_ifp
;
2866 int last_member_query_count
;
2868 switch (args
->event
) {
2869 case NB_EV_VALIDATE
:
2874 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2875 pim_ifp
= ifp
->info
;
2876 last_member_query_count
=
2877 yang_dnode_get_uint8(args
->dnode
, NULL
);
2878 pim_ifp
->gm_last_member_query_count
= last_member_query_count
;
2883 /* TBD Depends on MLD data structure changes */
2890 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/static-group
2892 int lib_interface_gmp_address_family_static_group_create(
2893 struct nb_cb_create_args
*args
)
2896 struct interface
*ifp
;
2897 struct ipaddr source_addr
;
2898 struct ipaddr group_addr
;
2900 const char *ifp_name
;
2901 const struct lyd_node
*if_dnode
;
2903 switch (args
->event
) {
2904 case NB_EV_VALIDATE
:
2905 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2906 if (!is_pim_interface(if_dnode
)) {
2907 ifp_name
= yang_dnode_get_string(if_dnode
, "name");
2908 snprintf(args
->errmsg
, args
->errmsg_len
,
2909 "multicast not enabled on interface %s",
2911 return NB_ERR_VALIDATION
;
2914 yang_dnode_get_ip(&group_addr
, args
->dnode
, "./group-addr");
2915 if (pim_is_group_224_0_0_0_24(group_addr
.ip
._v4_addr
)) {
2917 args
->errmsg
, args
->errmsg_len
,
2918 "Groups within 224.0.0.0/24 are reserved and cannot be joined");
2919 return NB_ERR_VALIDATION
;
2926 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2927 yang_dnode_get_ip(&source_addr
, args
->dnode
, "./source-addr");
2928 yang_dnode_get_ip(&group_addr
, args
->dnode
, "./group-addr");
2930 result
= pim_if_igmp_join_add(ifp
, group_addr
.ip
._v4_addr
,
2931 source_addr
.ip
._v4_addr
);
2933 snprintf(args
->errmsg
, args
->errmsg_len
,
2934 "Failure joining IGMP group");
2935 return NB_ERR_INCONSISTENCY
;
2939 /* TBD Depends on MLD data structure changes */
2940 #endif /* PIM_IPV == 4 */
2944 int lib_interface_gmp_address_family_static_group_destroy(
2945 struct nb_cb_destroy_args
*args
)
2947 struct interface
*ifp
;
2948 struct ipaddr source_addr
;
2949 struct ipaddr group_addr
;
2952 switch (args
->event
) {
2953 case NB_EV_VALIDATE
:
2958 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2959 yang_dnode_get_ip(&source_addr
, args
->dnode
, "./source-addr");
2960 yang_dnode_get_ip(&group_addr
, args
->dnode
, "./group-addr");
2962 result
= pim_if_igmp_join_del(ifp
, group_addr
.ip
._v4_addr
,
2963 source_addr
.ip
._v4_addr
);
2966 char src_str
[INET_ADDRSTRLEN
];
2967 char grp_str
[INET_ADDRSTRLEN
];
2969 ipaddr2str(&source_addr
, src_str
, sizeof(src_str
));
2970 ipaddr2str(&group_addr
, grp_str
, sizeof(grp_str
));
2972 snprintf(args
->errmsg
, args
->errmsg_len
,
2973 "%% Failure leaving IGMP group %s %s on interface %s: %d",
2974 src_str
, grp_str
, ifp
->name
, result
);
2976 return NB_ERR_INCONSISTENCY
;