aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjackiechen1985 <xiaobo.chen@tieto.com>2019-05-19 12:35:28 +0800
committerJunfeng Wang <drenfong.wang@intel.com>2019-05-22 04:37:38 +0000
commitce1a0daa15be4c3b7a3df64ea57ad231664e700f (patch)
treefdb1fac57156ebc6e12e8ce9cd7942a8f4023c03
parentaeb421c7219178ac464e8a2e62b35772a08a2c1c (diff)
Introduce a new registration mechanism to sweetcomb.
Sweetcomb plugins register for various [initialization] events by placing structures and __attribute__((constructor)) functions into the library. When sysrepo plugin is initializing, the framework walks constructor-generated singly-linked structure lists, calls the indicated functions. Change-Id: I0cb078391f2662e4f6dd08c1a383173f203adf2a Signed-off-by: jackiechen1985 <xiaobo.chen@tieto.com>
-rw-r--r--src/plugins/CMakeLists.txt5
-rw-r--r--src/plugins/ietf/ietf_interface.c101
-rw-r--r--src/plugins/ietf/ietf_nat.c57
-rw-r--r--src/plugins/openconfig/openconfig_interfaces.c105
-rw-r--r--src/plugins/openconfig/openconfig_local_routing.c124
-rw-r--r--src/plugins/sc_init.c48
-rw-r--r--src/plugins/sc_init.h113
-rw-r--r--src/plugins/sc_model.c82
-rw-r--r--src/plugins/sc_model.h85
-rw-r--r--src/plugins/sc_plugins.c28
-rw-r--r--src/plugins/sc_plugins.h17
11 files changed, 401 insertions, 364 deletions
diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt
index a07ae60..ce09682 100644
--- a/src/plugins/CMakeLists.txt
+++ b/src/plugins/CMakeLists.txt
@@ -53,10 +53,13 @@ set(CMAKE_C_FLAGS_DEBUG "-Wall -Wextra -std=gnu99 -g -O0 ${RIGOROUS_C_FLAGS}")
#NDEBUG to skip assert checks
set(CMAKE_C_FLAGS_RELEASE "-Wall -Wextra -std=gnu99 -DNDEBUG -O2 ${RIGOROUS_C_FLAGS}")
+# add plugin include directories
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+
# plugins sources
set(PLUGINS_SOURCES
+ sc_init.c
sc_plugins.c
- sc_model.c
ietf/ietf_interface.c
ietf/ietf_nat.c
openconfig/openconfig_interfaces.c
diff --git a/src/plugins/ietf/ietf_interface.c b/src/plugins/ietf/ietf_interface.c
index 0f8c37e..4d13d13 100644
--- a/src/plugins/ietf/ietf_interface.c
+++ b/src/plugins/ietf/ietf_interface.c
@@ -16,8 +16,7 @@
#include <stdio.h>
#include <sys/socket.h>
-#include "../sc_model.h"
-#include "../sys_util.h"
+#include <sc_plugins.h>
#include <scvpp/interface.h>
#include <scvpp/ip.h>
@@ -339,51 +338,55 @@ nothing_todo:
return rc;
}
-const xpath_t ietf_interfaces_xpaths[IETF_INTERFACES_SIZE] = {
- {
- .xpath = "/ietf-interfaces:interfaces/interface",
- .method = XPATH,
- .datastore = SR_DS_RUNNING,
- .cb.scb = ietf_interface_change_cb,
- .private_ctx = NULL,
- .priority = 0,
- .opts = SR_SUBSCR_CTX_REUSE | SR_SUBSCR_EV_ENABLED
- },
- {
- .xpath = "/ietf-interfaces:interfaces/interface/enabled",
- .method = XPATH,
- .datastore = SR_DS_RUNNING,
- .cb.scb = ietf_interface_enable_disable_cb,
- .private_ctx = NULL,
- .priority = 100,
- .opts = SR_SUBSCR_CTX_REUSE | SR_SUBSCR_EV_ENABLED
- },
- {
- .xpath = "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/address",
- .method = XPATH,
- .datastore = SR_DS_RUNNING,
- .cb.scb = ietf_interface_ipv46_address_change_cb,
- .private_ctx = NULL,
- .priority = 99,
- .opts = SR_SUBSCR_CTX_REUSE | SR_SUBSCR_EV_ENABLED
- },
- {
- .xpath = "/ietf-interfaces:interfaces/interface/ietf-ip:ipv6/address",
- .method = XPATH,
- .datastore = SR_DS_RUNNING,
- .cb.scb = ietf_interface_ipv46_address_change_cb,
- .private_ctx = NULL,
- .priority = 98,
- .opts = SR_SUBSCR_CTX_REUSE | SR_SUBSCR_EV_ENABLED
- },
- {
- .xpath = "/ietf-interfaces:interfaces-state",
- .method = GETITEM,
- .datastore = SR_DS_RUNNING,
- .cb.gcb = ietf_interface_state_cb,
- .private_ctx = NULL,
- .priority = 98,
- //.opts = SR_SUBSCR_DEFAULT,
- .opts = SR_SUBSCR_CTX_REUSE
+
+int
+ietf_interface_init(sc_plugin_main_t *pm)
+{
+ int rc = SR_ERR_OK;
+ SRP_LOG_DBG_MSG("Initializing ietf-interface plugin.");
+
+ rc = sr_subtree_change_subscribe(pm->session, "/ietf-interfaces:interfaces/interface",
+ ietf_interface_change_cb, NULL, 0, SR_SUBSCR_CTX_REUSE | SR_SUBSCR_EV_ENABLED, &pm->subscription);
+ if (SR_ERR_OK != rc) {
+ goto error;
+ }
+
+ rc = sr_subtree_change_subscribe(pm->session, "/ietf-interfaces:interfaces/interface/enabled",
+ ietf_interface_enable_disable_cb, NULL, 100, SR_SUBSCR_CTX_REUSE | SR_SUBSCR_EV_ENABLED, &pm->subscription);
+ if (SR_ERR_OK != rc) {
+ goto error;
+ }
+
+ rc = sr_subtree_change_subscribe(pm->session, "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/address",
+ ietf_interface_ipv46_address_change_cb, NULL, 99, SR_SUBSCR_CTX_REUSE | SR_SUBSCR_EV_ENABLED, &pm->subscription);
+ if (SR_ERR_OK != rc) {
+ goto error;
+ }
+
+ rc = sr_subtree_change_subscribe(pm->session, "/ietf-interfaces:interfaces/interface/ietf-ip:ipv6/address",
+ ietf_interface_ipv46_address_change_cb, NULL, 98, SR_SUBSCR_CTX_REUSE | SR_SUBSCR_EV_ENABLED, &pm->subscription);
+ if (SR_ERR_OK != rc) {
+ goto error;
+ }
+
+ rc = sr_dp_get_items_subscribe(pm->session, "/ietf-interfaces:interfaces-state",
+ ietf_interface_state_cb, NULL, SR_SUBSCR_CTX_REUSE, &pm->subscription);
+ if (SR_ERR_OK != rc) {
+ goto error;
}
-};
+
+ SRP_LOG_DBG_MSG("ietf-interface plugin initialized successfully.");
+ return SR_ERR_OK;
+
+error:
+ SRP_LOG_ERR("Error by initialization of ietf-interface plugin. Error : %d", rc);
+ return rc;
+}
+
+void
+ietf_interface_exit(__attribute__((unused)) sc_plugin_main_t *pm)
+{
+}
+
+SC_INIT_FUNCTION(ietf_interface_init);
+SC_EXIT_FUNCTION(ietf_interface_exit);
diff --git a/src/plugins/ietf/ietf_nat.c b/src/plugins/ietf/ietf_nat.c
index 3b82f28..287fa02 100644
--- a/src/plugins/ietf/ietf_nat.c
+++ b/src/plugins/ietf/ietf_nat.c
@@ -18,7 +18,7 @@
#include <scvpp/interface.h>
#include <scvpp/nat.h>
-#include "../sc_model.h"
+#include <sc_plugins.h>
#include <assert.h>
#include <string.h>
@@ -29,8 +29,6 @@
#include <netinet/in.h>
#include <arpa/inet.h>
-#include "../sys_util.h"
-
/**
* @brief Wrapper struct for VAPI address range payload.
*/
@@ -490,23 +488,36 @@ error:
return rc;
}
-const xpath_t ietf_nat_xpaths[IETF_NAT_SIZE] = {
- {
- .xpath = "/ietf-nat:nat/instances/instance/policy/external-ip-address-pool",
- .method = XPATH,
- .datastore = SR_DS_RUNNING,
- .cb.scb = instances_instance_policy_external_ip_address_pool_cb,
- .private_ctx = NULL,
- .priority = 0,
- .opts = SR_SUBSCR_CTX_REUSE
- },
- {
- .xpath = "/ietf-nat:nat/instances/instance/mapping-table/mapping-entry",
- .method = XPATH,
- .datastore = SR_DS_RUNNING,
- .cb.scb = instances_instance_mapping_table_mapping_entry_cb,
- .private_ctx = NULL,
- .priority = 0,
- .opts = SR_SUBSCR_CTX_REUSE
- },
-};
+int
+ietf_nat_init(sc_plugin_main_t *pm)
+{
+ int rc = SR_ERR_OK;
+ SRP_LOG_DBG_MSG("Initializing ietf-nat plugin.");
+
+ rc = sr_subtree_change_subscribe(pm->session, "/ietf-nat:nat/instances/instance/policy/external-ip-address-pool",
+ instances_instance_policy_external_ip_address_pool_cb, NULL, 0, SR_SUBSCR_CTX_REUSE, &pm->subscription);
+ if (rc != SR_ERR_OK) {
+ goto error;
+ }
+
+ rc = sr_subtree_change_subscribe(pm->session, "/ietf-nat:nat/instances/instance/mapping-table/mapping-entry",
+ instances_instance_mapping_table_mapping_entry_cb, NULL, 0, SR_SUBSCR_CTX_REUSE, &pm->subscription);
+ if (rc != SR_ERR_OK) {
+ goto error;
+ }
+
+ SRP_LOG_DBG_MSG("ietf-nat plugin initialized successfully.");
+ return SR_ERR_OK;
+
+error:
+ SRP_LOG_ERR("Error by initialization of ietf-nat plugin. Error : %d", rc);
+ return rc;
+}
+
+void
+ietf_nat_exit(__attribute__((unused)) sc_plugin_main_t *pm)
+{
+}
+
+SC_INIT_FUNCTION(ietf_nat_init);
+SC_EXIT_FUNCTION(ietf_nat_exit);
diff --git a/src/plugins/openconfig/openconfig_interfaces.c b/src/plugins/openconfig/openconfig_interfaces.c
index 7242c2b..67b9a3c 100644
--- a/src/plugins/openconfig/openconfig_interfaces.c
+++ b/src/plugins/openconfig/openconfig_interfaces.c
@@ -21,8 +21,7 @@
#include <scvpp/interface.h>
#include <scvpp/ip.h>
-#include "../sc_model.h"
-#include "../sys_util.h"
+#include <sc_plugins.h>
// XPATH: /openconfig-interfaces:interfaces/interface[name='%s']/config/
static int openconfig_interfaces_interfaces_interface_config_cb(
@@ -590,52 +589,58 @@ static int openconfig_interfaces_interfaces_interface_subinterfaces_subinterface
return SR_ERR_OK;
}
-const xpath_t oc_interfaces_xpaths[OC_INTERFACES_SIZE] = {
- {
- .xpath = "/openconfig-interfaces:interfaces/interface/config",
- .method = XPATH,
- .datastore = SR_DS_RUNNING,
- .cb.scb = openconfig_interfaces_interfaces_interface_config_cb,
- .private_ctx = NULL,
- .priority = 98,
- //.opts = SR_SUBSCR_DEFAULT
- .opts = SR_SUBSCR_CTX_REUSE
- },
- {
- .xpath = "/openconfig-interfaces:interfaces/interface/state",
- .method = GETITEM,
- .datastore = SR_DS_RUNNING,
- .cb.gcb = openconfig_interfaces_interfaces_interface_state_cb,
- .private_ctx = NULL,
- .priority = 98,
- .opts = SR_SUBSCR_CTX_REUSE
- },
- {
- .xpath = "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/state",
- .method = GETITEM,
- .datastore = SR_DS_RUNNING,
- .cb.gcb = openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_state_cb,
- .private_ctx = NULL,
- .priority = 99,
- .opts = SR_SUBSCR_CTX_REUSE
- },
- {
- .xpath = "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv4/openconfig-if-ip:addresses/openconfig-if-ip:address/openconfig-if-ip:config",
- .method = XPATH,
- .datastore = SR_DS_RUNNING,
- .cb.scb = openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_oc_ip_ipv4_oc_ip_addresses_oc_ip_address_oc_ip_config_cb,
- .private_ctx = NULL,
- .priority = 100,
- //.opts = SR_SUBSCR_DEFAULT
- .opts = SR_SUBSCR_CTX_REUSE
- },
- {
- .xpath = "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv4/openconfig-if-ip:addresses/openconfig-if-ip:address/openconfig-if-ip:state",
- .method = GETITEM,
- .datastore = SR_DS_RUNNING,
- .cb.gcb = openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_oc_ip_ipv4_oc_ip_addresses_oc_ip_address_oc_ip_state_cb,
- .private_ctx = NULL,
- .priority = 100,
- .opts = SR_SUBSCR_CTX_REUSE
+int
+openconfig_interface_init(sc_plugin_main_t *pm)
+{
+ int rc = SR_ERR_OK;
+ SRP_LOG_DBG_MSG("Initializing openconfig-interfaces plugin.");
+
+ rc = sr_subtree_change_subscribe(pm->session, "/openconfig-interfaces:interfaces/interface/config",
+ openconfig_interfaces_interfaces_interface_config_cb, NULL, 98, SR_SUBSCR_CTX_REUSE, &pm->subscription);
+ if (SR_ERR_OK != rc) {
+ goto error;
+ }
+
+ rc = sr_dp_get_items_subscribe(pm->session, "/openconfig-interfaces:interfaces/interface/state",
+ openconfig_interfaces_interfaces_interface_state_cb, NULL, SR_SUBSCR_CTX_REUSE, &pm->subscription);
+ if (SR_ERR_OK != rc) {
+ goto error;
+ }
+
+ rc = sr_dp_get_items_subscribe(pm->session, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/state",
+ openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_state_cb, NULL, SR_SUBSCR_CTX_REUSE, &pm->subscription);
+ if (SR_ERR_OK != rc) {
+ goto error;
+ }
+
+ rc = sr_subtree_change_subscribe(pm->session,
+ "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv4/openconfig-if-ip:addresses/openconfig-if-ip:address/openconfig-if-ip:config",
+ openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_oc_ip_ipv4_oc_ip_addresses_oc_ip_address_oc_ip_config_cb,
+ NULL, 100, SR_SUBSCR_CTX_REUSE, &pm->subscription);
+ if (SR_ERR_OK != rc) {
+ goto error;
+ }
+
+ rc = sr_dp_get_items_subscribe(pm->session,
+ "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv4/openconfig-if-ip:addresses/openconfig-if-ip:address/openconfig-if-ip:state",
+ openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_oc_ip_ipv4_oc_ip_addresses_oc_ip_address_oc_ip_state_cb,
+ NULL, SR_SUBSCR_CTX_REUSE, &pm->subscription);
+ if (SR_ERR_OK != rc) {
+ goto error;
}
-};
+
+ SRP_LOG_DBG_MSG("openconfig-interfaces plugin initialized successfully.");
+ return SR_ERR_OK;
+
+error:
+ SRP_LOG_ERR("Error by initialization of openconfig-interfaces plugin. Error : %d", rc);
+ return rc;
+}
+
+void
+openconfig_interface_exit(__attribute__((unused)) sc_plugin_main_t *pm)
+{
+}
+
+SC_INIT_FUNCTION(openconfig_interface_init);
+SC_EXIT_FUNCTION(openconfig_interface_exit);
diff --git a/src/plugins/openconfig/openconfig_local_routing.c b/src/plugins/openconfig/openconfig_local_routing.c
index 6a3b5bd..2d16da0 100644
--- a/src/plugins/openconfig/openconfig_local_routing.c
+++ b/src/plugins/openconfig/openconfig_local_routing.c
@@ -21,8 +21,7 @@
#include <scvpp/interface.h>
#include <scvpp/ip.h>
-#include "../sc_model.h"
-#include "../sys_util.h"
+#include <sc_plugins.h>
#define HOP_INDEX_SIZE 10 //number of digit in max 32 bit integer
@@ -400,7 +399,7 @@ oc_next_hop_state_cb(const char *xpath, sr_val_t **values, size_t *values_cnt,
if (strtoul(index, NULL, 0) != reply->path[0].next_hop_id) {
SRP_LOG_ERR("next hop index is %d for prefix %s",
reply->path[0].next_hop_id, prefix);
- SRP_LOG_ERR("before %s, stroul is %d", index, strtoul(index, NULL, 0));
+ SRP_LOG_ERR("before %s, stroul is %lu", index, strtoul(index, NULL, 0));
return SR_ERR_INVAL_ARG;
}
@@ -468,7 +467,7 @@ oc_next_hop_interface_state_cb(const char *xpath, sr_val_t **values,
if (strtoul(index, NULL, 0) != reply->path[0].next_hop_id) {
SRP_LOG_ERR("next hop index is %d for prefix %s",
reply->path[0].next_hop_id, prefix);
- SRP_LOG_ERR("before %s, stroul is %d", index, strtoul(index, NULL, 0));
+ SRP_LOG_ERR("before %s, stroul is %lu", index, strtoul(index, NULL, 0));
return SR_ERR_INVAL_ARG;
}
@@ -489,62 +488,61 @@ oc_next_hop_interface_state_cb(const char *xpath, sr_val_t **values,
return SR_ERR_OK;
}
-const xpath_t oc_local_routing_xpaths[OC_LROUTING_SIZE] = {
- {
- .xpath = "/openconfig-local-routing:local-routes/static-routes/static/config",
- .method = XPATH,
- .datastore = SR_DS_RUNNING,
- .cb.scb = oc_prefix_config_cb,
- .private_ctx = NULL,
- .priority = 0,
- //.opts = SR_SUBSCR_DEFAULT
- .opts = SR_SUBSCR_CTX_REUSE
- },
- {
- .xpath = "/openconfig-local-routing:local-routes/static-routes/static/next-hops/next-hop/config",
- .method = XPATH,
- .datastore = SR_DS_RUNNING,
- .cb.scb = oc_next_hop_config_cb,
- .private_ctx = NULL,
- .priority = 0,
- //.opts = SR_SUBSCR_DEFAULT
- .opts = SR_SUBSCR_CTX_REUSE
- },
- {
- .xpath = "/openconfig-local-routing:local-routes/static-routes/static/next-hops/next-hop/interface-ref/config",
- .method = XPATH,
- .datastore = SR_DS_RUNNING,
- .cb.scb = oc_next_hop_interface_config_cb,
- .private_ctx = NULL,
- .priority = 0,
- //.opts = SR_SUBSCR_DEFAULT
- .opts = SR_SUBSCR_CTX_REUSE
- },
- {
- .xpath = "/openconfig-local-routing:local-routes/static-routes/static/state",
- .method = GETITEM,
- .datastore = SR_DS_RUNNING,
- .cb.gcb = oc_prefix_state_cb,
- .private_ctx = NULL,
- .priority = 0,
- .opts = SR_SUBSCR_CTX_REUSE
- },
- {
- .xpath = "/openconfig-local-routing:local-routes/static-routes/static/next-hops/next-hop/state",
- .method = GETITEM,
- .datastore = SR_DS_RUNNING,
- .cb.gcb = oc_next_hop_state_cb,
- .private_ctx = NULL,
- .priority = 0,
- .opts = SR_SUBSCR_CTX_REUSE
- },
- {
- .xpath = "/openconfig-local-routing:local-routes/static-routes/static/next-hops/next-hop/interface-ref/state",
- .method = GETITEM,
- .datastore = SR_DS_RUNNING,
- .cb.gcb = oc_next_hop_interface_state_cb,
- .private_ctx = NULL,
- .priority = 0,
- .opts = SR_SUBSCR_CTX_REUSE
- },
-};
+int
+openconfig_local_routing_init(sc_plugin_main_t *pm)
+{
+ int rc = SR_ERR_OK;
+ SRP_LOG_DBG_MSG("Initializing openconfig-local-routing plugin.");
+
+ rc = sr_subtree_change_subscribe(pm->session, "/openconfig-local-routing:local-routes/static-routes/static/config",
+ oc_prefix_config_cb, NULL, 0, SR_SUBSCR_CTX_REUSE, &pm->subscription);
+ if (SR_ERR_OK != rc) {
+ goto error;
+ }
+
+ rc = sr_subtree_change_subscribe(pm->session, "/openconfig-local-routing:local-routes/static-routes/static/next-hops/next-hop/config",
+ oc_next_hop_config_cb, NULL, 0, SR_SUBSCR_CTX_REUSE, &pm->subscription);
+ if (SR_ERR_OK != rc) {
+ goto error;
+ }
+
+ rc = sr_subtree_change_subscribe(pm->session, "/openconfig-local-routing:local-routes/static-routes/static/next-hops/next-hop/interface-ref/config",
+ oc_next_hop_interface_config_cb, NULL, 0, SR_SUBSCR_CTX_REUSE, &pm->subscription);
+ if (SR_ERR_OK != rc) {
+ goto error;
+ }
+
+ rc = sr_dp_get_items_subscribe(pm->session, "/openconfig-local-routing:local-routes/static-routes/static/state",
+ oc_prefix_state_cb, NULL, SR_SUBSCR_CTX_REUSE, &pm->subscription);
+ if (SR_ERR_OK != rc) {
+ goto error;
+ }
+
+ rc = sr_dp_get_items_subscribe(pm->session, "/openconfig-local-routing:local-routes/static-routes/static/next-hops/next-hop/state",
+ oc_next_hop_state_cb, NULL, SR_SUBSCR_CTX_REUSE, &pm->subscription);
+ if (SR_ERR_OK != rc) {
+ goto error;
+ }
+
+ rc = sr_dp_get_items_subscribe(pm->session, "/openconfig-local-routing:local-routes/static-routes/static/next-hops/next-hop/interface-ref/state",
+ oc_next_hop_interface_state_cb, NULL, SR_SUBSCR_CTX_REUSE, &pm->subscription);
+ if (SR_ERR_OK != rc) {
+ goto error;
+ }
+
+ SRP_LOG_DBG_MSG("openconfig-local-routing plugin initialized successfully.");
+ return SR_ERR_OK;
+
+error:
+ SRP_LOG_ERR("Error by initialization of openconfig-local-routing plugin. Error : %d", rc);
+ return rc;
+}
+
+void
+openconfig_local_routing_exit(__attribute__((unused)) sc_plugin_main_t *pm)
+{
+}
+
+SC_INIT_FUNCTION(openconfig_local_routing_init);
+SC_EXIT_FUNCTION(openconfig_local_routing_exit);
+
diff --git a/src/plugins/sc_init.c b/src/plugins/sc_init.c
new file mode 100644
index 0000000..baae3f6
--- /dev/null
+++ b/src/plugins/sc_init.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2019 Tieto and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sc_plugins.h"
+
+int
+sc_call_all_init_function(sc_plugin_main_t *pm)
+{
+ int ret = SR_ERR_OK;
+ _sc_init_function_list_elt_t *p = pm->init_function_registrations;
+ while (p != NULL) {
+ if (!p->is_called) {
+ p->is_called = true;
+ ret = p->func(pm);
+ if (ret != SR_ERR_OK) {
+ return ret;
+ }
+ }
+ p = p->next;
+ }
+ return ret;
+}
+
+void
+sc_call_all_exit_function(sc_plugin_main_t *pm)
+{
+ _sc_exit_function_list_elt_t *p = pm->exit_function_registrations;
+ while (p != NULL) {
+ if (!p->is_called) {
+ p->is_called = true;
+ p->func(pm);
+ }
+ p = p->next;
+ }
+}
+
diff --git a/src/plugins/sc_init.h b/src/plugins/sc_init.h
new file mode 100644
index 0000000..b7ba1ef
--- /dev/null
+++ b/src/plugins/sc_init.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2019 Tieto and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SC_INIT_H__
+#define __SC_INIT_H__
+
+#include <sysrepo.h>
+
+struct sc_plugin_main_t;
+
+/* Init/exit functions: called at start/end of sr plugin init/cleaup. */
+typedef int (sc_init_function_t) (struct sc_plugin_main_t *pm);
+typedef void (sc_exit_function_t) (struct sc_plugin_main_t *pm);
+
+/* Declaration of init/exit Linked List structures */
+#define foreach_sc_declare_function_list \
+_(init) \
+_(exit)
+
+#define _(tag) \
+typedef struct _sc_##tag##_function_list_elt { \
+ struct _sc_##tag##_function_list_elt *next; \
+ sc_##tag##_function_t *func; \
+ bool is_called; \
+} _sc_##tag##_function_list_elt_t;
+foreach_sc_declare_function_list
+#undef _
+
+/* Declaration of add/rm function that need to be add/remote link list */
+#define SC_DECLARE_FUNCTION(f, tag) \
+static void __sc_add_##tag##_function_##f() __attribute__((__constructor__)); \
+static void __sc_add_##tag##_function_##f() \
+{ \
+ sc_plugin_main_t *pm = sc_get_plugin_main(); \
+ static _sc_##tag##_function_list_elt_t _sc_##tag##_function; \
+ _sc_##tag##_function.next = pm->tag##_function_registrations; \
+ _sc_##tag##_function.func = &f; \
+ _sc_##tag##_function.is_called = false; \
+ pm->tag##_function_registrations = &_sc_##tag##_function; \
+} \
+static void __sc_rm_##tag##_function_##f() __attribute__((__destructor__)); \
+static void __sc_rm_##tag##_function_##f() \
+{ \
+ sc_plugin_main_t *pm = sc_get_plugin_main(); \
+ _sc_##tag##_function_list_elt_t *p; \
+ if (pm->tag##_function_registrations->func == &f) { \
+ pm->tag##_function_registrations = pm->tag##_function_registrations->next; \
+ return; \
+ } \
+ p = pm->tag##_function_registrations; \
+ while (p->next != NULL) { \
+ if (p->next->func == &f) { \
+ p->next = p->next->next; \
+ return; \
+ } \
+ p = p->next; \
+ } \
+}
+
+/* Macros to be called from yang model implementation.
+ Register init and exit functions for YANG model implementation in Linked List. */
+#define SC_INIT_FUNCTION(f) SC_DECLARE_FUNCTION(f, init)
+#define SC_EXIT_FUNCTION(f) SC_DECLARE_FUNCTION(f, exit)
+
+/* Call given init/exit function: used for init/exit function dependencies. */
+#define sc_call_init_function(f, pm) \
+({ \
+ int _ret = SR_ERR_OK; \
+ _sc_init_function_list_elt_t *p = pm->init_function_registrations; \
+ while (p != NULL) { \
+ if (p->func == f && !p->is_called) { \
+ p->is_called = true; \
+ _ret = p->func(pm); \
+ break; \
+ } \
+ p = p->next; \
+ } \
+ _ret; \
+})
+
+#define sc_call_exit_function(f, pm) \
+({ \
+ _sc_exit_function_list_elt_t *p = pm->exit_function_registrations; \
+ while (p != NULL) { \
+ if (p->func == f && !p->is_called) { \
+ p->is_called = true; \
+ p->func(pm); \
+ break; \
+ } \
+ p = p->next; \
+ } \
+})
+
+/* Run through all registered init/exit functions of models. */
+int
+sc_call_all_init_function(struct sc_plugin_main_t *pm);
+
+void
+sc_call_all_exit_function(struct sc_plugin_main_t *pm);
+
+#endif //__SC_INIT_H__
diff --git a/src/plugins/sc_model.c b/src/plugins/sc_model.c
deleted file mode 100644
index d9bf92b..0000000
--- a/src/plugins/sc_model.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2018 PANTHEON.tech.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "sc_model.h"
-
-#include <sysrepo/plugins.h>
-
-static int
-subscribe(sr_session_ctx_t *ds, sr_subscription_ctx_t **sub,
- const xpath_t *xpath)
-{
- int rc;
-
- switch (xpath->method) {
- case MODULE:
- rc = sr_module_change_subscribe(ds, xpath->xpath, xpath->cb.mcb,
- xpath->private_ctx, xpath->priority,
- xpath->opts, sub);
- break;
-
- case XPATH:
- rc = sr_subtree_change_subscribe(ds, xpath->xpath, xpath->cb.scb,
- xpath->private_ctx,
- xpath->priority, xpath->opts, sub);
- break;
-
- case GETITEM:
- rc = sr_dp_get_items_subscribe(ds, xpath->xpath, xpath->cb.gcb,
- xpath->private_ctx, xpath->opts,
- sub);
- break;
-
- case RPC:
- rc = sr_rpc_subscribe(ds, xpath->xpath, xpath->cb.rcb,
- xpath->private_ctx, xpath->opts, sub);
- break;
-
- default:
- SRP_LOG_ERR("Unknown method %d", xpath->method);
- return SR_ERR_NOT_FOUND;
- }
-
- if (SR_ERR_OK != rc) {
- SRP_LOG_ERR("Error subscribing to %s", xpath->xpath);
- return rc;
- }
-
- SRP_LOG_INF("Subscribed to xpath: %s", xpath->xpath);
-
- return SR_ERR_OK;
-}
-
-int
-model_register(plugin_main_t* plugin_main, const xpath_t *xpaths, size_t size)
-{
- int rc = 0;
- uint32_t i = 0;
-
- ARG_CHECK(-1, plugin_main);
-
- for (i = 0; i < size; i++) {
- rc = subscribe(plugin_main->session, &plugin_main->subscription,
- &xpaths[i]);
- if (SR_ERR_OK != rc)
- SRP_LOG_ERR("Subscription failed for xpath: %s", xpaths[i].xpath);
- }
-
- return 0;
-}
diff --git a/src/plugins/sc_model.h b/src/plugins/sc_model.h
deleted file mode 100644
index a9392f9..0000000
--- a/src/plugins/sc_model.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2018 PANTHEON.tech.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __SC_MODEL_H__
-#define __SC_MODEL_H__
-
-/*
- * IETF or Openconfig YANG models registering/unregistering
- *
- * Every model supports a certain number of operations which require a
- * subscription to sysrepo : xpath_t
- */
-
-#include <sysrepo.h>
-#include <sysrepo/xpath.h>
-#include <sysrepo/values.h>
-#include <sysrepo/plugins.h>
-
-#include <scvpp/comm.h> //for ARG_CHECK only
-
-typedef enum {
- MODULE,
- XPATH,
- GETITEM,
- RPC,
-} method_e;
-
-#define ARRAY_SIZE(X) (sizeof(X) / sizeof(X[0]))
-
-typedef struct _xpath_t {
- char *xpath;
- method_e method;
- sr_datastore_t datastore;
- union {
- sr_module_change_cb mcb;
- sr_subtree_change_cb scb;
- sr_dp_get_items_cb gcb;
- sr_rpc_cb rcb;
- } cb;
- void *private_ctx;
- uint32_t priority;
- sr_subscr_options_t opts;
-} xpath_t;
-
-/*
- * Stateful informations. Keep sesssions informations about a user
- */
-
-typedef struct {
- sr_session_ctx_t *session;
- sr_subscription_ctx_t *subscription;
-} plugin_main_t;
-
-
-int
-model_register(plugin_main_t *plugin_main, const xpath_t *xpaths, size_t size);
-
-/* Declare registration */
-
-#define OC_INTERFACES_SIZE 5
-extern const xpath_t oc_interfaces_xpaths[OC_INTERFACES_SIZE];
-
-#define OC_LROUTING_SIZE 6
-extern const xpath_t oc_local_routing_xpaths[OC_LROUTING_SIZE];
-
-#define IETF_NAT_SIZE 2
-extern const xpath_t ietf_nat_xpaths[IETF_NAT_SIZE];
-
-#define IETF_INTERFACES_SIZE 5
-extern const xpath_t ietf_interfaces_xpaths[IETF_INTERFACES_SIZE];
-
-#endif /* __SC_MODEL_H__ */
diff --git a/src/plugins/sc_plugins.c b/src/plugins/sc_plugins.c
index df191bf..e0de0f6 100644
--- a/src/plugins/sc_plugins.c
+++ b/src/plugins/sc_plugins.c
@@ -13,12 +13,18 @@
* limitations under the License.
*/
-#include "sc_model.h"
#include "sc_plugins.h"
+
#include <dirent.h>
+sc_plugin_main_t sc_plugin_main;
static int vpp_pid_start;
+sc_plugin_main_t *sc_get_plugin_main()
+{
+ return &sc_plugin_main;
+}
+
/* get vpp pid in system */
int get_vpp_pid()
{
@@ -63,26 +69,24 @@ int get_vpp_pid()
int sr_plugin_init_cb(sr_session_ctx_t *session, void **private_ctx)
{
- plugin_main_t plugin_main;
int rc;
+ sc_plugin_main.session = session;
+
rc = sc_connect_vpp();
if (0 != rc) {
SRP_LOG_ERR("vpp connect error , with return %d.", rc);
return SR_ERR_INTERNAL;
}
- plugin_main.session = session;
- plugin_main.subscription = NULL;
-
- /* Use the same sr_subscription_ctx for all models */
- model_register(&plugin_main, ietf_interfaces_xpaths, IETF_INTERFACES_SIZE);
- model_register(&plugin_main, ietf_nat_xpaths, IETF_NAT_SIZE);
- model_register(&plugin_main, oc_interfaces_xpaths, OC_INTERFACES_SIZE);
- model_register(&plugin_main, oc_local_routing_xpaths, OC_LROUTING_SIZE);
+ rc = sc_call_all_init_function(&sc_plugin_main);
+ if (rc != SR_ERR_OK) {
+ SRP_LOG_ERR("Call all init function error: %d", rc);
+ return rc;
+ }
/* set subscription as our private context */
- *private_ctx = plugin_main.subscription;
+ *private_ctx = sc_plugin_main.subscription;
/* get the vpp pid sweetcomb connected, we assumed that only one vpp is run in system */
vpp_pid_start = get_vpp_pid();
return SR_ERR_OK;
@@ -90,6 +94,8 @@ int sr_plugin_init_cb(sr_session_ctx_t *session, void **private_ctx)
void sr_plugin_cleanup_cb(sr_session_ctx_t *session, void *private_ctx)
{
+ sc_call_all_exit_function(&sc_plugin_main);
+
/* subscription was set as our private context */
if (private_ctx != NULL)
sr_unsubscribe(session, private_ctx);
diff --git a/src/plugins/sc_plugins.h b/src/plugins/sc_plugins.h
index 4a784fb..681be6b 100644
--- a/src/plugins/sc_plugins.h
+++ b/src/plugins/sc_plugins.h
@@ -20,6 +20,23 @@
#include <sysrepo/values.h>
#include <sysrepo/plugins.h>
+#include "sc_init.h"
+#include "sys_util.h"
+
+typedef struct sc_plugin_main_t {
+ /* Session context acquired with ::sr_session_start call. */
+ sr_session_ctx_t *session;
+
+ /* Subscription context that is supposed to be released by ::sr_unsubscribe */
+ sr_subscription_ctx_t *subscription;
+
+ /* List of init/exit functions to call, setup by constructors */
+ _sc_init_function_list_elt_t *init_function_registrations;
+ _sc_exit_function_list_elt_t *exit_function_registrations;
+} sc_plugin_main_t;
+
+sc_plugin_main_t *sc_get_plugin_main();
+
//functions that sysrepo-plugin need
int sr_plugin_init_cb(sr_session_ctx_t *session, void **private_ctx);
void sr_plugin_cleanup_cb(sr_session_ctx_t *session, void *private_ctx);