]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib: yang: add yang_parse_data function
authorChristian Hopps <chopps@labn.net>
Thu, 16 Jan 2025 04:14:03 +0000 (04:14 +0000)
committerChristian Hopps <chopps@labn.net>
Sat, 18 Jan 2025 16:13:53 +0000 (16:13 +0000)
This is similar to notify and RPC parsers, but this is for normal datastore
data. This is initially used in handling datastore notifications being sent to
another backend client[s].

Signed-off-by: Christian Hopps <chopps@labn.net>
lib/yang.c
lib/yang.h

index 2aa35392596e1c8828eb6c9639ae3188f4e22ad8..dd48d8861b7dd83b8dd6d2d057f75064b13a1498 100644 (file)
@@ -874,6 +874,60 @@ static void ly_zlog_cb(LY_LOG_LEVEL level, const char *msg, const char *data_pat
                zlog(priority, "libyang: %s", msg);
 }
 
+LY_ERR yang_parse_data(const char *xpath, LYD_FORMAT format, bool as_subtree, bool is_oper,
+                      bool validate, const char *data, struct lyd_node **tree)
+{
+       struct ly_in *in = NULL;
+       struct lyd_node *subtree = NULL;
+       uint32_t parse_options = LYD_PARSE_STRICT | LYD_PARSE_ONLY;
+       uint32_t validate_options = LYD_VALIDATE_PRESENT;
+       LY_ERR err;
+
+       err = ly_in_new_memory(data, &in);
+       if (err != LY_SUCCESS)
+               return err;
+
+       if (as_subtree) {
+               struct lyd_node *parent;
+
+               /*
+                * Create the subtree branch from root using the xpath. This
+                * will be used below to parse the data rooted at the subtree --
+                * a common YANG JSON technique (vs XML which starts all
+                * data trees from the root).
+                */
+               err = lyd_new_path2(NULL, ly_native_ctx, xpath, NULL, 0, 0, 0, &parent, &subtree);
+               if (err != LY_SUCCESS)
+                       goto done;
+               err = lyd_find_path(parent, xpath, false, &subtree);
+               if (err != LY_SUCCESS)
+                       goto done;
+       }
+
+       if (is_oper)
+               validate_options |= LYD_VALIDATE_OPERATIONAL;
+
+#ifdef LYD_VALIDATE_NOT_FINAL
+       if (!validate)
+               validate_options |= LYD_VALIDATE_NOT_FINAL;
+#endif
+
+       err = lyd_parse_data(ly_native_ctx, subtree, in, format, parse_options, validate_options,
+                            tree);
+       if (err == LY_SUCCESS && subtree)
+               *tree = subtree;
+done:
+       ly_in_free(in, 0);
+       if (err != LY_SUCCESS) {
+               if (*tree)
+                       lyd_free_all(*tree);
+               else if (subtree)
+                       lyd_free_all(subtree);
+               *tree = NULL;
+       }
+       return err;
+}
+
 LY_ERR yang_parse_notification(const char *xpath, LYD_FORMAT format,
                               const char *data, struct lyd_node **notif)
 {
index eed2fa8dbe16016f1bdde3a441a5438deb980c88..748f089037d03d358ee6c7ce49d94ae47b4e4ac7 100644 (file)
@@ -681,6 +681,25 @@ extern struct ly_ctx *yang_ctx_new_setup(bool embedded_modules, bool explicit_co
  */
 extern void yang_debugging_set(bool enable);
 
+
+/*
+ * Parse YANG data.
+ *
+ * Args:
+ *     xpath: xpath of the data.
+ *     format: LYD_FORMAT of input data.
+ *     as_subtree: parse the data as starting at the subtree identified by xpath.
+ *     is_oper: parse as operational state allows for invalid (logs warning).
+ *     validate: validate the data (otherwise treat as non-final).
+ *     data: input data.
+ *     notif: pointer to the libyang data tree to store the parsed notification.
+ *            If the notification is not on the top level of the yang model,
+ *            the pointer to the notification node is still returned, but it's
+ *            part of the full data tree with all its parents.
+ */
+LY_ERR yang_parse_data(const char *xpath, LYD_FORMAT format, bool as_subtree, bool is_oper,
+                      bool validate, const char *data, struct lyd_node **tree);
+
 /*
  * Parse a YANG notification.
  *