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"
39 #define pim6_msdp_err(funcname, argtype) \
40 int funcname(struct argtype *args) \
42 snprintf(args->errmsg, args->errmsg_len, \
43 "Trying to configure MSDP in pim6d. " \
44 "MSDP does not exist for IPv6."); \
45 return NB_ERR_VALIDATION; \
47 MACRO_REQUIRE_SEMICOLON()
49 #define yang_dnode_get_pimaddr yang_dnode_get_ipv6
51 #else /* PIM_IPV != 6 */
52 #define pim6_msdp_err(funcname, argtype) \
53 MACRO_REQUIRE_SEMICOLON()
55 #define yang_dnode_get_pimaddr yang_dnode_get_ipv4
56 #endif /* PIM_IPV != 6 */
58 static void pim_if_membership_clear(struct interface
*ifp
)
60 struct pim_interface
*pim_ifp
;
65 if (PIM_IF_TEST_PIM(pim_ifp
->options
)
66 && PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
70 pim_ifchannel_membership_clear(ifp
);
74 * When PIM is disabled on interface, IGMPv3 local membership
75 * information is not injected into PIM interface state.
77 * The function pim_if_membership_refresh() fetches all IGMPv3 local
78 * membership information into PIM. It is intented to be called
79 * whenever PIM is enabled on the interface in order to collect missed
80 * local membership information.
82 static void pim_if_membership_refresh(struct interface
*ifp
)
84 struct pim_interface
*pim_ifp
;
85 struct listnode
*grpnode
;
92 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
94 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
))
98 * First clear off membership from all PIM (S,G) entries on the
102 pim_ifchannel_membership_clear(ifp
);
105 * Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
109 /* scan igmp groups */
110 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->gm_group_list
, grpnode
, grp
)) {
111 struct listnode
*srcnode
;
112 struct gm_source
*src
;
114 /* scan group sources */
115 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, srcnode
,
118 if (IGMP_SOURCE_TEST_FORWARDING(src
->source_flags
)) {
121 memset(&sg
, 0, sizeof(sg
));
122 sg
.src
= src
->source_addr
;
123 sg
.grp
= grp
->group_addr
;
124 pim_ifchannel_local_membership_add(
125 ifp
, &sg
, false /*is_vxlan*/);
128 } /* scan group sources */
129 } /* scan igmp groups */
132 * Finally delete every PIM (S,G) entry lacking all state info
135 pim_ifchannel_delete_on_noinfo(ifp
);
138 static int pim_cmd_interface_add(struct interface
*ifp
)
140 struct pim_interface
*pim_ifp
= ifp
->info
;
143 pim_ifp
= pim_if_new(ifp
, false, true, false, false);
145 PIM_IF_DO_PIM(pim_ifp
->options
);
147 pim_if_addr_add_all(ifp
);
148 pim_if_membership_refresh(ifp
);
150 pim_if_create_pimreg(pim_ifp
->pim
);
154 static int pim_cmd_interface_delete(struct interface
*ifp
)
156 struct pim_interface
*pim_ifp
= ifp
->info
;
161 PIM_IF_DONT_PIM(pim_ifp
->options
);
163 pim_if_membership_clear(ifp
);
166 * pim_sock_delete() removes all neighbors from
167 * pim_ifp->pim_neighbor_list.
169 pim_sock_delete(ifp
, "pim unconfigured on interface");
171 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
172 pim_if_addr_del_all(ifp
);
179 static int interface_pim_use_src_cmd_worker(struct interface
*ifp
,
180 pim_addr source_addr
, char *errmsg
, size_t errmsg_len
)
185 result
= pim_update_source_set(ifp
, source_addr
);
190 case PIM_IFACE_NOT_FOUND
:
192 snprintf(errmsg
, errmsg_len
,
193 "Pim not enabled on this interface %s",
196 case PIM_UPDATE_SOURCE_DUP
:
198 snprintf(errmsg
, errmsg_len
, "Source already set");
202 snprintf(errmsg
, errmsg_len
, "Source set failed");
208 static int pim_cmd_spt_switchover(struct pim_instance
*pim
,
209 enum pim_spt_switchover spt
,
212 pim
->spt
.switchover
= spt
;
214 switch (pim
->spt
.switchover
) {
215 case PIM_SPT_IMMEDIATE
:
216 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->spt
.plist
);
218 pim_upstream_add_lhr_star_pimreg(pim
);
220 case PIM_SPT_INFINITY
:
221 pim_upstream_remove_lhr_star_pimreg(pim
, plist
);
223 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->spt
.plist
);
226 pim
->spt
.plist
= XSTRDUP(MTYPE_PIM_PLIST_NAME
, plist
);
233 static int pim_ssm_cmd_worker(struct pim_instance
*pim
, const char *plist
,
234 char *errmsg
, size_t errmsg_len
)
236 int result
= pim_ssm_range_set(pim
, pim
->vrf
->vrf_id
, plist
);
239 if (result
== PIM_SSM_ERR_NONE
)
243 case PIM_SSM_ERR_NO_VRF
:
244 snprintf(errmsg
, errmsg_len
,
245 "VRF doesn't exist");
247 case PIM_SSM_ERR_DUP
:
248 snprintf(errmsg
, errmsg_len
,
252 snprintf(errmsg
, errmsg_len
,
253 "ssm range config failed");
259 static int pim_rp_cmd_worker(struct pim_instance
*pim
,
260 struct in_addr rp_addr
,
261 struct prefix group
, const char *plist
,
262 char *errmsg
, size_t errmsg_len
)
264 char rp_str
[INET_ADDRSTRLEN
];
267 inet_ntop(AF_INET
, &rp_addr
, rp_str
, sizeof(rp_str
));
269 result
= pim_rp_new(pim
, rp_addr
, group
, plist
, RP_SRC_STATIC
);
271 if (result
== PIM_RP_NO_PATH
) {
272 snprintf(errmsg
, errmsg_len
,
273 "No Path to RP address specified: %s", rp_str
);
274 return NB_ERR_INCONSISTENCY
;
277 if (result
== PIM_GROUP_OVERLAP
) {
278 snprintf(errmsg
, errmsg_len
,
279 "Group range specified cannot exact match another");
280 return NB_ERR_INCONSISTENCY
;
283 if (result
== PIM_GROUP_PFXLIST_OVERLAP
) {
284 snprintf(errmsg
, errmsg_len
,
285 "This group is already covered by a RP prefix-list");
286 return NB_ERR_INCONSISTENCY
;
289 if (result
== PIM_RP_PFXLIST_IN_USE
) {
290 snprintf(errmsg
, errmsg_len
,
291 "The same prefix-list cannot be applied to multiple RPs");
292 return NB_ERR_INCONSISTENCY
;
298 static int pim_no_rp_cmd_worker(struct pim_instance
*pim
,
299 struct in_addr rp_addr
, struct prefix group
,
301 char *errmsg
, size_t errmsg_len
)
303 char rp_str
[INET_ADDRSTRLEN
];
304 char group_str
[PREFIX2STR_BUFFER
];
307 inet_ntop(AF_INET
, &rp_addr
, rp_str
, sizeof(rp_str
));
308 prefix2str(&group
, group_str
, sizeof(group_str
));
310 result
= pim_rp_del(pim
, rp_addr
, group
, plist
, RP_SRC_STATIC
);
312 if (result
== PIM_GROUP_BAD_ADDRESS
) {
313 snprintf(errmsg
, errmsg_len
,
314 "Bad group address specified: %s", group_str
);
315 return NB_ERR_INCONSISTENCY
;
318 if (result
== PIM_RP_BAD_ADDRESS
) {
319 snprintf(errmsg
, errmsg_len
,
320 "Bad RP address specified: %s", rp_str
);
321 return NB_ERR_INCONSISTENCY
;
324 if (result
== PIM_RP_NOT_FOUND
) {
325 snprintf(errmsg
, errmsg_len
,
326 "Unable to find specified RP");
327 return NB_ERR_INCONSISTENCY
;
333 static bool is_pim_interface(const struct lyd_node
*dnode
)
335 char if_xpath
[XPATH_MAXLEN
];
336 const struct lyd_node
*pim_enable_dnode
;
337 const struct lyd_node
*igmp_enable_dnode
;
339 yang_dnode_get_path(dnode
, if_xpath
, sizeof(if_xpath
));
341 yang_dnode_getf(dnode
,
342 "%s/frr-pim:pim/address-family[address-family='%s']/pim-enable",
343 if_xpath
, "frr-routing:ipv4");
344 igmp_enable_dnode
= yang_dnode_getf(dnode
,
345 "%s/frr-gmp:gmp/address-family[address-family='%s']/enable",
346 if_xpath
, "frr-routing:ipv4");
348 if (((pim_enable_dnode
) &&
349 (yang_dnode_get_bool(pim_enable_dnode
, "."))) ||
350 ((igmp_enable_dnode
) &&
351 (yang_dnode_get_bool(igmp_enable_dnode
, "."))))
357 static int pim_cmd_igmp_start(struct interface
*ifp
)
359 struct pim_interface
*pim_ifp
;
360 uint8_t need_startup
= 0;
365 pim_ifp
= pim_if_new(ifp
, true, false, false, false);
368 if (!PIM_IF_TEST_IGMP(pim_ifp
->options
)) {
369 PIM_IF_DO_IGMP(pim_ifp
->options
);
373 pim_if_create_pimreg(pim_ifp
->pim
);
375 /* 'ip igmp' executed multiple times, with need_startup
376 * avoid multiple if add all and membership refresh
379 pim_if_addr_add_all(ifp
);
380 pim_if_membership_refresh(ifp
);
387 * CLI reconfiguration affects the interface level (struct pim_interface).
388 * This function propagates the reconfiguration to every active socket
389 * for that interface.
391 static void igmp_sock_query_interval_reconfig(struct gm_sock
*igmp
)
393 struct interface
*ifp
;
394 struct pim_interface
*pim_ifp
;
397 assert(igmp
->interface
);
398 assert(igmp
->interface
->info
);
400 ifp
= igmp
->interface
;
403 if (PIM_DEBUG_IGMP_TRACE
)
404 zlog_debug("%s: Querier %pPAs on %s reconfig query_interval=%d",
405 __func__
, &igmp
->ifaddr
, ifp
->name
,
406 pim_ifp
->gm_default_query_interval
);
409 * igmp_startup_mode_on() will reset QQI:
411 * igmp->querier_query_interval = pim_ifp->gm_default_query_interval;
413 igmp_startup_mode_on(igmp
);
416 static void igmp_sock_query_reschedule(struct gm_sock
*igmp
)
418 if (igmp
->mtrace_only
)
421 if (igmp
->t_igmp_query_timer
) {
422 /* other querier present */
423 assert(igmp
->t_igmp_query_timer
);
424 assert(!igmp
->t_other_querier_timer
);
426 pim_igmp_general_query_off(igmp
);
427 pim_igmp_general_query_on(igmp
);
429 assert(igmp
->t_igmp_query_timer
);
430 assert(!igmp
->t_other_querier_timer
);
432 /* this is the querier */
434 assert(!igmp
->t_igmp_query_timer
);
435 assert(igmp
->t_other_querier_timer
);
437 pim_igmp_other_querier_timer_off(igmp
);
438 pim_igmp_other_querier_timer_on(igmp
);
440 assert(!igmp
->t_igmp_query_timer
);
441 assert(igmp
->t_other_querier_timer
);
445 static void change_query_interval(struct pim_interface
*pim_ifp
,
448 struct listnode
*sock_node
;
449 struct gm_sock
*igmp
;
451 pim_ifp
->gm_default_query_interval
= query_interval
;
453 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->gm_socket_list
, sock_node
, igmp
)) {
454 igmp_sock_query_interval_reconfig(igmp
);
455 igmp_sock_query_reschedule(igmp
);
459 static void change_query_max_response_time(struct pim_interface
*pim_ifp
,
460 int query_max_response_time_dsec
)
462 struct listnode
*sock_node
;
463 struct gm_sock
*igmp
;
464 struct listnode
*grp_node
;
465 struct gm_group
*grp
;
467 if (pim_ifp
->gm_query_max_response_time_dsec
==
468 query_max_response_time_dsec
)
471 pim_ifp
->gm_query_max_response_time_dsec
= query_max_response_time_dsec
;
474 * Below we modify socket/group/source timers in order to quickly
475 * reflect the change. Otherwise, those timers would args->eventually
479 /* scan all sockets */
480 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->gm_socket_list
, sock_node
, igmp
)) {
481 /* reschedule socket general query */
482 igmp_sock_query_reschedule(igmp
);
485 /* scan socket groups */
486 for (ALL_LIST_ELEMENTS_RO(pim_ifp
->gm_group_list
, grp_node
, grp
)) {
487 struct listnode
*src_node
;
488 struct gm_source
*src
;
490 /* reset group timers for groups in EXCLUDE mode */
491 if (grp
->group_filtermode_isexcl
)
492 igmp_group_reset_gmi(grp
);
494 /* scan group sources */
495 for (ALL_LIST_ELEMENTS_RO(grp
->group_source_list
, src_node
,
498 /* reset source timers for sources with running
501 if (src
->t_source_timer
)
502 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 struct ipaddr source_addr
;
941 switch (args
->event
) {
947 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
949 yang_dnode_get_ip(&source_addr
, args
->dnode
, NULL
);
950 result
= pim_ssmpingd_start(pim
, source_addr
.ip
._v4_addr
);
952 char source_str
[INET_ADDRSTRLEN
];
954 ipaddr2str(&source_addr
, source_str
,
956 snprintf(args
->errmsg
, args
->errmsg_len
,
957 "%% Failure starting ssmpingd for source %s: %d",
959 return NB_ERR_INCONSISTENCY
;
966 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_pingd_source_ip_destroy(
967 struct nb_cb_destroy_args
*args
)
970 struct pim_instance
*pim
;
972 struct ipaddr source_addr
;
974 switch (args
->event
) {
980 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
982 yang_dnode_get_ip(&source_addr
, args
->dnode
, NULL
);
983 result
= pim_ssmpingd_stop(pim
, source_addr
.ip
._v4_addr
);
985 char source_str
[INET_ADDRSTRLEN
];
987 ipaddr2str(&source_addr
, source_str
,
989 snprintf(args
->errmsg
, args
->errmsg_len
,
990 "%% Failure stopping ssmpingd for source %s: %d",
992 return NB_ERR_INCONSISTENCY
;
1003 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/hold-time
1005 int pim_msdp_hold_time_modify(struct nb_cb_modify_args
*args
)
1007 struct pim_instance
*pim
;
1010 switch (args
->event
) {
1011 case NB_EV_VALIDATE
:
1016 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1018 pim
->msdp
.hold_time
= yang_dnode_get_uint16(args
->dnode
, NULL
);
1027 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/keep-alive
1029 int pim_msdp_keep_alive_modify(struct nb_cb_modify_args
*args
)
1031 struct pim_instance
*pim
;
1034 switch (args
->event
) {
1035 case NB_EV_VALIDATE
:
1040 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1042 pim
->msdp
.keep_alive
= yang_dnode_get_uint16(args
->dnode
, NULL
);
1051 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/connection-retry
1053 int pim_msdp_connection_retry_modify(struct nb_cb_modify_args
*args
)
1055 struct pim_instance
*pim
;
1058 switch (args
->event
) {
1059 case NB_EV_VALIDATE
:
1064 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1066 pim
->msdp
.connection_retry
=
1067 yang_dnode_get_uint16(args
->dnode
, NULL
);
1074 pim6_msdp_err(pim_msdp_mesh_group_destroy
, nb_cb_destroy_args
);
1075 pim6_msdp_err(pim_msdp_mesh_group_create
, nb_cb_create_args
);
1076 pim6_msdp_err(pim_msdp_mesh_group_source_modify
, nb_cb_modify_args
);
1077 pim6_msdp_err(pim_msdp_mesh_group_source_destroy
, nb_cb_destroy_args
);
1078 pim6_msdp_err(pim_msdp_mesh_group_members_create
, nb_cb_create_args
);
1079 pim6_msdp_err(pim_msdp_mesh_group_members_destroy
, nb_cb_destroy_args
);
1080 pim6_msdp_err(routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify
,
1082 pim6_msdp_err(routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_destroy
,
1083 nb_cb_destroy_args
);
1084 pim6_msdp_err(routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_create
,
1090 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups
1092 int pim_msdp_mesh_group_create(struct nb_cb_create_args
*args
)
1094 struct pim_msdp_mg
*mg
;
1097 switch (args
->event
) {
1098 case NB_EV_VALIDATE
:
1103 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1104 mg
= pim_msdp_mg_new(vrf
->info
, yang_dnode_get_string(
1105 args
->dnode
, "./name"));
1106 nb_running_set_entry(args
->dnode
, mg
);
1113 int pim_msdp_mesh_group_destroy(struct nb_cb_destroy_args
*args
)
1115 struct pim_msdp_mg
*mg
;
1118 switch (args
->event
) {
1119 case NB_EV_VALIDATE
:
1124 mg
= nb_running_unset_entry(args
->dnode
);
1125 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1126 pim_msdp_mg_free(vrf
->info
, &mg
);
1135 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups/source
1137 int pim_msdp_mesh_group_source_modify(struct nb_cb_modify_args
*args
)
1139 const struct lyd_node
*vrf_dnode
;
1140 struct pim_msdp_mg
*mg
;
1144 switch (args
->event
) {
1145 case NB_EV_VALIDATE
:
1150 mg
= nb_running_get_entry(args
->dnode
, NULL
, true);
1152 yang_dnode_get_parent(args
->dnode
, "address-family");
1153 vrf
= nb_running_get_entry(vrf_dnode
, "../../", true);
1154 yang_dnode_get_ip(&ip
, args
->dnode
, NULL
);
1156 pim_msdp_mg_src_add(vrf
->info
, mg
, &ip
.ip
._v4_addr
);
1162 int pim_msdp_mesh_group_source_destroy(struct nb_cb_destroy_args
*args
)
1164 const struct lyd_node
*vrf_dnode
;
1165 struct pim_msdp_mg
*mg
;
1167 struct in_addr addr
;
1169 switch (args
->event
) {
1170 case NB_EV_VALIDATE
:
1175 mg
= nb_running_get_entry(args
->dnode
, NULL
, true);
1177 yang_dnode_get_parent(args
->dnode
, "address-family");
1178 vrf
= nb_running_get_entry(vrf_dnode
, "../../", true);
1180 addr
.s_addr
= INADDR_ANY
;
1181 pim_msdp_mg_src_add(vrf
->info
, mg
, &addr
);
1190 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups/members
1192 int pim_msdp_mesh_group_members_create(struct nb_cb_create_args
*args
)
1194 const struct lyd_node
*vrf_dnode
;
1195 struct pim_msdp_mg_mbr
*mbr
;
1196 struct pim_msdp_mg
*mg
;
1200 switch (args
->event
) {
1201 case NB_EV_VALIDATE
:
1206 mg
= nb_running_get_entry(args
->dnode
, NULL
, true);
1208 yang_dnode_get_parent(args
->dnode
, "address-family");
1209 vrf
= nb_running_get_entry(vrf_dnode
, "../../", true);
1210 yang_dnode_get_ip(&ip
, args
->dnode
, "address");
1212 mbr
= pim_msdp_mg_mbr_add(vrf
->info
, mg
, &ip
.ip
._v4_addr
);
1213 nb_running_set_entry(args
->dnode
, mbr
);
1220 int pim_msdp_mesh_group_members_destroy(struct nb_cb_destroy_args
*args
)
1222 struct pim_msdp_mg_mbr
*mbr
;
1223 struct pim_msdp_mg
*mg
;
1224 const struct lyd_node
*mg_dnode
;
1226 switch (args
->event
) {
1227 case NB_EV_VALIDATE
:
1232 mbr
= nb_running_get_entry(args
->dnode
, NULL
, true);
1234 yang_dnode_get_parent(args
->dnode
, "msdp-mesh-groups");
1235 mg
= nb_running_get_entry(mg_dnode
, NULL
, true);
1236 pim_msdp_mg_mbr_del(mg
, mbr
);
1237 nb_running_unset_entry(args
->dnode
);
1245 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-peer
1247 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_create(
1248 struct nb_cb_create_args
*args
)
1250 struct pim_msdp_peer
*mp
;
1251 struct pim_instance
*pim
;
1253 struct ipaddr peer_ip
;
1254 struct ipaddr source_ip
;
1256 switch (args
->event
) {
1257 case NB_EV_VALIDATE
:
1262 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1264 yang_dnode_get_ip(&peer_ip
, args
->dnode
, "./peer-ip");
1265 yang_dnode_get_ip(&source_ip
, args
->dnode
, "./source-ip");
1266 mp
= pim_msdp_peer_add(pim
, &peer_ip
.ipaddr_v4
,
1267 &source_ip
.ipaddr_v4
, NULL
);
1268 nb_running_set_entry(args
->dnode
, mp
);
1275 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_destroy(
1276 struct nb_cb_destroy_args
*args
)
1278 struct pim_msdp_peer
*mp
;
1280 switch (args
->event
) {
1281 case NB_EV_VALIDATE
:
1286 mp
= nb_running_unset_entry(args
->dnode
);
1287 pim_msdp_peer_del(&mp
);
1295 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-peer/source-ip
1297 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify(
1298 struct nb_cb_modify_args
*args
)
1300 struct pim_msdp_peer
*mp
;
1301 struct ipaddr source_ip
;
1303 switch (args
->event
) {
1304 case NB_EV_VALIDATE
:
1309 mp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1310 yang_dnode_get_ip(&source_ip
, args
->dnode
, NULL
);
1311 pim_msdp_peer_change_source(mp
, &source_ip
.ipaddr_v4
);
1317 #endif /* PIM_IPV != 6 */
1320 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag
1322 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_create(
1323 struct nb_cb_create_args
*args
)
1325 switch (args
->event
) {
1326 case NB_EV_VALIDATE
:
1336 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_destroy(
1337 struct nb_cb_destroy_args
*args
)
1339 struct in_addr addr
;
1341 switch (args
->event
) {
1342 case NB_EV_VALIDATE
:
1348 pim_vxlan_mlag_update(true/*mlag_enable*/,
1349 false/*peer_state*/, MLAG_ROLE_NONE
,
1350 NULL
/*peerlink*/, &addr
);
1358 * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag
1360 void routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_apply_finish(
1361 struct nb_cb_apply_finish_args
*args
)
1366 struct interface
*ifp
;
1367 struct ipaddr reg_addr
;
1369 ifname
= yang_dnode_get_string(args
->dnode
, "./peerlink-rif");
1370 ifp
= if_lookup_by_name(ifname
, VRF_DEFAULT
);
1372 snprintf(args
->errmsg
, args
->errmsg_len
,
1373 "No such interface name %s", ifname
);
1376 role
= yang_dnode_get_enum(args
->dnode
, "./my-role");
1377 peer_state
= yang_dnode_get_bool(args
->dnode
, "./peer-state");
1378 yang_dnode_get_ip(®_addr
, args
->dnode
, "./reg-address");
1380 pim_vxlan_mlag_update(true, peer_state
, role
, ifp
,
1381 ®_addr
.ip
._v4_addr
);
1386 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/peerlink-rif
1388 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_peerlink_rif_modify(
1389 struct nb_cb_modify_args
*args
)
1391 switch (args
->event
) {
1392 case NB_EV_VALIDATE
:
1402 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_peerlink_rif_destroy(
1403 struct nb_cb_destroy_args
*args
)
1405 switch (args
->event
) {
1406 case NB_EV_VALIDATE
:
1417 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/reg-address
1419 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_reg_address_modify(
1420 struct nb_cb_modify_args
*args
)
1422 switch (args
->event
) {
1423 case NB_EV_VALIDATE
:
1433 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_reg_address_destroy(
1434 struct nb_cb_destroy_args
*args
)
1436 switch (args
->event
) {
1437 case NB_EV_VALIDATE
:
1448 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/my-role
1450 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_my_role_modify(
1451 struct nb_cb_modify_args
*args
)
1453 switch (args
->event
) {
1454 case NB_EV_VALIDATE
:
1465 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag/peer-state
1467 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_peer_state_modify(
1468 struct nb_cb_modify_args
*args
)
1470 switch (args
->event
) {
1471 case NB_EV_VALIDATE
:
1482 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/register-accept-list
1484 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_register_accept_list_modify(
1485 struct nb_cb_modify_args
*args
)
1488 struct pim_instance
*pim
;
1491 switch (args
->event
) {
1492 case NB_EV_VALIDATE
:
1497 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1499 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
1501 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
1502 pim
->register_plist
= XSTRDUP(MTYPE_PIM_PLIST_NAME
, plist
);
1510 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_register_accept_list_destroy(
1511 struct nb_cb_destroy_args
*args
)
1514 struct pim_instance
*pim
;
1516 switch (args
->event
) {
1517 case NB_EV_VALIDATE
:
1522 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
1525 XFREE(MTYPE_PIM_PLIST_NAME
, pim
->register_plist
);
1533 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family
1535 int lib_interface_pim_address_family_create(struct nb_cb_create_args
*args
)
1537 switch (args
->event
) {
1538 case NB_EV_VALIDATE
:
1548 int lib_interface_pim_address_family_destroy(struct nb_cb_destroy_args
*args
)
1550 struct interface
*ifp
;
1551 struct pim_interface
*pim_ifp
;
1553 switch (args
->event
) {
1554 case NB_EV_VALIDATE
:
1559 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1560 pim_ifp
= ifp
->info
;
1564 if (!pim_cmd_interface_delete(ifp
)) {
1565 snprintf(args
->errmsg
, args
->errmsg_len
,
1566 "Unable to delete interface information %s",
1568 return NB_ERR_INCONSISTENCY
;
1576 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/pim-enable
1578 int lib_interface_pim_address_family_pim_enable_modify(struct nb_cb_modify_args
*args
)
1580 struct interface
*ifp
;
1581 struct pim_interface
*pim_ifp
;
1583 const struct lyd_node
*if_dnode
;
1585 switch (args
->event
) {
1586 case NB_EV_VALIDATE
:
1587 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
1589 yang_get_list_elements_count(if_dnode
);
1591 /* Limiting mcast interfaces to number of VIFs */
1592 if (mcast_if_count
== MAXVIFS
) {
1593 snprintf(args
->errmsg
, args
->errmsg_len
,
1594 "Max multicast interfaces(%d) reached.",
1596 return NB_ERR_VALIDATION
;
1603 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1605 if (yang_dnode_get_bool(args
->dnode
, NULL
)) {
1606 if (!pim_cmd_interface_add(ifp
)) {
1607 snprintf(args
->errmsg
, args
->errmsg_len
,
1608 "Could not enable PIM SM on interface %s",
1610 return NB_ERR_INCONSISTENCY
;
1613 pim_ifp
= ifp
->info
;
1615 return NB_ERR_INCONSISTENCY
;
1617 if (!pim_cmd_interface_delete(ifp
)) {
1618 snprintf(args
->errmsg
, args
->errmsg_len
,
1619 "Unable to delete interface information");
1620 return NB_ERR_INCONSISTENCY
;
1630 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/hello-interval
1632 int lib_interface_pim_address_family_hello_interval_modify(
1633 struct nb_cb_modify_args
*args
)
1635 struct interface
*ifp
;
1636 struct pim_interface
*pim_ifp
;
1638 switch (args
->event
) {
1639 case NB_EV_VALIDATE
:
1644 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1645 pim_ifp
= ifp
->info
;
1646 pim_ifp
->pim_hello_period
=
1647 yang_dnode_get_uint8(args
->dnode
, NULL
);
1648 pim_ifp
->pim_default_holdtime
= -1;
1656 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/hello-holdtime
1658 int lib_interface_pim_address_family_hello_holdtime_modify(
1659 struct nb_cb_modify_args
*args
)
1661 struct interface
*ifp
;
1662 struct pim_interface
*pim_ifp
;
1664 switch (args
->event
) {
1665 case NB_EV_VALIDATE
:
1670 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1671 pim_ifp
= ifp
->info
;
1672 pim_ifp
->pim_default_holdtime
=
1673 yang_dnode_get_uint16(args
->dnode
, NULL
);
1681 int lib_interface_pim_address_family_hello_holdtime_destroy(
1682 struct nb_cb_destroy_args
*args
)
1684 struct interface
*ifp
;
1685 struct pim_interface
*pim_ifp
;
1687 switch (args
->event
) {
1688 case NB_EV_VALIDATE
:
1693 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1694 pim_ifp
= ifp
->info
;
1695 pim_ifp
->pim_default_holdtime
= -1;
1702 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd
1704 int lib_interface_pim_address_family_bfd_create(struct nb_cb_create_args
*args
)
1706 struct interface
*ifp
;
1707 struct pim_interface
*pim_ifp
;
1709 switch (args
->event
) {
1710 case NB_EV_VALIDATE
:
1716 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1717 pim_ifp
= ifp
->info
;
1718 pim_ifp
->bfd_config
.enabled
= true;
1725 int lib_interface_pim_address_family_bfd_destroy(
1726 struct nb_cb_destroy_args
*args
)
1728 struct interface
*ifp
;
1729 struct pim_interface
*pim_ifp
;
1730 const struct lyd_node
*if_dnode
;
1732 switch (args
->event
) {
1733 case NB_EV_VALIDATE
:
1734 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
1735 if (!is_pim_interface(if_dnode
)) {
1736 snprintf(args
->errmsg
, args
->errmsg_len
,
1737 "Pim not enabled on this interface");
1738 return NB_ERR_VALIDATION
;
1745 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1746 pim_ifp
= ifp
->info
;
1747 pim_ifp
->bfd_config
.enabled
= false;
1748 pim_bfd_reg_dereg_all_nbr(ifp
);
1756 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd
1758 void lib_interface_pim_address_family_bfd_apply_finish(
1759 struct nb_cb_apply_finish_args
*args
)
1761 struct interface
*ifp
;
1762 struct pim_interface
*pim_ifp
;
1764 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1765 pim_ifp
= ifp
->info
;
1768 zlog_debug("Pim not enabled on this interface");
1772 pim_ifp
->bfd_config
.detection_multiplier
=
1773 yang_dnode_get_uint8(args
->dnode
, "./detect_mult");
1774 pim_ifp
->bfd_config
.min_rx
=
1775 yang_dnode_get_uint16(args
->dnode
, "./min-rx-interval");
1776 pim_ifp
->bfd_config
.min_tx
=
1777 yang_dnode_get_uint16(args
->dnode
, "./min-tx-interval");
1779 pim_bfd_reg_dereg_all_nbr(ifp
);
1783 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/min-rx-interval
1785 int lib_interface_pim_address_family_bfd_min_rx_interval_modify(
1786 struct nb_cb_modify_args
*args
)
1788 switch (args
->event
) {
1789 case NB_EV_VALIDATE
:
1800 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/min-tx-interval
1802 int lib_interface_pim_address_family_bfd_min_tx_interval_modify(
1803 struct nb_cb_modify_args
*args
)
1805 switch (args
->event
) {
1806 case NB_EV_VALIDATE
:
1817 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/detect_mult
1819 int lib_interface_pim_address_family_bfd_detect_mult_modify(
1820 struct nb_cb_modify_args
*args
)
1822 switch (args
->event
) {
1823 case NB_EV_VALIDATE
:
1834 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bfd/profile
1836 int lib_interface_pim_address_family_bfd_profile_modify(
1837 struct nb_cb_modify_args
*args
)
1839 struct interface
*ifp
;
1840 struct pim_interface
*pim_ifp
;
1842 switch (args
->event
) {
1843 case NB_EV_VALIDATE
:
1849 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1850 pim_ifp
= ifp
->info
;
1851 XFREE(MTYPE_TMP
, pim_ifp
->bfd_config
.profile
);
1852 pim_ifp
->bfd_config
.profile
= XSTRDUP(
1853 MTYPE_TMP
, yang_dnode_get_string(args
->dnode
, NULL
));
1860 int lib_interface_pim_address_family_bfd_profile_destroy(
1861 struct nb_cb_destroy_args
*args
)
1863 struct interface
*ifp
;
1864 struct pim_interface
*pim_ifp
;
1866 switch (args
->event
) {
1867 case NB_EV_VALIDATE
:
1873 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1874 pim_ifp
= ifp
->info
;
1875 XFREE(MTYPE_TMP
, pim_ifp
->bfd_config
.profile
);
1883 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/bsm
1885 int lib_interface_pim_address_family_bsm_modify(struct nb_cb_modify_args
*args
)
1887 struct interface
*ifp
;
1888 struct pim_interface
*pim_ifp
;
1890 switch (args
->event
) {
1891 case NB_EV_VALIDATE
:
1896 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1897 pim_ifp
= ifp
->info
;
1898 pim_ifp
->bsm_enable
= yang_dnode_get_bool(args
->dnode
, NULL
);
1907 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/unicast-bsm
1909 int lib_interface_pim_address_family_unicast_bsm_modify(
1910 struct nb_cb_modify_args
*args
)
1912 struct interface
*ifp
;
1913 struct pim_interface
*pim_ifp
;
1915 switch (args
->event
) {
1916 case NB_EV_VALIDATE
:
1921 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1922 pim_ifp
= ifp
->info
;
1923 pim_ifp
->ucast_bsm_accept
=
1924 yang_dnode_get_bool(args
->dnode
, NULL
);
1933 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/active-active
1935 int lib_interface_pim_address_family_active_active_modify(
1936 struct nb_cb_modify_args
*args
)
1938 struct interface
*ifp
;
1939 struct pim_interface
*pim_ifp
;
1941 switch (args
->event
) {
1942 case NB_EV_VALIDATE
:
1947 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1948 pim_ifp
= ifp
->info
;
1949 if (yang_dnode_get_bool(args
->dnode
, NULL
)) {
1952 "Configuring PIM active-active on Interface: %s",
1954 pim_if_configure_mlag_dualactive(pim_ifp
);
1958 "UnConfiguring PIM active-active on Interface: %s",
1960 pim_if_unconfigure_mlag_dualactive(pim_ifp
);
1971 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/dr-priority
1973 int lib_interface_pim_address_family_dr_priority_modify(
1974 struct nb_cb_modify_args
*args
)
1976 struct interface
*ifp
;
1977 struct pim_interface
*pim_ifp
;
1978 uint32_t old_dr_prio
;
1979 const struct lyd_node
*if_dnode
;
1981 switch (args
->event
) {
1982 case NB_EV_VALIDATE
:
1983 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
1984 if (!is_pim_interface(if_dnode
)) {
1985 snprintf(args
->errmsg
, args
->errmsg_len
,
1986 "Pim not enabled on this interface");
1987 return NB_ERR_VALIDATION
;
1994 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
1995 pim_ifp
= ifp
->info
;
1996 old_dr_prio
= pim_ifp
->pim_dr_priority
;
1997 pim_ifp
->pim_dr_priority
= yang_dnode_get_uint32(args
->dnode
,
2000 if (old_dr_prio
!= pim_ifp
->pim_dr_priority
) {
2001 pim_if_dr_election(ifp
);
2002 pim_hello_restart_now(ifp
);
2011 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/use-source
2013 int lib_interface_pim_address_family_use_source_modify(
2014 struct nb_cb_modify_args
*args
)
2016 struct interface
*ifp
;
2017 pim_addr source_addr
;
2019 const struct lyd_node
*if_dnode
;
2021 switch (args
->event
) {
2022 case NB_EV_VALIDATE
:
2023 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2024 if (!is_pim_interface(if_dnode
)) {
2025 snprintf(args
->errmsg
, args
->errmsg_len
,
2026 "Pim not enabled on this interface");
2027 return NB_ERR_VALIDATION
;
2034 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2036 yang_dnode_get_ipv4(&source_addr
, args
->dnode
, NULL
);
2038 yang_dnode_get_ipv6(&source_addr
, args
->dnode
, NULL
);
2041 result
= interface_pim_use_src_cmd_worker(
2043 args
->errmsg
, args
->errmsg_len
);
2045 if (result
!= PIM_SUCCESS
)
2046 return NB_ERR_INCONSISTENCY
;
2054 int lib_interface_pim_address_family_use_source_destroy(
2055 struct nb_cb_destroy_args
*args
)
2057 struct interface
*ifp
;
2059 const struct lyd_node
*if_dnode
;
2061 switch (args
->event
) {
2062 case NB_EV_VALIDATE
:
2063 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2064 if (!is_pim_interface(if_dnode
)) {
2065 snprintf(args
->errmsg
, args
->errmsg_len
,
2066 "Pim not enabled on this interface");
2067 return NB_ERR_VALIDATION
;
2074 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2076 result
= interface_pim_use_src_cmd_worker(ifp
, PIMADDR_ANY
,
2080 if (result
!= PIM_SUCCESS
)
2081 return NB_ERR_INCONSISTENCY
;
2090 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/multicast-boundary-oil
2092 int lib_interface_pim_address_family_multicast_boundary_oil_modify(
2093 struct nb_cb_modify_args
*args
)
2095 struct interface
*ifp
;
2096 struct pim_interface
*pim_ifp
;
2098 const struct lyd_node
*if_dnode
;
2100 switch (args
->event
) {
2101 case NB_EV_VALIDATE
:
2102 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2103 if (!is_pim_interface(if_dnode
)) {
2104 snprintf(args
->errmsg
, args
->errmsg_len
,
2105 "Pim not enabled on this interface");
2106 return NB_ERR_VALIDATION
;
2113 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2114 pim_ifp
= ifp
->info
;
2115 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
2117 if (pim_ifp
->boundary_oil_plist
)
2118 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
2120 pim_ifp
->boundary_oil_plist
=
2121 XSTRDUP(MTYPE_PIM_INTERFACE
, plist
);
2129 int lib_interface_pim_address_family_multicast_boundary_oil_destroy(
2130 struct nb_cb_destroy_args
*args
)
2132 struct interface
*ifp
;
2133 struct pim_interface
*pim_ifp
;
2134 const struct lyd_node
*if_dnode
;
2136 switch (args
->event
) {
2137 case NB_EV_VALIDATE
:
2138 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2139 if (!is_pim_interface(if_dnode
)) {
2140 snprintf(args
->errmsg
, args
->errmsg_len
,
2141 "%% Enable PIM and/or IGMP on this interface first");
2142 return NB_ERR_VALIDATION
;
2149 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2150 pim_ifp
= ifp
->info
;
2151 if (pim_ifp
->boundary_oil_plist
)
2152 XFREE(MTYPE_PIM_INTERFACE
, pim_ifp
->boundary_oil_plist
);
2160 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/mroute
2162 int lib_interface_pim_address_family_mroute_create(
2163 struct nb_cb_create_args
*args
)
2165 switch (args
->event
) {
2166 case NB_EV_VALIDATE
:
2176 int lib_interface_pim_address_family_mroute_destroy(
2177 struct nb_cb_destroy_args
*args
)
2179 struct pim_instance
*pim
;
2180 struct pim_interface
*pim_iifp
;
2181 struct interface
*iif
;
2182 struct interface
*oif
;
2183 const char *oifname
;
2184 pim_addr source_addr
;
2185 pim_addr group_addr
;
2186 const struct lyd_node
*if_dnode
;
2188 switch (args
->event
) {
2189 case NB_EV_VALIDATE
:
2190 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2191 if (!is_pim_interface(if_dnode
)) {
2192 snprintf(args
->errmsg
, args
->errmsg_len
,
2193 "%% Enable PIM and/or IGMP on this interface first");
2194 return NB_ERR_VALIDATION
;
2201 iif
= nb_running_get_entry(args
->dnode
, NULL
, true);
2202 pim_iifp
= iif
->info
;
2203 pim
= pim_iifp
->pim
;
2205 oifname
= yang_dnode_get_string(args
->dnode
, "./oif");
2206 oif
= if_lookup_by_name(oifname
, pim
->vrf
->vrf_id
);
2209 snprintf(args
->errmsg
, args
->errmsg_len
,
2210 "No such interface name %s",
2212 return NB_ERR_INCONSISTENCY
;
2215 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
, "./source-addr");
2216 yang_dnode_get_pimaddr(&group_addr
, args
->dnode
, "./group-addr");
2218 if (pim_static_del(pim
, iif
, oif
, group_addr
, source_addr
)) {
2219 snprintf(args
->errmsg
, args
->errmsg_len
,
2220 "Failed to remove static mroute");
2221 return NB_ERR_INCONSISTENCY
;
2231 * XPath: /frr-interface:lib/interface/frr-pim:pim/address-family/mroute/oif
2233 int lib_interface_pim_address_family_mroute_oif_modify(
2234 struct nb_cb_modify_args
*args
)
2236 struct pim_instance
*pim
;
2237 struct pim_interface
*pim_iifp
;
2238 struct interface
*iif
;
2239 struct interface
*oif
;
2240 const char *oifname
;
2241 pim_addr source_addr
;
2242 pim_addr group_addr
;
2243 const struct lyd_node
*if_dnode
;
2245 switch (args
->event
) {
2246 case NB_EV_VALIDATE
:
2247 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2248 if (!is_pim_interface(if_dnode
)) {
2249 snprintf(args
->errmsg
, args
->errmsg_len
,
2250 "%% Enable PIM and/or IGMP on this interface first");
2251 return NB_ERR_VALIDATION
;
2254 #ifdef PIM_ENFORCE_LOOPFREE_MFC
2255 iif
= nb_running_get_entry(args
->dnode
, NULL
, false);
2260 pim_iifp
= iif
->info
;
2261 pim
= pim_iifp
->pim
;
2263 oifname
= yang_dnode_get_string(args
->dnode
, NULL
);
2264 oif
= if_lookup_by_name(oifname
, pim
->vrf
->vrf_id
);
2266 if (oif
&& (iif
->ifindex
== oif
->ifindex
)) {
2267 strlcpy(args
->errmsg
,
2268 "% IIF same as OIF and loopfree enforcement is enabled; rejecting",
2270 return NB_ERR_VALIDATION
;
2278 iif
= nb_running_get_entry(args
->dnode
, NULL
, true);
2279 pim_iifp
= iif
->info
;
2280 pim
= pim_iifp
->pim
;
2282 oifname
= yang_dnode_get_string(args
->dnode
, NULL
);
2283 oif
= if_lookup_by_name(oifname
, pim
->vrf
->vrf_id
);
2285 snprintf(args
->errmsg
, args
->errmsg_len
,
2286 "No such interface name %s",
2288 return NB_ERR_INCONSISTENCY
;
2291 yang_dnode_get_pimaddr(&source_addr
, args
->dnode
, "../source-addr");
2292 yang_dnode_get_pimaddr(&group_addr
, args
->dnode
, "../group-addr");
2294 if (pim_static_add(pim
, iif
, oif
, group_addr
, source_addr
)) {
2295 snprintf(args
->errmsg
, args
->errmsg_len
,
2296 "Failed to add static mroute");
2297 return NB_ERR_INCONSISTENCY
;
2306 int lib_interface_pim_address_family_mroute_oif_destroy(
2307 struct nb_cb_destroy_args
*args
)
2309 switch (args
->event
) {
2310 case NB_EV_VALIDATE
:
2321 * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/static-rp/rp-list
2323 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_create(
2324 struct nb_cb_create_args
*args
)
2326 switch (args
->event
) {
2327 case NB_EV_VALIDATE
:
2337 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_destroy(
2338 struct nb_cb_destroy_args
*args
)
2341 struct pim_instance
*pim
;
2342 struct prefix group
;
2343 struct ipaddr rp_addr
;
2347 switch (args
->event
) {
2348 case NB_EV_VALIDATE
:
2353 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2355 yang_dnode_get_ip(&rp_addr
, args
->dnode
, "./rp-address");
2357 if (yang_dnode_get(args
->dnode
, "./group-list")) {
2358 yang_dnode_get_ipv4p(&group
, args
->dnode
,
2360 apply_mask_ipv4((struct prefix_ipv4
*)&group
);
2361 result
= pim_no_rp_cmd_worker(pim
, rp_addr
.ip
._v4_addr
,
2362 group
, NULL
, args
->errmsg
,
2366 else if (yang_dnode_get(args
->dnode
, "./prefix-list")) {
2367 plist
= yang_dnode_get_string(args
->dnode
,
2369 if (!str2prefix("224.0.0.0/4", &group
)) {
2372 "Unable to convert 224.0.0.0/4 to prefix");
2373 return NB_ERR_INCONSISTENCY
;
2376 result
= pim_no_rp_cmd_worker(pim
, rp_addr
.ip
._v4_addr
,
2383 return NB_ERR_INCONSISTENCY
;
2391 * 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
2393 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_group_list_create(
2394 struct nb_cb_create_args
*args
)
2397 struct pim_instance
*pim
;
2398 struct prefix group
;
2399 struct ipaddr rp_addr
;
2401 switch (args
->event
) {
2402 case NB_EV_VALIDATE
:
2407 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2409 yang_dnode_get_ip(&rp_addr
, args
->dnode
, "../rp-address");
2410 yang_dnode_get_ipv4p(&group
, args
->dnode
, NULL
);
2411 apply_mask_ipv4((struct prefix_ipv4
*)&group
);
2413 return pim_rp_cmd_worker(pim
, rp_addr
.ip
._v4_addr
, group
,
2414 NULL
, args
->errmsg
, args
->errmsg_len
);
2420 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_group_list_destroy(
2421 struct nb_cb_destroy_args
*args
)
2424 struct pim_instance
*pim
;
2425 struct prefix group
;
2426 struct ipaddr rp_addr
;
2428 switch (args
->event
) {
2429 case NB_EV_VALIDATE
:
2434 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2436 yang_dnode_get_ip(&rp_addr
, args
->dnode
, "../rp-address");
2437 yang_dnode_get_ipv4p(&group
, args
->dnode
, NULL
);
2438 apply_mask_ipv4((struct prefix_ipv4
*)&group
);
2440 return pim_no_rp_cmd_worker(pim
, rp_addr
.ip
._v4_addr
, group
,
2449 * 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
2451 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_prefix_list_modify(
2452 struct nb_cb_modify_args
*args
)
2455 struct pim_instance
*pim
;
2456 struct prefix group
;
2457 struct ipaddr rp_addr
;
2460 switch (args
->event
) {
2461 case NB_EV_VALIDATE
:
2466 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2468 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
2469 yang_dnode_get_ip(&rp_addr
, args
->dnode
, "../rp-address");
2470 if (!str2prefix("224.0.0.0/4", &group
)) {
2471 flog_err(EC_LIB_DEVELOPMENT
,
2472 "Unable to convert 224.0.0.0/4 to prefix");
2473 return NB_ERR_INCONSISTENCY
;
2475 return pim_rp_cmd_worker(pim
, rp_addr
.ip
._v4_addr
, group
,
2476 plist
, args
->errmsg
, args
->errmsg_len
);
2482 int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_prefix_list_destroy(
2483 struct nb_cb_destroy_args
*args
)
2486 struct pim_instance
*pim
;
2487 struct prefix group
;
2488 struct ipaddr rp_addr
;
2491 switch (args
->event
) {
2492 case NB_EV_VALIDATE
:
2497 vrf
= nb_running_get_entry(args
->dnode
, NULL
, true);
2499 yang_dnode_get_ip(&rp_addr
, args
->dnode
, "../rp-address");
2500 plist
= yang_dnode_get_string(args
->dnode
, NULL
);
2501 if (!str2prefix("224.0.0.0/4", &group
)) {
2502 flog_err(EC_LIB_DEVELOPMENT
,
2503 "Unable to convert 224.0.0.0/4 to prefix");
2504 return NB_ERR_INCONSISTENCY
;
2506 return pim_no_rp_cmd_worker(pim
, rp_addr
.ip
._v4_addr
, group
,
2507 plist
, args
->errmsg
,
2516 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family
2518 int lib_interface_gmp_address_family_create(struct nb_cb_create_args
*args
)
2520 switch (args
->event
) {
2521 case NB_EV_VALIDATE
:
2531 int lib_interface_gmp_address_family_destroy(struct nb_cb_destroy_args
*args
)
2533 struct interface
*ifp
;
2534 struct pim_interface
*pim_ifp
;
2536 switch (args
->event
) {
2537 case NB_EV_VALIDATE
:
2542 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2543 pim_ifp
= ifp
->info
;
2548 PIM_IF_DONT_IGMP(pim_ifp
->options
);
2550 pim_if_membership_clear(ifp
);
2552 pim_if_addr_del_all_igmp(ifp
);
2554 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
2562 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/enable
2564 int lib_interface_gmp_address_family_enable_modify(
2565 struct nb_cb_modify_args
*args
)
2567 struct interface
*ifp
;
2569 struct pim_interface
*pim_ifp
;
2571 const char *ifp_name
;
2572 const struct lyd_node
*if_dnode
;
2574 switch (args
->event
) {
2575 case NB_EV_VALIDATE
:
2576 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2578 yang_get_list_elements_count(if_dnode
);
2579 /* Limiting mcast interfaces to number of VIFs */
2580 if (mcast_if_count
== MAXVIFS
) {
2581 ifp_name
= yang_dnode_get_string(if_dnode
, "name");
2582 snprintf(args
->errmsg
, args
->errmsg_len
,
2583 "Max multicast interfaces(%d) Reached. Could not enable IGMP on interface %s",
2585 return NB_ERR_VALIDATION
;
2592 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2593 igmp_enable
= yang_dnode_get_bool(args
->dnode
, NULL
);
2596 return pim_cmd_igmp_start(ifp
);
2599 pim_ifp
= ifp
->info
;
2602 return NB_ERR_INCONSISTENCY
;
2604 PIM_IF_DONT_IGMP(pim_ifp
->options
);
2606 pim_if_membership_clear(ifp
);
2608 pim_if_addr_del_all_igmp(ifp
);
2610 if (!PIM_IF_TEST_PIM(pim_ifp
->options
))
2619 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/igmp-version
2621 int lib_interface_gmp_address_family_igmp_version_modify(
2622 struct nb_cb_modify_args
*args
)
2624 struct interface
*ifp
;
2625 struct pim_interface
*pim_ifp
;
2626 int igmp_version
, old_version
= 0;
2628 switch (args
->event
) {
2629 case NB_EV_VALIDATE
:
2634 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2635 pim_ifp
= ifp
->info
;
2638 return NB_ERR_INCONSISTENCY
;
2640 igmp_version
= yang_dnode_get_uint8(args
->dnode
, NULL
);
2641 old_version
= pim_ifp
->igmp_version
;
2642 pim_ifp
->igmp_version
= igmp_version
;
2644 /* Current and new version is different refresh existing
2645 * membership. Going from 3 -> 2 or 2 -> 3.
2647 if (old_version
!= igmp_version
)
2648 pim_if_membership_refresh(ifp
);
2656 int lib_interface_gmp_address_family_igmp_version_destroy(
2657 struct nb_cb_destroy_args
*args
)
2659 struct interface
*ifp
;
2660 struct pim_interface
*pim_ifp
;
2662 switch (args
->event
) {
2663 case NB_EV_VALIDATE
:
2668 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2669 pim_ifp
= ifp
->info
;
2670 pim_ifp
->igmp_version
= IGMP_DEFAULT_VERSION
;
2678 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/mld-version
2680 int lib_interface_gmp_address_family_mld_version_modify(
2681 struct nb_cb_modify_args
*args
)
2683 switch (args
->event
) {
2684 case NB_EV_VALIDATE
:
2694 int lib_interface_gmp_address_family_mld_version_destroy(
2695 struct nb_cb_destroy_args
*args
)
2697 switch (args
->event
) {
2698 case NB_EV_VALIDATE
:
2709 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/query-interval
2711 int lib_interface_gmp_address_family_query_interval_modify(
2712 struct nb_cb_modify_args
*args
)
2714 struct interface
*ifp
;
2717 switch (args
->event
) {
2718 case NB_EV_VALIDATE
:
2723 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2724 query_interval
= yang_dnode_get_uint16(args
->dnode
, NULL
);
2725 change_query_interval(ifp
->info
, query_interval
);
2732 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/query-max-response-time
2734 int lib_interface_gmp_address_family_query_max_response_time_modify(
2735 struct nb_cb_modify_args
*args
)
2737 struct interface
*ifp
;
2738 int query_max_response_time_dsec
;
2740 switch (args
->event
) {
2741 case NB_EV_VALIDATE
:
2746 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2747 query_max_response_time_dsec
=
2748 yang_dnode_get_uint16(args
->dnode
, NULL
);
2749 change_query_max_response_time(ifp
->info
,
2750 query_max_response_time_dsec
);
2757 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/last-member-query-interval
2759 int lib_interface_gmp_address_family_last_member_query_interval_modify(
2760 struct nb_cb_modify_args
*args
)
2762 struct interface
*ifp
;
2763 struct pim_interface
*pim_ifp
;
2764 int last_member_query_interval
;
2766 switch (args
->event
) {
2767 case NB_EV_VALIDATE
:
2772 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2773 pim_ifp
= ifp
->info
;
2774 last_member_query_interval
=
2775 yang_dnode_get_uint16(args
->dnode
, NULL
);
2776 pim_ifp
->gm_specific_query_max_response_time_dsec
=
2777 last_member_query_interval
;
2786 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/robustness-variable
2788 int lib_interface_gmp_address_family_robustness_variable_modify(
2789 struct nb_cb_modify_args
*args
)
2791 struct interface
*ifp
;
2792 struct pim_interface
*pim_ifp
;
2793 int last_member_query_count
;
2795 switch (args
->event
) {
2796 case NB_EV_VALIDATE
:
2801 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2802 pim_ifp
= ifp
->info
;
2803 last_member_query_count
=
2804 yang_dnode_get_uint8(args
->dnode
, NULL
);
2805 pim_ifp
->gm_last_member_query_count
= last_member_query_count
;
2814 * XPath: /frr-interface:lib/interface/frr-gmp:gmp/address-family/static-group
2816 int lib_interface_gmp_address_family_static_group_create(
2817 struct nb_cb_create_args
*args
)
2819 struct interface
*ifp
;
2820 struct ipaddr source_addr
;
2821 struct ipaddr group_addr
;
2823 const char *ifp_name
;
2824 const struct lyd_node
*if_dnode
;
2826 switch (args
->event
) {
2827 case NB_EV_VALIDATE
:
2828 if_dnode
= yang_dnode_get_parent(args
->dnode
, "interface");
2829 if (!is_pim_interface(if_dnode
)) {
2830 ifp_name
= yang_dnode_get_string(if_dnode
, "name");
2831 snprintf(args
->errmsg
, args
->errmsg_len
,
2832 "multicast not enabled on interface %s",
2834 return NB_ERR_VALIDATION
;
2837 yang_dnode_get_ip(&group_addr
, args
->dnode
, "./group-addr");
2838 if (pim_is_group_224_0_0_0_24(group_addr
.ip
._v4_addr
)) {
2840 args
->errmsg
, args
->errmsg_len
,
2841 "Groups within 224.0.0.0/24 are reserved and cannot be joined");
2842 return NB_ERR_VALIDATION
;
2849 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2850 yang_dnode_get_ip(&source_addr
, args
->dnode
, "./source-addr");
2851 yang_dnode_get_ip(&group_addr
, args
->dnode
, "./group-addr");
2853 result
= pim_if_igmp_join_add(ifp
, group_addr
.ip
._v4_addr
,
2854 source_addr
.ip
._v4_addr
);
2856 snprintf(args
->errmsg
, args
->errmsg_len
,
2857 "Failure joining IGMP group");
2858 return NB_ERR_INCONSISTENCY
;
2865 int lib_interface_gmp_address_family_static_group_destroy(
2866 struct nb_cb_destroy_args
*args
)
2868 struct interface
*ifp
;
2869 struct ipaddr source_addr
;
2870 struct ipaddr group_addr
;
2873 switch (args
->event
) {
2874 case NB_EV_VALIDATE
:
2879 ifp
= nb_running_get_entry(args
->dnode
, NULL
, true);
2880 yang_dnode_get_ip(&source_addr
, args
->dnode
, "./source-addr");
2881 yang_dnode_get_ip(&group_addr
, args
->dnode
, "./group-addr");
2883 result
= pim_if_igmp_join_del(ifp
, group_addr
.ip
._v4_addr
,
2884 source_addr
.ip
._v4_addr
);
2887 char src_str
[INET_ADDRSTRLEN
];
2888 char grp_str
[INET_ADDRSTRLEN
];
2890 ipaddr2str(&source_addr
, src_str
, sizeof(src_str
));
2891 ipaddr2str(&group_addr
, grp_str
, sizeof(grp_str
));
2893 snprintf(args
->errmsg
, args
->errmsg_len
,
2894 "%% Failure leaving IGMP group %s %s on interface %s: %d",
2895 src_str
, grp_str
, ifp
->name
, result
);
2897 return NB_ERR_INCONSISTENCY
;