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
);
457 static void change_query_max_response_time(struct interface
*ifp
,
458 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
;
467 struct pim_interface
*pim_ifp
= ifp
->info
;
469 if (pim_ifp
->gm_query_max_response_time_dsec
==
470 query_max_response_time_dsec
)
473 pim_ifp
->gm_query_max_response_time_dsec
= query_max_response_time_dsec
;
479 * Below we modify socket/group/source timers in order to quickly
480 * reflect the change. Otherwise, those timers would args->eventually
484 /* scan all sockets */
485 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->gm_socket_list
, sock_node
, igmp
)) {
486 /* reschedule socket general query */
487 igmp_sock_query_reschedule(igmp
);
490 /* scan socket groups */
491 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->gm_group_list
, grp_node
, grp
)) {
492 struct listnode
*src_node
;
493 struct gm_source
*src
;
495 /* reset group timers for groups in EXCLUDE mode */
496 if (grp
->group_filtermode_isexcl
)
497 igmp_group_reset_gmi(grp
);
499 /* scan group sources */
500 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, src_node
,
503 /* reset source timers for sources with running
506 if (src
->t_source_timer
)
507 igmp_source_reset_gmi(grp
, src
);
510 #endif /* PIM_IPV == 4 */
513 int routing_control_plane_protocols_name_validate(
514 struct nb_cb_create_args
*args
)
518 name
= yang_dnode_get_string(args
->dnode
, "./name");
519 if (!strmatch(name
, "pim")) {
520 snprintf(args
->errmsg
, args
->errmsg_len
,
521 "pim supports only one instance with name pimd");
522 return NB_ERR_VALIDATION
;
528 * XPath: /frr-pim:pim/address-family
530 int pim_address_family_create(struct nb_cb_create_args
*args
)
532 switch (args
->event
) {
543 int pim_address_family_destroy(struct nb_cb_destroy_args
*args
)
545 switch (args
->event
) {
557 * XPath: /frr-pim:pim/address-family/packets
559 int pim_address_family_packets_modify(struct nb_cb_modify_args
*args
)
561 switch (args
->event
) {
567 router
->packet_process
= yang_dnode_get_uint8(args
->dnode
,
576 * XPath: /frr-pim:pim/address-family/join-prune-interval
578 int pim_address_family_join_prune_interval_modify(
579 struct nb_cb_modify_args
*args
)
581 switch (args
->event
) {
587 router
->t_periodic
= yang_dnode_get_uint16(args
->dnode
, NULL
);
595 * XPath: /frr-pim:pim/address-family/register-suppress-time
597 int pim_address_family_register_suppress_time_modify(
598 struct nb_cb_modify_args
*args
)
601 switch (args
->event
) {
603 value
= yang_dnode_get_uint16(args
->dnode
, NULL
);
605 * As soon as this is non-constant it needs to be replaced with
606 * a yang_dnode_get to lookup the candidate value, *not* the
607 * operational value. Since the code has a field assigned and
608 * used for this value it should have YANG/CLI to set it too,
609 * otherwise just use the #define!
611 /* RFC7761: 4.11. Timer Values */
612 if (value
<= router
->register_probe_time
* 2) {
614 args
->errmsg
, args
->errmsg_len
,
615 "Register suppress time (%u) must be more than "
616 "twice the register probe time (%u).",
617 value
, router
->register_probe_time
);
618 return NB_ERR_VALIDATION
;
625 pim_update_suppress_timers(
626 yang_dnode_get_uint16(args
->dnode
, NULL
));
634 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/ecmp
636 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ecmp_modify(
637 struct nb_cb_modify_args
*args
)
640 struct pim_instance
*pim
;
642 switch (args
->event
) {
648 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
650 pim
->ecmp_enable
= yang_dnode_get_bool(args
->dnode
, NULL
);
657 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/ecmp-rebalance
659 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ecmp_rebalance_modify(
660 struct nb_cb_modify_args
*args
)
663 struct pim_instance
*pim
;
665 switch (args
->event
) {
671 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
673 pim
->ecmp_rebalance_enable
=
674 yang_dnode_get_bool(args
->dnode
, NULL
);
681 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/keep-alive-timer
683 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_keep_alive_timer_modify(
684 struct nb_cb_modify_args
*args
)
687 struct pim_instance
*pim
;
689 switch (args
->event
) {
695 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
697 pim
->keep_alive_time
= yang_dnode_get_uint16(args
->dnode
, NULL
);
705 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/rp-keep-alive-timer
707 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_keep_alive_timer_modify(
708 struct nb_cb_modify_args
*args
)
711 struct pim_instance
*pim
;
713 switch (args
->event
) {
719 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
721 pim
->rp_keep_alive_time
= yang_dnode_get_uint16(args
->dnode
,
730 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family
732 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_create(
733 struct nb_cb_create_args
*args
)
735 switch (args
->event
) {
746 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_destroy(
747 struct nb_cb_destroy_args
*args
)
749 switch (args
->event
) {
761 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/send-v6-secondary
763 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_send_v6_secondary_modify(
764 struct nb_cb_modify_args
*args
)
767 struct pim_instance
*pim
;
769 switch (args
->event
) {
775 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
777 pim
->send_v6_secondary
= yang_dnode_get_bool(args
->dnode
, NULL
);
784 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_send_v6_secondary_destroy(
785 struct nb_cb_destroy_args
*args
)
787 switch (args
->event
) {
800 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/spt-switchover
802 void routing_control_plane_protocols_control_plane_protocol_pim_address_family_spt_switchover_apply_finish(
803 struct nb_cb_apply_finish_args
*args
)
806 struct pim_instance
*pim
;
807 int spt_switch_action
;
808 const char *prefix_list
= NULL
;
810 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
812 spt_switch_action
= yang_dnode_get_enum(args
->dnode
, "./spt-action");
814 switch (spt_switch_action
) {
815 case PIM_SPT_INFINITY
:
816 if (yang_dnode_exists(args
->dnode
,
817 "./spt-infinity-prefix-list"))
818 prefix_list
= yang_dnode_get_string(
819 args
->dnode
, "./spt-infinity-prefix-list");
821 pim_cmd_spt_switchover(pim
, PIM_SPT_INFINITY
,
824 case PIM_SPT_IMMEDIATE
:
825 pim_cmd_spt_switchover(pim
, PIM_SPT_IMMEDIATE
, NULL
);
830 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/spt-switchover/spt-action
832 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_spt_switchover_spt_action_modify(
833 struct nb_cb_modify_args
*args
)
835 switch (args
->event
) {
847 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/spt-switchover/spt-infinity-prefix-list
849 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_spt_switchover_spt_infinity_prefix_list_modify(
850 struct nb_cb_modify_args
*args
)
852 switch (args
->event
) {
863 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_spt_switchover_spt_infinity_prefix_list_destroy(
864 struct nb_cb_destroy_args
*args
)
866 switch (args
->event
) {
878 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/ssm-prefix-list
880 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_prefix_list_modify(
881 struct nb_cb_modify_args
*args
)
884 struct pim_instance
*pim
;
885 const char *plist_name
;
888 switch (args
->event
) {
894 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
896 plist_name
= yang_dnode_get_string(args
->dnode
, NULL
);
897 result
= pim_ssm_cmd_worker(pim
, plist_name
, args
->errmsg
,
901 return NB_ERR_INCONSISTENCY
;
909 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_prefix_list_destroy(
910 struct nb_cb_destroy_args
*args
)
913 struct pim_instance
*pim
;
916 switch (args
->event
) {
922 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
924 result
= pim_ssm_cmd_worker(pim
, NULL
, args
->errmsg
,
928 return NB_ERR_INCONSISTENCY
;
937 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/ssm-pingd-source-ip
939 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_pingd_source_ip_create(
940 struct nb_cb_create_args
*args
)
943 struct pim_instance
*pim
;
945 pim_addr source_addr
;
947 switch (args
->event
) {
953 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
955 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
,
957 result
= pim_ssmpingd_start(pim
, source_addr
);
960 args
->errmsg
, args
->errmsg_len
,
961 "%% Failure starting ssmpingd for source %pPA: %d",
962 &source_addr
, result
);
963 return NB_ERR_INCONSISTENCY
;
970 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_pingd_source_ip_destroy(
971 struct nb_cb_destroy_args
*args
)
974 struct pim_instance
*pim
;
976 pim_addr source_addr
;
978 switch (args
->event
) {
984 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
986 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
,
988 result
= pim_ssmpingd_stop(pim
, source_addr
);
991 args
->errmsg
, args
->errmsg_len
,
992 "%% Failure stopping ssmpingd for source %pPA: %d",
993 &source_addr
, result
);
994 return NB_ERR_INCONSISTENCY
;
1005 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/hold-time
1007 int pim_msdp_hold_time_modify(struct nb_cb_modify_args
*args
)
1009 struct pim_instance
*pim
;
1012 switch (args
->event
) {
1013 case NB_EV_VALIDATE
:
1018 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1020 pim
->msdp
.hold_time
= yang_dnode_get_uint16(args
->dnode
, NULL
);
1029 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/keep-alive
1031 int pim_msdp_keep_alive_modify(struct nb_cb_modify_args
*args
)
1033 struct pim_instance
*pim
;
1036 switch (args
->event
) {
1037 case NB_EV_VALIDATE
:
1042 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1044 pim
->msdp
.keep_alive
= yang_dnode_get_uint16(args
->dnode
, NULL
);
1053 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/connection-retry
1055 int pim_msdp_connection_retry_modify(struct nb_cb_modify_args
*args
)
1057 struct pim_instance
*pim
;
1060 switch (args
->event
) {
1061 case NB_EV_VALIDATE
:
1066 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1068 pim
->msdp
.connection_retry
=
1069 yang_dnode_get_uint16(args
->dnode
, NULL
);
1076 pim6_msdp_err(pim_msdp_mesh_group_destroy
, nb_cb_destroy_args
);
1077 pim6_msdp_err(pim_msdp_mesh_group_create
, nb_cb_create_args
);
1078 pim6_msdp_err(pim_msdp_mesh_group_source_modify
, nb_cb_modify_args
);
1079 pim6_msdp_err(pim_msdp_mesh_group_source_destroy
, nb_cb_destroy_args
);
1080 pim6_msdp_err(pim_msdp_mesh_group_members_create
, nb_cb_create_args
);
1081 pim6_msdp_err(pim_msdp_mesh_group_members_destroy
, nb_cb_destroy_args
);
1082 pim6_msdp_err(routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify
,
1084 pim6_msdp_err(routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_destroy
,
1085 nb_cb_destroy_args
);
1086 pim6_msdp_err(routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_create
,
1092 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups
1094 int pim_msdp_mesh_group_create(struct nb_cb_create_args
*args
)
1096 struct pim_msdp_mg
*mg
;
1099 switch (args
->event
) {
1100 case NB_EV_VALIDATE
:
1105 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1106 mg
= pim_msdp_mg_new(vrf
->info
, yang_dnode_get_string(
1107 args
->dnode
, "./name"));
1108 nb_running_set_entry(args
->dnode
, mg
);
1115 int pim_msdp_mesh_group_destroy(struct nb_cb_destroy_args
*args
)
1117 struct pim_msdp_mg
*mg
;
1120 switch (args
->event
) {
1121 case NB_EV_VALIDATE
:
1126 mg
= nb_running_unset_entry(args
->dnode
);
1127 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1128 pim_msdp_mg_free(vrf
->info
, &mg
);
1137 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups/source
1139 int pim_msdp_mesh_group_source_modify(struct nb_cb_modify_args
*args
)
1141 const struct lyd_node
*vrf_dnode
;
1142 struct pim_msdp_mg
*mg
;
1146 switch (args
->event
) {
1147 case NB_EV_VALIDATE
:
1152 mg
= nb_running_get_entry(args
->dnode
, NULL
, true);
1154 yang_dnode_get_parent(args
->dnode
, "address-family");
1155 vrf
= nb_running_get_entry(vrf_dnode
, "../../", true);
1156 yang_dnode_get_ip(&ip
, args
->dnode
, NULL
);
1158 pim_msdp_mg_src_add(vrf
->info
, mg
, &ip
.ip
._v4_addr
);
1164 int pim_msdp_mesh_group_source_destroy(struct nb_cb_destroy_args
*args
)
1166 const struct lyd_node
*vrf_dnode
;
1167 struct pim_msdp_mg
*mg
;
1169 struct in_addr addr
;
1171 switch (args
->event
) {
1172 case NB_EV_VALIDATE
:
1177 mg
= nb_running_get_entry(args
->dnode
, NULL
, true);
1179 yang_dnode_get_parent(args
->dnode
, "address-family");
1180 vrf
= nb_running_get_entry(vrf_dnode
, "../../", true);
1182 addr
.s_addr
= INADDR_ANY
;
1183 pim_msdp_mg_src_add(vrf
->info
, mg
, &addr
);
1192 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups/members
1194 int pim_msdp_mesh_group_members_create(struct nb_cb_create_args
*args
)
1196 const struct lyd_node
*vrf_dnode
;
1197 struct pim_msdp_mg_mbr
*mbr
;
1198 struct pim_msdp_mg
*mg
;
1202 switch (args
->event
) {
1203 case NB_EV_VALIDATE
:
1208 mg
= nb_running_get_entry(args
->dnode
, NULL
, true);
1210 yang_dnode_get_parent(args
->dnode
, "address-family");
1211 vrf
= nb_running_get_entry(vrf_dnode
, "../../", true);
1212 yang_dnode_get_ip(&ip
, args
->dnode
, "address");
1214 mbr
= pim_msdp_mg_mbr_add(vrf
->info
, mg
, &ip
.ip
._v4_addr
);
1215 nb_running_set_entry(args
->dnode
, mbr
);
1222 int pim_msdp_mesh_group_members_destroy(struct nb_cb_destroy_args
*args
)
1224 struct pim_msdp_mg_mbr
*mbr
;
1225 struct pim_msdp_mg
*mg
;
1226 const struct lyd_node
*mg_dnode
;
1228 switch (args
->event
) {
1229 case NB_EV_VALIDATE
:
1234 mbr
= nb_running_get_entry(args
->dnode
, NULL
, true);
1236 yang_dnode_get_parent(args
->dnode
, "msdp-mesh-groups");
1237 mg
= nb_running_get_entry(mg_dnode
, NULL
, true);
1238 pim_msdp_mg_mbr_del(mg
, mbr
);
1239 nb_running_unset_entry(args
->dnode
);
1247 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-peer
1249 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_create(
1250 struct nb_cb_create_args
*args
)
1252 struct pim_msdp_peer
*mp
;
1253 struct pim_instance
*pim
;
1255 struct ipaddr peer_ip
;
1256 struct ipaddr source_ip
;
1258 switch (args
->event
) {
1259 case NB_EV_VALIDATE
:
1264 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1266 yang_dnode_get_ip(&peer_ip
, args
->dnode
, "./peer-ip");
1267 yang_dnode_get_ip(&source_ip
, args
->dnode
, "./source-ip");
1268 mp
= pim_msdp_peer_add(pim
, &peer_ip
.ipaddr_v4
,
1269 &source_ip
.ipaddr_v4
, NULL
);
1270 nb_running_set_entry(args
->dnode
, mp
);
1277 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_destroy(
1278 struct nb_cb_destroy_args
*args
)
1280 struct pim_msdp_peer
*mp
;
1282 switch (args
->event
) {
1283 case NB_EV_VALIDATE
:
1288 mp
= nb_running_unset_entry(args
->dnode
);
1289 pim_msdp_peer_del(&mp
);
1297 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-peer/source-ip
1299 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify(
1300 struct nb_cb_modify_args
*args
)
1302 struct pim_msdp_peer
*mp
;
1303 struct ipaddr source_ip
;
1305 switch (args
->event
) {
1306 case NB_EV_VALIDATE
:
1311 mp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1312 yang_dnode_get_ip(&source_ip
, args
->dnode
, NULL
);
1313 pim_msdp_peer_change_source(mp
, &source_ip
.ipaddr_v4
);
1319 #endif /* PIM_IPV != 6 */
1322 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag
1324 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_create(
1325 struct nb_cb_create_args
*args
)
1327 switch (args
->event
) {
1328 case NB_EV_VALIDATE
:
1338 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_destroy(
1339 struct nb_cb_destroy_args
*args
)
1341 struct in_addr addr
;
1343 switch (args
->event
) {
1344 case NB_EV_VALIDATE
:
1350 pim_vxlan_mlag_update(true/*mlag_enable*/,
1351 false/*peer_state*/, MLAG_ROLE_NONE
,
1352 NULL
/*peerlink*/, &addr
);
1360 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag
1362 void routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_apply_finish(
1363 struct nb_cb_apply_finish_args
*args
)
1368 struct interface
*ifp
;
1369 struct ipaddr reg_addr
;
1371 ifname
= yang_dnode_get_string(args
->dnode
, "./peerlink-rif");
1372 ifp
= if_lookup_by_name(ifname
, VRF_DEFAULT
);
1374 snprintf(args
->errmsg
, args
->errmsg_len
,
1375 "No such interface name %s", ifname
);
1378 role
= yang_dnode_get_enum(args
->dnode
, "./my-role");
1379 peer_state
= yang_dnode_get_bool(args
->dnode
, "./peer-state");
1380 yang_dnode_get_ip(®_addr
, args
->dnode
, "./reg-address");
1382 pim_vxlan_mlag_update(true, peer_state
, role
, ifp
,
1383 ®_addr
.ip
._v4_addr
);
1388 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/peerlink-rif
1390 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_peerlink_rif_modify(
1391 struct nb_cb_modify_args
*args
)
1393 switch (args
->event
) {
1394 case NB_EV_VALIDATE
:
1404 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_peerlink_rif_destroy(
1405 struct nb_cb_destroy_args
*args
)
1407 switch (args
->event
) {
1408 case NB_EV_VALIDATE
:
1419 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/reg-address
1421 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_reg_address_modify(
1422 struct nb_cb_modify_args
*args
)
1424 switch (args
->event
) {
1425 case NB_EV_VALIDATE
:
1435 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_reg_address_destroy(
1436 struct nb_cb_destroy_args
*args
)
1438 switch (args
->event
) {
1439 case NB_EV_VALIDATE
:
1450 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/my-role
1452 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_my_role_modify(
1453 struct nb_cb_modify_args
*args
)
1455 switch (args
->event
) {
1456 case NB_EV_VALIDATE
:
1467 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/peer-state
1469 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_peer_state_modify(
1470 struct nb_cb_modify_args
*args
)
1472 switch (args
->event
) {
1473 case NB_EV_VALIDATE
:
1484 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/register-accept-list
1486 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_register_accept_list_modify(
1487 struct nb_cb_modify_args
*args
)
1490 struct pim_instance
*pim
;
1493 switch (args
->event
) {
1494 case NB_EV_VALIDATE
:
1499 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1501 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
1503 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
1504 pim
->register_plist
= XSTRDUP(MTYPE_PIM_PLIST_NAME
, plist
);
1512 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_register_accept_list_destroy(
1513 struct nb_cb_destroy_args
*args
)
1516 struct pim_instance
*pim
;
1518 switch (args
->event
) {
1519 case NB_EV_VALIDATE
:
1524 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1527 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
1535 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family
1537 int lib_interface_pim_address_family_create(struct nb_cb_create_args
*args
)
1539 switch (args
->event
) {
1540 case NB_EV_VALIDATE
:
1550 int lib_interface_pim_address_family_destroy(struct nb_cb_destroy_args
*args
)
1552 struct interface
*ifp
;
1553 struct pim_interface
*pim_ifp
;
1555 switch (args
->event
) {
1556 case NB_EV_VALIDATE
:
1561 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1562 pim_ifp
= ifp
->info
;
1566 if (!pim_cmd_interface_delete(ifp
)) {
1567 snprintf(args
->errmsg
, args
->errmsg_len
,
1568 "Unable to delete interface information %s",
1570 return NB_ERR_INCONSISTENCY
;
1578 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/pim-enable
1580 int lib_interface_pim_address_family_pim_enable_modify(struct nb_cb_modify_args
*args
)
1582 struct interface
*ifp
;
1583 struct pim_interface
*pim_ifp
;
1585 const struct lyd_node
*if_dnode
;
1587 switch (args
->event
) {
1588 case NB_EV_VALIDATE
:
1589 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
1591 yang_get_list_elements_count(if_dnode
);
1593 /* Limiting mcast interfaces to number of VIFs */
1594 if (mcast_if_count
== MAXVIFS
) {
1595 snprintf(args
->errmsg
, args
->errmsg_len
,
1596 "Max multicast interfaces(%d) reached.",
1598 return NB_ERR_VALIDATION
;
1605 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1607 if (yang_dnode_get_bool(args
->dnode
, NULL
)) {
1608 if (!pim_cmd_interface_add(ifp
)) {
1609 snprintf(args
->errmsg
, args
->errmsg_len
,
1610 "Could not enable PIM SM on interface %s",
1612 return NB_ERR_INCONSISTENCY
;
1615 pim_ifp
= ifp
->info
;
1617 return NB_ERR_INCONSISTENCY
;
1619 if (!pim_cmd_interface_delete(ifp
)) {
1620 snprintf(args
->errmsg
, args
->errmsg_len
,
1621 "Unable to delete interface information");
1622 return NB_ERR_INCONSISTENCY
;
1633 * /frr-interface:lib/interface/frr-pim:pim/address-family/pim-passive-enable
1635 int lib_interface_pim_address_family_pim_passive_enable_modify(
1636 struct nb_cb_modify_args
*args
)
1638 struct interface
*ifp
;
1639 struct pim_interface
*pim_ifp
;
1641 switch (args
->event
) {
1642 case NB_EV_VALIDATE
:
1647 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1648 pim_ifp
= ifp
->info
;
1649 pim_ifp
->pim_passive_enable
=
1650 yang_dnode_get_bool(args
->dnode
, NULL
);
1658 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/hello-interval
1660 int lib_interface_pim_address_family_hello_interval_modify(
1661 struct nb_cb_modify_args
*args
)
1663 struct interface
*ifp
;
1664 struct pim_interface
*pim_ifp
;
1666 switch (args
->event
) {
1667 case NB_EV_VALIDATE
:
1672 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1673 pim_ifp
= ifp
->info
;
1674 pim_ifp
->pim_hello_period
=
1675 yang_dnode_get_uint8(args
->dnode
, NULL
);
1676 pim_ifp
->pim_default_holdtime
= -1;
1684 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/hello-holdtime
1686 int lib_interface_pim_address_family_hello_holdtime_modify(
1687 struct nb_cb_modify_args
*args
)
1689 struct interface
*ifp
;
1690 struct pim_interface
*pim_ifp
;
1692 switch (args
->event
) {
1693 case NB_EV_VALIDATE
:
1698 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1699 pim_ifp
= ifp
->info
;
1700 pim_ifp
->pim_default_holdtime
=
1701 yang_dnode_get_uint16(args
->dnode
, NULL
);
1709 int lib_interface_pim_address_family_hello_holdtime_destroy(
1710 struct nb_cb_destroy_args
*args
)
1712 struct interface
*ifp
;
1713 struct pim_interface
*pim_ifp
;
1715 switch (args
->event
) {
1716 case NB_EV_VALIDATE
:
1721 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1722 pim_ifp
= ifp
->info
;
1723 pim_ifp
->pim_default_holdtime
= -1;
1730 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd
1732 int lib_interface_pim_address_family_bfd_create(struct nb_cb_create_args
*args
)
1734 struct interface
*ifp
;
1735 struct pim_interface
*pim_ifp
;
1737 switch (args
->event
) {
1738 case NB_EV_VALIDATE
:
1744 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1745 pim_ifp
= ifp
->info
;
1746 pim_ifp
->bfd_config
.enabled
= true;
1753 int lib_interface_pim_address_family_bfd_destroy(
1754 struct nb_cb_destroy_args
*args
)
1756 struct interface
*ifp
;
1757 struct pim_interface
*pim_ifp
;
1758 const struct lyd_node
*if_dnode
;
1760 switch (args
->event
) {
1761 case NB_EV_VALIDATE
:
1762 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
1763 if (!is_pim_interface(if_dnode
)) {
1764 snprintf(args
->errmsg
, args
->errmsg_len
,
1765 "Pim not enabled on this interface");
1766 return NB_ERR_VALIDATION
;
1773 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1774 pim_ifp
= ifp
->info
;
1775 pim_ifp
->bfd_config
.enabled
= false;
1776 pim_bfd_reg_dereg_all_nbr(ifp
);
1784 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd
1786 void lib_interface_pim_address_family_bfd_apply_finish(
1787 struct nb_cb_apply_finish_args
*args
)
1789 struct interface
*ifp
;
1790 struct pim_interface
*pim_ifp
;
1792 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1793 pim_ifp
= ifp
->info
;
1796 zlog_debug("Pim not enabled on this interface");
1800 pim_ifp
->bfd_config
.detection_multiplier
=
1801 yang_dnode_get_uint8(args
->dnode
, "./detect_mult");
1802 pim_ifp
->bfd_config
.min_rx
=
1803 yang_dnode_get_uint16(args
->dnode
, "./min-rx-interval");
1804 pim_ifp
->bfd_config
.min_tx
=
1805 yang_dnode_get_uint16(args
->dnode
, "./min-tx-interval");
1807 pim_bfd_reg_dereg_all_nbr(ifp
);
1811 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/min-rx-interval
1813 int lib_interface_pim_address_family_bfd_min_rx_interval_modify(
1814 struct nb_cb_modify_args
*args
)
1816 switch (args
->event
) {
1817 case NB_EV_VALIDATE
:
1828 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/min-tx-interval
1830 int lib_interface_pim_address_family_bfd_min_tx_interval_modify(
1831 struct nb_cb_modify_args
*args
)
1833 switch (args
->event
) {
1834 case NB_EV_VALIDATE
:
1845 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/detect_mult
1847 int lib_interface_pim_address_family_bfd_detect_mult_modify(
1848 struct nb_cb_modify_args
*args
)
1850 switch (args
->event
) {
1851 case NB_EV_VALIDATE
:
1862 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/profile
1864 int lib_interface_pim_address_family_bfd_profile_modify(
1865 struct nb_cb_modify_args
*args
)
1867 struct interface
*ifp
;
1868 struct pim_interface
*pim_ifp
;
1870 switch (args
->event
) {
1871 case NB_EV_VALIDATE
:
1877 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1878 pim_ifp
= ifp
->info
;
1879 XFREE(MTYPE_TMP
, pim_ifp
->bfd_config
.profile
);
1880 pim_ifp
->bfd_config
.profile
= XSTRDUP(
1881 MTYPE_TMP
, yang_dnode_get_string(args
->dnode
, NULL
));
1888 int lib_interface_pim_address_family_bfd_profile_destroy(
1889 struct nb_cb_destroy_args
*args
)
1891 struct interface
*ifp
;
1892 struct pim_interface
*pim_ifp
;
1894 switch (args
->event
) {
1895 case NB_EV_VALIDATE
:
1901 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1902 pim_ifp
= ifp
->info
;
1903 XFREE(MTYPE_TMP
, pim_ifp
->bfd_config
.profile
);
1911 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bsm
1913 int lib_interface_pim_address_family_bsm_modify(struct nb_cb_modify_args
*args
)
1915 struct interface
*ifp
;
1916 struct pim_interface
*pim_ifp
;
1918 switch (args
->event
) {
1919 case NB_EV_VALIDATE
:
1924 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1925 pim_ifp
= ifp
->info
;
1926 pim_ifp
->bsm_enable
= yang_dnode_get_bool(args
->dnode
, NULL
);
1935 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/unicast-bsm
1937 int lib_interface_pim_address_family_unicast_bsm_modify(
1938 struct nb_cb_modify_args
*args
)
1940 struct interface
*ifp
;
1941 struct pim_interface
*pim_ifp
;
1943 switch (args
->event
) {
1944 case NB_EV_VALIDATE
:
1949 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1950 pim_ifp
= ifp
->info
;
1951 pim_ifp
->ucast_bsm_accept
=
1952 yang_dnode_get_bool(args
->dnode
, NULL
);
1961 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/active-active
1963 int lib_interface_pim_address_family_active_active_modify(
1964 struct nb_cb_modify_args
*args
)
1966 struct interface
*ifp
;
1967 struct pim_interface
*pim_ifp
;
1969 switch (args
->event
) {
1970 case NB_EV_VALIDATE
:
1975 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1976 pim_ifp
= ifp
->info
;
1977 if (yang_dnode_get_bool(args
->dnode
, NULL
)) {
1980 "Configuring PIM active-active on Interface: %s",
1982 pim_if_configure_mlag_dualactive(pim_ifp
);
1986 "UnConfiguring PIM active-active on Interface: %s",
1988 pim_if_unconfigure_mlag_dualactive(pim_ifp
);
1999 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/dr-priority
2001 int lib_interface_pim_address_family_dr_priority_modify(
2002 struct nb_cb_modify_args
*args
)
2004 struct interface
*ifp
;
2005 struct pim_interface
*pim_ifp
;
2006 uint32_t old_dr_prio
;
2007 const struct lyd_node
*if_dnode
;
2009 switch (args
->event
) {
2010 case NB_EV_VALIDATE
:
2011 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2012 if (!is_pim_interface(if_dnode
)) {
2013 snprintf(args
->errmsg
, args
->errmsg_len
,
2014 "Pim not enabled on this interface");
2015 return NB_ERR_VALIDATION
;
2022 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2023 pim_ifp
= ifp
->info
;
2024 old_dr_prio
= pim_ifp
->pim_dr_priority
;
2025 pim_ifp
->pim_dr_priority
= yang_dnode_get_uint32(args
->dnode
,
2028 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
2029 pim_if_dr_election(ifp
);
2030 pim_hello_restart_now(ifp
);
2039 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/use-source
2041 int lib_interface_pim_address_family_use_source_modify(
2042 struct nb_cb_modify_args
*args
)
2044 struct interface
*ifp
;
2045 pim_addr source_addr
;
2047 const struct lyd_node
*if_dnode
;
2049 switch (args
->event
) {
2050 case NB_EV_VALIDATE
:
2051 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2052 if (!is_pim_interface(if_dnode
)) {
2053 snprintf(args
->errmsg
, args
->errmsg_len
,
2054 "Pim not enabled on this interface");
2055 return NB_ERR_VALIDATION
;
2062 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2064 yang_dnode_get_ipv4(&source_addr
, args
->dnode
, NULL
);
2066 yang_dnode_get_ipv6(&source_addr
, args
->dnode
, NULL
);
2069 result
= interface_pim_use_src_cmd_worker(
2071 args
->errmsg
, args
->errmsg_len
);
2073 if (result
!= PIM_SUCCESS
)
2074 return NB_ERR_INCONSISTENCY
;
2082 int lib_interface_pim_address_family_use_source_destroy(
2083 struct nb_cb_destroy_args
*args
)
2085 struct interface
*ifp
;
2087 const struct lyd_node
*if_dnode
;
2089 switch (args
->event
) {
2090 case NB_EV_VALIDATE
:
2091 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2092 if (!is_pim_interface(if_dnode
)) {
2093 snprintf(args
->errmsg
, args
->errmsg_len
,
2094 "Pim not enabled on this interface");
2095 return NB_ERR_VALIDATION
;
2102 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2104 result
= interface_pim_use_src_cmd_worker(ifp
, PIMADDR_ANY
,
2108 if (result
!= PIM_SUCCESS
)
2109 return NB_ERR_INCONSISTENCY
;
2118 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/multicast-boundary-oil
2120 int lib_interface_pim_address_family_multicast_boundary_oil_modify(
2121 struct nb_cb_modify_args
*args
)
2123 struct interface
*ifp
;
2124 struct pim_interface
*pim_ifp
;
2126 const struct lyd_node
*if_dnode
;
2128 switch (args
->event
) {
2129 case NB_EV_VALIDATE
:
2130 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2131 if (!is_pim_interface(if_dnode
)) {
2132 snprintf(args
->errmsg
, args
->errmsg_len
,
2133 "Pim not enabled on this interface");
2134 return NB_ERR_VALIDATION
;
2141 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2142 pim_ifp
= ifp
->info
;
2143 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
2145 if (pim_ifp
->boundary_oil_plist
)
2146 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
2148 pim_ifp
->boundary_oil_plist
=
2149 XSTRDUP(MTYPE_PIM_INTERFACE
, plist
);
2157 int lib_interface_pim_address_family_multicast_boundary_oil_destroy(
2158 struct nb_cb_destroy_args
*args
)
2160 struct interface
*ifp
;
2161 struct pim_interface
*pim_ifp
;
2162 const struct lyd_node
*if_dnode
;
2164 switch (args
->event
) {
2165 case NB_EV_VALIDATE
:
2166 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2167 if (!is_pim_interface(if_dnode
)) {
2168 snprintf(args
->errmsg
, args
->errmsg_len
,
2169 "%% Enable PIM and/or IGMP on this interface first");
2170 return NB_ERR_VALIDATION
;
2177 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2178 pim_ifp
= ifp
->info
;
2179 if (pim_ifp
->boundary_oil_plist
)
2180 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
2188 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/mroute
2190 int lib_interface_pim_address_family_mroute_create(
2191 struct nb_cb_create_args
*args
)
2193 switch (args
->event
) {
2194 case NB_EV_VALIDATE
:
2204 int lib_interface_pim_address_family_mroute_destroy(
2205 struct nb_cb_destroy_args
*args
)
2207 struct pim_instance
*pim
;
2208 struct pim_interface
*pim_iifp
;
2209 struct interface
*iif
;
2210 struct interface
*oif
;
2211 const char *oifname
;
2212 pim_addr source_addr
;
2213 pim_addr group_addr
;
2214 const struct lyd_node
*if_dnode
;
2216 switch (args
->event
) {
2217 case NB_EV_VALIDATE
:
2218 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2219 if (!is_pim_interface(if_dnode
)) {
2220 snprintf(args
->errmsg
, args
->errmsg_len
,
2221 "%% Enable PIM and/or IGMP on this interface first");
2222 return NB_ERR_VALIDATION
;
2229 iif
= nb_running_get_entry(args
->dnode
, NULL
, true);
2230 pim_iifp
= iif
->info
;
2231 pim
= pim_iifp
->pim
;
2233 oifname
= yang_dnode_get_string(args
->dnode
, "./oif");
2234 oif
= if_lookup_by_name(oifname
, pim
->vrf
->vrf_id
);
2237 snprintf(args
->errmsg
, args
->errmsg_len
,
2238 "No such interface name %s",
2240 return NB_ERR_INCONSISTENCY
;
2243 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
, "./source-addr");
2244 yang_dnode_get_pimaddr(&group_addr
, args
->dnode
, "./group-addr");
2246 if (pim_static_del(pim
, iif
, oif
, group_addr
, source_addr
)) {
2247 snprintf(args
->errmsg
, args
->errmsg_len
,
2248 "Failed to remove static mroute");
2249 return NB_ERR_INCONSISTENCY
;
2259 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/mroute/oif
2261 int lib_interface_pim_address_family_mroute_oif_modify(
2262 struct nb_cb_modify_args
*args
)
2264 struct pim_instance
*pim
;
2265 struct pim_interface
*pim_iifp
;
2266 struct interface
*iif
;
2267 struct interface
*oif
;
2268 const char *oifname
;
2269 pim_addr source_addr
;
2270 pim_addr group_addr
;
2271 const struct lyd_node
*if_dnode
;
2273 switch (args
->event
) {
2274 case NB_EV_VALIDATE
:
2275 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2276 if (!is_pim_interface(if_dnode
)) {
2277 snprintf(args
->errmsg
, args
->errmsg_len
,
2278 "%% Enable PIM and/or IGMP on this interface first");
2279 return NB_ERR_VALIDATION
;
2282 #ifdef PIM_ENFORCE_LOOPFREE_MFC
2283 iif
= nb_running_get_entry(args
->dnode
, NULL
, false);
2288 pim_iifp
= iif
->info
;
2289 pim
= pim_iifp
->pim
;
2291 oifname
= yang_dnode_get_string(args
->dnode
, NULL
);
2292 oif
= if_lookup_by_name(oifname
, pim
->vrf
->vrf_id
);
2294 if (oif
&& (iif
->ifindex
== oif
->ifindex
)) {
2295 strlcpy(args
->errmsg
,
2296 "% IIF same as OIF and loopfree enforcement is enabled; rejecting",
2298 return NB_ERR_VALIDATION
;
2306 iif
= nb_running_get_entry(args
->dnode
, NULL
, true);
2307 pim_iifp
= iif
->info
;
2308 pim
= pim_iifp
->pim
;
2310 oifname
= yang_dnode_get_string(args
->dnode
, NULL
);
2311 oif
= if_lookup_by_name(oifname
, pim
->vrf
->vrf_id
);
2313 snprintf(args
->errmsg
, args
->errmsg_len
,
2314 "No such interface name %s",
2316 return NB_ERR_INCONSISTENCY
;
2319 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
, "../source-addr");
2320 yang_dnode_get_pimaddr(&group_addr
, args
->dnode
, "../group-addr");
2322 if (pim_static_add(pim
, iif
, oif
, group_addr
, source_addr
)) {
2323 snprintf(args
->errmsg
, args
->errmsg_len
,
2324 "Failed to add static mroute");
2325 return NB_ERR_INCONSISTENCY
;
2334 int lib_interface_pim_address_family_mroute_oif_destroy(
2335 struct nb_cb_destroy_args
*args
)
2337 switch (args
->event
) {
2338 case NB_EV_VALIDATE
:
2349 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/static-rp/rp-list
2351 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_create(
2352 struct nb_cb_create_args
*args
)
2354 switch (args
->event
) {
2355 case NB_EV_VALIDATE
:
2365 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_destroy(
2366 struct nb_cb_destroy_args
*args
)
2369 struct pim_instance
*pim
;
2370 struct prefix group
;
2375 switch (args
->event
) {
2376 case NB_EV_VALIDATE
:
2381 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2383 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "./rp-address");
2385 if (yang_dnode_get(args
->dnode
, "./group-list")) {
2386 yang_dnode_get_prefix(&group
, args
->dnode
,
2389 result
= pim_no_rp_cmd_worker(pim
, rp_addr
, group
, NULL
,
2394 else if (yang_dnode_get(args
->dnode
, "./prefix-list")) {
2395 plist
= yang_dnode_get_string(args
->dnode
,
2397 if (!pim_get_all_mcast_group(&group
)) {
2400 "Unable to convert 224.0.0.0/4 to prefix");
2401 return NB_ERR_INCONSISTENCY
;
2404 result
= pim_no_rp_cmd_worker(pim
, rp_addr
, group
,
2405 plist
, args
->errmsg
,
2410 return NB_ERR_INCONSISTENCY
;
2418 * 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
2420 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_group_list_create(
2421 struct nb_cb_create_args
*args
)
2424 struct pim_instance
*pim
;
2425 struct prefix group
;
2428 switch (args
->event
) {
2429 case NB_EV_VALIDATE
:
2434 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2436 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "../rp-address");
2437 yang_dnode_get_prefix(&group
, args
->dnode
, NULL
);
2439 return pim_rp_cmd_worker(pim
, rp_addr
, group
, NULL
,
2440 args
->errmsg
, args
->errmsg_len
);
2446 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_group_list_destroy(
2447 struct nb_cb_destroy_args
*args
)
2450 struct pim_instance
*pim
;
2451 struct prefix group
;
2454 switch (args
->event
) {
2455 case NB_EV_VALIDATE
:
2460 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2462 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "../rp-address");
2463 yang_dnode_get_prefix(&group
, args
->dnode
, NULL
);
2466 return pim_no_rp_cmd_worker(pim
, rp_addr
, group
, NULL
,
2467 args
->errmsg
, args
->errmsg_len
);
2474 * 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
2476 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_prefix_list_modify(
2477 struct nb_cb_modify_args
*args
)
2480 struct pim_instance
*pim
;
2481 struct prefix group
;
2485 switch (args
->event
) {
2486 case NB_EV_VALIDATE
:
2491 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2493 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
2494 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "../rp-address");
2495 if (!pim_get_all_mcast_group(&group
)) {
2496 flog_err(EC_LIB_DEVELOPMENT
,
2497 "Unable to convert 224.0.0.0/4 to prefix");
2498 return NB_ERR_INCONSISTENCY
;
2500 return pim_rp_cmd_worker(pim
, rp_addr
, group
, plist
,
2501 args
->errmsg
, args
->errmsg_len
);
2507 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_prefix_list_destroy(
2508 struct nb_cb_destroy_args
*args
)
2511 struct pim_instance
*pim
;
2512 struct prefix group
;
2516 switch (args
->event
) {
2517 case NB_EV_VALIDATE
:
2522 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2524 yang_dnode_get_pimaddr(&rp_addr
, args
->dnode
, "../rp-address");
2525 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
2526 if (!pim_get_all_mcast_group(&group
)) {
2527 flog_err(EC_LIB_DEVELOPMENT
,
2528 "Unable to convert 224.0.0.0/4 to prefix");
2529 return NB_ERR_INCONSISTENCY
;
2531 return pim_no_rp_cmd_worker(pim
, rp_addr
, group
, plist
,
2532 args
->errmsg
, args
->errmsg_len
);
2540 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family
2542 int lib_interface_gmp_address_family_create(struct nb_cb_create_args
*args
)
2544 switch (args
->event
) {
2545 case NB_EV_VALIDATE
:
2555 int lib_interface_gmp_address_family_destroy(struct nb_cb_destroy_args
*args
)
2557 struct interface
*ifp
;
2558 struct pim_interface
*pim_ifp
;
2560 switch (args
->event
) {
2561 case NB_EV_VALIDATE
:
2566 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2567 pim_ifp
= ifp
->info
;
2572 pim_ifp
->gm_enable
= false;
2574 pim_if_membership_clear(ifp
);
2576 pim_if_addr_del_all_igmp(ifp
);
2578 if (!pim_ifp
->pim_enable
)
2586 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/enable
2588 int lib_interface_gmp_address_family_enable_modify(
2589 struct nb_cb_modify_args
*args
)
2591 struct interface
*ifp
;
2593 struct pim_interface
*pim_ifp
;
2595 const char *ifp_name
;
2596 const struct lyd_node
*if_dnode
;
2598 switch (args
->event
) {
2599 case NB_EV_VALIDATE
:
2600 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2602 yang_get_list_elements_count(if_dnode
);
2603 /* Limiting mcast interfaces to number of VIFs */
2604 if (mcast_if_count
== MAXVIFS
) {
2605 ifp_name
= yang_dnode_get_string(if_dnode
, "name");
2607 args
->errmsg
, args
->errmsg_len
,
2608 "Max multicast interfaces(%d) Reached. Could not enable %s on interface %s",
2609 MAXVIFS
, GM
, ifp_name
);
2610 return NB_ERR_VALIDATION
;
2617 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2618 gm_enable
= yang_dnode_get_bool(args
->dnode
, NULL
);
2621 return pim_cmd_gm_start(ifp
);
2624 pim_ifp
= ifp
->info
;
2627 return NB_ERR_INCONSISTENCY
;
2629 pim_ifp
->gm_enable
= false;
2631 pim_if_membership_clear(ifp
);
2634 pim_if_addr_del_all_igmp(ifp
);
2636 gm_ifp_teardown(ifp
);
2639 if (!pim_ifp
->pim_enable
)
2647 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/igmp-version
2649 int lib_interface_gmp_address_family_igmp_version_modify(
2650 struct nb_cb_modify_args
*args
)
2652 struct interface
*ifp
;
2653 struct pim_interface
*pim_ifp
;
2654 int igmp_version
, old_version
= 0;
2656 switch (args
->event
) {
2657 case NB_EV_VALIDATE
:
2662 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2663 pim_ifp
= ifp
->info
;
2666 return NB_ERR_INCONSISTENCY
;
2668 igmp_version
= yang_dnode_get_uint8(args
->dnode
, NULL
);
2669 old_version
= pim_ifp
->igmp_version
;
2670 pim_ifp
->igmp_version
= igmp_version
;
2672 /* Current and new version is different refresh existing
2673 * membership. Going from 3 -> 2 or 2 -> 3.
2675 if (old_version
!= igmp_version
)
2676 pim_if_membership_refresh(ifp
);
2684 int lib_interface_gmp_address_family_igmp_version_destroy(
2685 struct nb_cb_destroy_args
*args
)
2687 struct interface
*ifp
;
2688 struct pim_interface
*pim_ifp
;
2690 switch (args
->event
) {
2691 case NB_EV_VALIDATE
:
2696 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2697 pim_ifp
= ifp
->info
;
2698 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
2706 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/mld-version
2708 int lib_interface_gmp_address_family_mld_version_modify(
2709 struct nb_cb_modify_args
*args
)
2711 struct interface
*ifp
;
2712 struct pim_interface
*pim_ifp
;
2714 switch (args
->event
) {
2715 case NB_EV_VALIDATE
:
2720 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2721 pim_ifp
= ifp
->info
;
2723 return NB_ERR_INCONSISTENCY
;
2725 pim_ifp
->mld_version
= yang_dnode_get_uint8(args
->dnode
, NULL
);
2733 int lib_interface_gmp_address_family_mld_version_destroy(
2734 struct nb_cb_destroy_args
*args
)
2736 struct interface
*ifp
;
2737 struct pim_interface
*pim_ifp
;
2739 switch (args
->event
) {
2740 case NB_EV_VALIDATE
:
2745 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2746 pim_ifp
= ifp
->info
;
2748 return NB_ERR_INCONSISTENCY
;
2750 pim_ifp
->mld_version
= 2;
2759 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/query-interval
2761 int lib_interface_gmp_address_family_query_interval_modify(
2762 struct nb_cb_modify_args
*args
)
2764 struct interface
*ifp
;
2768 switch (args
->event
) {
2769 case NB_EV_VALIDATE
:
2774 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2775 query_interval
= yang_dnode_get_uint16(args
->dnode
, NULL
);
2776 change_query_interval(ifp
->info
, query_interval
);
2779 struct pim_interface
*pim_ifp
;
2781 switch (args
->event
) {
2782 case NB_EV_VALIDATE
:
2787 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2788 pim_ifp
= ifp
->info
;
2790 return NB_ERR_INCONSISTENCY
;
2792 query_interval
= yang_dnode_get_uint16(args
->dnode
, NULL
);
2793 pim_ifp
->gm_default_query_interval
= query_interval
;
2801 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/query-max-response-time
2803 int lib_interface_gmp_address_family_query_max_response_time_modify(
2804 struct nb_cb_modify_args
*args
)
2806 struct interface
*ifp
;
2807 int query_max_response_time_dsec
;
2809 switch (args
->event
) {
2810 case NB_EV_VALIDATE
:
2815 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2816 query_max_response_time_dsec
=
2817 yang_dnode_get_uint16(args
->dnode
, NULL
);
2818 change_query_max_response_time(ifp
,
2819 query_max_response_time_dsec
);
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
)
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
;
2855 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/robustness-variable
2857 int lib_interface_gmp_address_family_robustness_variable_modify(
2858 struct nb_cb_modify_args
*args
)
2860 struct interface
*ifp
;
2861 struct pim_interface
*pim_ifp
;
2862 int last_member_query_count
;
2864 switch (args
->event
) {
2865 case NB_EV_VALIDATE
:
2870 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2871 pim_ifp
= ifp
->info
;
2872 last_member_query_count
=
2873 yang_dnode_get_uint8(args
->dnode
, NULL
);
2874 pim_ifp
->gm_last_member_query_count
= last_member_query_count
;
2883 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/static-group
2885 int lib_interface_gmp_address_family_static_group_create(
2886 struct nb_cb_create_args
*args
)
2889 struct interface
*ifp
;
2890 struct ipaddr source_addr
;
2891 struct ipaddr group_addr
;
2893 const char *ifp_name
;
2894 const struct lyd_node
*if_dnode
;
2896 switch (args
->event
) {
2897 case NB_EV_VALIDATE
:
2898 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2899 if (!is_pim_interface(if_dnode
)) {
2900 ifp_name
= yang_dnode_get_string(if_dnode
, "name");
2901 snprintf(args
->errmsg
, args
->errmsg_len
,
2902 "multicast not enabled on interface %s",
2904 return NB_ERR_VALIDATION
;
2907 yang_dnode_get_ip(&group_addr
, args
->dnode
, "./group-addr");
2908 if (pim_is_group_224_0_0_0_24(group_addr
.ip
._v4_addr
)) {
2910 args
->errmsg
, args
->errmsg_len
,
2911 "Groups within 224.0.0.0/24 are reserved and cannot be joined");
2912 return NB_ERR_VALIDATION
;
2919 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2920 yang_dnode_get_ip(&source_addr
, args
->dnode
, "./source-addr");
2921 yang_dnode_get_ip(&group_addr
, args
->dnode
, "./group-addr");
2923 result
= pim_if_igmp_join_add(ifp
, group_addr
.ip
._v4_addr
,
2924 source_addr
.ip
._v4_addr
);
2926 snprintf(args
->errmsg
, args
->errmsg_len
,
2927 "Failure joining IGMP group");
2928 return NB_ERR_INCONSISTENCY
;
2932 /* TBD Depends on MLD data structure changes */
2933 #endif /* PIM_IPV == 4 */
2937 int lib_interface_gmp_address_family_static_group_destroy(
2938 struct nb_cb_destroy_args
*args
)
2940 struct interface
*ifp
;
2941 struct ipaddr source_addr
;
2942 struct ipaddr group_addr
;
2945 switch (args
->event
) {
2946 case NB_EV_VALIDATE
:
2951 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2952 yang_dnode_get_ip(&source_addr
, args
->dnode
, "./source-addr");
2953 yang_dnode_get_ip(&group_addr
, args
->dnode
, "./group-addr");
2955 result
= pim_if_igmp_join_del(ifp
, group_addr
.ip
._v4_addr
,
2956 source_addr
.ip
._v4_addr
);
2959 char src_str
[INET_ADDRSTRLEN
];
2960 char grp_str
[INET_ADDRSTRLEN
];
2962 ipaddr2str(&source_addr
, src_str
, sizeof(src_str
));
2963 ipaddr2str(&group_addr
, grp_str
, sizeof(grp_str
));
2965 snprintf(args
->errmsg
, args
->errmsg_len
,
2966 "%% Failure leaving IGMP group %s %s on interface %s: %d",
2967 src_str
, grp_str
, ifp
->name
, result
);
2969 return NB_ERR_INCONSISTENCY
;