]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: convert interface ipv6 nd prefix command to NB
authorIgor Ryzhov <iryzhov@nfware.com>
Tue, 23 Jan 2024 19:32:16 +0000 (21:32 +0200)
committerIgor Ryzhov <iryzhov@nfware.com>
Sun, 28 Jan 2024 21:28:40 +0000 (23:28 +0200)
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
yang/frr-zebra.yang
zebra/rtadv.c
zebra/rtadv.h
zebra/zebra_nb.c
zebra/zebra_nb.h
zebra/zebra_nb_config.c

index 1433cb23c58b4c5711abd93dcec6ffa63efd48b1..66107d1a19ab5529d552ad8f133298e81d4d7c8d 100644 (file)
@@ -2494,6 +2494,119 @@ module frr-zebra {
             "RFC 4191: Default Router Preferences and More-Specific
                        Routes";
         }
+        container prefix-list {
+          description
+            "Support for prefixes to be placed in Prefix
+            Information options in Router Advertisement messages
+            sent from the interface.
+
+            Prefixes that are advertised by default but do not
+            have their entries in the child 'prefix' list are
+            advertised with the default values of all parameters.
+
+            The link-local prefix SHOULD NOT be included in the
+            list of advertised prefixes.";
+          reference
+            "RFC 4861: Neighbor Discovery for IP version 6 (IPv6)
+                       - AdvPrefixList";
+          list prefix {
+            key "prefix-spec";
+            description
+              "Support for an advertised prefix entry.";
+            leaf prefix-spec {
+              type inet:ipv6-prefix;
+              description
+                "IPv6 address prefix.";
+            }
+            // FRR doesn't support 'no-advertise'. Keeping the code
+            // here for future reference.
+            /*
+            choice control-adv-prefixes {
+              default "advertise";
+              description
+                "Either (1) the prefix is explicitly removed from the
+                set of advertised prefixes or (2) the parameters with
+                which the prefix is advertised are specified (default
+                case).";
+              leaf no-advertise {
+                type empty;
+                description
+                  "The prefix will not be advertised.
+
+                  This can be used for removing the prefix from
+                  the default set of advertised prefixes.";
+              }
+              case advertise {
+            */
+                leaf valid-lifetime {
+                  type uint32;
+                  units "seconds";
+                  default "2592000";
+                  description
+                    "The value to be placed in the Valid Lifetime
+                    in the Prefix Information option.  The
+                    designated value of all 1's (0xffffffff)
+                      represents infinity.";
+                  reference
+                    "RFC 4861: Neighbor Discovery for IP version 6
+                              (IPv6) - AdvValidLifetime";
+                }
+                leaf on-link-flag {
+                  type boolean;
+                  default "true";
+                  description
+                    "The value to be placed in the on-link flag
+                    ('L-bit') field in the Prefix Information
+                    option.";
+                  reference
+                    "RFC 4861: Neighbor Discovery for IP version 6
+                              (IPv6) - AdvOnLinkFlag";
+                }
+                leaf preferred-lifetime {
+                  type uint32;
+                  units "seconds";
+                  must ". <= ../valid-lifetime" {
+                    description
+                      "This value MUST NOT be greater than
+                      valid-lifetime.";
+                  }
+                  default "604800";
+                  description
+                    "The value to be placed in the Preferred
+                    Lifetime in the Prefix Information option.
+                    The designated value of all 1's (0xffffffff)
+                    represents infinity.";
+                  reference
+                    "RFC 4861: Neighbor Discovery for IP version 6
+                              (IPv6) - AdvPreferredLifetime";
+                }
+                leaf autonomous-flag {
+                  type boolean;
+                  default "true";
+                  description
+                    "The value to be placed in the Autonomous Flag
+                    field in the Prefix Information option.";
+                  reference
+                    "RFC 4861: Neighbor Discovery for IP version 6
+                              (IPv6) - AdvAutonomousFlag";
+                }
+                leaf router-address-flag {
+                  type boolean;
+                  default "false";
+                  description
+                    "The value to be placed in the Router Address
+                    flag field in the Prefix Information option.";
+                  reference
+                    "RFC 6275: Mobility Support in IPv6";
+                }
+            /*
+              }
+            }
+            */
+            // This is closing brackets for `case advertise` and
+            // `choice control-adv-prefixes`.
+          }
+        }
       }
       container state {
         config false;
index fb037a00f250f27dab6ec3a3aad5343accd1739c..04ae248f86a01f0d16b32f1dbb9ba8fc61e73546 100644 (file)
@@ -1135,7 +1135,8 @@ static void rtadv_prefix_set_defaults(struct rtadv_prefix *rp)
        rp->AdvValidLifetime = RTADV_VALID_LIFETIME;
 }
 
