C Configd Client Library

Introduction

Please refer to Configd Client Library for the general concepts behind the API. This document will cover only C specifics. It is not recommended that the C configd API is used in end user code; it is very low level and path creation can be tricky to do correctly. A path in this API is a "/" separated string where each element is URL escaped.

Mechanics

Before we can use the configd API we need to establish a connection to the daemon, one uses "configd_open_connection" to do this. The "configd_close_connection" function will terminate the connection.

#include <vyatta-cfg/client/connect.h> int main(int argc, char **argv) { struct configd_conn conn; if (configd_open_connection(&conn) != 0) { fprintf(stderr, "failed to open configd connection"); return -1; } configd_close_connection(&conn); }

Once connected we can do a variety of actions on the system, one can configure the device, request the operational state of the device, or perform feature specific RPCs. When configuring the device via the Configd APIs one follows much the same procedure as with the CLI. One creates a configuration session, makes changes, commits those changes, then tears down the session. One may view the RUNNING datastore without a session being created. Sessions persist process exit and must be explicitly removed with "configd_sess_teardown". The minimal configuration application looks like the following.

#define _GNU_SOURCE #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <vyatta-cfg/client/connect.h> #include <vyatta-cfg/client/error.h> #include <vyatta-cfg/client/session.h> int main(int argc, char **argv) { struct configd_conn conn; struct configd_error err = {0}; if (configd_open_connection(&conn) != 0) { fprintf(stderr, "failed to open configd connection\n"); return -1; } pid_t pid = getpid(); char *sess_id = NULL; asprintf(&sess_id, "%d", pid); configd_set_session_id(&conn, sess_id); free(sess_id); if (configd_sess_setup(&conn, &err) != 0) { fprintf(stderr, "failed to setup session %s\n", err.text); return -1; } //do something with the config if (configd_sess_teardown(&conn, &err) != 0) { fprintf(stderr, "failed to teardown session %s\n", err.text); return -1; } configd_error_free(&err); configd_close_connection(&conn); }

From here, one may perform actions similar to what one does on the CLI. Since the interface here is meant for programatic interaction, one may also introspect on the data-model and the current state of the candidate tree to determine available actions, this is similar to using "tab-completion" to inspect the CLI.

Examples

Configuration

The following example uses the C configd API to set all dataplane interfaces to listen for DHCP addresses if no other address is assigned to that interface. While this is a silly thing to do, it demonstrates the basic mechanics of the this API.

#define _GNU_SOURCE #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <vyatta-cfg/client/connect.h> #include <vyatta-cfg/client/error.h> #include <vyatta-cfg/client/node.h> #include <vyatta-cfg/client/rpc.h> #include <vyatta-cfg/client/session.h> #include <vyatta-cfg/client/transaction.h> #include <vyatta-util/vector.h> static int setup_interface_address(struct configd_conn *conn, const char *intf, struct configd_error *err) { int rc = 0; char *path = NULL; char *dhcp_path = NULL; asprintf(&path, "/interfaces/dataplane/%s/address", intf); asprintf(&dhcp_path, "/interfaces/dataplane/%s/address/dhcp", intf); printf("%s:", intf); struct vector *addrs = configd_node_get(conn, AUTO, path, err); if (!addrs) { rc = -1; goto out; } const char *addr = NULL; if ((addr = vector_next(addrs, addr)) != NULL) { printf("%s", addr); while ((addr = vector_next(addrs, addr))) { printf(", %s", addr); } } printf("\n"); if (vector_count(addrs) == 0) { char *out = configd_set(conn, dhcp_path, err); if (!out) { rc = -1; goto free_vector; } free(out); } free_vector: vector_free(addrs); out: free(path); free(dhcp_path); return rc; } int main(int argc, char **argv) { int rc = 0; struct configd_conn conn; struct configd_error err = {0}; if (configd_open_connection(&conn) != 0) { fprintf(stderr, "failed to open configd connection\n"); return -1; } pid_t pid = getpid(); char *sess_id = NULL; asprintf(&sess_id, "%d", pid); configd_set_session_id(&conn, sess_id); free(sess_id); if (configd_sess_setup(&conn, &err) != 0) { fprintf(stderr, "failed to setup session %s\n", err.text); rc = -1; goto done; } struct vector * intfs = configd_node_get(&conn, AUTO, "/interfaces/dataplane", &err); if (!intfs) { fprintf(stderr, "%s\n", err.text); rc = -1; goto done; } const char *intf = NULL; while ((intf = vector_next(intfs, intf)) != NULL) { if (setup_interface_address(&conn, intf, &err) != 0) { fprintf(stderr, "%s\n", err.text); rc = -1; goto free_vector; } } char *out = configd_commit(&conn, "setup interface addresses", &err); if (!out) { fprintf(stderr, "%s\n", err.text); rc = -1; goto free_vector; } else { printf("%s\n", out); free(out); } if (configd_sess_teardown(&conn, &err) != 0) { fprintf(stderr, "failed to teardown session %s\n", err.text); rc = -1; } free_vector: vector_free(intfs); done: configd_error_free(&err); configd_close_connection(&conn); return rc; }

Below is a sample run of the above application.

RPC

One can also call an RPC via this interface.

Below is an example run of the RPC application.

Operational State Data

Finally one may query for operational data information.

Below is an example execution of this program.



Man Page

The following documentation was generated automatically using Doxygen.

auth.h



callrpc.h

connect.h



error.h



file.h

node.h



rpc.h



session.h



template.h



transaction.h