-static void rtadv_prefix_set(struct zebra_if *zif, struct rtadv_prefix *rp)
+static struct rtadv_prefix *rtadv_prefix_set(struct zebra_if *zif,
+                                            struct rtadv_prefix *rp)
 {
        struct rtadv_prefix *rprefix;
 
@@ -1168,13 +1169,16 @@ static void rtadv_prefix_set(struct zebra_if *zif, struct rtadv_prefix *rp)
                        rtadv_prefix_set_defaults(rprefix);
                }
        }
+
+       return rprefix;
 }
 
-static int rtadv_prefix_reset(struct zebra_if *zif, struct rtadv_prefix *rp)
+static void rtadv_prefix_reset(struct zebra_if *zif, struct rtadv_prefix *rp,
+                              struct rtadv_prefix *rprefix)
 {
-       struct rtadv_prefix *rprefix;
+       if (!rprefix)
+               rprefix = rtadv_prefixes_find(zif->rtadv.prefixes, rp);
 
-       rprefix = rtadv_prefixes_find(zif->rtadv.prefixes, rp);
        if (rprefix != NULL) {
 
                /*
@@ -1188,20 +1192,35 @@ static int rtadv_prefix_reset(struct zebra_if *zif, struct rtadv_prefix *rp)
                        if (rprefix->AdvPrefixCreate == PREFIX_SRC_BOTH) {
                                rprefix->AdvPrefixCreate = PREFIX_SRC_AUTO;
                                rtadv_prefix_set_defaults(rprefix);
-                               return 1;
+                               return;
                        }
                } else if (rp->AdvPrefixCreate == PREFIX_SRC_AUTO) {
                        if (rprefix->AdvPrefixCreate == PREFIX_SRC_BOTH) {
                                rprefix->AdvPrefixCreate = PREFIX_SRC_MANUAL;
-                               return 1;
+                               return;
                        }
                }
 
                rtadv_prefixes_del(zif->rtadv.prefixes, rprefix);
                rtadv_prefix_free(rprefix);
-               return 1;
-       } else
-               return 0;
+       }
+}
+
+struct rtadv_prefix *rtadv_add_prefix_manual(struct zebra_if *zif,
+                                            struct rtadv_prefix *rp)
+{
+       rp->AdvPrefixCreate = PREFIX_SRC_MANUAL;
+       return rtadv_prefix_set(zif, rp);
+}
+
+void rtadv_delete_prefix_manual(struct zebra_if *zif,
+                               struct rtadv_prefix *rprefix)
+{
+       struct rtadv_prefix rp;
+
+       rp.AdvPrefixCreate = PREFIX_SRC_MANUAL;
+
+       rtadv_prefix_reset(zif, &rp, rprefix);
 }
 
 /* Add IPv6 prefixes learned from the kernel to the RA prefix list */
@@ -1223,7 +1242,7 @@ void rtadv_delete_prefix(struct zebra_if *zif, const struct prefix *p)
        rp.prefix = *((struct prefix_ipv6 *)p);
        apply_mask_ipv6(&rp.prefix);
        rp.AdvPrefixCreate = PREFIX_SRC_AUTO;
-       rtadv_prefix_reset(zif, &rp);
+       rtadv_prefix_reset(zif, &rp, NULL);
 }
 
 static void rtadv_start_interface_events(struct zebra_vrf *zvrf,
@@ -1445,7 +1464,7 @@ void rtadv_stop_ra_all(void)
 
                        frr_each_safe (rtadv_prefixes, zif->rtadv.prefixes,
                                       rprefix)
-                               rtadv_prefix_reset(zif, rprefix);
+                               rtadv_prefix_reset(zif, rprefix, rprefix);
 
                        rtadv_stop_ra(ifp);
                }
@@ -1794,9 +1813,10 @@ DEFPY_YANG (ipv6_nd_other_config_flag,
        return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (ipv6_nd_prefix,
+DEFPY_YANG (ipv6_nd_prefix,
        ipv6_nd_prefix_cmd,
-       "ipv6 nd prefix X:X::X:X/M [<(0-4294967295)|infinite> <(0-4294967295)|infinite>] [<router-address|off-link [no-autoconfig]|no-autoconfig [off-link]>]",
+       "[no] ipv6 nd prefix X:X::X:X/M$prefix [<(0-4294967295)|infinite>$valid <(0-4294967295)|infinite>$preferred] [{router-address$routeraddr|off-link$offlink|no-autoconfig$noautoconf}]",
+       NO_STR
        "Interface IPv6 config commands\n"
        "Neighbor discovery\n"
        "Prefix information\n"
@@ -1807,116 +1827,53 @@ DEFUN (ipv6_nd_prefix,
        "Infinite preferred lifetime\n"
        "Set Router Address flag\n"
        "Do not use prefix for onlink determination\n"
-       "Do not use prefix for autoconfiguration\n"
-       "Do not use prefix for autoconfiguration\n"
-       "Do not use prefix for onlink determination\n")
-{
-       /* prelude */
-       char *prefix = argv[3]->arg;
-       int lifetimes = (argc > 4) && (argv[4]->type == RANGE_TKN
-                                      || strmatch(argv[4]->text, "infinite"));
-       int routeropts = lifetimes ? argc > 6 : argc > 4;
-
-       int idx_routeropts = routeropts ? (lifetimes ? 6 : 4) : 0;
-
-       char *lifetime = NULL, *preflifetime = NULL;
-       int routeraddr = 0, offlink = 0, noautoconf = 0;
-       if (lifetimes) {
-               lifetime = argv[4]->type == RANGE_TKN ? argv[4]->arg
-                                                     : argv[4]->text;
-               preflifetime = argv[5]->type == RANGE_TKN ? argv[5]->arg
-                                                         : argv[5]->text;
-       }
-       if (routeropts) {
-               routeraddr =
-                       strmatch(argv[idx_routeropts]->text, "router-address");
-               if (!routeraddr) {
-                       offlink = (argc > idx_routeropts + 1
-                                  || strmatch(argv[idx_routeropts]->text,
-                                              "off-link"));
-                       noautoconf = (argc > idx_routeropts + 1
-                                     || strmatch(argv[idx_routeropts]->text,
-                                                 "no-autoconfig"));
+       "Do not use prefix for autoconfiguration\n")
+{
+       if (!no) {
+               nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+               if (valid) {
+                       if (strmatch(valid, "infinite"))
+                               valid = "4294967295";
+                       nb_cli_enqueue_change(vty, "./valid-lifetime",
+                                             NB_OP_MODIFY, valid);
+               } else {
+                       nb_cli_enqueue_change(vty, "./valid-lifetime",
+                                             NB_OP_DESTROY, NULL);
                }
-       }
-
-       /* business */
-       VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct zebra_if *zebra_if = ifp->info;
-       int ret;
-       struct rtadv_prefix rp;
-
-       ret = str2prefix_ipv6(prefix, &rp.prefix);
-       if (!ret) {
-               vty_out(vty, "Malformed IPv6 prefix\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-       apply_mask_ipv6(&rp.prefix); /* RFC4861 4.6.2 */
-       rp.AdvOnLinkFlag = !offlink;
-       rp.AdvAutonomousFlag = !noautoconf;
-       rp.AdvRouterAddressFlag = routeraddr;
-       rp.AdvValidLifetime = RTADV_VALID_LIFETIME;
-       rp.AdvPreferredLifetime = RTADV_PREFERRED_LIFETIME;
-       rp.AdvPrefixCreate = PREFIX_SRC_MANUAL;
-
-       if (lifetimes) {
-               rp.AdvValidLifetime = strmatch(lifetime, "infinite")
-                                             ? UINT32_MAX
-                                             : strtoll(lifetime, NULL, 10);
-               rp.AdvPreferredLifetime =
-                       strmatch(preflifetime, "infinite")
-                               ? UINT32_MAX
-                               : strtoll(preflifetime, NULL, 10);
-               if (rp.AdvPreferredLifetime > rp.AdvValidLifetime) {
-                       vty_out(vty, "Invalid preferred lifetime\n");
-                       return CMD_WARNING_CONFIG_FAILED;
+               if (preferred) {
+                       if (strmatch(preferred, "infinite"))
+                               preferred = "4294967295";
+                       nb_cli_enqueue_change(vty, "./preferred-lifetime",
+                                             NB_OP_MODIFY, preferred);
+               } else {
+                       nb_cli_enqueue_change(vty, "./preferred-lifetime",
+                                             NB_OP_DESTROY, NULL);
                }
+               if (routeraddr)
+                       nb_cli_enqueue_change(vty, "./router-address-flag",
+                                             NB_OP_MODIFY, "true");
+               else
+                       nb_cli_enqueue_change(vty, "./router-address-flag",
+                                             NB_OP_DESTROY, NULL);
+               if (offlink)
+                       nb_cli_enqueue_change(vty, "./on-link-flag",
+                                             NB_OP_MODIFY, "false");
+               else
+                       nb_cli_enqueue_change(vty, "./on-link-flag",
+                                             NB_OP_DESTROY, NULL);
+               if (noautoconf)
+                       nb_cli_enqueue_change(vty, "./autonomous-flag",
+                                             NB_OP_MODIFY, "false");
+               else
+                       nb_cli_enqueue_change(vty, "./autonomous-flag",
+                                             NB_OP_DESTROY, NULL);
+       } else {
+               nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
        }
-
-       rtadv_prefix_set(zebra_if, &rp);
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_ipv6_nd_prefix,
-       no_ipv6_nd_prefix_cmd,
-       "no ipv6 nd prefix X:X::X:X/M [<(0-4294967295)|infinite> <(0-4294967295)|infinite>] [<router-address|off-link [no-autoconfig]|no-autoconfig [off-link]>]",
-        NO_STR
-       "Interface IPv6 config commands\n"
-       "Neighbor discovery\n"
-       "Prefix information\n"
-       "IPv6 prefix\n"
-       "Valid lifetime in seconds\n"
-       "Infinite valid lifetime\n"
-       "Preferred lifetime in seconds\n"
-       "Infinite preferred lifetime\n"
-       "Set Router Address flag\n"
-       "Do not use prefix for onlink determination\n"
-       "Do not use prefix for autoconfiguration\n"
-       "Do not use prefix for autoconfiguration\n"
-       "Do not use prefix for onlink determination\n")
-{
-       VTY_DECLVAR_CONTEXT(interface, ifp);
-       struct zebra_if *zebra_if = ifp->info;
-       int ret;
-       struct rtadv_prefix rp;
-       char *prefix = argv[4]->arg;
-
-       ret = str2prefix_ipv6(prefix, &rp.prefix);
-       if (!ret) {
-               vty_out(vty, "Malformed IPv6 prefix\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-       apply_mask_ipv6(&rp.prefix); /* RFC4861 4.6.2 */
-       rp.AdvPrefixCreate = PREFIX_SRC_MANUAL;
-
-       ret = rtadv_prefix_reset(zebra_if, &rp);
-       if (!ret) {
-               vty_out(vty, "Non-existant IPv6 prefix\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(
+               vty,
+               "./frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix[prefix-spec='%s']",
+               prefix_str);
 }
 
 DEFPY_YANG (ipv6_nd_router_preference,
@@ -2626,7 +2583,6 @@ void rtadv_cmd_init(void)
        install_element(INTERFACE_NODE, &ipv6_nd_homeagent_lifetime_cmd);
        install_element(INTERFACE_NODE, &ipv6_nd_adv_interval_config_option_cmd);
        install_element(INTERFACE_NODE, &ipv6_nd_prefix_cmd);
-       install_element(INTERFACE_NODE, &no_ipv6_nd_prefix_cmd);
        install_element(INTERFACE_NODE, &ipv6_nd_router_preference_cmd);
        install_element(INTERFACE_NODE, &ipv6_nd_mtu_cmd);
        install_element(INTERFACE_NODE, &ipv6_nd_rdnss_cmd);
index 14a54435b0fd4c3fdaf8e502f2ba9257eaa770f3..8c434651329367b6d3be71cbf3309330002afbf3 100644 (file)
@@ -385,6 +385,13 @@ extern void rtadv_if_fini(struct zebra_if *zif);
 extern void rtadv_add_prefix(struct zebra_if *zif, const struct prefix_ipv6 *p);
 extern void rtadv_delete_prefix(struct zebra_if *zif, const struct prefix *p);
 
+/* returns created prefix */
+struct rtadv_prefix *rtadv_add_prefix_manual(struct zebra_if *zif,
+                                            struct rtadv_prefix *rp);
+/* rprefix must be the one returned by rtadv_add_prefix_manual */
+void rtadv_delete_prefix_manual(struct zebra_if *zif,
+                               struct rtadv_prefix *rprefix);
+
 void ipv6_nd_suppress_ra_set(struct interface *ifp,
                             enum ipv6_nd_suppress_ra_status status);
 void ipv6_nd_interval_set(struct interface *ifp, uint32_t interval);
index 794ccfadcb4b08b45a34cd3ad5579e0c8ceb2adc..40a4ee4a0249da0eefade20eaea38a7b06788915 100644 (file)
@@ -640,6 +640,43 @@ const struct frr_yang_module_info frr_zebra_info = {
                                .modify = lib_interface_zebra_ipv6_router_advertisements_default_router_preference_modify,
                        }
                },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix",
+                       .cbs = {
+                               .create = lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_create,
+                               .destroy = lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix/valid-lifetime",
+                       .cbs = {
+                               .modify = lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_valid_lifetime_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix/on-link-flag",
+                       .cbs = {
+                               .modify = lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_on_link_flag_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix/preferred-lifetime",
+                       .cbs = {
+                               .modify = lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_preferred_lifetime_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix/autonomous-flag",
+                       .cbs = {
+                               .modify = lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_autonomous_flag_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix/router-address-flag",
+                       .cbs = {
+                               .modify = lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_router_address_flag_modify,
+                       }
+               },
                {
                        .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/state/up-count",
                        .cbs = {
index ebe86769dcca1b71183e7a6744b4ff69e50faaca..d831a249d185966739952672d6a2ed84f0cb1fe3 100644 (file)
@@ -219,6 +219,20 @@ int lib_interface_zebra_ipv6_router_advertisements_home_agent_lifetime_destroy(
        struct nb_cb_destroy_args *args);
 int lib_interface_zebra_ipv6_router_advertisements_default_router_preference_modify(
        struct nb_cb_modify_args *args);
+int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_create(
+       struct nb_cb_create_args *args);
+int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_destroy(
+       struct nb_cb_destroy_args *args);
+int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_valid_lifetime_modify(
+       struct nb_cb_modify_args *args);
+int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_on_link_flag_modify(
+       struct nb_cb_modify_args *args);
+int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_preferred_lifetime_modify(
+       struct nb_cb_modify_args *args);
+int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_autonomous_flag_modify(
+       struct nb_cb_modify_args *args);
+int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_router_address_flag_modify(
+       struct nb_cb_modify_args *args);
 struct yang_data *
 lib_interface_zebra_state_up_count_get_elem(struct nb_cb_get_elem_args *args);
 struct yang_data *
index 83f691ffe42387dcf817b33be837d7039058da18..2fc42cc0d9562581e72799a0004f734b291529bd 100644 (file)
@@ -2869,6 +2869,144 @@ int lib_interface_zebra_ipv6_router_advertisements_default_router_preference_mod
        return NB_OK;
 }
 
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix
+ */
+int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_create(
+       struct nb_cb_create_args *args)
+{
+       struct interface *ifp;
+       struct rtadv_prefix rp, *prefix;
+
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       ifp = nb_running_get_entry(args->dnode, NULL, true);
+
+       yang_dnode_get_ipv6p(&rp.prefix, args->dnode, "prefix-spec");
+       rp.AdvOnLinkFlag = !!yang_dnode_get_bool(args->dnode, "on-link-flag");
+       rp.AdvAutonomousFlag = !!yang_dnode_get_bool(args->dnode,
+                                                    "autonomous-flag");
+       rp.AdvRouterAddressFlag = !!yang_dnode_get_bool(args->dnode,
+                                                       "router-address-flag");
+       rp.AdvValidLifetime = yang_dnode_get_uint32(args->dnode,
+                                                   "valid-lifetime");
+       rp.AdvPreferredLifetime = yang_dnode_get_uint32(args->dnode,
+                                                       "preferred-lifetime");
+
+       prefix = rtadv_add_prefix_manual(ifp->info, &rp);
+       nb_running_set_entry(args->dnode, prefix);
+
+       return NB_OK;
+}
+
+int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       struct interface *ifp;
+       struct rtadv_prefix *prefix;
+
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       prefix = nb_running_unset_entry(args->dnode);
+       ifp = nb_running_get_entry(args->dnode, NULL, true);
+
+       rtadv_delete_prefix_manual(ifp->info, prefix);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix/valid-lifetime
+ */
+int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_valid_lifetime_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct rtadv_prefix *prefix;
+
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       prefix = nb_running_get_entry(args->dnode, NULL, true);
+
+       prefix->AdvValidLifetime = yang_dnode_get_uint32(args->dnode, NULL);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix/on-link-flag
+ */
+int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_on_link_flag_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct rtadv_prefix *prefix;
+
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       prefix = nb_running_get_entry(args->dnode, NULL, true);
+
+       prefix->AdvOnLinkFlag = !!yang_dnode_get_bool(args->dnode, NULL);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix/preferred-lifetime
+ */
+int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_preferred_lifetime_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct rtadv_prefix *prefix;
+
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       prefix = nb_running_get_entry(args->dnode, NULL, true);
+
+       prefix->AdvPreferredLifetime = yang_dnode_get_uint32(args->dnode, NULL);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix/autonomous-flag
+ */
+int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_autonomous_flag_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct rtadv_prefix *prefix;
+
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       prefix = nb_running_get_entry(args->dnode, NULL, true);
+
+       prefix->AdvAutonomousFlag = !!yang_dnode_get_bool(args->dnode, NULL);
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/prefix-list/prefix/router-address-flag
+ */
+int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_router_address_flag_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct rtadv_prefix *prefix;
+
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       prefix = nb_running_get_entry(args->dnode, NULL, true);
+
+       prefix->AdvRouterAddressFlag = !!yang_dnode_get_bool(args->dnode, NULL);
+
+       return NB_OK;
+}
+
 /*
  * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/l3vni-id
  */