From ad3e1e26d02e19a47e32ab850554ca383c5c5d19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 9 Aug 2022 16:04:55 +0200 Subject: [PATCH 001/247] interfaces-plugin: remove current plugin implementation --- src/interfaces/CMakeLists.txt | 54 - src/interfaces/datastore.c | 348 ---- src/interfaces/datastore.h | 117 -- src/interfaces/if_nic_stats.c | 125 -- src/interfaces/if_nic_stats.h | 31 - src/interfaces/if_state.c | 89 - src/interfaces/if_state.h | 45 - src/interfaces/interfaces.c | 3116 --------------------------------- src/interfaces/ip_data.c | 285 --- src/interfaces/ip_data.h | 92 - src/interfaces/ipv4_data.h | 21 - src/interfaces/ipv6_data.c | 56 - src/interfaces/ipv6_data.h | 43 - src/interfaces/link_data.c | 638 ------- src/interfaces/link_data.h | 106 -- 15 files changed, 5166 deletions(-) delete mode 100644 src/interfaces/CMakeLists.txt delete mode 100644 src/interfaces/datastore.c delete mode 100644 src/interfaces/datastore.h delete mode 100644 src/interfaces/if_nic_stats.c delete mode 100644 src/interfaces/if_nic_stats.h delete mode 100644 src/interfaces/if_state.c delete mode 100644 src/interfaces/if_state.h delete mode 100644 src/interfaces/interfaces.c delete mode 100644 src/interfaces/ip_data.c delete mode 100644 src/interfaces/ip_data.h delete mode 100644 src/interfaces/ipv4_data.h delete mode 100644 src/interfaces/ipv6_data.c delete mode 100644 src/interfaces/ipv6_data.h delete mode 100644 src/interfaces/link_data.c delete mode 100644 src/interfaces/link_data.h diff --git a/src/interfaces/CMakeLists.txt b/src/interfaces/CMakeLists.txt deleted file mode 100644 index a436010f..00000000 --- a/src/interfaces/CMakeLists.txt +++ /dev/null @@ -1,54 +0,0 @@ -cmake_minimum_required(VERSION 2.8) -project(sysrepo-plugin-interfaces C) - -set(SOURCES - interfaces.c - if_state.c - link_data.c - ip_data.c - ipv6_data.c - if_nic_stats.c - datastore.c - ${CMAKE_SOURCE_DIR}/src/utils/memory.c -) - -# get sysrepo version -find_package(PkgConfig) -if (PKG_CONFIG_FOUND) - execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} "--modversion" "sysrepo" OUTPUT_VARIABLE SYSREPO_VERSION) - if(SYSREPO_VERSION) - # strip new line from string - string(STRIP ${SYSREPO_VERSION} SYSREPO_VERSION) - if(${SYSREPO_VERSION} VERSION_LESS "1.0.0") - message(FATAL_ERROR "${PROJECT_NAME} requires at least libsysrepo verision 1.0.0") - endif() - endif() -endif() - -if(PLUGIN) - add_library(${PROJECT_NAME} MODULE ${SOURCES}) - install(TARGETS ${PROJECT_NAME} DESTINATION lib) -else() - add_executable(${PROJECT_NAME} ${SOURCES}) - install(TARGETS ${PROJECT_NAME} DESTINATION bin) -endif() - -set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME ${PROJECT_NAME} PREFIX "") - -find_package(NL REQUIRED) - -# pthread api -set(THREADS_PREFER_PTHREAD_FLAG ON) -find_package(Threads REQUIRED) - -target_link_libraries( - ${PROJECT_NAME} - ${SYSREPO_LIBRARIES} - ${LIBYANG_LIBRARIES} - ${NL_LIBRARIES} - Threads::Threads -) - -include_directories( - ${NL_INCLUDE_DIRS} -) diff --git a/src/interfaces/datastore.c b/src/interfaces/datastore.c deleted file mode 100644 index 1364783b..00000000 --- a/src/interfaces/datastore.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * telekom / sysrepo-plugin-interfaces - * - * This program is made available under the terms of the - * BSD 3-Clause license which is available at - * https://opensource.org/licenses/BSD-3-Clause - * - * SPDX-FileCopyrightText: 2021 Deutsche Telekom AG - * SPDX-FileContributor: Sartura Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include - -#include -#include -#include - -#include "datastore.h" - -/* - * Set the value of multiple YANG module leafs. The path for each leaf node is determined - * by concatenating base_xpath with its name from leaf_names. All leaf nodes with a non-NULL - * entry in leaf_values will be set. - */ -static int ds_set_leaf_values(sr_session_ctx_t *session, char *base_xpath, char **leaf_names, - uint32_t leaf_count, char **leaf_values, bool log_changes) -{ - int error = SR_ERR_OK; - char xpath[PATH_MAX] = {0}; - - for (uint32_t i = 0; i < leaf_count; i++) { - if (leaf_values[i] == NULL) { - continue; - } - error = snprintf(xpath, sizeof(xpath), "%s/%s", base_xpath, leaf_names[i]); - if (error < 0 || error >= PATH_MAX) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf error (%d): %s", error, strerror(error)); - goto out; - } - error = sr_set_item_str(session, xpath, leaf_values[i], NULL, SR_EDIT_DEFAULT); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_set_item_str error (%d): %s", error, sr_strerror(error)); - goto out; - } - if (log_changes) { - SRPLG_LOG_DBG(PLUGIN_NAME, "%s = %s", xpath, leaf_values[i]); - } - } -out: - return error; -} - -static char *interface_leaf_names[IF_LEAF_COUNT] = { - [IF_TYPE] = "type", - [IF_DESCRIPTION] = "description", - [IF_ENABLED] = "enabled", - [IF_PARENT_INTERFACE] = "ietf-if-extensions:parent-interface" -}; - -int ds_set_general_interface_config(sr_session_ctx_t *session, char *interface_name, - char *leaf_values[IF_LEAF_COUNT]) -{ - int error = SR_ERR_OK; - char base_xpath[PATH_MAX] = {0}; - error = snprintf(base_xpath, sizeof(base_xpath), "%s[name=\"%s\"]", - INTERFACE_LIST_YANG_PATH, interface_name); - if (error < 0 || error >= PATH_MAX) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf error (%d): %s", error, strerror(error)); - goto out; - } - error = ds_set_leaf_values(session, base_xpath, interface_leaf_names, - IF_LEAF_COUNT, leaf_values, true); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "ds_set_leaf_values error"); - } -out: - return error; -} - -/* Leaf nodes defined for both ipv4 and ipv6 */ -static char *interface_ip_leaf_names[IF_IP_LEAF_COUNT] = { - [IF_IP_ENABLED] = "enabled", - [IF_IP_FORWARDING] = "forwarding", - [IF_IP_MTU] = "mtu" -}; - -int ds_set_interface_ip_config(sr_session_ctx_t *session, char *interface_name, char *ip_version, - char *leaf_values[IF_IP_LEAF_COUNT]) -{ - int error = SR_ERR_OK; - char base_xpath[PATH_MAX] = {0}; - error = snprintf(base_xpath, sizeof(base_xpath), "%s[name=\"%s\"]/ietf-ip:%s", - INTERFACE_LIST_YANG_PATH, interface_name, ip_version); - if (error < 0 || error >= PATH_MAX) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf error (%d): %s", error, strerror(error)); - goto out; - } - error = ds_set_leaf_values(session, base_xpath, interface_ip_leaf_names, - IF_IP_LEAF_COUNT, leaf_values, true); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "ds_set_leaf_values error"); - } -out: - return error; -} - -int ds_set_interface_ipv4_config(sr_session_ctx_t *session, char *interface_name, - char *leaf_values[IF_IP_LEAF_COUNT]) -{ - return ds_set_interface_ip_config(session, interface_name, "ipv4", leaf_values); -} - -int ds_set_interface_ipv6_config(sr_session_ctx_t *session, char *interface_name, - char *leaf_values[IF_IP_LEAF_COUNT]) -{ - return ds_set_interface_ip_config(session, interface_name, "ipv6", leaf_values); -} - -static char *interface_ipv4_addr_leaf_names[IF_IPV4_ADDR_LEAF_COUNT] = { - [IF_IPV4_ADDR_SUBNET] = "subnet", - [IF_IPV4_ADDR_PREFIX_LENGTH] = "prefix-length", - [IF_IPV4_ADDR_ORIGIN] = "origin" -}; - -int ds_add_interface_ipv4_address(sr_session_ctx_t *session, char *interface_name, - char *ip, char *leaf_values[IF_IPV4_ADDR_LEAF_COUNT]) -{ - int error = SR_ERR_OK; - char base_xpath[PATH_MAX] = {0}; - error = snprintf(base_xpath, sizeof(base_xpath), "%s[name=\"%s\"]/ietf-ip:ipv4/address[ip='%s']", - INTERFACE_LIST_YANG_PATH, interface_name, ip); - if (error < 0 || error >= PATH_MAX) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf error (%d): %s", error, strerror(error)); - goto out; - } - error = ds_set_leaf_values(session, base_xpath, interface_ipv4_addr_leaf_names, - IF_IPV4_ADDR_LEAF_COUNT, leaf_values, true); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "ds_set_leaf_values error"); - } -out: - return error; -} - -static char *interface_ipv4_neigh_leaf_names[IF_IPV4_NEIGH_LEAF_COUNT] = { - [IF_IPV4_NEIGH_LINK_LAYER_ADDR] = "link-layer-address", - [IF_IPV4_NEIGH_ORIGIN] = "origin" -}; - -int ds_add_interface_ipv4_neighbor(sr_session_ctx_t *session, char *interface_name, - char *neigh_ip, char *leaf_values[IF_IPV4_NEIGH_LEAF_COUNT]) -{ - int error = SR_ERR_OK; - char base_xpath[PATH_MAX] = {0}; - error = snprintf(base_xpath, sizeof(base_xpath), "%s[name=\"%s\"]/ietf-ip:ipv4/neighbor[ip='%s']", - INTERFACE_LIST_YANG_PATH, interface_name, neigh_ip); - if (error < 0 || error >= PATH_MAX) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf error (%d): %s", error, strerror(error)); - goto out; - } - error = ds_set_leaf_values(session, base_xpath, interface_ipv4_neigh_leaf_names, - IF_IPV4_NEIGH_LEAF_COUNT, leaf_values, true); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "ds_set_leaf_values error"); - } -out: - return error; -} - -static char *interface_ipv6_addr_leaf_names[IF_IPV6_ADDR_LEAF_COUNT] = { - [IF_IPV6_ADDR_PREFIX_LENGTH] = "prefix-length", - [IF_IPV6_ADDR_ORIGIN] = "origin", - [IF_IPV6_ADDR_STATUS] = "status" -}; - -int ds_add_interface_ipv6_address(sr_session_ctx_t *session, char *interface_name, - char *ip, char *leaf_values[IF_IPV6_ADDR_LEAF_COUNT]) -{ - int error = SR_ERR_OK; - char base_xpath[PATH_MAX] = {0}; - error = snprintf(base_xpath, sizeof(base_xpath), "%s[name=\"%s\"]/ietf-ip:ipv6/address[ip='%s']", - INTERFACE_LIST_YANG_PATH, interface_name, ip); - if (error < 0 || error >= PATH_MAX) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf error (%d): %s", error, strerror(error)); - goto out; - } - error = ds_set_leaf_values(session, base_xpath, interface_ipv6_addr_leaf_names, - IF_IPV6_ADDR_LEAF_COUNT, leaf_values, true); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "ds_set_leaf_values error"); - } -out: - return error; -} - -static char *interface_ipv6_neigh_leaf_names[IF_IPV6_NEIGH_LEAF_COUNT] = { - [IF_IPV6_NEIGH_LINK_LAYER_ADDR] = "link-layer-address", - [IF_IPV6_NEIGH_ORIGIN] = "origin", - [IF_IPV6_NEIGH_IS_ROUTER] = "is-router", - [IF_IPV6_NEIGH_STATE] = "state" -}; - -int ds_add_interface_ipv6_neighbor(sr_session_ctx_t *session, char *interface_name, - char *neigh_ip, char *leaf_values[IF_IPV6_NEIGH_LEAF_COUNT]) -{ - int error = SR_ERR_OK; - char base_xpath[PATH_MAX] = {0}; - error = snprintf(base_xpath, sizeof(base_xpath), "%s[name=\"%s\"]/ietf-ip:ipv6/neighbor[ip='%s']", - INTERFACE_LIST_YANG_PATH, interface_name, neigh_ip); - if (error < 0 || error >= PATH_MAX) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf error (%d): %s", error, strerror(error)); - goto out; - } - error = ds_set_leaf_values(session, base_xpath, interface_ipv6_neigh_leaf_names, - IF_IPV6_NEIGH_LEAF_COUNT, leaf_values, true); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "ds_set_leaf_values error"); - } -out: - return error; -} - -static char *interface_oper_info_leaf_names[IF_OPER_LEAF_COUNT] = { - [IF_ADMIN_STATUS] = "admin-status", - [IF_OPER_STATUS] = "oper-status", - [IF_LAST_CHANGE] = "last-change", - [IF_IF_INDEX] = "if-index", - [IF_PHYS_ADDRESS] = "phys-address", - [IF_SPEED] = "speed" -}; - -int ds_oper_set_interface_info(struct lyd_node *parent, const struct ly_ctx *ly_ctx, char *interface_name, - char *leaf_values[IF_OPER_LEAF_COUNT]) -{ - int error = SR_ERR_OK; - for (uint32_t i = 0; i < IF_OPER_LEAF_COUNT; i++) { - if (leaf_values[i] == NULL) { - continue; - } - char xpath[PATH_MAX] = {0}; - error = snprintf(xpath, sizeof(xpath), "%s[name=\"%s\"]/%s", INTERFACE_LIST_YANG_PATH, - interface_name, interface_oper_info_leaf_names[i]); - if (error < 0 || error >= PATH_MAX) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf error (%d): %s", error, strerror(error)); - goto out; - } - error = 0; - SRPLG_LOG_DBG(PLUGIN_NAME, "%s = %s", xpath, leaf_values[i]); - error = lyd_new_path(parent, ly_ctx, xpath, leaf_values[i], LYD_ANYDATA_STRING, NULL); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "lyd_new_path error (%d)", error); - goto out; - } - } -out: - return error; -} - -int ds_oper_add_interface_higher_layer_if(struct lyd_node *parent, const struct ly_ctx *ly_ctx, - char *interface_name, char *higher_layer_if) -{ - int error = SR_ERR_OK; - char xpath[PATH_MAX] = {0}; - error = snprintf(xpath, sizeof(xpath), "%s[name=\"%s\"]/higher-layer-if", - INTERFACE_LIST_YANG_PATH, interface_name); - if (error < 0 || error >= PATH_MAX) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf error (%d): %s", error, strerror(error)); - goto out; - } - error = 0; - SRPLG_LOG_DBG(PLUGIN_NAME, "%s += %s", xpath, higher_layer_if); - error = lyd_new_path(parent, ly_ctx, xpath, higher_layer_if, LYD_ANYDATA_STRING, NULL); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "lyd_new_path error (%d)", error); - } -out: - return error; -} - -int ds_oper_add_interface_lower_layer_if(struct lyd_node *parent, const struct ly_ctx *ly_ctx, - char *interface_name, char *lower_layer_if) -{ - int error = SR_ERR_OK; - char xpath[PATH_MAX] = {0}; - error = snprintf(xpath, sizeof(xpath), "%s[name=\"%s\"]/lower-layer-if", - INTERFACE_LIST_YANG_PATH, interface_name); - if (error < 0 || error >= PATH_MAX) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf error (%d): %s", error, strerror(error)); - goto out; - } - error = 0; - SRPLG_LOG_DBG(PLUGIN_NAME, "%s += %s", xpath, lower_layer_if); - error = lyd_new_path(parent, ly_ctx, xpath, lower_layer_if, LYD_ANYDATA_STRING, NULL); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "lyd_new_path error (%d)", error); - } -out: - return error; -} - -static char *interface_statistics_leaf_names[IF_STATS_LEAF_COUNT] = { - [IF_STATS_DISCONTINUITY_TIME] = "discontinuity-time", - [IF_STATS_IN_OCTETS] = "in-octets", - [IF_STATS_IN_UNICAST_PKTS] = "in-unicast-pkts", - [IF_STATS_IN_BROADCAST_PKTS] = "in-broadcast-pkts", - [IF_STATS_IN_MULTICAST_PKTS] = "in-multicast-pkts", - [IF_STATS_IN_DISCARDS] = "in-discards", - [IF_STATS_IN_ERRORS] = "in-errors", - [IF_STATS_IN_UNKNOWN_PROTOS] = "in-unknown-protos", - [IF_STATS_OUT_OCTETS] = "out-octets", - [IF_STATS_OUT_UNICAST_PKTS] = "out-unicast-pkts", - [IF_STATS_OUT_BROADCAST_PKTS] = "out-broadcast-pkts", - [IF_STATS_OUT_MULTICAST_PKTS] = "out-multicast-pkts", - [IF_STATS_OUT_DISCARDS] = "out-discards", - [IF_STATS_OUT_ERRORS] = "out-errors" -}; - -int ds_oper_set_interface_statistics(struct lyd_node *parent, const struct ly_ctx *ly_ctx, - char *interface_name, char *leaf_values[IF_STATS_LEAF_COUNT]) -{ - int error = SR_ERR_OK; - for (uint32_t i = 0; i < IF_STATS_LEAF_COUNT; i++) { - if (leaf_values[i] == NULL) { - continue; - } - char xpath[PATH_MAX] = {0}; - error = snprintf(xpath, sizeof(xpath), "%s[name=\"%s\"]/statistics/%s", INTERFACE_LIST_YANG_PATH, - interface_name, interface_statistics_leaf_names[i]); - if (error < 0 || error >= PATH_MAX) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf error (%d): %s", error, strerror(error)); - goto out; - } - error = 0; - SRPLG_LOG_DBG(PLUGIN_NAME, "%s = %s", xpath, leaf_values[i]); - error = lyd_new_path(parent, ly_ctx, xpath, leaf_values[i], LYD_ANYDATA_STRING, NULL); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "lyd_new_path error (%d)", error); - goto out; - } - } -out: - return error; -} \ No newline at end of file diff --git a/src/interfaces/datastore.h b/src/interfaces/datastore.h deleted file mode 100644 index 43ef45e7..00000000 --- a/src/interfaces/datastore.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * telekom / sysrepo-plugin-interfaces - * - * This program is made available under the terms of the - * BSD 3-Clause license which is available at - * https://opensource.org/licenses/BSD-3-Clause - * - * SPDX-FileCopyrightText: 2021 Deutsche Telekom AG - * SPDX-FileContributor: Sartura Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef DATASTORE_H_ONCE -#define DATASTORE_H_ONCE - -#define PLUGIN_NAME "interfaces-plugin" - -#define BASE_YANG_MODEL "ietf-interfaces" -#define BASE_IP_YANG_MODEL "ietf-ip" -// config data -#define INTERFACES_YANG_MODEL "/" BASE_YANG_MODEL ":interfaces" -#define INTERFACE_LIST_YANG_PATH INTERFACES_YANG_MODEL "/interface" - -enum interface_general_leaf { - IF_TYPE = 0, - IF_DESCRIPTION, - IF_ENABLED, - IF_PARENT_INTERFACE, - IF_LEAF_COUNT -}; - -int ds_set_general_interface_config(sr_session_ctx_t *session, char *interface_name, char *leaf_values[IF_LEAF_COUNT]); - -/* leaf nodes defined for both ipv4 and ipv6 */ -enum interface_ip_leaf { - IF_IP_ENABLED = 0, - IF_IP_FORWARDING, - IF_IP_MTU, - IF_IP_LEAF_COUNT -}; - -int ds_set_interface_ipv4_config(sr_session_ctx_t *session, char *interface_name, char *leaf_values[IF_IP_LEAF_COUNT]); -int ds_set_interface_ipv6_config(sr_session_ctx_t *session, char *interface_name, char *leaf_values[IF_IP_LEAF_COUNT]); - -enum interface_ipv4_addr_leaf { - IF_IPV4_ADDR_SUBNET = 0, - IF_IPV4_ADDR_PREFIX_LENGTH, - IF_IPV4_ADDR_ORIGIN, - IF_IPV4_ADDR_LEAF_COUNT -}; - -int ds_add_interface_ipv4_address(sr_session_ctx_t *session, char *interface_name, char *ip, char *leaf_values[IF_IPV4_ADDR_LEAF_COUNT]); - -enum interface_ipv4_neighbour_leaf { - IF_IPV4_NEIGH_LINK_LAYER_ADDR = 0, - IF_IPV4_NEIGH_ORIGIN, - IF_IPV4_NEIGH_LEAF_COUNT -}; - -int ds_add_interface_ipv4_neighbor(sr_session_ctx_t *session, char *interface_name, char *neigh_ip, char *leaf_values[IF_IPV4_NEIGH_LEAF_COUNT]); - -enum interface_ipv6_addr_leaf { - IF_IPV6_ADDR_PREFIX_LENGTH = 0, - IF_IPV6_ADDR_ORIGIN, - IF_IPV6_ADDR_STATUS, - IF_IPV6_ADDR_LEAF_COUNT -}; - -int ds_add_interface_ipv6_address(sr_session_ctx_t *session, char *interface_name, char *ip, char *leaf_values[IF_IPV6_ADDR_LEAF_COUNT]); - -enum interface_ipv6_neighbour_leaf { - IF_IPV6_NEIGH_LINK_LAYER_ADDR = 0, - IF_IPV6_NEIGH_ORIGIN, - IF_IPV6_NEIGH_IS_ROUTER, - IF_IPV6_NEIGH_STATE, - IF_IPV6_NEIGH_LEAF_COUNT -}; - -int ds_add_interface_ipv6_neighbor(sr_session_ctx_t *session, char *interface_name, char *neigh_ip, char *leaf_values[IF_IPV6_NEIGH_LEAF_COUNT]); - -enum interface_oper_info_leaf { - IF_ADMIN_STATUS, - IF_OPER_STATUS, - IF_LAST_CHANGE, - IF_IF_INDEX, - IF_PHYS_ADDRESS, - IF_SPEED, - IF_OPER_LEAF_COUNT -}; - -int ds_oper_set_interface_info(struct lyd_node *parent, const struct ly_ctx *ly_ctx, char *interface_name, char *leaf_values[IF_OPER_LEAF_COUNT]); - -int ds_oper_add_interface_higher_layer_if(struct lyd_node *parent, const struct ly_ctx *ly_ctx, char *interface_name, char *higher_layer_if); -int ds_oper_add_interface_lower_layer_if(struct lyd_node *parent, const struct ly_ctx *ly_ctx, char *interface_name, char *lower_layer_if); - -enum interface_statistics_leaf { - IF_STATS_DISCONTINUITY_TIME, - IF_STATS_IN_OCTETS, - IF_STATS_IN_UNICAST_PKTS, - IF_STATS_IN_BROADCAST_PKTS, - IF_STATS_IN_MULTICAST_PKTS, - IF_STATS_IN_DISCARDS, - IF_STATS_IN_ERRORS, - IF_STATS_IN_UNKNOWN_PROTOS, - IF_STATS_OUT_OCTETS, - IF_STATS_OUT_UNICAST_PKTS, - IF_STATS_OUT_BROADCAST_PKTS, - IF_STATS_OUT_MULTICAST_PKTS, - IF_STATS_OUT_DISCARDS, - IF_STATS_OUT_ERRORS, - IF_STATS_LEAF_COUNT -}; - -int ds_oper_set_interface_statistics(struct lyd_node *parent, const struct ly_ctx *ly_ctx, char *interface_name, char *leaf_values[IF_STATS_LEAF_COUNT]); - -#endif // DATASTORE_H_ONCE \ No newline at end of file diff --git a/src/interfaces/if_nic_stats.c b/src/interfaces/if_nic_stats.c deleted file mode 100644 index cf4f65ea..00000000 --- a/src/interfaces/if_nic_stats.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * telekom / sysrepo-plugin-interfaces - * - * This program is made available under the terms of the - * BSD 3-Clause license which is available at - * https://opensource.org/licenses/BSD-3-Clause - * - * SPDX-FileCopyrightText: 2021 Deutsche Telekom AG - * SPDX-FileContributor: Sartura Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "if_nic_stats.h" -#include "utils/memory.h" - -int get_nic_stats(char *if_name, nic_stats_t *nic_stats) -{ - int skfd = -1; - struct ethtool_drvinfo drvinfo = {0}; - struct ethtool_gstrings *gstrings = NULL; - struct ethtool_stats *stats = NULL; - struct ifreq ifr = {0}; - unsigned int n_stats = 0; - unsigned int sz_str = 0; - unsigned int sz_stats = 0; - - skfd = socket(AF_INET, SOCK_DGRAM, 0); - if (skfd < 0) { - goto error_out; - } - - // set interface name - strncpy(&ifr.ifr_name[0], if_name, IFNAMSIZ); - ifr.ifr_name[IFNAMSIZ - 1] = 0; - - // how many stats are available - drvinfo.cmd = ETHTOOL_GDRVINFO; - ifr.ifr_data = (caddr_t) &drvinfo; - - if (ioctl(skfd, SIOCETHTOOL, &ifr) != 0) { - goto error_out; - } - - n_stats = drvinfo.n_stats; - if (n_stats < 1) { - goto error_out; - } - - // allocate memory for stat names and values - sz_str = n_stats * ETH_GSTRING_LEN; - sz_stats = n_stats * sizeof(uint64_t); - - gstrings = xcalloc(1, sz_str + sizeof(struct ethtool_gstrings)); - - stats = xcalloc(1, sz_stats + sizeof(struct ethtool_stats)); - - // get stat names - gstrings->cmd = ETHTOOL_GSTRINGS; - gstrings->string_set = ETH_SS_STATS; - gstrings->len = n_stats; - ifr.ifr_data = (caddr_t) gstrings; - - if (ioctl(skfd, SIOCETHTOOL, &ifr) != 0) { - goto error_out; - } - - // get stat values - stats->cmd = ETHTOOL_GSTATS; - stats->n_stats = n_stats; - ifr.ifr_data = (caddr_t) stats; - - if (ioctl(skfd, SIOCETHTOOL, &ifr) != 0) { - goto error_out; - } - - for (unsigned int i = 0; i < n_stats; i++) { - char *stat_name = (char *)&gstrings->data[i * ETH_GSTRING_LEN]; - uint64_t stat_val = stats->data[i]; - - if (strncmp(stat_name, "rx_packets", ETH_GSTRING_LEN) == 0) { - nic_stats->rx_packets = stat_val; - } else if (strncmp(stat_name, "rx_broadcast", ETH_GSTRING_LEN) == 0) { - nic_stats->rx_broadcast = stat_val; - } else if (strncmp(stat_name, "tx_packets", ETH_GSTRING_LEN) == 0) { - nic_stats->tx_packets = stat_val; - } else if (strncmp(stat_name, "tx_broadcast", ETH_GSTRING_LEN) == 0) { - nic_stats->tx_broadcast = stat_val; - } else if (strncmp(stat_name, "tx_multicast", ETH_GSTRING_LEN) == 0) { - nic_stats->tx_multicast = stat_val; - } - } - - FREE_SAFE(gstrings); - FREE_SAFE(stats); - close(skfd); - - return 0; - -error_out: - if (gstrings != NULL) { - FREE_SAFE(gstrings); - } - - if (stats != NULL) { - FREE_SAFE(stats); - } - - if (skfd >= 0) { - close(skfd); - } - - return -1; -} diff --git a/src/interfaces/if_nic_stats.h b/src/interfaces/if_nic_stats.h deleted file mode 100644 index 36f54a07..00000000 --- a/src/interfaces/if_nic_stats.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * telekom / sysrepo-plugin-interfaces - * - * This program is made available under the terms of the - * BSD 3-Clause license which is available at - * https://opensource.org/licenses/BSD-3-Clause - * - * SPDX-FileCopyrightText: 2021 Deutsche Telekom AG - * SPDX-FileContributor: Sartura Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef IF_NIC_STATS_H_ONCE -#define IF_NIC_STATS_H_ONCE - -#include - -typedef struct nic_stats_s nic_stats_t; - -struct nic_stats_s { - uint64_t rx_packets; - uint64_t rx_broadcast; - uint64_t tx_packets; - uint64_t tx_broadcast; - uint64_t tx_multicast; -}; - -int get_nic_stats(char *if_name, nic_stats_t *nic_stats); - -#endif /* IF_NIC_STATS_H_ONCE */ diff --git a/src/interfaces/if_state.c b/src/interfaces/if_state.c deleted file mode 100644 index dd2b6f11..00000000 --- a/src/interfaces/if_state.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * telekom / sysrepo-plugin-interfaces - * - * This program is made available under the terms of the - * BSD 3-Clause license which is available at - * https://opensource.org/licenses/BSD-3-Clause - * - * SPDX-FileCopyrightText: 2021 Deutsche Telekom AG - * SPDX-FileContributor: Sartura Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "if_state.h" -#include "utils/memory.h" -#include -#include - -void if_state_init(if_state_t *st) -{ - st->name = NULL; - st->last_change = 0; - st->state = 0; -} - -void if_state_free(if_state_t *st) -{ - if (st->name != NULL) { - FREE_SAFE(st->name); - } -} - -void if_state_list_init(if_state_list_t *ls) -{ - ls->data = NULL; - ls->count = 0; -} - -if_state_t *if_state_list_get(if_state_list_t *ls, uint idx) -{ - if (idx < ls->count) { - return &ls->data[idx]; - } - return NULL; -} - -if_state_t *if_state_list_get_by_if_name(if_state_list_t *ls, char *name) -{ - for (uint i = 0; i < ls->count; i++) { - if (strcmp(ls->data[i].name, name) == 0) { - return &ls->data[i]; - } - } - return NULL; -} - -void if_state_list_alloc(if_state_list_t *ls, uint count) -{ - ls->count = count; - ls->data = (if_state_t *) malloc(sizeof(if_state_t) * count); - for (uint i = 0; i < count; i++) { - if_state_init(ls->data + i); - } -} - -void if_state_list_add(if_state_list_t *ls, uint8_t state, char *name) -{ - uint count = ++ls->count; - ls->data = (if_state_t *) realloc(ls->data, sizeof(if_state_t) * count); - - ls->data[count-1].last_change = 0; - - size_t len = strlen(name); - ls->data[count-1].name = xcalloc(len + 1, sizeof(char)); - strncpy(ls->data[count-1].name, name, len); - ls->data[count-1].name[len] = '\0'; - - ls->data[count-1].state = state; -} - -void if_state_list_free(if_state_list_t *ls) -{ - if (ls->count) { - for (uint i = 0; i < ls->count; i++) { - if_state_free(ls->data + i); - } - FREE_SAFE(ls->data); - } -} diff --git a/src/interfaces/if_state.h b/src/interfaces/if_state.h deleted file mode 100644 index 850cd134..00000000 --- a/src/interfaces/if_state.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * telekom / sysrepo-plugin-interfaces - * - * This program is made available under the terms of the - * BSD 3-Clause license which is available at - * https://opensource.org/licenses/BSD-3-Clause - * - * SPDX-FileCopyrightText: 2021 Deutsche Telekom AG - * SPDX-FileContributor: Sartura Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef IF_STATE_H_ONCE -#define IF_STATE_H_ONCE - -#include -#include - -typedef struct if_state_s if_state_t; -typedef struct if_state_list_s if_state_list_t; -typedef unsigned int uint; - -struct if_state_s { - char *name; - uint8_t state; - time_t last_change; -}; - -void if_state_init(if_state_t *st); -void if_state_free(if_state_t *st); - -struct if_state_list_s { - if_state_t *data; - uint count; -}; - -void if_state_list_init(if_state_list_t *ls); -if_state_t *if_state_list_get(if_state_list_t *ls, uint idx); -if_state_t *if_state_list_get_by_if_name(if_state_list_t *ls, char *name); -void if_state_list_alloc(if_state_list_t *ls, uint count); -void if_state_list_add(if_state_list_t *ls, uint8_t state, char *name); -void if_state_list_free(if_state_list_t *ls); - -#endif /* IF_STATE_H_ONCE */ diff --git a/src/interfaces/interfaces.c b/src/interfaces/interfaces.c deleted file mode 100644 index 10945957..00000000 --- a/src/interfaces/interfaces.c +++ /dev/null @@ -1,3116 +0,0 @@ -/* - * telekom / sysrepo-plugin-interfaces - * - * This program is made available under the terms of the - * BSD 3-Clause license which is available at - * https://opensource.org/licenses/BSD-3-Clause - * - * SPDX-FileCopyrightText: 2021 Deutsche Telekom AG - * SPDX-FileContributor: Sartura Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "if_nic_stats.h" -#include "if_state.h" -#include "ip_data.h" -#include "link_data.h" -#include "utils/memory.h" -#include "datastore.h" - - -// other #defines -#define MAC_ADDR_MAX_LENGTH 18 -#define MAX_DESCR_LEN 100 -#define DATETIME_BUF_SIZE 30 -#define CLASS_NET_LINE_LEN 1024 -#define ADDR_STR_BUF_SIZE 45 // max ip string length (15 for ipv4 and 45 for ipv6) -#define MAX_IF_NAME_LEN IFNAMSIZ // 16 bytes - -// callbacks -static int interfaces_module_change_cb(sr_session_ctx_t *session, uint32_t subscription_id, const char *module_name, const char *xpath, sr_event_t event, uint32_t request_id, void *private_data); -static int interfaces_state_data_cb(sr_session_ctx_t *session, uint32_t subscription_id, const char *module_name, const char *path, const char *request_xpath, uint32_t request_id, struct lyd_node **parent, void *private_data); - -// helper functions -static bool system_running_datastore_is_empty_check(sr_session_ctx_t *session); -static int fill_datastore_interface_list(sr_session_ctx_t *session, link_data_list_t *ld); -static int load_startup(sr_session_ctx_t *session, link_data_list_t *ld); -static bool check_system_interface(const char *interface_name, bool *system_interface); -int set_config_value(const char *xpath, const char *value); -int add_interface_ipv4(link_data_t *ld, struct rtnl_link *old, struct rtnl_link *req, int if_idx); -static int remove_ipv4_address(ip_address_list_t *addr_list, struct nl_sock *socket, struct rtnl_link *old); -int add_interface_ipv6(link_data_t *ld, struct rtnl_link *old, struct rtnl_link *req, int if_idx); -static int remove_ipv6_address(ip_address_list_t *addr_list, struct nl_sock *socket, struct rtnl_link *old); -static int remove_neighbors(ip_neighbor_list_t *nbor_list, struct nl_sock *socket, int addr_ver, int if_index); -int write_to_proc_file(const char *dir_path, char *interface, const char *fn, int val); -static int read_from_proc_file(const char *dir_path, char *interface, const char *fn, int *val); -static int read_interface_type_from_sys_file(const char *dir_path, char *interface, int *val); -int delete_config_value(const char *xpath, const char *value); -int update_link_info(link_data_list_t *ld, sr_change_oper_t operation); -static char *convert_ianaiftype(char *iana_if_type); -int add_existing_links(sr_session_ctx_t *session, link_data_list_t *ld); -static int get_interface_description(sr_session_ctx_t *session, char *name, char **description); -static int create_vlan_qinq(struct nl_sock *socket, struct nl_cache *cache, char *second_vlan_name, char *name, char *parent_interface, uint16_t outer_vlan_id, uint16_t second_vlan_id); -static int get_system_boot_time(char boot_datetime[]); - -// function to start all threads for each interface -static int init_state_changes(void); - -// callback function for a thread to track state changes on a specific interface (ifindex passed using void* data param) -static void *manager_thread_cb(void *data); -static void cache_change_cb(struct nl_cache *cache, struct nl_object *obj, int val, void *arg); - -// static list of interface states for tracking state changes using threads -static if_state_list_t if_state_changes; - -// global list of link_data structs -static link_data_list_t link_data_list = {0}; - -// link manager used for cacheing links info constantly -static struct nl_cache_mngr *link_manager = NULL; -static struct nl_cache *link_cache = NULL; - -volatile int exit_application = 0; - -int sr_plugin_init_cb(sr_session_ctx_t *session, void **private_data) -{ - int error = 0; - sr_conn_ctx_t *connection = NULL; - sr_session_ctx_t *startup_session = NULL; - sr_subscription_ctx_t *subscription = NULL; - char *desc_file_path = NULL; - - *private_data = NULL; - - error = link_data_list_init(&link_data_list); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_init error"); - goto out; - } - - error = add_existing_links(session, &link_data_list); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "add_existing_links error"); - goto out; - } - - SRPLG_LOG_INF(PLUGIN_NAME, "start session to startup datastore"); - - if_state_list_init(&if_state_changes); - - error = init_state_changes(); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "Error occurred while initializing threads to track interface changes... exiting"); - goto out; - } - - connection = sr_session_get_connection(session); - error = sr_session_start(connection, SR_DS_STARTUP, &startup_session); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_session_start error (%d): %s", error, sr_strerror(error)); - goto error_out; - } - - *private_data = startup_session; - - if (system_running_datastore_is_empty_check(session) == true) { - SRPLG_LOG_INF(PLUGIN_NAME, "running DS is empty, loading data"); - - error = fill_datastore_interface_list(session, &link_data_list); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "fill_datastore_interface_list error"); - goto error_out; - } - - error = sr_copy_config(startup_session, BASE_YANG_MODEL, SR_DS_RUNNING, 0); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_copy_config error (%d): %s", error, sr_strerror(error)); - goto error_out; - } - } - - // load data from startup datastore to internal list - error = load_startup(startup_session, &link_data_list); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "load_startup error"); - goto error_out; - } - - // apply what is present in the startup datastore - error = update_link_info(&link_data_list, SR_OP_CREATED); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "update_link_info error"); - goto error_out; - } - - SRPLG_LOG_INF(PLUGIN_NAME, "subscribing to module change"); - - // sub to any module change - for now - error = sr_module_change_subscribe(session, BASE_YANG_MODEL, "/" BASE_YANG_MODEL ":*", interfaces_module_change_cb, *private_data, 0, 0, &subscription); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_module_change_subscribe error (%d): %s", error, sr_strerror(error)); - goto error_out; - } - - error = sr_oper_get_subscribe(session, BASE_YANG_MODEL, INTERFACES_YANG_MODEL "/*", interfaces_state_data_cb, NULL, 1, &subscription); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_oper_get_subscribe error (%d): %s", error, sr_strerror(error)); - goto error_out; - } - - SRPLG_LOG_INF(PLUGIN_NAME, "plugin init done"); - - FREE_SAFE(desc_file_path); - - goto out; - -error_out: - if (subscription != NULL) { - sr_unsubscribe(subscription); - } - - if (desc_file_path != NULL) { - FREE_SAFE(desc_file_path); - } -out: - return error ? SR_ERR_CALLBACK_FAILED : SR_ERR_OK; -} - -static bool system_running_datastore_is_empty_check(sr_session_ctx_t *session) -{ - int error = SR_ERR_OK; - bool is_empty = true; - sr_val_t *values = NULL; - size_t value_cnt = 0; - - error = sr_get_items(session, INTERFACE_LIST_YANG_PATH, 0, SR_OPER_DEFAULT, &values, &value_cnt); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_get_items error (%d): %s", error, sr_strerror(error)); - goto out; - } - - // check if interface list is empty - if (value_cnt > 0) { - sr_free_values(values, value_cnt); - is_empty = false; - } -out: - return is_empty; -} - -static int fill_datastore_interface_list(sr_session_ctx_t *session, link_data_list_t *ld) -{ - int error = 0; - for (int i = 0; i < ld->count; i++) { - link_data_t *link = &ld->links[i]; - - // general interface config - char *interface_leaf_values[IF_LEAF_COUNT] = {NULL}; - interface_leaf_values[IF_DESCRIPTION] = link->description != NULL ? ld->links[i].description : ""; - interface_leaf_values[IF_ENABLED] = link->enabled; - interface_leaf_values[IF_PARENT_INTERFACE] = link->extensions.parent_interface; - char *type = link->type; - if (strcmp(type, "lo") == 0) { - interface_leaf_values[IF_TYPE] = "iana-if-type:softwareLoopback"; - } else if (strcmp(type, "eth") == 0) { - interface_leaf_values[IF_TYPE] = "iana-if-type:ethernetCsmacd"; - } else if (strcmp(type, "vlan") == 0) { - interface_leaf_values[IF_TYPE] = "iana-if-type:l2vlan"; - } else if (strcmp(type, "bridge") == 0) { - interface_leaf_values[IF_TYPE] = "iana-if-type:bridge"; - } else if (strcmp(type, "dummy") == 0) { - interface_leaf_values[IF_TYPE] = "iana-if-type:other"; // since dummy is not a real type - } else { - SRPLG_LOG_INF(PLUGIN_NAME, "fill_datastore_interface_list unsupported interface type %s", type); - continue; - } - - error = ds_set_general_interface_config(session, link->name, interface_leaf_values); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "ds_set_interface_general_info error"); - goto error_out; - } - - // TODO: handle vlan interfaces - - // ipv4 config - char *ipv4_leaf_values[IF_IP_LEAF_COUNT] = {NULL}; - ipv4_leaf_values[IF_IP_ENABLED] = link->ipv4.enabled == 0 ? "false" : "true"; - ipv4_leaf_values[IF_IP_FORWARDING] = link->ipv4.forwarding == 0 ? "false" : "true"; - char ipv4_mtu[16] = {0}; - if (link->ipv4.mtu > 0) { - snprintf(ipv4_mtu, sizeof(ipv4_mtu), "%u", ld->links[i].ipv4.mtu); - ipv4_leaf_values[IF_IP_MTU] = ipv4_mtu; - } - error = ds_set_interface_ipv4_config(session, link->name, ipv4_leaf_values); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "ds_set_interface_ipv4_config error"); - goto error_out; - } - - // list of ipv4 addresses - uint32_t ipv4_addr_count = link->ipv4.addr_list.count; - for (uint32_t j = 0; j < ipv4_addr_count; j++) { - if (link->ipv4.addr_list.addr[j].ip == NULL) { // in case we deleted an ip address it will be NULL - continue; - } - ip_address_t *addr = &link->ipv4.addr_list.addr[j]; - - char *ipv4_addr_leaf_values[IF_IPV4_ADDR_LEAF_COUNT] = {NULL}; - char prefix_len[8] = {0}; - snprintf(prefix_len, sizeof(prefix_len), "%u", addr->subnet); - ipv4_addr_leaf_values[IF_IPV4_ADDR_PREFIX_LENGTH] = prefix_len; - - error = ds_add_interface_ipv4_address(session, link->name, addr->ip, ipv4_addr_leaf_values); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "ds_add_interface_ipv4_address error"); - goto error_out; - } - } - - // list of ipv4 neighbors - uint32_t ipv4_neigh_count = link->ipv4.nbor_list.count; - for (uint32_t j = 0; j < ipv4_neigh_count; j++) { - ip_neighbor_t *neigh = &link->ipv4.nbor_list.nbor[j]; - - char *ipv4_neigh_leaf_values[IF_IPV4_NEIGH_LEAF_COUNT] = {NULL}; - ipv4_neigh_leaf_values[IF_IPV4_NEIGH_LINK_LAYER_ADDR] = neigh->phys_addr; - - error = ds_add_interface_ipv4_neighbor(session, link->name, neigh->ip, ipv4_neigh_leaf_values); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "ds_add_interface_ipv4_neighbor error"); - goto error_out; - } - } - - // ipv6 config - char *ipv6_leaf_values[IF_IP_LEAF_COUNT] = {NULL}; - ipv6_leaf_values[IF_IP_ENABLED] = link->ipv6.ip_data.enabled == 0 ? "false" : "true"; - ipv6_leaf_values[IF_IP_FORWARDING] = link->ipv6.ip_data.forwarding == 0 ? "false" : "true"; - char ipv6_mtu[16] = {0}; - if (link->ipv6.ip_data.mtu > 0) { - snprintf(ipv6_mtu, sizeof(ipv6_mtu), "%u", ld->links[i].ipv6.ip_data.mtu); - ipv4_leaf_values[IF_IP_MTU] = ipv6_mtu; - } - error = ds_set_interface_ipv6_config(session, link->name, ipv6_leaf_values); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "ds_set_interface_ipv6_config error"); - goto error_out; - } - - // list of ipv6 addresses - uint32_t ipv6_addr_count = link->ipv6.ip_data.addr_list.count; - for (uint32_t j = 0; j < ipv6_addr_count; j++) { - if (link->ipv6.ip_data.addr_list.addr[j].ip == NULL) { // in case we deleted an ip address it will be NULL - continue; - } - ip_address_t *addr = &link->ipv6.ip_data.addr_list.addr[j]; - - char *ipv6_addr_leaf_values[IF_IPV6_ADDR_LEAF_COUNT] = {NULL}; - char prefix_len[8] = {0}; - snprintf(prefix_len, sizeof(prefix_len), "%u", addr->subnet); - ipv6_addr_leaf_values[IF_IPV6_ADDR_PREFIX_LENGTH] = prefix_len; - - error = ds_add_interface_ipv6_address(session, link->name, addr->ip, ipv6_addr_leaf_values); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "ds_add_interface_ipv6_address error"); - goto error_out; - } - } - - // list of ipv6 neighbors - uint32_t ipv6_neigh_count = ld->links[i].ipv6.ip_data.nbor_list.count; - for (uint32_t j = 0; j < ipv6_neigh_count; j++) { - ip_neighbor_t *neigh = &link->ipv6.ip_data.nbor_list.nbor[j]; - - char *ipv6_neigh_leaf_values[IF_IPV6_NEIGH_LEAF_COUNT] = {NULL}; - ipv6_neigh_leaf_values[IF_IPV6_NEIGH_LINK_LAYER_ADDR] = neigh->phys_addr; - - error = ds_add_interface_ipv6_neighbor(session, link->name, neigh->ip, ipv6_neigh_leaf_values); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "ds_add_interface_ipv6_neighbor error"); - goto error_out; - } - } - } - error = sr_apply_changes(session, 0); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_apply_changes error (%d): %s", error, sr_strerror(error)); - goto error_out; - } - - return 0; -error_out: - return -1; -} - -static int load_startup(sr_session_ctx_t *session, link_data_list_t *ld) -{ - int error = 0; - sr_val_t *vals = NULL; - char *val = NULL; - char val_buf[10] = {0}; - char *xpath = NULL; - size_t i, val_count = 0; - int rc = -1; - - error = sr_get_items(session, "/ietf-interfaces:interfaces//.", 0, 0, &vals, &val_count); - if (error != SR_ERR_OK) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_get_items error (%d): %s", error, sr_strerror(error)); - goto error_out; - } - - for (i = 0; i < val_count; ++i) { - switch (vals[i].type) { - case SR_STRING_T: - case SR_IDENTITYREF_T: - val = xstrdup(vals[i].data.string_val); - break; - case SR_BOOL_T: - val = xstrdup(vals[i].data.bool_val ? "true" : "false"); - break; - case SR_UINT8_T: - case SR_UINT16_T: - case SR_UINT32_T: - error = snprintf(val_buf, sizeof(val_buf), "%d", vals[i].data.uint16_val); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf error"); - goto error_out; - } - - val = xstrdup(val_buf); - break; - default: - continue; - } - - xpath = xstrdup(vals[i].xpath); - - error = set_config_value(xpath, val); - - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "set_config_value error (%d)", error); - goto error_out; - } - - FREE_SAFE(xpath); - FREE_SAFE(val); - } - - rc = 0; - -error_out: - if (xpath != NULL) { - FREE_SAFE(xpath); - } - if (val != NULL) { - FREE_SAFE(val); - } - if (vals) { - sr_free_values(vals, val_count); - } - - return rc; -} - -void sr_plugin_cleanup_cb(sr_session_ctx_t *session, void *private_data) -{ - sr_session_ctx_t *startup_session = (sr_session_ctx_t *) private_data; - - // copy the running datastore to startup one, in case we reboot - sr_copy_config(startup_session, BASE_YANG_MODEL, SR_DS_RUNNING, 0); - - exit_application = 1; - - if (startup_session) { - sr_session_stop(startup_session); - } - - link_data_list_free(&link_data_list); - if_state_list_free(&if_state_changes); - nl_cache_mngr_free(link_manager); - - SRPLG_LOG_INF(PLUGIN_NAME, "plugin cleanup finished"); -} - -static int interfaces_module_change_cb(sr_session_ctx_t *session, uint32_t subscription_id, const char *module_name, const char *xpath, sr_event_t event, uint32_t request_id, void *private_data) -{ - int error = 0; - sr_change_iter_t *system_change_iter = NULL; - sr_change_oper_t operation = SR_OP_CREATED; - const struct lyd_node *node = NULL; - char path[512] = {0}; - const char *prev_value = NULL; - const char *prev_list = NULL; - int prev_default = false; - char *node_xpath = NULL; - char *node_value = NULL; - - SRPLG_LOG_INF(PLUGIN_NAME, "module_name: %s, xpath: %s, event: %d, request_id: %u", module_name, xpath, event, request_id); - - if (event == SR_EV_ABORT) { - SRPLG_LOG_ERR(PLUGIN_NAME, "aborting changes for: %s", xpath); - error = -1; - goto error_out; - } - - if (event == SR_EV_DONE) { - error = sr_copy_config(session, BASE_YANG_MODEL, SR_DS_RUNNING, 0); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_copy_config error (%d): %s", error, sr_strerror(error)); - goto error_out; - } - } - - if (event == SR_EV_CHANGE) { - sprintf(path, "%s//.", xpath); - - error = sr_get_changes_iter(session, path, &system_change_iter); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_get_changes_iter error (%d): %s", error, sr_strerror(error)); - goto error_out; - } - while (sr_get_change_tree_next(session, system_change_iter, &operation, &node, &prev_value, &prev_list, &prev_default) == SR_ERR_OK) { - node_xpath = lyd_path(node, LYD_PATH_STD, NULL, 0); - - if (node->schema->nodetype == LYS_LEAF || node->schema->nodetype == LYS_LEAFLIST) { - node_value = xstrdup(lyd_get_value(node)); - } - - SRPLG_LOG_DBG(PLUGIN_NAME, "node_xpath: %s; prev_val: %s; node_val: %s; operation: %d", node_xpath, prev_value, node_value, operation); - - if (node->schema->nodetype == LYS_LEAF || node->schema->nodetype == LYS_LEAFLIST) { - if (operation == SR_OP_CREATED || operation == SR_OP_MODIFIED) { - error = set_config_value(node_xpath, node_value); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "set_config_value error (%d)", error); - goto error_out; - } - } else if (operation == SR_OP_DELETED) { - // check if this is a system interface (e.g.: lo, wlan0, enp0s31f6 etc.) - bool system_interface = false; - error = check_system_interface(node_value, &system_interface); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "check_system_interface error"); - goto error_out; - } - - // check if system interface but also - // check if parent-interface node (virtual interfaces can have a system interface as parent) - if (system_interface && !(strstr(node_xpath, "/ietf-if-extensions:parent-interface") != NULL)) { - SRPLG_LOG_ERR(PLUGIN_NAME, "Can't delete a system interface"); - FREE_SAFE(node_xpath); - sr_free_change_iter(system_change_iter); - return SR_ERR_INVAL_ARG; - } - - error = delete_config_value(node_xpath, node_value); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "delete_config_value error (%d)", error); - goto error_out; - } - } - } - FREE_SAFE(node_xpath); - FREE_SAFE(node_value); - } - - error = update_link_info(&link_data_list, operation); - if (error) { - error = SR_ERR_CALLBACK_FAILED; - SRPLG_LOG_ERR(PLUGIN_NAME, "update_link_info error"); - goto error_out; - } - } - goto out; - -error_out: - // nothing for now -out: - if (node_xpath != NULL) { - FREE_SAFE(node_xpath); - } - if (node_value != NULL) { - FREE_SAFE(node_value); - } - if (system_change_iter != NULL) { - sr_free_change_iter(system_change_iter); - } - - return error ? SR_ERR_CALLBACK_FAILED : SR_ERR_OK; -} - -int set_config_value(const char *xpath, const char *value) -{ - int error = SR_ERR_OK; - char *interface_node = NULL; - char *interface_node_name = NULL; - char *address_node_ip = NULL; - char *neighbor_node_ip = NULL; - sr_xpath_ctx_t state = {0}; - char *xpath_cpy = strdup(xpath); - - interface_node = sr_xpath_node_name((char *) xpath); - if (interface_node == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_xpath_node_name error"); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - - interface_node_name = sr_xpath_key_value((char *) xpath, "interface", "name", &state); - - if (interface_node_name == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_xpath_key_value error"); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - - error = link_data_list_add(&link_data_list, interface_node_name); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_add error"); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - - if (strcmp(interface_node, "description") == 0) { - // change desc - error = link_data_list_set_description(&link_data_list, interface_node_name, (char *) value); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_description error"); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } else if (strcmp(interface_node, "type") == 0) { - // change type - - // convert the iana-if-type to a "real" interface type which libnl understands - char *interface_type = convert_ianaiftype((char *) value); - if (interface_type == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "convert_ianaiftype error"); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - - error = link_data_list_set_type(&link_data_list, interface_node_name, interface_type); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_type error"); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } else if (strcmp(interface_node, "enabled") == 0 && strstr(xpath_cpy, "ietf-ip:") == 0) { - // change enabled - error = link_data_list_set_enabled(&link_data_list, interface_node_name, (char *) value); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_enabled error"); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } - else if (strstr(xpath_cpy, "ietf-ip:ipv4") != 0) { - SRPLG_LOG_DBG(PLUGIN_NAME, "ietf-ip:ipv4 change: '%s' on interface '%s'", interface_node, interface_node_name); - memset(&state, 0, sizeof(sr_xpath_ctx_t)); - // check if an ip address has been added - address_node_ip = sr_xpath_key_value((char *) xpath_cpy, "address", "ip", &state); - - // check if a neighbor has been added - neighbor_node_ip = sr_xpath_key_value((char *) xpath_cpy, "neighbor", "ip", &state); - - if (address_node_ip != NULL) { - // address has been added -> check for interface node (last node of the path) -> (prefix-length || netmask) - if (strcmp(interface_node, "prefix-length") == 0) { - error = link_data_list_add_ipv4_address(&link_data_list, interface_node_name, address_node_ip, (char *) value, ip_subnet_type_prefix_length); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_add_ipv4_address error (%d) : %s", error, strerror(error)); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } else if (strcmp(interface_node, "netmask") == 0) { - error = link_data_list_add_ipv4_address(&link_data_list, interface_node_name, address_node_ip, (char *) value, ip_subnet_type_netmask); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_add_ipv4_address error (%d) : %s", error, strerror(error)); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } - } else if (neighbor_node_ip != NULL) { - if (strcmp(interface_node, "link-layer-address") == 0) { - error = link_data_list_add_ipv4_neighbor(&link_data_list, interface_node_name, neighbor_node_ip, (char *) value); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_add_ipv4_neighbor error (%d) : %s", error, strerror(error)); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } - } else if (strcmp(interface_node, "enabled") == 0) { - error = link_data_list_set_ipv4_enabled(&link_data_list, interface_node_name, (char *) value); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_ipv4_enabled error (%d) : %s", error, strerror(error)); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } else if (strcmp(interface_node, "forwarding") == 0) { - error = link_data_list_set_ipv4_forwarding(&link_data_list, interface_node_name, (char *) value); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_ipv4_forwarding error (%d) : %s", error, strerror(error)); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } else if (strcmp(interface_node, "mtu") == 0) { - error = link_data_list_set_ipv4_mtu(&link_data_list, interface_node_name, (char *) value); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_ipv4_mtu error (%d) : %s", error, strerror(error)); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } - } else if (strstr(xpath_cpy, "ietf-ip:ipv6") != 0) { - SRPLG_LOG_DBG(PLUGIN_NAME, "ietf-ip:ipv6 change: '%s' on interface '%s'", interface_node, interface_node_name); - // check if an ip address has been added - address_node_ip = sr_xpath_key_value((char *) xpath_cpy, "address", "ip", &state); - // check if a neighbor has been added - neighbor_node_ip = sr_xpath_key_value((char *) xpath_cpy, "neighbor", "ip", &state); - - if (address_node_ip != NULL) { - // address has been added -> check for interface node (last node of the path) -> (prefix-length || netmask) - if (strcmp(interface_node, "prefix-length") == 0) { - error = link_data_list_add_ipv6_address(&link_data_list, interface_node_name, address_node_ip, (char *) value); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_add_ipv4_address error (%d) : %s", error, strerror(error)); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } else if (strcmp(interface_node, "netmask") == 0) { - error = link_data_list_add_ipv6_address(&link_data_list, interface_node_name, address_node_ip, (char *) value); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_add_ipv4_address error (%d) : %s", error, strerror(error)); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } - } else if (neighbor_node_ip != NULL) { - if (strcmp(interface_node, "link-layer-address") == 0) { - error = link_data_list_add_ipv6_neighbor(&link_data_list, interface_node_name, neighbor_node_ip, (char *) value); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_add_ipv4_neighbor error (%d) : %s", error, strerror(error)); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } - } else if (strcmp(interface_node, "enabled") == 0) { - error = link_data_list_set_ipv6_enabled(&link_data_list, interface_node_name, (char *) value); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_ipv4_enabled error (%d) : %s", error, strerror(error)); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } else if (strcmp(interface_node, "forwarding") == 0) { - error = link_data_list_set_ipv6_forwarding(&link_data_list, interface_node_name, (char *) value); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_ipv4_forwarding error (%d) : %s", error, strerror(error)); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } else if (strcmp(interface_node, "mtu") == 0) { - error = link_data_list_set_ipv6_mtu(&link_data_list, interface_node_name, (char *) value); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_ipv4_mtu error (%d) : %s", error, strerror(error)); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } - } else if (strcmp(interface_node, "ietf-if-extensions:parent-interface") == 0) { - // change parent-interface - error = link_data_list_set_parent(&link_data_list, interface_node_name, (char *) value); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_parent error"); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } else if (strstr(xpath_cpy, "ietf-if-extensions:encapsulation/ietf-if-vlan-encapsulation:dot1q-vlan/outer-tag/tag-type") != 0) { - error = link_data_list_set_outer_tag_type(&link_data_list, interface_node_name, (char *)value); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_parent error"); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } else if (strstr(xpath_cpy, "ietf-if-extensions:encapsulation/ietf-if-vlan-encapsulation:dot1q-vlan/outer-tag/vlan-id") != 0) { - error = link_data_list_set_outer_vlan_id(&link_data_list, interface_node_name, (uint16_t) atoi(value)); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_parent error"); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } else if (strstr(xpath_cpy, "ietf-if-extensions:encapsulation/ietf-if-vlan-encapsulation:dot1q-vlan/second-tag/tag-type") != 0) { - error = link_data_list_set_second_tag_type(&link_data_list, interface_node_name, (char *)value); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_parent error"); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } else if (strstr(xpath_cpy, "ietf-if-extensions:encapsulation/ietf-if-vlan-encapsulation:dot1q-vlan/second-tag/vlan-id") != 0) { - error = link_data_list_set_second_vlan_id(&link_data_list, interface_node_name, (uint16_t) atoi(value)); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_parent error"); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } - - goto out; - -out: - FREE_SAFE(xpath_cpy); - if (xpath_cpy != NULL) { - FREE_SAFE(xpath_cpy); - } - - return error ? SR_ERR_CALLBACK_FAILED : SR_ERR_OK; -} - -// TODO: move this function to a helper functions file in utils -static char *convert_ianaiftype(char *iana_if_type) -{ - char *if_type = NULL; - - if (strstr(iana_if_type, "softwareLoopback") != NULL) { - if_type = "lo"; - } else if (strstr(iana_if_type, "ethernetCsmacd") != NULL) { - if_type = "eth"; - } else if (strstr(iana_if_type, "l2vlan") != NULL) { - if_type = "vlan"; - } else if (strstr(iana_if_type, "bridge") != NULL) { - if_type = "bridge"; - } else if (strstr(iana_if_type, "other") != NULL) { - if_type = "dummy"; - } - // TODO: add support for more interface types - - return if_type; -} - -int delete_config_value(const char *xpath, const char *value) -{ - int error = SR_ERR_OK; - char *interface_node = NULL; - char *interface_node_name = NULL; - sr_xpath_ctx_t state = {0}; - char *xpath_cpy = strdup(xpath); - - interface_node = sr_xpath_node_name((char *) xpath); - if (interface_node == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_xpath_node_name error"); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - - interface_node_name = sr_xpath_key_value((char *) xpath, "interface", "name", &state); - if (interface_node_name == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_xpath_key_value error"); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - - if (strcmp(interface_node, "name") == 0) { - // mark for deletion - error = link_data_list_set_delete(&link_data_list, interface_node_name, true); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_delete error"); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } else if (strcmp(interface_node, "description") == 0) { - // set description to empty string - error = link_data_list_set_description(&link_data_list, interface_node_name, ""); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_description error"); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } else if (strcmp(interface_node, "enabled") == 0) { - // set enabled to false - error = link_data_list_set_enabled(&link_data_list, interface_node_name, ""); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_enabled error"); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } else if (strstr(xpath_cpy, "ietf-ip:ipv4") != 0) { - memset(&state, 0, sizeof(sr_xpath_ctx_t)); - - // check if an ip address needs to be removed - char *address_node_ip = sr_xpath_key_value((char *) xpath_cpy, "address", "ip", &state); - - // check if a neighbor needs to be removed - char *neighbor_node_ip = sr_xpath_key_value((char *) xpath_cpy, "neighbor", "ip", &state); - - if (address_node_ip != NULL) { - if (strcmp(interface_node, "ip") == 0) { - error = link_data_list_set_delete_ipv4_address(&link_data_list, interface_node_name, address_node_ip); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_delete_ipv4_address error (%d) : %s", error, strerror(error)); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } - } else if (neighbor_node_ip != NULL) { - if (strcmp(interface_node, "ip") == 0) { - error = link_data_list_set_delete_ipv4_neighbor(&link_data_list, interface_node_name, (char *) value); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_delete_ipv4_neighbor error (%d) : %s", error, strerror(error)); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } - } - } else if (strstr(xpath_cpy, "ietf-ip:ipv6") != 0) { - memset(&state, 0, sizeof(sr_xpath_ctx_t)); - - // check if an ip address needs to be removed - char *address_node_ip = sr_xpath_key_value((char *) xpath_cpy, "address", "ip", &state); - - // check if a neighbor needs to be removed - char *neighbor_node_ip = sr_xpath_key_value((char *) xpath_cpy, "neighbor", "ip", &state); - - if (address_node_ip != NULL) { - if (strcmp(interface_node, "ip") == 0) { - error = link_data_list_set_delete_ipv6_address(&link_data_list, interface_node_name, address_node_ip); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_delete_ipv6_address error (%d) : %s", error, strerror(error)); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } - } else if (neighbor_node_ip != NULL) { - if (strcmp(interface_node, "ip") == 0) { - error = link_data_list_set_delete_ipv6_neighbor(&link_data_list, interface_node_name, (char *) value); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_delete_ipv6_neighbor error (%d) : %s", error, strerror(error)); - error = SR_ERR_CALLBACK_FAILED; - goto out; - } - } - } - } - -out: - FREE_SAFE(xpath_cpy); - return error ? SR_ERR_CALLBACK_FAILED : SR_ERR_OK; -} - -int update_link_info(link_data_list_t *ld, sr_change_oper_t operation) -{ - struct nl_sock *socket = NULL; - struct nl_cache *cache = NULL; - struct rtnl_link *old = NULL; - struct rtnl_link *old_vlan_qinq = NULL; - struct rtnl_link *request = NULL; - - int error = SR_ERR_OK; - - socket = nl_socket_alloc(); - if (socket == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_socket_alloc error: invalid socket"); - goto out; - } - - if ((error = nl_connect(socket, NETLINK_ROUTE)) != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_connect error (%d): %s", error, nl_geterror(error)); - goto out; - } - - error = rtnl_link_alloc_cache(socket, AF_UNSPEC, &cache); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_alloc_cache error (%d): %s", error, nl_geterror(error)); - goto out; - } - - for (int i = 0; i < ld->count; i++) { - char *name = ld->links[i].name; - char *type = ld->links[i].type; - char *enabled = ld->links[i].enabled; - char *parent_interface = ld->links[i].extensions.parent_interface; - uint16_t outer_vlan_id = ld->links[i].extensions.encapsulation.dot1q_vlan.outer_vlan_id; - uint16_t second_vlan_id = ld->links[i].extensions.encapsulation.dot1q_vlan.second_vlan_id; - char second_vlan_name[MAX_IF_NAME_LEN] = {0}; - bool delete = ld->links[i].delete; - - if (name == NULL ){//|| type == 0) { - continue; - } - - // handle vlan QinQ interfaces - if (type != NULL && strcmp(type, "vlan") == 0 && second_vlan_id != 0) { - error = snprintf(second_vlan_name, sizeof(second_vlan_name), "%s.%d", name, second_vlan_id); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf error"); - goto out; - } - } - - old = rtnl_link_get_by_name(cache, name); - // check for second vlan (QinQ) as well - old_vlan_qinq = rtnl_link_get_by_name(cache, second_vlan_name); - request = rtnl_link_alloc(); - - // delete link (interface) if marked for deletion - if (delete) { - // delete the link - error = rtnl_link_delete(socket, old); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_delete error (%d): %s", error, nl_geterror(error)); - goto out; - } - - // free the link from link_data_list - link_data_free(&ld->links[i]); - // set delete to false - ld->links[i].delete = false; - - // cleanup - if (old != NULL) { - rtnl_link_put(old); - } - - if (old_vlan_qinq != NULL) { - rtnl_link_put(old_vlan_qinq); - } - - if (request != NULL) { - rtnl_link_put(request); - } - - // and continue - continue; - } - - // check if any ipv4 addresses need to be removed - uint32_t ipv4_addr_count = ld->links[i].ipv4.addr_list.count; - - if (ipv4_addr_count > 0) { - error = remove_ipv4_address(&ld->links[i].ipv4.addr_list, socket, old); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "remove_ipv4_address error (%d): %s", error, nl_geterror(error)); - goto out; - } - } - - // check if any ipv6 addresses need to be removed - uint32_t ipv6_addr_count = ld->links[i].ipv6.ip_data.addr_list.count; - - if (ipv6_addr_count > 0) { - error = remove_ipv6_address(&ld->links[i].ipv6.ip_data.addr_list, socket, old); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "remove_ipv6_address error (%d): %s", error, nl_geterror(error)); - goto out; - } - } - - if (old != NULL) { - int index = rtnl_link_get_ifindex(old); - - // check if any ipv4 neighbors need to be removed - uint32_t ipv4_neigh_count = ld->links[i].ipv4.nbor_list.count; - - if (ipv4_neigh_count > 0) { - error = remove_neighbors(&ld->links[i].ipv4.nbor_list, socket, AF_INET, index); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "remove_neighbors error"); - goto out; - } - } - - // check if any ipv6 neighbors need to be removed - uint32_t ipv6_neigh_count = ld->links[i].ipv6.ip_data.nbor_list.count; - - if (ipv6_neigh_count > 0) { - error = remove_neighbors(&ld->links[i].ipv6.ip_data.nbor_list, socket, AF_INET6, index); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "remove_neighbors error"); - goto out; - } - } - } - - // type - if (type != NULL) { - // handle vlan interfaces - if (strcmp(type, "vlan") == 0) { - // if second vlan id is present treat it as QinQ vlan - if (second_vlan_id != 0) { - // update the last-change state list - uint8_t state = rtnl_link_get_operstate(request); - - if_state_list_add(&if_state_changes, state, second_vlan_name); - if_state_list_add(&if_state_changes, state, name); - - // then create the interface with new parameters - create_vlan_qinq(socket, cache, second_vlan_name, name, parent_interface, outer_vlan_id, second_vlan_id); - - } else if (second_vlan_id == 0) { - // normal vlan interface - error = rtnl_link_set_type(request, type); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_set_type error (%d): %s", error, nl_geterror(error)); - goto out; - } - // if only the outer vlan is present, treat is an normal vlan - int master_index = rtnl_link_name2i(cache, parent_interface); - rtnl_link_set_link(request, master_index); - - error = rtnl_link_vlan_set_id(request, outer_vlan_id); - } - } else { - error = rtnl_link_set_type(request, type); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_set_type error (%d): %s", error, nl_geterror(error)); - goto out; - } - } - } - - // enabled - if (enabled != NULL) { - if (strcmp(enabled, "true") == 0) { - // set the interface to UP - rtnl_link_set_flags(request, (unsigned int) rtnl_link_str2flags("up")); - rtnl_link_set_operstate(request, IF_OPER_UP); - } else { - // set the interface to DOWN - rtnl_link_unset_flags(request, (unsigned int) rtnl_link_str2flags("up")); - rtnl_link_set_operstate(request, IF_OPER_DOWN); - } - } - - if (old != NULL) { - // add ipv4/ipv6 options - error = add_interface_ipv4(&ld->links[i], old, request, rtnl_link_get_ifindex(old)); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "add_interface_ipv4 error"); - goto out; - } - - // the interface with name already exists, change it - error = rtnl_link_change(socket, old, request, 0); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_change error (%d): %s", error, nl_geterror(error)); - goto out; - } - - error = add_interface_ipv6(&ld->links[i], old, request, rtnl_link_get_ifindex(old)); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "add_interface_ipv6 error"); - goto out; - } - - // update ipv6 config - error = rtnl_link_change(socket, old, request, 0); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_change error (%d): %s", error, nl_geterror(error)); - goto out; - } - } else if (operation != SR_OP_DELETED) { - // the interface doesn't exist - - // check if the interface is a system interface - // non-virtual interfaces can't be created - bool system_interface = false; - error = check_system_interface(name, &system_interface); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "check_system_interface error"); - error = -1; - goto out; - } - - if (system_interface || strcmp(type, "eth") == 0 || strcmp(type, "lo") == 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "Can't create non-virtual interface %s of type: %s", name, type); - error = -1; - goto out; - } - - // don't create if it's a QinQ vlan interface since it's already been created - if (second_vlan_id == 0) { - // update the last-change state list - uint8_t state = rtnl_link_get_operstate(request); - - if_state_list_add(&if_state_changes, state, name); - - // set the new name - rtnl_link_set_name(request, name); - - // add the interface - // note: if type is not set, you can't add the new link - error = rtnl_link_add(socket, request, NLM_F_CREATE); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_add error (%d): %s", error, nl_geterror(error)); - goto out; - } - } - - // in order to add ipv4/ipv6 options we first have to create the interface - // and then get its interface index, because we need it inside add_interface_ipv4/ipv6 - // and don't want to set it manually... - nl_cache_free(cache); - error = rtnl_link_alloc_cache(socket, AF_UNSPEC, &cache); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_alloc_cache error (%d): %s", error, nl_geterror(error)); - goto out; - } - - old = rtnl_link_get_by_name(cache, name); - old_vlan_qinq = rtnl_link_get_by_name(cache, second_vlan_name); - - if (old != NULL) { - error = add_interface_ipv4(&ld->links[i], old, request, rtnl_link_get_ifindex(old)); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "add_interface_ipv4 error"); - goto out; - } - // ipv4 config - error = rtnl_link_change(socket, old, request, 0); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_change error (%d): %s", error, nl_geterror(error)); - goto out; - } - error = add_interface_ipv6(&ld->links[i], old, request, rtnl_link_get_ifindex(old)); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "add_interface_ipv6 error"); - goto out; - } - - // ipv6 config - error = rtnl_link_change(socket, old, request, 0); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_change error (%d): %s", error, nl_geterror(error)); - goto out; - } - } - - if (old_vlan_qinq != NULL) { - error = add_interface_ipv4(&ld->links[i], old_vlan_qinq, request, rtnl_link_get_ifindex(old_vlan_qinq)); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "add_interface_ipv4 error"); - goto out; - } - - error = add_interface_ipv6(&ld->links[i], old_vlan_qinq, request, rtnl_link_get_ifindex(old_vlan_qinq)); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "add_interface_ipv6 error"); - goto out; - } - - error = rtnl_link_change(socket, old_vlan_qinq, request, 0); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_change error (%d): %s", error, nl_geterror(error)); - goto out; - } - } - } - rtnl_link_put(old); - rtnl_link_put(old_vlan_qinq); - rtnl_link_put(request); - } - -out: - nl_socket_free(socket); - nl_cache_free(cache); - - return error; -} - -static int remove_ipv4_address(ip_address_list_t *addr_list, struct nl_sock *socket, struct rtnl_link *old) -{ - int error = 0; - uint32_t addr_count = addr_list->count; - - // iterate through list of IPv4 addresses and check delete flag - for (uint32_t j = 0; j < addr_count; j++) { - - if (addr_list->addr[j].delete == true) { - struct rtnl_addr *addr = rtnl_addr_alloc(); - struct nl_addr *local_addr = NULL; - - error = nl_addr_parse(addr_list->addr[j].ip, AF_INET, &local_addr); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_addr_parse error (%d): %s", error, nl_geterror(error)); - rtnl_addr_put(addr); - nl_addr_put(local_addr); - return -1; - } - int32_t if_index = rtnl_link_get_ifindex(old); - - nl_addr_set_prefixlen(local_addr, addr_list->addr[j].subnet); - - rtnl_addr_set_ifindex(addr, if_index); - - rtnl_addr_set_local(addr, local_addr); - - error = rtnl_addr_delete(socket, addr, 0); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_addr_delete error (%d): %s", error, nl_geterror(error)); - rtnl_addr_put(addr); - nl_addr_put(local_addr); - return -1; - } - - rtnl_addr_put(addr); - nl_addr_put(local_addr); - - // remove this IP address from list - ip_address_free(&addr_list->addr[j]); - } - } - - return 0; -} - -int add_interface_ipv4(link_data_t *ld, struct rtnl_link *old, struct rtnl_link *req, int if_idx) -{ - int error = 0; - const char *ipv4_base = "/proc/sys/net/ipv4/conf"; - char *if_name = ld->name; - ipv4_data_t *ipv4 = &ld->ipv4; - ip_address_list_t *addr_ls = &ipv4->addr_list; - ip_neighbor_list_t *neigh_ls = &ipv4->nbor_list; - struct nl_sock *socket = NULL; - struct nl_addr *local_addr = NULL; - struct rtnl_addr *r_addr = NULL; - struct rtnl_neigh *neigh = NULL; - struct nl_addr *ll_addr = NULL; - struct nl_cache *cache = NULL; - - // add ipv4 options from given link data to the req link object - // also set forwarding options to the given files for a particular link - // enabled - // TODO: fix this - // note: commented out because there is no disable_ipv4 file on arch (need to find workaround) - /* - error = write_to_proc_file(ipv4_base, if_name, "disable_ipv4", ipv4->enabled == 0); - if (error != 0) { - goto out; - }*/ - - // forwarding - error = write_to_proc_file(ipv4_base, if_name, "forwarding", ipv4->forwarding); - if (error != 0) { - goto out; - } - - // set mtu - if (ipv4->mtu != 0) { - rtnl_link_set_mtu(req, ipv4->mtu); - } - - // address list - socket = nl_socket_alloc(); - if (socket == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_socket_alloc error: invalid socket"); - goto out; - } - - if ((error = nl_connect(socket, NETLINK_ROUTE)) != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_connect error (%d): %s", error, nl_geterror(error)); - goto out; - } - - for (uint i = 0; i < addr_ls->count; i++) { - if (addr_ls->addr[i].ip == NULL) { // ip was deleted - continue; - } - r_addr = rtnl_addr_alloc(); - error = nl_addr_parse(addr_ls->addr[i].ip, AF_INET, &local_addr); - if (error != 0) { - rtnl_addr_put(r_addr); - nl_addr_put(local_addr); - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_addr_parse error (%d): %s", error, nl_geterror(error)); - goto out; - } - nl_addr_set_prefixlen(local_addr, addr_ls->addr[i].subnet); - - // configure rtln_addr for a link - rtnl_addr_set_ifindex(r_addr, if_idx); - rtnl_addr_set_local(r_addr, local_addr); - - // send message - rtnl_addr_add(socket, r_addr, 0); - - // Free the memory - nl_addr_put(local_addr); - rtnl_addr_put(r_addr); - } - - for (uint i = 0; i < neigh_ls->count; i++) { - if (neigh_ls->nbor[i].ip == NULL) { // neighbor was deleted - continue; - } - neigh = rtnl_neigh_alloc(); - - error = nl_addr_parse(neigh_ls->nbor[i].ip, AF_INET, &local_addr); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_addr_parse error (%d): %s", error, nl_geterror(error)); - goto loop_end; - } - - error = nl_addr_parse(neigh_ls->nbor[i].phys_addr, AF_LLC, &ll_addr); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_addr_parse error (%d): %s", error, nl_geterror(error)); - goto loop_end; - } - - rtnl_neigh_set_ifindex(neigh, if_idx); - - // set dst and ll addr - rtnl_neigh_set_lladdr(neigh, ll_addr); - rtnl_neigh_set_dst(neigh, local_addr); - - error = rtnl_link_alloc_cache(socket, AF_UNSPEC, &cache); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_alloc_cache error (%d): %s", error, nl_geterror(error)); - goto loop_end; - } - - struct rtnl_neigh *tmp_neigh = rtnl_neigh_get(cache, if_idx, local_addr); - int neigh_oper = NLM_F_CREATE; - - if (tmp_neigh != NULL) { - // if the neighbor already exists, replace it - // otherwise create it (NLM_F_CREATE) - neigh_oper = NLM_F_REPLACE; - rtnl_neigh_put(tmp_neigh); - } - - error = rtnl_neigh_add(socket, neigh, neigh_oper); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_neigh_add error (%d): %s", error, nl_geterror(error)); - goto loop_end; - } - - loop_end: - nl_cache_free(cache); - nl_addr_put(ll_addr); - nl_addr_put(local_addr); - rtnl_neigh_put(neigh); - if (error != 0) { - break; - } - } - -out: - nl_socket_free(socket); - return error; -} - -static int remove_ipv6_address(ip_address_list_t *addr_list, struct nl_sock *socket, struct rtnl_link *old) -{ - int error = 0; - uint32_t addr_count = addr_list->count; - - // iterate through list of IPv6 addresses and check delete flag - if (addr_count > 0) { - for (uint32_t j = 0; j < addr_count; j++) { - - if (addr_list->addr[j].delete == true) { - struct rtnl_addr *addr = rtnl_addr_alloc(); - struct nl_addr *local_addr = NULL; - - error = nl_addr_parse(addr_list->addr[j].ip, AF_INET6, &local_addr); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_addr_parse error (%d): %s", error, nl_geterror(error)); - rtnl_addr_put(addr); - nl_addr_put(local_addr); - return -1; - } - int32_t if_index = rtnl_link_get_ifindex(old); - - nl_addr_set_prefixlen(local_addr, addr_list->addr[j].subnet); - - rtnl_addr_set_ifindex(addr, if_index); - - rtnl_addr_set_local(addr, local_addr); - - error = rtnl_addr_delete(socket, addr, 0); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_addr_delete error (%d): %s", error, nl_geterror(error)); - rtnl_addr_put(addr); - nl_addr_put(local_addr); - return -1; - } - rtnl_addr_put(addr); - nl_addr_put(local_addr); - - // remove this IP address from list - ip_address_free(&addr_list->addr[j]); - } - } - } - - return 0; -} - -int add_interface_ipv6(link_data_t *ld, struct rtnl_link *old, struct rtnl_link *req, int if_idx) -{ - int error = 0; - const char *ipv6_base = "/proc/sys/net/ipv6/conf"; - char *if_name = ld->name; - ipv6_data_t *ipv6 = &ld->ipv6; - ip_address_list_t *addr_ls = &ipv6->ip_data.addr_list; - ip_neighbor_list_t *neigh_ls = &ipv6->ip_data.nbor_list; - struct nl_sock *socket = NULL; - struct nl_addr *local_addr = NULL; - struct rtnl_addr *r_addr = NULL; - struct rtnl_neigh *neigh = NULL; - struct nl_addr *ll_addr = NULL; - struct nl_cache *cache = NULL; - - // enabled - error = write_to_proc_file(ipv6_base, if_name, "disable_ipv6", ipv6->ip_data.enabled == 0); - if (error != 0) { - goto out; - } - - // forwarding - error = write_to_proc_file(ipv6_base, if_name, "forwarding", ipv6->ip_data.forwarding); - if (error != 0) { - goto out; - } - - // set mtu - if (ipv6->ip_data.mtu != 0) { - // If the new ipv6 MTU value is greater than link (ipv4) MTU, the - // kernel will return EINVAL when attempting to write - // the value to the MTU proc file. - if (ipv6->ip_data.mtu > ld->ipv4.mtu) { - SRPLG_LOG_ERR(PLUGIN_NAME, "Attempted to set ipv6 MTU value (%hd) greater than the current ipv4 MTU value (%hd) on interface: %s.", ipv6->ip_data.mtu, ld->ipv4.mtu, ld->name); - error = -1; - goto out; - } - error = write_to_proc_file(ipv6_base, if_name, "mtu", ipv6->ip_data.mtu); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "write_to_proc_file error (mtu)"); - goto out; - } - } - - // address list - socket = nl_socket_alloc(); - if (socket == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_socket_alloc error: invalid socket"); - goto out; - } - - if ((error = nl_connect(socket, NETLINK_ROUTE)) != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_connect error (%d): %s", error, nl_geterror(error)); - goto out; - } - - for (uint i = 0; i < addr_ls->count; i++) { - if (addr_ls->addr[i].ip == NULL) { // ip was deleted - continue; - } - - r_addr = rtnl_addr_alloc(); - - error = nl_addr_parse(addr_ls->addr[i].ip, AF_INET6, &local_addr); - if (error != 0) { - rtnl_addr_put(r_addr); - nl_addr_put(local_addr); - goto out; - } - nl_addr_set_prefixlen(local_addr, addr_ls->addr[i].subnet); - - // configure rtln_addr for a link - rtnl_addr_set_ifindex(r_addr, if_idx); - rtnl_addr_set_local(r_addr, local_addr); - - if (ipv6->autoconf.temp_valid_lifetime != 0) { - rtnl_addr_set_valid_lifetime(r_addr, ipv6->autoconf.temp_valid_lifetime); - } - - if (ipv6->autoconf.temp_preffered_lifetime != 0) { - rtnl_addr_set_preferred_lifetime(r_addr, ipv6->autoconf.temp_preffered_lifetime); - } - - // send message - rtnl_addr_add(socket, r_addr, 0); - - // Free the memory - nl_addr_put(local_addr); - rtnl_addr_put(r_addr); - } - - for (uint i = 0; i < neigh_ls->count; i++) { - if (neigh_ls->nbor[i].ip == NULL) { // neighbor was deleted - continue; - } - neigh = rtnl_neigh_alloc(); - - error = nl_addr_parse(neigh_ls->nbor[i].ip, AF_INET6, &local_addr); - if (error != 0) { - goto loop_end; - } - - error = nl_addr_parse(neigh_ls->nbor[i].phys_addr, AF_LLC, &ll_addr); - if (error != 0) { - goto loop_end; - } - - rtnl_neigh_set_ifindex(neigh, if_idx); - - // set dst and ll addr - rtnl_neigh_set_lladdr(neigh, ll_addr); - rtnl_neigh_set_dst(neigh, local_addr); - - error = rtnl_link_alloc_cache(socket, AF_UNSPEC, &cache); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_alloc_cache error (%d): %s", error, nl_geterror(error)); - goto loop_end; - } - - struct rtnl_neigh *tmp_neigh = rtnl_neigh_get(cache, if_idx, local_addr); - int neigh_oper = NLM_F_CREATE; - - if (tmp_neigh != NULL) { - // if the neighbor already exists, replace it - // otherwise create it (NLM_F_CREATE) - neigh_oper = NLM_F_REPLACE; - rtnl_neigh_put(tmp_neigh); - } - - error = rtnl_neigh_add(socket, neigh, neigh_oper); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_neigh_add error (%d): %s", error, nl_geterror(error)); - goto loop_end; - } - - loop_end: - nl_cache_free(cache); - nl_addr_put(ll_addr); - nl_addr_put(local_addr); - rtnl_neigh_put(neigh); - - if (error != 0) { - break; - } - } -out: - nl_socket_free(socket); - return error; -} - -static int remove_neighbors(ip_neighbor_list_t *nbor_list, struct nl_sock *socket, int addr_ver, int if_index) -{ - int error = 0; - // Iterate through list of neighbors and check delete flag - for (uint32_t i = 0; i < nbor_list->count; i++) { - - if (nbor_list->nbor[i].delete == true) { - // Allocate an empty neighbour object to be filled out with the attributes - // matching the neighbour to be deleted. Alternatively a fully equipped - // neighbour object out of a cache can be used instead. - struct nl_addr *dst_addr = NULL; - struct rtnl_neigh *neigh = rtnl_neigh_alloc(); - - error = nl_addr_parse(nbor_list->nbor[i].ip, addr_ver, &dst_addr); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_addr_parse error (%d): %s", error, nl_geterror(error)); - nl_addr_put(dst_addr); - rtnl_neigh_put(neigh); - return -1; - } - // Neighbours are uniquely identified by their interface index and - // destination address, you may fill out other attributes but they - // will have no influence. - rtnl_neigh_set_ifindex(neigh, if_index); - rtnl_neigh_set_dst(neigh, dst_addr); - - // Build the netlink message and send it to the kernel, the operation will - // block until the operation has been completed. Alternatively the required - // netlink message can be built using rtnl_neigh_build_delete_request() - // to be sent out using nl_send_auto_complete(). - error = rtnl_neigh_delete(socket, neigh, NLM_F_ACK); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_neigh_delete error (%d): %s", error, nl_geterror(error)); - nl_addr_put(dst_addr); - rtnl_neigh_put(neigh); - return -1; - } - - // Free the memory - nl_addr_put(dst_addr); - rtnl_neigh_put(neigh); - - // Remove neighbor from list - ip_neighbor_free(&nbor_list->nbor[i]); - } - } - - return 0; -} - -static int create_vlan_qinq(struct nl_sock *socket, struct nl_cache *cache, char *second_vlan_name, char *name, char *parent_interface, uint16_t outer_vlan_id, uint16_t second_vlan_id) -{ - int error = 0; - struct rtnl_link *outer_tag_link = rtnl_link_alloc(); - struct rtnl_link *second_tag_link = rtnl_link_alloc(); - - // create virtual link for outer tag - error = rtnl_link_set_type(outer_tag_link, "vlan"); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_set_type error (%d): %s", error, nl_geterror(error)); - goto out; - } - rtnl_link_set_name(outer_tag_link, name); - // set parent interface - int parent_index = rtnl_link_name2i(cache, parent_interface); - rtnl_link_set_link(outer_tag_link, parent_index); - // set protocol to 802.1ad (QinQ) - error = rtnl_link_vlan_set_protocol(outer_tag_link, htons(ETH_P_8021AD)); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_vlan_set_protocol error (%d): %s", error, nl_geterror(error)); - goto out; - } - // set outer vlan id (s-tag) - error = rtnl_link_vlan_set_id(outer_tag_link, outer_vlan_id); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_vlan_set_id error (%d): %s", error, nl_geterror(error)); - goto out; - } - error = rtnl_link_add(socket, outer_tag_link, NLM_F_CREATE); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_add error (%d): %s", error, nl_geterror(error)); - goto out; - } - - // create virtual link for second tag - error = rtnl_link_set_type(second_tag_link, "vlan"); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_set_type error (%d): %s", error, nl_geterror(error)); - goto out; - } - rtnl_link_set_name(second_tag_link, second_vlan_name); - // retrieve outer_tag_link struct from the kernel so that it contains the correct ifindex - rtnl_link_put(outer_tag_link); - outer_tag_link = NULL; - error = rtnl_link_get_kernel(socket, 0, name, &outer_tag_link); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_get_kernel error (%d): %s", error, nl_geterror(error)); - goto out; - } - // set outer_tag_link as the parent of second_tag_link to ensure it - // will be deleted automatically when outer_tag_link is deleted - rtnl_link_set_link(second_tag_link, rtnl_link_get_ifindex(outer_tag_link)); - // set second vlan id (c-tag) - error = rtnl_link_vlan_set_id(second_tag_link, second_vlan_id); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_vlan_set_id error (%d): %s", error, nl_geterror(error)); - goto out; - } - error = rtnl_link_add(socket, second_tag_link, NLM_F_CREATE); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_add error (%d): %s", error, nl_geterror(error)); - goto out; - } -out: - rtnl_link_put(outer_tag_link); - rtnl_link_put(second_tag_link); - return error; -} - -static bool check_system_interface(const char *interface_name, bool *system_interface) -{ - int error = 0; - char *all_devices_cmd = "ls /sys/class/net"; - char *check_system_devices_cmd = "ls -l /sys/class/net"; - char line[CLASS_NET_LINE_LEN] = {0}; - int all_cnt = 0; - int sys_cnt = 0; - char *all_interfaces[LD_MAX_LINKS] = {0}; - char *system_interfaces[LD_MAX_LINKS] = {0}; - FILE *system_interface_check = NULL; - - system_interface_check = popen(all_devices_cmd, "r"); - if (system_interface_check == NULL) { - SRPLG_LOG_WRN(PLUGIN_NAME, "could not execute %s", all_devices_cmd); - *system_interface = false; - error = -1; - goto out; - } - - // get all interfaces from /sys/class/net - while (fgets(line, sizeof(line), system_interface_check) != NULL) { - // remove newline char from line - line[strlen(line) - 1] = '\0'; - all_interfaces[all_cnt] = strndup(line, strlen(line) + 1); - all_cnt++; - } - - pclose(system_interface_check); - // reset everything to reuse it - system_interface_check = NULL; - memset(line, 0, CLASS_NET_LINE_LEN); - - system_interface_check = popen(check_system_devices_cmd, "r"); - if (system_interface_check == NULL) { - SRPLG_LOG_WRN(PLUGIN_NAME, "could not execute %s", check_system_devices_cmd); - *system_interface = false; - error = -1; - goto out; - } - - // check if an interface is virtual or system - while (fgets(line, sizeof(line), system_interface_check) != NULL) { - // loopback device is virtual but handle it as a physical device here - // because libnl won't let us delete it - if (strstr(line, "/lo") != NULL || - (strstr(line, "/virtual/") == NULL && - strncmp(line, "total", strlen("total") != 0))) { - // this is a system interface - - // add it to system_interfaces - for (int i = 0; i < LD_MAX_LINKS; i++) { - if (all_interfaces[i] != 0) { - if (strstr(line, all_interfaces[i]) != NULL) { - system_interfaces[sys_cnt] = strndup(all_interfaces[i], strlen(all_interfaces[i]) + 1); - sys_cnt++; - break; - } - } - } - } - memset(line, 0, CLASS_NET_LINE_LEN); - } - - for (int i = 0; i < LD_MAX_LINKS; i++) { - if (system_interfaces[i] != 0) { - if (strcmp(interface_name, system_interfaces[i]) == 0) { - *system_interface = true; - break; - } - } - } - - // cleanup - for (int i = 0; i < LD_MAX_LINKS; i++) { - if (system_interfaces[i] != 0) { - FREE_SAFE(system_interfaces[i]); - } - - if (all_interfaces[i] != 0) { - FREE_SAFE(all_interfaces[i]); - } - } - -out: - if (system_interface_check) { - pclose(system_interface_check); - } - - return error; -} - -int write_to_proc_file(const char *dir_path, char *interface, const char *fn, int val) -{ - int error = 0; - char tmp_buffer[PATH_MAX]; - FILE *fptr = NULL; - - error = snprintf(tmp_buffer, sizeof(tmp_buffer), "%s/%s/%s", dir_path, interface, fn); - if (error < 0) { - // snprintf error - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf failed"); - goto out; - } - - // snprintf returns return the number of bytes that are written - // reset error to 0 - error = 0; - - fptr = fopen((const char *) tmp_buffer, "w"); - if (fptr == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "failed to open %s: %s", tmp_buffer, strerror(errno)); - error = -1; - goto out; - } - - error = fprintf(fptr, "%d", val); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "fprintf error: %s", strerror(errno)); - error = -1; - goto out; - } - - error = 0; - error = fclose(fptr); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "fclose error: %s", strerror(errno)); - error = -1; - goto out; - } -out: - return error; -} - - -static int read_from_proc_file(const char *dir_path, char *interface, const char *fn, int *val) -{ - int error = 0; - char tmp_buffer[PATH_MAX]; - FILE *fptr = NULL; - char val_str[20] = {0}; - - error = snprintf(tmp_buffer, sizeof(tmp_buffer), "%s/%s/%s", dir_path, interface, fn); - if (error < 0) { - // snprintf error - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf failed"); - goto out; - } - - // snprintf returns return the number of bytes that are written - // reset error to 0 - error = 0; - fptr = fopen((const char *) tmp_buffer, "r"); - if (fptr == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "failed to open %s: %s", tmp_buffer, strerror(errno)); - error = -1; - goto out; - } - - char *s = fgets(val_str, sizeof(val_str), fptr); - if (s == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "fgets error: %s", strerror(errno)); - error = -1; - goto out; - } - - errno = 0; - *val = (int) strtol(val_str, NULL, 10); - if (errno != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "strtol error: %s", strerror(errno)); - error = -1; - goto out; - } - - error = fclose(fptr); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "fclose error: %s", strerror(errno)); - error = -1; - goto out; - } - -out: - return error; -} - -static int read_interface_type_from_sys_file(const char *dir_path, char *interface, int *val) -{ - int error = 0; - char tmp_buffer[PATH_MAX]; - FILE *fptr = NULL; - char val_str[20] = {0}; - - error = snprintf(tmp_buffer, sizeof(tmp_buffer), "%s/%s/type", dir_path, interface); - if (error < 0) { - // snprintf error - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf failed"); - goto out; - } - - // snprintf returns return the number of bytes that are written - // reset error to 0 - error = 0; - fptr = fopen((const char *) tmp_buffer, "r"); - if (fptr == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "failed to open %s: %s", tmp_buffer, strerror(errno)); - error = -1; - goto out; - } - - char *s = fgets(val_str, sizeof(val_str), fptr); - if (s == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "fgets error: %s", strerror(errno)); - error = -1; - goto out; - } - - errno = 0; - *val = (int) strtol(val_str, NULL, 10); - if (errno != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "strtol error: %s", strerror(errno)); - error = -1; - goto out; - } - - error = fclose(fptr); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "fclose error: %s", strerror(errno)); - error = -1; - goto out; - } - -out: - return error; -} - -int add_existing_links(sr_session_ctx_t *session, link_data_list_t *ld) -{ - int error = 0; - struct nl_sock *socket = NULL; - struct nl_cache *cache = NULL; - struct rtnl_link *link = NULL; - struct nl_cache *addr_cache = NULL; - struct nl_cache *neigh_cache = NULL; - struct rtnl_addr *addr = {0}; - char *name = NULL; - char *description = NULL; - char *type = NULL; - char *enabled = NULL; - char *parent_interface = NULL; - uint16_t vlan_id = 0; - unsigned int mtu = 0; - char tmp_buffer[10] = {0}; - char parent_buffer[MAX_IF_NAME_LEN] = {0}; - int addr_family = 0; - char addr_str[ADDR_STR_BUF_SIZE]; - char dst_addr_str[ADDR_STR_BUF_SIZE]; - char ll_addr_str[ADDR_STR_BUF_SIZE]; - - socket = nl_socket_alloc(); - if (socket == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_socket_alloc error: invalid socket"); - goto error_out; - } - - error = nl_connect(socket, NETLINK_ROUTE); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_connect error (%d): %s", error, nl_geterror(error)); - goto error_out; - } - - error = rtnl_link_alloc_cache(socket, AF_UNSPEC, &cache); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_alloc_cache error (%d): %s", error, nl_geterror(error)); - goto error_out; - } - - link = (struct rtnl_link *) nl_cache_get_first(cache); - - while (link != NULL) { - // reset parent interface - parent_interface = NULL; - - name = rtnl_link_get_name(link); - if (name == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_get_name error"); - goto error_out; - } - - error = get_interface_description(session, name, &description); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "get_interface_description error"); - goto error_out; - } - - type = rtnl_link_get_type(link); - if (type == NULL) { - /* rtnl_link_get_type() will return NULL for interfaces that were not - * set with rtnl_link_set_type() - * - * get the type from: /sys/class/net//type - */ - const char *path_to_sys = "/sys/class/net/"; - int type_id = 0; - - error = read_interface_type_from_sys_file(path_to_sys, name, &type_id); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "read_interface_type_from_sys_file error"); - goto error_out; - } - - // values taken from: if_arp.h - if (type_id == 1) { - // eth interface - type = "eth"; - } else if (type_id == 772) { - // loopback interface - type = "lo"; - } - } - - // enabled - uint8_t tmp_enabled = rtnl_link_get_operstate(link); - // lo interface has state unknown, treat it as enabled - // otherwise it will be set to down, and dns resolution won't work - if (IF_OPER_UP == tmp_enabled || IF_OPER_UNKNOWN == tmp_enabled) { - enabled = "true"; - } else if (IF_OPER_DOWN == tmp_enabled ) { - enabled = "false"; - } - - // vlan - if (rtnl_link_is_vlan(link)) { - // parent interface - int parent_index = rtnl_link_get_link(link); - parent_interface = rtnl_link_i2name(cache, parent_index, parent_buffer, MAX_IF_NAME_LEN); - - // outer vlan id - vlan_id = (uint16_t)rtnl_link_vlan_get_id(link); - if (vlan_id <= 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "couldn't get vlan ID"); - goto error_out; - } - - // check if vlan_id in name, if it is this is the QinQ interface, skip it - char *first = NULL; - char *second = NULL; - - first = strchr(name, '.'); - second = strchr(first+1, '.'); - - if (second != 0) { - link = (struct rtnl_link *) nl_cache_get_next((struct nl_object *) link); - continue; - } - } - - error = link_data_list_add(ld, name); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_add error"); - goto error_out; - } - - if (description != NULL) { - error = link_data_list_set_description(ld, name, description); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_description error"); - goto error_out; - } - } - - if (type != NULL) { - error = link_data_list_set_type(ld, name, type); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_type error"); - goto error_out; - } - } - - error = link_data_list_set_enabled(ld, name, enabled); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_enabled error"); - goto error_out; - } - - if (parent_interface != 0) { - error = link_data_list_set_parent(ld, name, parent_interface); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_parent error"); - goto error_out; - } - } - - if (vlan_id != 0) { - error = link_data_list_set_outer_vlan_id(ld, name, vlan_id); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_outer_vlan_id error"); - goto error_out; - } - } - - // get ipv4 mtu - mtu = rtnl_link_get_mtu(link); - - snprintf(tmp_buffer, sizeof(tmp_buffer), "%u", mtu); - - if (mtu > 0) { - error = link_data_list_set_ipv4_mtu(&link_data_list, name, tmp_buffer); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_ipv4_mtu error (%d) : %s", error, strerror(error)); - goto error_out; - } - } - - // get ipv6 mtu - const char *ipv6_base = "/proc/sys/net/ipv6/conf"; - int ipv6_mtu = 0; - - error = read_from_proc_file(ipv6_base, name, "mtu", &ipv6_mtu); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "read_from_proc_file error (%d) : %s", error, strerror(error)); - goto error_out; - } - - snprintf(tmp_buffer, sizeof(tmp_buffer), "%u", ipv6_mtu); - - if (ipv6_mtu > 0) { - error = link_data_list_set_ipv6_mtu(&link_data_list, name, tmp_buffer); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_ipv6_mtu error (%d) : %s", error, strerror(error)); - goto error_out; - } - } - - int if_index = rtnl_link_get_ifindex(link); - - // neighbors - error = rtnl_neigh_alloc_cache(socket, &neigh_cache); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_neigh_alloc_cache error (%d): %s", error, nl_geterror(error)); - goto error_out; - } - - int neigh_count = nl_cache_nitems(neigh_cache); - - struct nl_object *nl_neigh_object; - nl_neigh_object = nl_cache_get_first(neigh_cache); - - for (int i=0; i < neigh_count; i++) { - struct nl_addr *nl_dst_addr = rtnl_neigh_get_dst((struct rtnl_neigh *) nl_neigh_object); - - char *dst_addr = nl_addr2str(nl_dst_addr, dst_addr_str, sizeof(dst_addr_str)); - if (dst_addr == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_addr2str error"); - goto error_out; - } - - struct rtnl_neigh *neigh = rtnl_neigh_get(neigh_cache, if_index, nl_dst_addr); - - if (neigh != NULL) { - // get neigh state - int neigh_state = rtnl_neigh_get_state(neigh); - - // skip neighs with no arp state - if (NUD_NOARP == neigh_state) { - nl_neigh_object = nl_cache_get_next(nl_neigh_object); - rtnl_neigh_put(neigh); - continue; - } - - int cur_neigh_index = rtnl_neigh_get_ifindex(neigh); - - if (if_index != cur_neigh_index) { - nl_neigh_object = nl_cache_get_next(nl_neigh_object); - rtnl_neigh_put(neigh); - continue; - } - - struct nl_addr *ll_addr = rtnl_neigh_get_lladdr(neigh); - - char *ll_addr_s = nl_addr2str(ll_addr, ll_addr_str, sizeof(ll_addr_str)); - if (NULL == ll_addr_s) { - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_addr2str error"); - rtnl_neigh_put(neigh); - goto error_out; - } - - // check if ipv4 or ipv6 - addr_family = rtnl_neigh_get_family(neigh); - - if (addr_family == AF_INET) { - error = link_data_list_add_ipv4_neighbor(&link_data_list, name, dst_addr, ll_addr_s); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_add_ipv4_neighbor error (%d) : %s", error, strerror(error)); - rtnl_neigh_put(neigh); - goto error_out; - } - } else if (addr_family == AF_INET6) { - error = link_data_list_add_ipv6_neighbor(&link_data_list, name, dst_addr, ll_addr_s); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_add_ipv6_neighbor error (%d) : %s", error, strerror(error)); - rtnl_neigh_put(neigh); - goto error_out; - } - } - rtnl_neigh_put(neigh); - } - nl_neigh_object = nl_cache_get_next(nl_neigh_object); - } - - nl_cache_free(neigh_cache); - neigh_cache = NULL; - - error = rtnl_addr_alloc_cache(socket, &addr_cache); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_addr_alloc_cache error (%d): %s", error, nl_geterror(error)); - goto error_out; - } - - // get ipv4 and ipv6 addresses - int addr_count = nl_cache_nitems(addr_cache); - - struct nl_object *nl_object; - nl_object = nl_cache_get_first(addr_cache); - - addr = (struct rtnl_addr *) nl_object; - - for (int i=0; i < addr_count; i++) { - struct nl_addr *nl_addr_local = rtnl_addr_get_local(addr); - if (nl_addr_local == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_addr_get_local error"); - goto error_out; - } - - int cur_if_index = rtnl_addr_get_ifindex(addr); - - if (if_index != cur_if_index) { - nl_object = nl_cache_get_next(nl_object); - addr = (struct rtnl_addr *) nl_object; - continue; - } - - const char*addr_s = nl_addr2str(nl_addr_local, addr_str, sizeof(addr_str)); - if (NULL == addr_s) { - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_addr2str error"); - goto error_out; - } - - char *str = xstrdup(addr_s); - - // get address - char *token = strtok(str, "/"); - if (token == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "couldn't parse ip address"); - - FREE_SAFE(str); - goto error_out; - } - - char *address = xstrdup(token); - - // get subnet - token = strtok(NULL, "/"); - if (token == NULL) { - // the address exists - // skip it - // we didn't add this address - // e.g.: ::1 - FREE_SAFE(str); - FREE_SAFE(address); - continue; - } - - char *subnet = xstrdup(token); - - // check if ipv4 or ipv6 - addr_family = rtnl_addr_get_family(addr); - - if (addr_family == AF_INET) { - // ipv4 - error = link_data_list_add_ipv4_address(&link_data_list, name, address, subnet, ip_subnet_type_prefix_length); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_add_ipv4_address error (%d) : %s", error, strerror(error)); - - FREE_SAFE(str); - FREE_SAFE(address); - FREE_SAFE(subnet); - goto error_out; - } - - // enabled - const char *ipv4_base = "/proc/sys/net/ipv4/conf"; - // TODO: figure out how to enable/disable ipv4 - // since disable_ipv4 doesn't exist in /proc/sys/net/ipv6/conf/interface_name - - // forwarding - int ipv4_forwarding = 0; - - error = read_from_proc_file(ipv4_base, name, "forwarding", &ipv4_forwarding); - if (error != 0) { - FREE_SAFE(str); - FREE_SAFE(address); - FREE_SAFE(subnet); - goto error_out; - } - - error = link_data_list_set_ipv4_forwarding(&link_data_list, name, ipv4_forwarding == 0 ? "false" : "true"); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_ipv4_forwarding error (%d) : %s", error, strerror(error)); - - FREE_SAFE(str); - FREE_SAFE(address); - FREE_SAFE(subnet); - goto error_out; - } - - } else if (addr_family == AF_INET6) { - // ipv6 - error = link_data_list_add_ipv6_address(&link_data_list, name, address, subnet); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_add_ipv6_address error (%d) : %s", error, strerror(error)); - - FREE_SAFE(str); - FREE_SAFE(address); - FREE_SAFE(subnet); - goto error_out; - } - - // enabled - ipv6_base = "/proc/sys/net/ipv6/conf"; - - int ipv6_enabled = 0; - - error = read_from_proc_file(ipv6_base, name, "disable_ipv6", &ipv6_enabled); - if (error != 0) { - FREE_SAFE(str); - FREE_SAFE(address); - FREE_SAFE(subnet); - goto error_out; - } - // since we check the value of 'disable_ipv6' file, the ipv6_enabled should be reversed - error = link_data_list_set_ipv6_enabled(&link_data_list, name, ipv6_enabled == 0 ? "true" : "false"); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_ipv6_enabled error (%d) : %s", error, strerror(error)); - - FREE_SAFE(str); - FREE_SAFE(address); - FREE_SAFE(subnet); - goto error_out; - } - - // forwarding - int ipv6_forwarding = 0; - - error = read_from_proc_file(ipv6_base, name, "forwarding", &ipv6_forwarding); - if (error != 0) { - FREE_SAFE(str); - FREE_SAFE(address); - FREE_SAFE(subnet); - goto error_out; - } - - error = link_data_list_set_ipv6_forwarding(&link_data_list, name, ipv6_forwarding == 0 ? "false" : "true"); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "link_data_list_set_ipv6_forwarding error (%d) : %s", error, strerror(error)); - - FREE_SAFE(str); - FREE_SAFE(address); - FREE_SAFE(subnet); - goto error_out; - } - } - - nl_object = nl_cache_get_next(nl_object); - addr = (struct rtnl_addr *) nl_object; - - FREE_SAFE(str); - FREE_SAFE(address); - FREE_SAFE(subnet); - } - nl_cache_free(addr_cache); - addr_cache = NULL; - - link = (struct rtnl_link *) nl_cache_get_next((struct nl_object *) link); - - if (description != NULL) { // it was allocated in get_interface_description - FREE_SAFE(description); - } - } - - rtnl_link_put(link); - - nl_socket_free(socket); - nl_cache_free(cache); - - return 0; - -error_out: - if (socket != NULL) { - nl_socket_free(socket); - } - - if (link != NULL) { - rtnl_link_put(link); - } - - nl_cache_free(cache); - - if (addr_cache != NULL) { - nl_cache_free(addr_cache); - } - - if (description != NULL) { - FREE_SAFE(description); - } - - return -1; -} - -static int get_interface_description(sr_session_ctx_t *session, char *name, char **description) -{ - int error = SR_ERR_OK; - char path_buffer[PATH_MAX] = {0}; - sr_val_t *val = NULL; - - // conjure description path for this interface - // /ietf-interfaces:interfaces/interface[name='test_interface']/description - error = snprintf(path_buffer, sizeof(path_buffer) / sizeof(char), "%s[name=\"%s\"]/description", INTERFACE_LIST_YANG_PATH, name); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf error"); - goto error_out; - } - - // get the interface description value - error = sr_get_item(session, path_buffer, 0, &val); - if (error != SR_ERR_OK) { - SRPLG_LOG_INF(PLUGIN_NAME, "interface description is not yet present in the datastore"); - } else if (strlen(val->data.string_val) > 0) { - *description = xstrdup(val->data.string_val); - } - - sr_free_values(val, 1); - - return 0; - -error_out: - return -1; -} - -/* - * function: create_node_neighbor_origin - * ------------------------------------- - * creates a neighbor node: "static", "dynamic" or "other" - * - * @arg ip_addr - * neighbor destination address - * - * @arg if_index - * interface index - * - * @arg family - * address family AF_INET OR AF_INET6 - * - * @returns: - * 0 on successful neighbor-origin node creation, -1 on error - */ -int create_node_neighbor_origin(struct lyd_node **parent, const struct ly_ctx *ly_ctx, char *interface_name, - struct nl_sock *socket, int32_t if_index, char *ip_addr, int family) -{ - struct nl_cache *cache = NULL; - struct nl_addr *dst_addr = NULL; - struct rtnl_neigh *neigh = NULL; - char xpath_buffer[PATH_MAX]; - - int state = -1; - char *origin = NULL; - - int error = -1; - int rc = -1; - - error = rtnl_neigh_alloc_cache(socket, &cache); - if (error < 0) { - goto error; - } - - error = nl_addr_parse(ip_addr, family, &dst_addr); - if (error != 0) { - goto error; - } - - neigh = rtnl_neigh_get(cache, if_index, dst_addr); - if (neigh == NULL) { - goto error; - } - - // TODO: discern dynamic/static/other neighbor origin, currently only dynamic/static are used - state = rtnl_neigh_get_state(neigh); - if (state == -1) { - goto error; - } - - // since state is a bit mask - // NUD_PERMANENT signifies a static entry - origin = state & NUD_PERMANENT ? "static" : "dynamic"; - - error = snprintf(xpath_buffer, PATH_MAX, "%s[name=\"%s\"]/ietf-ip:ipv%u/neighbor[ip='%s']/origin", - INTERFACE_LIST_YANG_PATH, interface_name, family == AF_INET6 ? 6 : 4, ip_addr); - // null character not counted in written chars, therefore greater or equal than - if (error < 0 || error >= PATH_MAX) { - goto error; - } - - // add neighbor origin node to the oper datastore, if successful show it (debug) - error = lyd_new_path(*parent, ly_ctx, xpath_buffer, origin, LYD_ANYDATA_STRING, 0); - if (error != LY_SUCCESS) { - goto error; - } - - SRPLG_LOG_DBG(PLUGIN_NAME, "%s = %s", xpath_buffer, origin); - rc = 0; - goto out; - -error: - SRPLG_LOG_ERR(PLUGIN_NAME, "create_node_neighbor_origin failed for address %s", ip_addr); -out: - if (cache != NULL) { - nl_cache_free(cache); - } - if (dst_addr != NULL) { - nl_addr_put(dst_addr); - } - if (neigh) { - rtnl_neigh_put(neigh); - } - - return rc; -} - -static int interfaces_state_data_cb(sr_session_ctx_t *session, uint32_t subscription_id, const char *module_name, const char *path, const char *request_xpath, uint32_t request_id, struct lyd_node **parent, void *private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx *ly_ctx = NULL; - struct nl_sock *socket = NULL; - struct nl_cache *cache = NULL; - struct rtnl_link *link = NULL; - struct nl_addr *addr = NULL; - struct rtnl_tc *tc = NULL; - struct rtnl_qdisc *qdisc = NULL; - if_state_t *tmp_ifs = NULL; - struct tm *last_change = NULL; - - const char *OPER_STRING_MAP[] = { - [IF_OPER_UNKNOWN] = "unknown", - [IF_OPER_NOTPRESENT] = "not-present", - [IF_OPER_DOWN] = "down", - [IF_OPER_LOWERLAYERDOWN] = "lower-layer-down", - [IF_OPER_TESTING] = "testing", - [IF_OPER_DORMANT] = "dormant", - [IF_OPER_UP] = "up", - }; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - error = SR_ERR_CALLBACK_FAILED; - goto error_out; - } - lyd_new_path(*parent, ly_ctx, request_xpath, NULL, 0, NULL); - } - - // copy configuration data (subtree of the requested xpath) - // from the running datastore in order to return it along with the state data - // (merge it with the data tree which will be filled in the rest of this callback) - error = sr_session_switch_ds(session, SR_DS_RUNNING); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_session_switch_ds error (%d): %s", error, sr_strerror(error)); - goto error_out; - } - sr_data_t *running_ds_data = NULL; - error = sr_get_subtree(session, request_xpath, 0, &running_ds_data); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_get_subtree error (%d): %s", error, sr_strerror(error)); - goto error_out; - } - error = lyd_merge_tree(parent, running_ds_data->tree, 0); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "lyd_merge_tree error"); - goto error_out; - } - sr_release_data(running_ds_data); - error = sr_session_switch_ds(session, SR_DS_OPERATIONAL); // switch back - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_session_switch_ds error (%d): %s", error, sr_strerror(error)); - goto error_out; - } - - socket = nl_socket_alloc(); - if (socket == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_socket_alloc error: invalid socket"); - goto error_out; - } - - if ((error = nl_connect(socket, NETLINK_ROUTE)) != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_connect error (%d): %s", error, nl_geterror(error)); - goto error_out; - } - - error = rtnl_link_alloc_cache(socket, AF_UNSPEC, &cache); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_alloc_cache error (%d): %s", error, nl_geterror(error)); - goto error_out; - } - - char system_boot_time[DATETIME_BUF_SIZE] = {0}; - error = get_system_boot_time(system_boot_time); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "get_system_boot_time error: %s", strerror(errno)); - goto error_out; - } - - link = (struct rtnl_link *) nl_cache_get_first(cache); - qdisc = rtnl_qdisc_alloc(); - - while (link != NULL) { - // get tc and set the link - tc = TC_CAST(qdisc); - rtnl_tc_set_link(tc, link); - - char *interface_name = rtnl_link_get_name(link); - - // collect operational state information - char *interface_oper_leaf_values[IF_OPER_LEAF_COUNT] = {NULL}; - - // interface_data.link_up_down_trap_enable = ? - // interface_data.admin_status = ? - - // oper-status - interface_oper_leaf_values[IF_OPER_STATUS] = (char *) OPER_STRING_MAP[rtnl_link_get_operstate(link)]; - - // last-change - tmp_ifs = if_state_list_get_by_if_name(&if_state_changes, interface_name); - last_change = (tmp_ifs->last_change != 0) ? localtime(&tmp_ifs->last_change) : NULL; - char last_change_time[DATETIME_BUF_SIZE] = {0}; - // last-change -> only if changed at one point - if (last_change != NULL) { - // convert it to human readable format here - strftime(last_change_time, sizeof(last_change_time), "%FT%TZ", last_change); - interface_oper_leaf_values[IF_LAST_CHANGE] = last_change_time; - } else { - // default value of last-change should be system boot time - interface_oper_leaf_values[IF_LAST_CHANGE] = system_boot_time; - } - - // if-index - char if_index[16] = {0}; - snprintf(if_index, sizeof(if_index), "%u", rtnl_link_get_ifindex(link)); - interface_oper_leaf_values[IF_IF_INDEX] = if_index; - - // phys-address - addr = rtnl_link_get_addr(link); - char phys_address[MAC_ADDR_MAX_LENGTH + 1] = {0}; - nl_addr2str(addr, phys_address, MAC_ADDR_MAX_LENGTH + 1); - phys_address[MAC_ADDR_MAX_LENGTH] = 0; - interface_oper_leaf_values[IF_PHYS_ADDRESS] = phys_address; - - // speed - char speed[32] = {0}; - snprintf(speed, sizeof(speed), "%lu", rtnl_tc_get_stat(tc, RTNL_TC_RATE_BPS)); - interface_oper_leaf_values[IF_SPEED] = speed; - - // set interface state info in operational ds - error = ds_oper_set_interface_info(*parent, ly_ctx, interface_name, interface_oper_leaf_values); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "ds_oper_set_interface_info error"); - goto error_out; - } - - // collect operational statistics - char *statistics[IF_STATS_LEAF_COUNT] = {NULL}; - - // gather interface statistics that are not accessable via netlink - nic_stats_t nic_stats = {0}; - error = get_nic_stats(interface_name, &nic_stats); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "get_nic_stats error: %s", strerror(errno)); - } - - // discontinuity-time - statistics[IF_STATS_DISCONTINUITY_TIME] = system_boot_time; - - // Rx - // in-octets - char in_octets[32] = {0}; - snprintf(in_octets, sizeof(in_octets), "%lu", rtnl_link_get_stat(link, RTNL_LINK_RX_BYTES)); - statistics[IF_STATS_IN_OCTETS] = in_octets; - // in-broadcast-pkts - char in_broadcast_pkts[32] = {0}; - snprintf(in_broadcast_pkts, sizeof(in_broadcast_pkts), "%lu", nic_stats.rx_broadcast); - statistics[IF_STATS_IN_BROADCAST_PKTS] = in_broadcast_pkts; - // in-multicast-pkts - uint64_t in_multicast_pkts = rtnl_link_get_stat(link, RTNL_LINK_MULTICAST); - char in_multicast_pkts_str[32] = {0}; - snprintf(in_multicast_pkts_str, sizeof(in_multicast_pkts_str), "%lu", in_multicast_pkts); - statistics[IF_STATS_IN_MULTICAST_PKTS] = in_multicast_pkts_str; - // in-unicast-pkts - uint64_t in_unicast_pkts = nic_stats.rx_packets - nic_stats.rx_broadcast - in_multicast_pkts; - char in_unicast_pkts_str[32] = {0}; - snprintf(in_unicast_pkts_str, sizeof(in_unicast_pkts_str), "%lu", in_unicast_pkts); - statistics[IF_STATS_IN_UNICAST_PKTS] = in_unicast_pkts_str; - // in-discards - char in_discards[32] = {0}; - snprintf(in_discards, sizeof(in_discards), "%u", (uint32_t) rtnl_link_get_stat(link, RTNL_LINK_RX_DROPPED)); - statistics[IF_STATS_IN_DISCARDS] = in_discards; - // in-errors - char in_errors[32] = {0}; - snprintf(in_errors, sizeof(in_errors), "%u", (uint32_t) rtnl_link_get_stat(link, RTNL_LINK_RX_ERRORS)); - statistics[IF_STATS_IN_ERRORS] = in_errors; - // in-unknown-protos - char in_unknown_protos[32] = {0}; - snprintf(in_unknown_protos, sizeof(in_unknown_protos), "%u", (uint32_t) rtnl_link_get_stat(link, RTNL_LINK_IP6_INUNKNOWNPROTOS)); - statistics[IF_STATS_IN_UNKNOWN_PROTOS] = in_unknown_protos; - - // Tx - // out-octets - char out_octets[32] = {0}; - snprintf(out_octets, sizeof(out_octets), "%lu",rtnl_link_get_stat(link, RTNL_LINK_TX_BYTES)); - statistics[IF_STATS_OUT_OCTETS] = out_octets; - // out-unicast-pkts - char out_unicast_pkts[32] = {0}; - snprintf(out_unicast_pkts, sizeof(out_unicast_pkts), "%lu", nic_stats.tx_packets - nic_stats.tx_broadcast - nic_stats.tx_multicast); - statistics[IF_STATS_OUT_UNICAST_PKTS] = out_unicast_pkts; - // out-broadcast-pkts - char out_broadcast_pkts[32] = {0}; - snprintf(out_broadcast_pkts, sizeof(out_broadcast_pkts), "%lu", nic_stats.tx_broadcast); - statistics[IF_STATS_OUT_BROADCAST_PKTS] = out_broadcast_pkts; - // out-multicast-pkts - char out_multicast_pkts[32] = {0}; - snprintf(out_multicast_pkts, sizeof(out_multicast_pkts), "%lu", nic_stats.tx_multicast); - statistics[IF_STATS_OUT_MULTICAST_PKTS] = out_multicast_pkts; - // out-discards - char out_discards[32] = {0}; - snprintf(out_discards, sizeof(out_discards), "%u", (uint32_t) rtnl_link_get_stat(link, RTNL_LINK_TX_DROPPED)); - statistics[IF_STATS_OUT_DISCARDS] = out_discards; - // out-errors - char out_errors[32] = {0}; - snprintf(out_errors, sizeof(out_errors), "%u", (uint32_t) rtnl_link_get_stat(link, RTNL_LINK_TX_ERRORS)); - statistics[IF_STATS_OUT_ERRORS] = out_errors; - - error = ds_oper_set_interface_statistics(*parent, ly_ctx, interface_name, statistics); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "ds_oper_set_interface_statistics error"); - goto error_out; - } - - // find all interfaces which are layered on top of this interface - // and update the operational datastore accordingly - int32_t master_if_index = rtnl_link_get_master(link); - struct rtnl_link *master_link = NULL; - while (master_if_index) { - master_link = rtnl_link_get(cache, master_if_index); - char *master_name = rtnl_link_get_name(master_link); - - error = ds_oper_add_interface_higher_layer_if(*parent, ly_ctx, interface_name, master_name); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "ds_oper_add_interface_higher_layer_if error"); - goto error_out; - } - error = ds_oper_add_interface_lower_layer_if(*parent, ly_ctx, master_name, interface_name); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "ds_oper_add_interface_lower_layer_if error"); - goto error_out; - } - - // go one layer higher - master_if_index = rtnl_link_get_master(master_link); - } - - link_data_t *l = data_list_get_by_name(&link_data_list, interface_name); - if (l != NULL) { - // set origin for ipv4 neighbors - uint32_t ipv4_neigh_count = l->ipv4.nbor_list.count; - for (uint32_t i = 0; i < ipv4_neigh_count; i++) { - char *neigh_ip = l->ipv4.nbor_list.nbor[i].ip; - error = create_node_neighbor_origin(parent, ly_ctx, interface_name, socket, rtnl_link_get_ifindex(link), neigh_ip, AF_INET); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "create_node_neighbor_origin error (ipv4)"); - goto error_out; - } - } - // set origin for ipv6 neighbors - uint32_t ipv6_neigh_count = l->ipv6.ip_data.nbor_list.count; - for (uint32_t i = 0; i < ipv6_neigh_count; i++) { - char *neigh_ip = l->ipv6.ip_data.nbor_list.nbor[i].ip; - error = create_node_neighbor_origin(parent, ly_ctx, interface_name, socket, rtnl_link_get_ifindex(link), neigh_ip, AF_INET6); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "create_node_neighbor_origin error (ipv6)"); - goto error_out; - } - } - } - - // free all allocated data - - // continue to next link node - link = (struct rtnl_link *) nl_cache_get_next((struct nl_object *) link); - } - - rtnl_qdisc_put(qdisc); - nl_cache_free(cache); - - error = SR_ERR_OK; // set error to OK, since it will be modified by snprintf - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - nl_socket_free(socket); - return error ? SR_ERR_CALLBACK_FAILED : SR_ERR_OK; -} - -static int get_system_boot_time(char boot_datetime[]) -{ - time_t now = 0; - struct tm *ts = {0}; - struct sysinfo s_info = {0}; - time_t uptime_seconds = 0; - - now = time(NULL); - - ts = localtime(&now); - if (ts == NULL) - return -1; - - if (sysinfo(&s_info) != 0) - return -1; - - uptime_seconds = s_info.uptime; - - time_t diff = now - uptime_seconds; - - ts = localtime(&diff); - if (ts == NULL) - return -1; - - /* must satisfy constraint (type yang:date-and-time): - "\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[\+\-]\d{2}:\d{2})" - TODO: Add support for: - - 2021-02-09T06:02:39.234+01:00 - - 2021-02-09T06:02:39.234Z - - 2021-02-09T06:02:39+11:11 - */ - - strftime(boot_datetime, DATETIME_BUF_SIZE, "%FT%TZ", ts); - - return 0; -} - -static int init_state_changes(void) -{ - int error = 0; - struct nl_sock *socket = NULL; - struct nl_cache *cache = NULL; - struct rtnl_link *link = NULL; - if_state_t *tmp_st = NULL; - pthread_attr_t attr; - - uint if_cnt = 0; - - struct { - pthread_t *data; - uint count; - } thread_ls; - - pthread_t manager_thread; - - socket = nl_socket_alloc(); - if (socket == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_socket_alloc error: invalid socket"); - return -1; - } - - if ((error = nl_connect(socket, NETLINK_ROUTE)) != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_connect error (%d): %s", error, nl_geterror(error)); - goto error_out; - } - - error = rtnl_link_alloc_cache(socket, AF_UNSPEC, &cache); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_alloc_cache error (%d): %s", error, nl_geterror(error)); - goto error_out; - } - - link = (struct rtnl_link *) nl_cache_get_first(cache); - - while (link != NULL) { - ++if_cnt; - - link = (struct rtnl_link *) nl_cache_get_next((struct nl_object *) link); - } - - // allocate a list to contain if_cnt number of interface states - if_state_list_alloc(&if_state_changes, if_cnt); - - thread_ls.data = (pthread_t *) malloc(sizeof(pthread_t) * if_cnt); - thread_ls.count = if_cnt; - - link = (struct rtnl_link *) nl_cache_get_first(cache); - if_cnt = 0; - - while (link != NULL) { - tmp_st = if_state_list_get(&if_state_changes, if_cnt); - if (tmp_st) { - tmp_st->state = rtnl_link_get_operstate(link); - - char *tmp_name = NULL; - tmp_name = rtnl_link_get_name(link); - - size_t len = strlen(tmp_name); - tmp_st->name = xcalloc(len + 1, sizeof(char)); - strncpy(tmp_st->name, tmp_name, len); - tmp_st->name[len] = '\0'; - } - - ++if_cnt; - link = (struct rtnl_link *) nl_cache_get_next((struct nl_object *) link); - } - - error = nl_cache_mngr_alloc(NULL, NETLINK_ROUTE, 0, &link_manager); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_cache_mngr_alloc failed (%d): %s", error, nl_geterror(error)); - goto error_out; - } - - error = nl_cache_mngr_add(link_manager, "route/link", cache_change_cb, NULL, &link_cache); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_cache_mngr_add failed (%d): %s", error, nl_geterror(error)); - goto error_out; - } - - error = pthread_attr_init(&attr); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "pthread_attr_init failed (%d)", error); - goto error_out; - } - error = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "pthread_attr_setdetachstate failed (%d): invalid value in detachstate", error); - goto error_out; - } - error = pthread_create(&manager_thread, &attr, manager_thread_cb, NULL); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "pthread_create failed (%d)", error); - goto error_out; - } - -error_out: - - // clear libnl data - nl_cache_free(cache); - nl_socket_free(socket); - - // free tmp struct - if (thread_ls.count) { - free(thread_ls.data); - } - - return error; -} - -static void cache_change_cb(struct nl_cache *cache, struct nl_object *obj, int val, void *arg) -{ - struct rtnl_link *link = NULL; - char *name = NULL; - if_state_t *tmp_st = NULL; - uint8_t tmp_state = 0; - - SRPLG_LOG_DBG(PLUGIN_NAME, "entered cb function for a link manager"); - - link = (struct rtnl_link *) nl_cache_get_first(cache); - - while (link != NULL) { - name = rtnl_link_get_name(link); - tmp_st = if_state_list_get_by_if_name(&if_state_changes, name); - tmp_state = rtnl_link_get_operstate(link); - - if (tmp_state != tmp_st->state) { - SRPLG_LOG_DBG(PLUGIN_NAME, "Interface %s changed operstate from %d to %d", name, tmp_st->state, tmp_state); - tmp_st->state = tmp_state; - tmp_st->last_change = time(NULL); - } - link = (struct rtnl_link *) nl_cache_get_next((struct nl_object *) link); - } -} - -static void *manager_thread_cb(void *data) -{ - do { - nl_cache_mngr_data_ready(link_manager); - sleep(1); - } while (exit_application == 0); - - return NULL; -} - -#ifndef PLUGIN -#include -#include - -static void sigint_handler(__attribute__((unused)) int signum); - -int main(void) -{ - int error = SR_ERR_OK; - sr_conn_ctx_t *connection = NULL; - sr_session_ctx_t *session = NULL; - void *private_data = NULL; - - sr_log_stderr(SR_LL_DBG); - - error = sr_connect(SR_CONN_DEFAULT, &connection); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_connect error (%d): %s", error, sr_strerror(error)); - goto out; - } - - error = sr_session_start(connection, SR_DS_RUNNING, &session); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_session_start error (%d): %s", error, sr_strerror(error)); - goto out; - } - - error = sr_plugin_init_cb(session, &private_data); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_plugin_init_cb error"); - goto out; - } - - signal(SIGINT, sigint_handler); - signal(SIGPIPE, SIG_IGN); - while (!exit_application) { - sleep(1); - } - -out: - sr_plugin_cleanup_cb(session, private_data); - sr_disconnect(connection); - - pthread_exit(0); - - return error ? -1 : 0; -} - -static void sigint_handler(__attribute__((unused)) int signum) -{ - SRPLG_LOG_INF(PLUGIN_NAME, "Sigint called, exiting..."); - exit_application = 1; -} - -#endif diff --git a/src/interfaces/ip_data.c b/src/interfaces/ip_data.c deleted file mode 100644 index 4b7d1ddf..00000000 --- a/src/interfaces/ip_data.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * telekom / sysrepo-plugin-interfaces - * - * This program is made available under the terms of the - * BSD 3-Clause license which is available at - * https://opensource.org/licenses/BSD-3-Clause - * - * SPDX-FileCopyrightText: 2021 Deutsche Telekom AG - * SPDX-FileContributor: Sartura Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "ip_data.h" -#include "utils/memory.h" -#include -#include -#include - -void ip_data_init(ip_data_t *ip) -{ - ip->enabled = 0; - ip->forwarding = 0; - ip->mtu = 0; - ip_address_list_init(&ip->addr_list); - ip_neighbor_list_init(&ip->nbor_list); -} - -void ip_data_set_enabled(ip_data_t *ip, char *enabled) -{ - ip->enabled = (strcmp(enabled, "true") == 0) ? 1 : 0; -} - -void ip_data_set_forwarding(ip_data_t *ip, char *forwarding) -{ - ip->forwarding = (strcmp(forwarding, "true") == 0) ? 1 : 0; -} - -void ip_data_set_mtu(ip_data_t *ip, char *mtu) -{ - ip->mtu = (uint16_t) atoi(mtu); -} - -void ip_data_add_address(ip_data_t *ip, char *addr, char *subnet, ip_subnet_type_t st) -{ - ip_address_list_add(&ip->addr_list, addr, subnet, st); -} - -void ip_data_add_neighbor(ip_data_t *ip, char *addr, char *phys_addr) -{ - ip_neighbor_list_add(&ip->nbor_list, addr, phys_addr); -} - -void ip_data_free(ip_data_t *ip) -{ - ip_address_list_free(&ip->addr_list); - ip_neighbor_list_free(&ip->nbor_list); - ip_data_init(ip); -} - -void ip_address_init(ip_address_t *addr) -{ - addr->ip = NULL; - addr->subnet_type = ip_subnet_type_unknown; - addr->delete = false; -} - -void ip_address_set_ip(ip_address_t *addr, char *ip) -{ - addr->ip = xstrdup(ip); -} - -void ip_address_set_delete(ip_address_list_t *addr_ls, char *ip) -{ - if (addr_ls->count > 0) { - for (uint32_t i = 0; i < addr_ls->count; i++) { - if (addr_ls->addr[i].ip != NULL) { - if (strcmp(addr_ls->addr[i].ip, ip) == 0) { - addr_ls->addr[i].delete = true; - } - } - } - } -} - -/* - * Function: netmask_to_prefix_len - * -------------------------------- - * calculates the prefix length (32 or 128 bit Hamming weight) of a network mask - * - * nm: network mask - * - * returns: - * prefix length - */ -uint8_t netmask_to_prefix_len(char *nm) -{ - int ret; - struct sockaddr_in sa; - struct sockaddr_in6 sa6; - - // IPv6 if a ':' is found - if (strchr(nm, ':')) { - ret = inet_pton(AF_INET6, nm, &(sa6.sin6_addr)); - // invalid network address mask - if (!ret) { - // TODO: error handling on refactor - } - - // s6_addr is a uint8_t array of length 16, all the byte popcounts need to be summarized - // avoid branching, use popcountll's 64 bits minimum - uint64_t *s6_addr64 = (uint64_t *) sa6.sin6_addr.s6_addr; - - return __builtin_popcountll(s6_addr64[0]) + __builtin_popcountll(s6_addr64[1]); - - } - - // IPv4 otherwise - ret = inet_pton(AF_INET, nm, &(sa.sin_addr)); - // invalid network address mask - if (!ret) { - // TODO: error handling on refactor - } - - return __builtin_popcountl(sa.sin_addr.s_addr); -} - -void ip_address_set_subnet(ip_address_t *addr, char *subnet, ip_subnet_type_t st) -{ - addr->subnet_type = st; - if (st == ip_subnet_type_netmask) { - addr->subnet = netmask_to_prefix_len(subnet); - } else { - addr->subnet = (uint8_t) atoi(subnet); - } -} - -void ip_address_free(ip_address_t *addr) -{ - if (addr->ip != NULL) { - FREE_SAFE(addr->ip); - } - ip_address_init(addr); -} - -void ip_address_list_init(ip_address_list_t *addr_ls) -{ - addr_ls->addr = NULL; - addr_ls->count = 0; -} - -void ip_address_list_add(ip_address_list_t *addr_ls, char *ip, char *subnet, ip_subnet_type_t st) -{ - ip_address_t *addr = NULL; - - if (addr_ls->count > 0) { - for (uint32_t i = 0; i < addr_ls->count; i++) { - if (addr_ls->addr[i].ip == NULL) { - continue; - } - // if the address is already in the list, don't add it - if (strcmp(addr_ls->addr[i].ip, ip) == 0) { - return; - } - // in case an address was deleted, we can reuse that portion of memory - // find it and set the new address at that location - if (addr_ls->addr[i].ip == NULL) { - addr = &addr_ls->addr[i]; - break; - } - } - } - - // in case the list doesn't contain empty space (none of the addresses were deleted) - if (addr == NULL) { - ++addr_ls->count; - addr_ls->addr = (ip_address_t *) xrealloc(addr_ls->addr, sizeof(ip_address_t) * addr_ls->count); - addr = &addr_ls->addr[addr_ls->count - 1]; - } - - ip_address_init(addr); - ip_address_set_ip(addr, ip); - ip_address_set_subnet(addr, subnet, st); -} - -void ip_address_list_free(ip_address_list_t *addr_ls) -{ - if (addr_ls->count > 0) { - for (uint32_t i = 0; i < addr_ls->count; i++) { - ip_address_free(&addr_ls->addr[i]); - } - FREE_SAFE(addr_ls->addr); - } - ip_address_list_init(addr_ls); -} - -void ip_neighbor_init(ip_neighbor_t *n) -{ - n->ip = 0; - n->phys_addr = 0; - n->delete = false; -} - -void ip_neighbor_set_ip(ip_neighbor_t *n, char *ip) -{ - n->ip = xstrdup(ip); -} - -void ip_neighbor_set_delete(ip_neighbor_list_t *nbor_ls, char *ip) -{ - if (nbor_ls->count > 0) { - for (uint32_t i = 0; i < nbor_ls->count; i++) { - if (nbor_ls->nbor[i].ip != NULL) { - if (strcmp(nbor_ls->nbor[i].ip, ip) == 0) { - nbor_ls->nbor[i].delete = true; - } - } - } - } -} - -void ip_neighbor_set_phys_addr(ip_neighbor_t *n, char *phys_addr) -{ - n->phys_addr = xstrdup(phys_addr); -} - -void ip_neighbor_free(ip_neighbor_t *n) -{ - if (n->ip != NULL) { - FREE_SAFE(n->ip); - } - if (n->phys_addr != NULL) { - FREE_SAFE(n->phys_addr); - } - ip_neighbor_init(n); -} - -void ip_neighbor_list_init(ip_neighbor_list_t *nbor_ls) -{ - nbor_ls->count = 0; - nbor_ls->nbor = NULL; -} - -void ip_neighbor_list_add(ip_neighbor_list_t *nbor_ls, char *ip, char *phys_addr) -{ - - ip_neighbor_t *n = NULL; - - if (nbor_ls->count > 0) { - for (uint32_t i = 0; i < nbor_ls->count; i++) { - // in case a neighbor was deleted, we can reuse that portion of memory - // find it and set the new neighbor at that location - if (nbor_ls->nbor[i].ip == NULL) { - n = &nbor_ls->nbor[i]; - break; - } - } - } - - // in case the list doesn't contain empty space (none of the neighbors were deleted) - if (n == NULL) { - ++nbor_ls->count; - nbor_ls->nbor = (ip_neighbor_t *) xrealloc(nbor_ls->nbor, sizeof(ip_neighbor_t) * nbor_ls->count); - n = &nbor_ls->nbor[nbor_ls->count - 1]; - } - - ip_neighbor_init(n); - ip_neighbor_set_ip(n, ip); - - // don't set if phys_addr is "none" - if (strcmp(phys_addr, "none") != 0) { - ip_neighbor_set_phys_addr(n, phys_addr); - } -} - -void ip_neighbor_list_free(ip_neighbor_list_t *nbor_ls) -{ - if (nbor_ls->count > 0) { - for (uint32_t i = 0; i < nbor_ls->count; i++) { - ip_neighbor_free(&nbor_ls->nbor[i]); - } - FREE_SAFE(nbor_ls->nbor); - } - ip_neighbor_list_init(nbor_ls); -} diff --git a/src/interfaces/ip_data.h b/src/interfaces/ip_data.h deleted file mode 100644 index 4d61b21b..00000000 --- a/src/interfaces/ip_data.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * telekom / sysrepo-plugin-interfaces - * - * This program is made available under the terms of the - * BSD 3-Clause license which is available at - * https://opensource.org/licenses/BSD-3-Clause - * - * SPDX-FileCopyrightText: 2021 Deutsche Telekom AG - * SPDX-FileContributor: Sartura Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef IP_DATA_H_ONCE -#define IP_DATA_H_ONCE - -#include -#include - -enum ip_subnet_type_e { - ip_subnet_type_unknown = 0, - ip_subnet_type_prefix_length, - ip_subnet_type_netmask, -}; - -typedef enum ip_subnet_type_e ip_subnet_type_t; -typedef struct ip_address_s ip_address_t; -typedef struct ip_address_list_s ip_address_list_t; -typedef struct ip_neighbor_s ip_neighbor_t; -typedef struct ip_neighbor_list_s ip_neighbor_list_t; -typedef struct ip_data_s ip_data_t; - -struct ip_address_s { - char *ip; - uint8_t subnet; - ip_subnet_type_t subnet_type; - bool delete; -}; - -struct ip_address_list_s { - ip_address_t *addr; - uint32_t count; -}; - -struct ip_neighbor_s { - char *ip; - char *phys_addr; - bool delete; -}; - -struct ip_neighbor_list_s { - ip_neighbor_t *nbor; - uint32_t count; -}; - -struct ip_data_s { - uint8_t enabled; - uint8_t forwarding; - uint16_t mtu; - ip_address_list_t addr_list; - ip_neighbor_list_t nbor_list; -}; - -void ip_data_init(ip_data_t *ip); -void ip_data_set_enabled(ip_data_t *ip, char *enabled); -void ip_data_set_forwarding(ip_data_t *ip, char *forwarding); -void ip_data_set_mtu(ip_data_t *ip, char *mtu); -void ip_data_add_address(ip_data_t *ip, char *addr, char *subnet, ip_subnet_type_t st); -void ip_data_add_neighbor(ip_data_t *ip, char *addr, char *phys_addr); -void ip_data_free(ip_data_t *ip); - -void ip_address_init(ip_address_t *addr); -void ip_address_set_ip(ip_address_t *addr, char *ip); -void ip_address_set_delete(ip_address_list_t *addr_ls, char *ip); -void ip_address_set_subnet(ip_address_t *addr, char *subnet, ip_subnet_type_t st); -void ip_address_free(ip_address_t *addr); - -void ip_address_list_init(ip_address_list_t *addr_ls); -void ip_address_list_add(ip_address_list_t *addr_ls, char *ip, char *subnet, ip_subnet_type_t st); -void ip_address_list_free(ip_address_list_t *addr_ls); - -void ip_neighbor_init(ip_neighbor_t *n); -void ip_neighbor_set_ip(ip_neighbor_t *n, char *ip); -void ip_neighbor_set_delete(ip_neighbor_list_t *nbor_ls, char *ip); -void ip_neighbor_set_phys_addr(ip_neighbor_t *n, char *phys_addr); -void ip_neighbor_free(ip_neighbor_t *n); - -void ip_neighbor_list_init(ip_neighbor_list_t *nbor_ls); -void ip_neighbor_list_add(ip_neighbor_list_t *nbor_ls, char *ip, char *phys_addr); -void ip_neighbor_list_free(ip_neighbor_list_t *nbor_ls); - -#endif // IP_DATA_H_ONCE diff --git a/src/interfaces/ipv4_data.h b/src/interfaces/ipv4_data.h deleted file mode 100644 index 37964bed..00000000 --- a/src/interfaces/ipv4_data.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * telekom / sysrepo-plugin-interfaces - * - * This program is made available under the terms of the - * BSD 3-Clause license which is available at - * https://opensource.org/licenses/BSD-3-Clause - * - * SPDX-FileCopyrightText: 2021 Deutsche Telekom AG - * SPDX-FileContributor: Sartura Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef IPv4_DATA_H_ONCE -#define IPv4_DATA_H_ONCE - -#include "ip_data.h" - -typedef ip_data_t ipv4_data_t; - -#endif // IPv4_DATA_H_ONCE diff --git a/src/interfaces/ipv6_data.c b/src/interfaces/ipv6_data.c deleted file mode 100644 index ec8368af..00000000 --- a/src/interfaces/ipv6_data.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * telekom / sysrepo-plugin-interfaces - * - * This program is made available under the terms of the - * BSD 3-Clause license which is available at - * https://opensource.org/licenses/BSD-3-Clause - * - * SPDX-FileCopyrightText: 2021 Deutsche Telekom AG - * SPDX-FileContributor: Sartura Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "ipv6_data.h" -#include -#include - -void ipv6_data_init(ipv6_data_t *ipv6) -{ - ipv6_autoconf_init(&ipv6->autoconf); - ip_data_init(&ipv6->ip_data); -} - -void ipv6_data_set_cga(ipv6_data_t *ipv6, char *cga) -{ - ipv6->autoconf.create_global_addr = (strcmp(cga, "true") == 0) ? 1 : 0; -} - -void ipv6_data_set_cta(ipv6_data_t *ipv6, char *cta) -{ - ipv6->autoconf.create_temp_addr = (strcmp(cta, "true") == 0) ? 1 : 0; -} - -void ipv6_data_set_tvl(ipv6_data_t *ipv6, char *tvl) -{ - ipv6->autoconf.temp_valid_lifetime = (uint32_t) atoi(tvl); -} - -void ipv6_data_set_tpl(ipv6_data_t *ipv6, char *tpl) -{ - ipv6->autoconf.temp_preffered_lifetime = (uint32_t) atoi(tpl); -} - -void ipv6_data_free(ipv6_data_t *ipv6) -{ - ipv6_autoconf_init(&ipv6->autoconf); - ip_data_free(&ipv6->ip_data); -} - -void ipv6_autoconf_init(ipv6_autoconf_t *a) -{ - a->create_global_addr = 0; - a->create_temp_addr = 0; - a->temp_preffered_lifetime = 0; - a->temp_valid_lifetime = 0; -} diff --git a/src/interfaces/ipv6_data.h b/src/interfaces/ipv6_data.h deleted file mode 100644 index 9d10390a..00000000 --- a/src/interfaces/ipv6_data.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * telekom / sysrepo-plugin-interfaces - * - * This program is made available under the terms of the - * BSD 3-Clause license which is available at - * https://opensource.org/licenses/BSD-3-Clause - * - * SPDX-FileCopyrightText: 2021 Deutsche Telekom AG - * SPDX-FileContributor: Sartura Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef IPv6_DATA_H_ONCE -#define IPv6_DATA_H_ONCE - -#include "ip_data.h" - -typedef struct ipv6_data_s ipv6_data_t; -typedef struct ipv6_autoconf_s ipv6_autoconf_t; - -struct ipv6_autoconf_s { - uint8_t create_global_addr; - uint8_t create_temp_addr; - uint32_t temp_valid_lifetime; - uint32_t temp_preffered_lifetime; -}; - -struct ipv6_data_s { - ip_data_t ip_data; - ipv6_autoconf_t autoconf; -}; - -void ipv6_data_init(ipv6_data_t *ipv6); -void ipv6_data_set_cga(ipv6_data_t *ipv6, char *cga); -void ipv6_data_set_cta(ipv6_data_t *ipv6, char *cta); -void ipv6_data_set_tvl(ipv6_data_t *ipv6, char *tvl); -void ipv6_data_set_tpl(ipv6_data_t *ipv6, char *tpl); -void ipv6_data_free(ipv6_data_t *ipv6); - -void ipv6_autoconf_init(ipv6_autoconf_t *a); - -#endif // IPv4_DATA_H_ONCE diff --git a/src/interfaces/link_data.c b/src/interfaces/link_data.c deleted file mode 100644 index dba566bb..00000000 --- a/src/interfaces/link_data.c +++ /dev/null @@ -1,638 +0,0 @@ -/* - * telekom / sysrepo-plugin-interfaces - * - * This program is made available under the terms of the - * BSD 3-Clause license which is available at - * https://opensource.org/licenses/BSD-3-Clause - * - * SPDX-FileCopyrightText: 2021 Deutsche Telekom AG - * SPDX-FileContributor: Sartura Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include "ip_data.h" -#include "ipv4_data.h" -#include "ipv6_data.h" -#include "link_data.h" -#include "utils/memory.h" -#include -#include - -void link_data_init(link_data_t *l) -{ - l->name = NULL; - l->description = NULL; - l->type = NULL; - l->enabled = NULL; - l->delete = false; - ip_data_init(&l->ipv4); - ipv6_data_init(&l->ipv6); - l->extensions.parent_interface = NULL; - l->extensions.encapsulation.dot1q_vlan.outer_tag_type = NULL; - l->extensions.encapsulation.dot1q_vlan.outer_vlan_id = 0; - l->extensions.encapsulation.dot1q_vlan.second_tag_type = NULL; - l->extensions.encapsulation.dot1q_vlan.second_vlan_id = 0; -} - -int link_data_list_init(link_data_list_t *ld) -{ - for (int i = 0; i < LD_MAX_LINKS; i++) { - link_data_init(&ld->links[i]); - } - ld->count = 0; - - return 0; -} - -void link_data_set_name(link_data_t *l, char *name) -{ - l->name = xstrdup(name); -} - -int link_data_list_add(link_data_list_t *ld, char *name) -{ - bool name_found = false; - - if (ld->count >= LD_MAX_LINKS) { - return EINVAL; - } - - for (int i = 0; i < ld->count; i++) { - if (ld->links[i].name != NULL) { // in case we deleted a link it will be NULL - if (strcmp(ld->links[i].name, name) == 0) { - name_found = true; - break; - } - } - } - - if (!name_found) { - // set the new link to the first free one in the list - // the one with name == 0 - int pos = ld->count; - for (int i = 0; i < ld->count; i++) { - if (ld->links[i].name == NULL) { - pos = i; - break; - } - } - link_data_set_name(&ld->links[pos], name); - if (pos == ld->count) { - ++ld->count; - } - } - - return 0; -} - -int link_data_list_set_ipv4_forwarding(link_data_list_t *ld, char *name, char *forwarding) -{ - int error = 0; - link_data_t *l = NULL; - - l = data_list_get_by_name(ld, name); - - if (l != NULL) { - ip_data_set_forwarding(&l->ipv4, forwarding); - } else { - error = EINVAL; - } - - return error; -} - -int link_data_list_set_ipv4_enabled(link_data_list_t *ld, char *name, char *enabled) -{ - int error = 0; - link_data_t *l = NULL; - - l = data_list_get_by_name(ld, name); - - if (l != NULL) { - ip_data_set_enabled(&l->ipv4, enabled); - } else { - error = EINVAL; - } - - return error; -} - -int link_data_list_set_ipv4_mtu(link_data_list_t *ld, char *name, char *mtu) -{ - int error = 0; - link_data_t *l = NULL; - - l = data_list_get_by_name(ld, name); - - if (l != NULL) { - ip_data_set_mtu(&l->ipv4, mtu); - } else { - error = EINVAL; - } - - return error; -} - -int link_data_list_add_ipv4_address(link_data_list_t *ld, char *name, char *ip, char *subnet, ip_subnet_type_t st) -{ - int error = 0; - link_data_t *l = NULL; - - l = data_list_get_by_name(ld, name); - - if (l != NULL) { - ip_data_add_address(&l->ipv4, ip, subnet, st); - } else { - error = EINVAL; - } - return error; -} - -int link_data_list_set_delete_ipv4_address(link_data_list_t *ld, char *name, char *ip) -{ - int error = 0; - link_data_t *l = NULL; - - l = data_list_get_by_name(ld, name); - - if (l != NULL) { - ip_address_set_delete(&l->ipv4.addr_list, ip); - } else { - error = EINVAL; - } - return error; -} - -int link_data_list_add_ipv4_neighbor(link_data_list_t *ld, char *name, char *ip, char *phys_addr) -{ - int error = 0; - link_data_t *l = NULL; - - l = data_list_get_by_name(ld, name); - - if (l != NULL) { - ip_data_add_neighbor(&l->ipv4, ip, phys_addr); - } else { - error = EINVAL; - } - return error; -} - -int link_data_list_set_delete_ipv4_neighbor(link_data_list_t *ld, char *name, char *ip) -{ - int error = 0; - link_data_t *l = NULL; - - l = data_list_get_by_name(ld, name); - - if (l != NULL) { - ip_neighbor_set_delete(&l->ipv4.nbor_list, ip); - } else { - error = EINVAL; - } - return error; -} - -int link_data_list_set_ipv6_forwarding(link_data_list_t *ld, char *name, char *forwarding) -{ - int error = 0; - link_data_t *l = NULL; - - l = data_list_get_by_name(ld, name); - - if (l != NULL) { - ip_data_set_forwarding(&l->ipv6.ip_data, forwarding); - } else { - error = EINVAL; - } - - return error; -} - -int link_data_list_set_ipv6_enabled(link_data_list_t *ld, char *name, char *enabled) -{ - int error = 0; - link_data_t *l = NULL; - - l = data_list_get_by_name(ld, name); - - if (l != NULL) { - ip_data_set_enabled(&l->ipv6.ip_data, enabled); - } else { - error = EINVAL; - } - - return error; -} - -int link_data_list_set_ipv6_mtu(link_data_list_t *ld, char *name, char *mtu) -{ - int error = 0; - link_data_t *l = NULL; - - l = data_list_get_by_name(ld, name); - - if (l != NULL) { - ip_data_set_mtu(&l->ipv6.ip_data, mtu); - } else { - error = EINVAL; - } - - return error; -} - -int link_data_list_add_ipv6_address(link_data_list_t *ld, char *name, char *ip, char *subnet) -{ - int error = 0; - link_data_t *l = NULL; - - l = data_list_get_by_name(ld, name); - - if (l != NULL) { - ip_data_add_address(&l->ipv6.ip_data, ip, subnet, ip_subnet_type_prefix_length); - } else { - error = EINVAL; - } - return error; -} - -int link_data_list_set_delete_ipv6_address(link_data_list_t *ld, char *name, char *ip) -{ - int error = 0; - link_data_t *l = NULL; - - l = data_list_get_by_name(ld, name); - - if (l != NULL) { - ip_address_set_delete(&l->ipv6.ip_data.addr_list, ip); - } else { - error = EINVAL; - } - return error; -} - -int link_data_list_add_ipv6_neighbor(link_data_list_t *ld, char *name, char *ip, char *phys_addr) -{ - int error = 0; - link_data_t *l = NULL; - - l = data_list_get_by_name(ld, name); - - if (l != NULL) { - ip_data_add_neighbor(&l->ipv6.ip_data, ip, phys_addr); - } else { - error = EINVAL; - } - return error; -} - -int link_data_list_set_delete_ipv6_neighbor(link_data_list_t *ld, char *name, char *ip) -{ - int error = 0; - link_data_t *l = NULL; - - l = data_list_get_by_name(ld, name); - - if (l != NULL) { - ip_neighbor_set_delete(&l->ipv6.ip_data.nbor_list, ip); - } else { - error = EINVAL; - } - return error; -} - -int link_data_list_set_ipv6_cga(link_data_list_t *ld, char *name, char *cga) -{ - int error = 0; - link_data_t *l = NULL; - - l = data_list_get_by_name(ld, name); - - if (l != NULL) { - ipv6_data_set_cga(&l->ipv6, cga); - } else { - error = EINVAL; - } - return error; -} - -int link_data_list_set_ipv6_cta(link_data_list_t *ld, char *name, char *cta) -{ - int error = 0; - link_data_t *l = NULL; - - l = data_list_get_by_name(ld, name); - - if (l != NULL) { - ipv6_data_set_cta(&l->ipv6, cta); - } else { - error = EINVAL; - } - return error; -} - -int link_data_list_set_ipv6_tvl(link_data_list_t *ld, char *name, char *tvl) -{ - int error = 0; - link_data_t *l = NULL; - - l = data_list_get_by_name(ld, name); - - if (l != NULL) { - ipv6_data_set_tvl(&l->ipv6, tvl); - } else { - error = EINVAL; - } - return error; -} - -int link_data_list_set_ipv6_tpl(link_data_list_t *ld, char *name, char *tpl) -{ - int error = 0; - link_data_t *l = NULL; - - l = data_list_get_by_name(ld, name); - - if (l != NULL) { - ipv6_data_set_tpl(&l->ipv6, tpl); - } else { - error = EINVAL; - } - return error; -} - -int link_data_list_set_description(link_data_list_t *ld, char *name, char *description) -{ - int error = 0; - link_data_t *l = NULL; - - l = data_list_get_by_name(ld, name); - - if (l != NULL) { - if (l->description) { - FREE_SAFE(l->description); - } - l->description = xstrdup(description); - if (l->description == NULL) { - error = EINVAL; - } - } else { - error = EINVAL; - } - - return error; -} - -int link_data_list_set_type(link_data_list_t *ld, char *name, char *type) -{ - int error = 0; - link_data_t *l = NULL; - - l = data_list_get_by_name(ld, name); - - if (l != NULL) { - // if previously set -> free allocated mem - if (l->type) { - FREE_SAFE(l->type); - } - l->type = xstrdup(type); - if (l->type == NULL) { - error = EINVAL; - } - } else { - error = EINVAL; - } - - return error; -} - -int link_data_list_set_enabled(link_data_list_t *ld, char *name, char *enabled) -{ - int error = 0; - link_data_t *l = NULL; - - l = data_list_get_by_name(ld, name); - - if (l != NULL) { - if (l->enabled) { - FREE_SAFE(l->enabled); - } - l->enabled = xstrdup(enabled); - if (l->enabled == NULL) { - error = EINVAL; - } - } else { - error = EINVAL; - } - - return error; -} - -int link_data_list_set_delete(link_data_list_t *ld, char *name, bool delete) -{ - int error = 0; - link_data_t *l = NULL; - - l = data_list_get_by_name(ld, name); - - if (l != NULL) { - l->delete = delete; - } else { - error = EINVAL; - } - - return error; -} - -link_data_t *data_list_get_by_name(link_data_list_t *ld, char *name) -{ - link_data_t *l = NULL; - for (int i = 0; i < ld->count; i++) { - if (ld->links[i].name != NULL) { - if (strcmp(ld->links[i].name, name) == 0) { - l = &ld->links[i]; - break; - } - } - } - return l; -} - -// TODO: update -int link_data_list_set_parent(link_data_list_t *ld, char *name, char *parent) -{ - int error = 0; - int name_found = 0; - - for (int i = 0; i < ld->count; i++) { - if (ld->links[i].name != NULL) { - if (strcmp(ld->links[i].name, name) == 0) { - name_found = 1; - - if (ld->links[i].extensions.parent_interface != NULL) { - FREE_SAFE(ld->links[i].extensions.parent_interface); - } - - unsigned long tmp_len = 0; - tmp_len = strlen(parent); - ld->links[i].extensions.parent_interface = xmalloc(sizeof(char) * (tmp_len + 1)); - memcpy(ld->links[i].extensions.parent_interface, parent, tmp_len); - ld->links[i].extensions.parent_interface[tmp_len] = 0; - - break; - } - } - } - if (!name_found) { - // error - error = EINVAL; - } - return error; -} - -int link_data_list_set_outer_vlan_id(link_data_list_t *ld, char *name, uint16_t outer_vlan_id) -{ - int error = 0; - int name_found = 0; - - for (int i = 0; i < ld->count; i++) { - if (ld->links[i].name != NULL) { - if (strcmp(ld->links[i].name, name) == 0) { - name_found = 1; - ld->links[i].extensions.encapsulation.dot1q_vlan.outer_vlan_id = outer_vlan_id; - break; - } - } - } - if (!name_found) { - // error - error = EINVAL; - } - return error; -} - -int link_data_list_set_outer_tag_type(link_data_list_t *ld, char *name, char *outer_tag_type) -{ - int error = 0; - int name_found = 0; - - for (int i = 0; i < ld->count; i++) { - if (ld->links[i].name != NULL) { - if (strcmp(ld->links[i].name, name) == 0) { - name_found = 1; - - if (ld->links[i].extensions.encapsulation.dot1q_vlan.outer_tag_type != NULL) { - FREE_SAFE(ld->links[i].extensions.encapsulation.dot1q_vlan.outer_tag_type); - } - - unsigned long tmp_len = 0; - tmp_len = strlen(outer_tag_type); - ld->links[i].extensions.encapsulation.dot1q_vlan.outer_tag_type = xmalloc(sizeof(char) * (tmp_len + 1)); - memcpy(ld->links[i].extensions.encapsulation.dot1q_vlan.outer_tag_type, outer_tag_type, tmp_len); - ld->links[i].extensions.encapsulation.dot1q_vlan.outer_tag_type[tmp_len] = 0; - - break; - } - } - } - if (!name_found) { - // error - error = EINVAL; - } - return error; -} - -int link_data_list_set_second_vlan_id(link_data_list_t *ld, char *name, uint16_t second_vlan_id) -{ - int error = 0; - int name_found = 0; - - for (int i = 0; i < ld->count; i++) { - if (ld->links[i].name != NULL) { - if (strcmp(ld->links[i].name, name) == 0) { - name_found = 1; - ld->links[i].extensions.encapsulation.dot1q_vlan.second_vlan_id = second_vlan_id; - break; - } - } - } - if (!name_found) { - // error - error = EINVAL; - } - return error; -} - -int link_data_list_set_second_tag_type(link_data_list_t *ld, char *name, char *second_tag_type) -{ - int error = 0; - int name_found = 0; - - for (int i = 0; i < ld->count; i++) { - if (ld->links[i].name != NULL) { - if (strcmp(ld->links[i].name, name) == 0) { - name_found = 1; - - if (ld->links[i].extensions.encapsulation.dot1q_vlan.second_tag_type != NULL) { - FREE_SAFE(ld->links[i].extensions.encapsulation.dot1q_vlan.second_tag_type); - } - - unsigned long tmp_len = 0; - tmp_len = strlen(second_tag_type); - ld->links[i].extensions.encapsulation.dot1q_vlan.second_tag_type = xmalloc(sizeof(char) * (tmp_len + 1)); - memcpy(ld->links[i].extensions.encapsulation.dot1q_vlan.second_tag_type, second_tag_type, tmp_len); - ld->links[i].extensions.encapsulation.dot1q_vlan.second_tag_type[tmp_len] = 0; - - break; - } - } - } - if (!name_found) { - // error - error = EINVAL; - } - return error; -} - -void link_data_free(link_data_t *l) -{ - if (l->name) { - FREE_SAFE(l->name); - } - - if (l->description) { - FREE_SAFE(l->description); - } - - if (l->type) { - FREE_SAFE(l->type); - } - - if (l->enabled) { - FREE_SAFE(l->enabled); - } - - ip_data_free(&l->ipv4); - ipv6_data_free(&l->ipv6); - - if (l->extensions.parent_interface) { - FREE_SAFE(l->extensions.parent_interface); - } - - if (l->extensions.encapsulation.dot1q_vlan.outer_tag_type) { - FREE_SAFE(l->extensions.encapsulation.dot1q_vlan.outer_tag_type); - } - - if (l->extensions.encapsulation.dot1q_vlan.second_tag_type) { - FREE_SAFE(l->extensions.encapsulation.dot1q_vlan.second_tag_type); - } -} - -void link_data_list_free(link_data_list_t *ld) -{ - for (int i = 0; i < ld->count; i++) { - link_data_free(&ld->links[i]); - } -} diff --git a/src/interfaces/link_data.h b/src/interfaces/link_data.h deleted file mode 100644 index 1b97c4b2..00000000 --- a/src/interfaces/link_data.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * telekom / sysrepo-plugin-interfaces - * - * This program is made available under the terms of the - * BSD 3-Clause license which is available at - * https://opensource.org/licenses/BSD-3-Clause - * - * SPDX-FileCopyrightText: 2021 Deutsche Telekom AG - * SPDX-FileContributor: Sartura Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef LINK_DATA_H_ONCE -#define LINK_DATA_H_ONCE - -#include -#include -#include "ip_data.h" -#include "ipv4_data.h" -#include "ipv6_data.h" - -#define LD_MAX_LINKS 100 // TODO: check this - -typedef struct link_data_s link_data_t; -typedef struct link_data_list_s link_data_list_t; - -struct link_data_s { - char *name; - char *description; - char *type; - char *enabled; - bool delete; - ipv4_data_t ipv4; - ipv6_data_t ipv6; - struct { - struct { - struct { - char *outer_tag_type; - uint16_t outer_vlan_id; - char *second_tag_type; - uint16_t second_vlan_id; - } dot1q_vlan; - // TODO: add more interface types that can have a configurable L2 encapsulation - } encapsulation; - - char *parent_interface; - // TOOD: cover more yang nodes from extensions - } extensions; -}; - -struct link_data_list_s { - link_data_t links[LD_MAX_LINKS]; - uint8_t count; -}; - -// link_data struct functions -void link_data_init(link_data_t *l); -void link_data_set_name(link_data_t *l, char *name); -void link_data_free(link_data_t *l); - -// link_data_list functions - init -int link_data_list_init(link_data_list_t *ld); -int link_data_list_add(link_data_list_t *ld, char *name); - -// basic options -link_data_t *data_list_get_by_name(link_data_list_t *ld, char *name); -int link_data_list_set_description(link_data_list_t *ld, char *name, char *description); -int link_data_list_set_type(link_data_list_t *ld, char *name, char *type); -int link_data_list_set_enabled(link_data_list_t *ld, char *name, char *enabled); -int link_data_list_set_delete(link_data_list_t *ld, char *name, bool delete); - -// ipv4 options -int link_data_list_set_ipv4_forwarding(link_data_list_t *ld, char *name, char *forwarding); -int link_data_list_set_ipv4_enabled(link_data_list_t *ld, char *name, char *enabled); -int link_data_list_set_ipv4_mtu(link_data_list_t *ld, char *name, char *mtu); -int link_data_list_add_ipv4_address(link_data_list_t *ld, char *name, char *ip, char *subnet, ip_subnet_type_t st); -int link_data_list_set_delete_ipv4_address(link_data_list_t *ld, char *name, char *ip); -int link_data_list_add_ipv4_neighbor(link_data_list_t *ld, char *name, char *ip, char *phys_addr); -int link_data_list_set_delete_ipv4_neighbor(link_data_list_t *ld, char *name, char *ip); - -// ipv6 options -int link_data_list_set_ipv6_forwarding(link_data_list_t *ld, char *name, char *forwarding); -int link_data_list_set_ipv6_enabled(link_data_list_t *ld, char *name, char *enabled); -int link_data_list_set_ipv6_mtu(link_data_list_t *ld, char *name, char *mtu); -int link_data_list_add_ipv6_address(link_data_list_t *ld, char *name, char *ip, char *subnet); -int link_data_list_set_delete_ipv6_address(link_data_list_t *ld, char *name, char *ip); -int link_data_list_add_ipv6_neighbor(link_data_list_t *ld, char *name, char *ip, char *phys_addr); -int link_data_list_set_delete_ipv6_neighbor(link_data_list_t *ld, char *name, char *ip); -int link_data_list_set_ipv6_cga(link_data_list_t *ld, char *name, char *cga); -int link_data_list_set_ipv6_cta(link_data_list_t *ld, char *name, char *cta); -int link_data_list_set_ipv6_tvl(link_data_list_t *ld, char *name, char *tvl); -int link_data_list_set_ipv6_tpl(link_data_list_t *ld, char *name, char *tpl); - -// if-extensions options -int link_data_list_set_parent(link_data_list_t *ld, char *name, char *parent); - -// vlan-encapsulation options -int link_data_list_set_outer_tag_type(link_data_list_t *ld, char *name, char *outer_tag_type); -int link_data_list_set_outer_vlan_id(link_data_list_t *ld, char *name, uint16_t outer_vlan_id); -int link_data_list_set_second_tag_type(link_data_list_t *ld, char *name, char *second_tag_type); -int link_data_list_set_second_vlan_id(link_data_list_t *ld, char *name, uint16_t second_vlan_id); - -void link_data_list_free(link_data_list_t *ld); - -#endif /* IF_STATE_H_ONCE */ From 20f19805d083d763c5be433ce9fa7017aa3605ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 9 Aug 2022 16:14:24 +0200 Subject: [PATCH 002/247] *: change clang-format --- .clang-format | 181 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 165 insertions(+), 16 deletions(-) diff --git a/.clang-format b/.clang-format index e364fce6..ae441e8c 100644 --- a/.clang-format +++ b/.clang-format @@ -1,17 +1,166 @@ -Language : Cpp -BasedOnStyle: LLVM -BreakBeforeBraces : Linux -IndentWidth: 4 -TabWidth : 4 -UseTab : Always -ColumnLimit : 0 +--- +Language: Cpp +# BasedOnStyle: WebKit +AccessModifierOffset: -4 +AlignAfterOpenBracket: DontAlign +AlignConsecutiveMacros: None +AlignConsecutiveAssignments: None +AlignConsecutiveBitFields: None +AlignConsecutiveDeclarations: None +AlignEscapedNewlines: Right +AlignOperands: DontAlign +AlignTrailingComments: false +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortEnumsOnASingleLine: true +AllowShortBlocksOnASingleLine: Empty +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine +AttributeMacros: + - __capability +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: All +BreakBeforeConceptDeclarations: true +BreakBeforeBraces: WebKit +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeComma +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 0 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: false +DeriveLineEnding: true +DerivePointerAlignment: false +DisableFormat: false +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: false +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +StatementAttributeLikeMacros: + - Q_EMIT +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 1 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentCaseLabels: false +IndentCaseBlocks: false +IndentGotoLabels: true +IndentPPDirectives: None +IndentExternBlock: AfterExternBlock +IndentRequires: false +IndentWidth: 4 +IndentWrappedFunctionNames: false +InsertTrailingCommas: None +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: Inner +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 4 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PenaltyIndentedWhitespace: 0 +PointerAlignment: Left +ReflowComments: true +SortIncludes: true +SortJavaStaticImport: Before +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: true +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceAroundPointerQualifiers: Default +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: true +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +BitFieldColonSpacing: Both +Standard: Latest +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseCRLF: false +UseTab: Never +WhitespaceSensitiveMacros: + - STRINGIZE + - PP_STRINGIZE + - BOOST_PP_STRINGIZE + - NS_SWIFT_NAME + - CF_SWIFT_NAME +... -SortIncludes: false -AllowShortIfStatementsOnASingleLine : false -AllowShortFunctionsOnASingleLine : Empty -AlwaysBreakAfterReturnType : None -AlignAfterOpenBracket : Align -AlignOperands : true -AlignTrailingComments : true -IndentCaseLabels : true -SpaceAfterCStyleCast : true \ No newline at end of file From 567da7c436ce4bd69e036f2b3eaccd753cf10af5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 9 Aug 2022 17:56:59 +0200 Subject: [PATCH 003/247] interfaces-plugin: setup new code structure --- CMakeLists.txt | 30 +- CMakeModules/FindAUGYANG.cmake | 32 + CMakeModules/FindLIBSYSTEMD.cmake | 24 + .../FindLIBYANG.cmake | 0 {cmake/Modules => CMakeModules}/FindNL.cmake | 0 CMakeModules/FindSRPC.cmake | 25 + CMakeModules/FindSYSREPO.cmake | 24 + cmake/Modules/FindSYSREPO.cmake | 26 - src/interfaces/CMakeLists.txt | 89 ++ src/interfaces/src/main.c | 58 + src/interfaces/src/plugin.c | 242 ++++ src/interfaces/src/plugin.h | 9 + .../src/plugin/api/interfaces/change.c | 26 + .../src/plugin/api/interfaces/change.h | 9 + .../src/plugin/api/interfaces/check.c | 7 + .../src/plugin/api/interfaces/check.h | 9 + .../plugin/api/interfaces/interface/change.c | 114 ++ .../plugin/api/interfaces/interface/change.h | 13 + .../src/plugin/api/interfaces/load.c | 7 + .../src/plugin/api/interfaces/load.h | 9 + .../src/plugin/api/interfaces/store.c | 7 + .../src/plugin/api/interfaces/store.h | 9 + src/interfaces/src/plugin/common.h | 68 ++ src/interfaces/src/plugin/context.h | 13 + src/interfaces/src/plugin/ly_tree.c | 291 +++++ src/interfaces/src/plugin/ly_tree.h | 64 + src/interfaces/src/plugin/startup/load.c | 74 ++ src/interfaces/src/plugin/startup/load.h | 8 + src/interfaces/src/plugin/startup/store.c | 55 + src/interfaces/src/plugin/startup/store.h | 8 + .../src/plugin/subscription/change.c | 55 + .../src/plugin/subscription/change.h | 8 + .../src/plugin/subscription/operational.c | 1065 +++++++++++++++++ .../src/plugin/subscription/operational.h | 55 + src/interfaces/src/plugin/subscription/rpc.c | 7 + src/interfaces/src/plugin/subscription/rpc.h | 6 + src/interfaces/src/plugin/types.h | 35 + 37 files changed, 2534 insertions(+), 47 deletions(-) create mode 100644 CMakeModules/FindAUGYANG.cmake create mode 100644 CMakeModules/FindLIBSYSTEMD.cmake rename {cmake/Modules => CMakeModules}/FindLIBYANG.cmake (100%) rename {cmake/Modules => CMakeModules}/FindNL.cmake (100%) create mode 100644 CMakeModules/FindSRPC.cmake create mode 100644 CMakeModules/FindSYSREPO.cmake delete mode 100644 cmake/Modules/FindSYSREPO.cmake create mode 100644 src/interfaces/CMakeLists.txt create mode 100644 src/interfaces/src/main.c create mode 100644 src/interfaces/src/plugin.c create mode 100644 src/interfaces/src/plugin.h create mode 100644 src/interfaces/src/plugin/api/interfaces/change.c create mode 100644 src/interfaces/src/plugin/api/interfaces/change.h create mode 100644 src/interfaces/src/plugin/api/interfaces/check.c create mode 100644 src/interfaces/src/plugin/api/interfaces/check.h create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/change.c create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/change.h create mode 100644 src/interfaces/src/plugin/api/interfaces/load.c create mode 100644 src/interfaces/src/plugin/api/interfaces/load.h create mode 100644 src/interfaces/src/plugin/api/interfaces/store.c create mode 100644 src/interfaces/src/plugin/api/interfaces/store.h create mode 100644 src/interfaces/src/plugin/common.h create mode 100644 src/interfaces/src/plugin/context.h create mode 100644 src/interfaces/src/plugin/ly_tree.c create mode 100644 src/interfaces/src/plugin/ly_tree.h create mode 100644 src/interfaces/src/plugin/startup/load.c create mode 100644 src/interfaces/src/plugin/startup/load.h create mode 100644 src/interfaces/src/plugin/startup/store.c create mode 100644 src/interfaces/src/plugin/startup/store.h create mode 100644 src/interfaces/src/plugin/subscription/change.c create mode 100644 src/interfaces/src/plugin/subscription/change.h create mode 100644 src/interfaces/src/plugin/subscription/operational.c create mode 100644 src/interfaces/src/plugin/subscription/operational.h create mode 100644 src/interfaces/src/plugin/subscription/rpc.c create mode 100644 src/interfaces/src/plugin/subscription/rpc.h create mode 100644 src/interfaces/src/plugin/types.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 6746a97b..a78c2fea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.0) project(sysrepo-interfaces-plugins C) include(CompileOptions.cmake) @@ -11,41 +11,29 @@ include_directories( ${CMAKE_SOURCE_DIR}/deps/uthash/include/ ) -# get sysrepo version -find_package(PkgConfig) -if (PKG_CONFIG_FOUND) - execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} "--modversion" "sysrepo" OUTPUT_VARIABLE SYSREPO_VERSION) - if(SYSREPO_VERSION) - # strip new line from string - string(STRIP ${SYSREPO_VERSION} SYSREPO_VERSION) - if(${SYSREPO_VERSION} VERSION_LESS "1.0.0") - message(FATAL_ERROR "${PROJECT_NAME} requires at least libsysrepo verision 1.0.0") - endif() - endif() -endif() - -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules") +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMakeModules") find_package(SYSREPO REQUIRED) find_package(LIBYANG REQUIRED) +find_package(SRPC REQUIRED) include_directories( ${SYSREPO_INCLUDE_DIRS} ${LIBYANG_INCLUDE_DIRS} ) -option(INTERFACES_PLUGIN "Enable interfaces plugin" ON) -option(ROUTING_PLUGIN "Enable interfaces plugin" ON) +option(INTERFACES_PLUGIN "Enable interfaces plugin" OFF) +option(ROUTING_PLUGIN "Enable interfaces plugin" OFF) if(INTERFACES_PLUGIN) - add_subdirectory(src/interfaces) + add_subdirectory(src/interfaces) endif() if(ROUTING_PLUGIN) - add_subdirectory(src/routing) + add_subdirectory(src/routing) endif() if(ENABLE_BUILD_TESTS) - find_package(CMOCKA REQUIRED) - include (CTest) + find_package(CMOCKA REQUIRED) + include(CTest) include(tests/Tests.cmake) endif() diff --git a/CMakeModules/FindAUGYANG.cmake b/CMakeModules/FindAUGYANG.cmake new file mode 100644 index 00000000..d8bf3530 --- /dev/null +++ b/CMakeModules/FindAUGYANG.cmake @@ -0,0 +1,32 @@ +if (AUGYANG_LIBRARIES) + # in cache already + set(AUGYANG_FOUND TRUE) +else(AUGYANG_LIBRARIES) + find_library( + AUGYANG_LIBRARY + NAMES + srds_augeas.so + PATHS + /usr/lib + /usr/lib64 + /usr/local/lib + /usr/local/lib64 + /opt/local/lib + /sw/lib + ${CMAKE_LIBRARY_PATH} + ${CMAKE_INSTALL_PREFIX}/lib + + # srds_augeas.so + ${CMAKE_INSTALL_PREFIX}/lib/sysrepo/plugins + ) + + if (AUGYANG_LIBRARY) + set(AUGYANG_FOUND TRUE) + else (AUGYANG_LIBRARY) + set(AUGYANG_FOUND FALSE) + endif (AUGYANG_LIBRARY) + + set(AUGYANG_LIBRARIES ${AUGYANG_LIBRARY}) + + mark_as_advanced(AUGYANG_LIBRARIES) +endif(AUGYANG_LIBRARIES) \ No newline at end of file diff --git a/CMakeModules/FindLIBSYSTEMD.cmake b/CMakeModules/FindLIBSYSTEMD.cmake new file mode 100644 index 00000000..31224416 --- /dev/null +++ b/CMakeModules/FindLIBSYSTEMD.cmake @@ -0,0 +1,24 @@ +# - Try to find SYSTEMD +# Once done, this will define +# +# SYSTEMD_FOUND - system has SYSTEMD +# SYSTEMD_INCLUDE_DIRS - the SYSTEMD include directories +# SYSTEMD_LIBRARIES - the SYSTEMD library +find_package(PkgConfig) + +pkg_check_modules(SYSTEMD_PKGCONF libsystemd) + +find_path(SYSTEMD_INCLUDE_DIRS + NAMES systemd/sd-bus.h + PATHS ${SYSTEMD_PKGCONF_INCLUDE_DIRS} +) + +find_library(SYSTEMD_LIBRARIES + NAMES systemd + PATHS ${SYSTEMD_PKGCONF_LIBRARY_DIRS} +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Systemd DEFAULT_MSG SYSTEMD_INCLUDE_DIRS SYSTEMD_LIBRARIES) + +mark_as_advanced(SYSTEMD_INCLUDE_DIRS SYSTEMD_LIBRARIES) \ No newline at end of file diff --git a/cmake/Modules/FindLIBYANG.cmake b/CMakeModules/FindLIBYANG.cmake similarity index 100% rename from cmake/Modules/FindLIBYANG.cmake rename to CMakeModules/FindLIBYANG.cmake diff --git a/cmake/Modules/FindNL.cmake b/CMakeModules/FindNL.cmake similarity index 100% rename from cmake/Modules/FindNL.cmake rename to CMakeModules/FindNL.cmake diff --git a/CMakeModules/FindSRPC.cmake b/CMakeModules/FindSRPC.cmake new file mode 100644 index 00000000..128189a0 --- /dev/null +++ b/CMakeModules/FindSRPC.cmake @@ -0,0 +1,25 @@ +if (SRPC_LIBRARIES AND SRPC_INCLUDE_DIRS) + set(SRPC_FOUND TRUE) +else () + + find_path( + SRPC_INCLUDE_DIR + NAMES srpc.h + PATHS /usr/include /usr/local/include /opt/local/include /sw/include ${CMAKE_INCLUDE_PATH} ${CMAKE_INSTALL_PREFIX}/include + ) + + find_library( + SRPC_LIBRARY + NAMES srpc + PATHS /usr/lib /usr/lib64 /usr/local/lib /usr/local/lib64 /opt/local/lib /sw/lib ${CMAKE_LIBRARY_PATH} ${CMAKE_INSTALL_PREFIX}/lib + ) + + if (SRPC_INCLUDE_DIR AND SRPC_LIBRARY) + set(SRPC_FOUND TRUE) + else (SRPC_INCLUDE_DIR AND SRPC_LIBRARY) + set(SRPC_FOUND FALSE) + endif (SRPC_INCLUDE_DIR AND SRPC_LIBRARY) + + set(SRPC_INCLUDE_DIRS ${SRPC_INCLUDE_DIR}) + set(SRPC_LIBRARIES ${SRPC_LIBRARY}) +endif () \ No newline at end of file diff --git a/CMakeModules/FindSYSREPO.cmake b/CMakeModules/FindSYSREPO.cmake new file mode 100644 index 00000000..532bf9d5 --- /dev/null +++ b/CMakeModules/FindSYSREPO.cmake @@ -0,0 +1,24 @@ +if(SYSREPO_LIBRARIES AND SYSREPO_INCLUDE_DIRS) + set(SYSREPO_FOUND TRUE) +else() + find_path( + SYSREPO_INCLUDE_DIR + NAMES sysrepo.h + PATHS /usr/include /usr/local/include /opt/local/include /sw/include ${CMAKE_INCLUDE_PATH} ${CMAKE_INSTALL_PREFIX}/include + ) + + find_library( + SYSREPO_LIBRARY + NAMES sysrepo + PATHS /usr/lib /usr/lib64 /usr/local/lib /usr/local/lib64 /opt/local/lib /sw/lib ${CMAKE_LIBRARY_PATH} ${CMAKE_INSTALL_PREFIX}/lib + ) + + if(SYSREPO_INCLUDE_DIR AND SYSREPO_LIBRARY) + set(SYSREPO_FOUND TRUE) + else(SYSREPO_INCLUDE_DIR AND SYSREPO_LIBRARY) + set(SYSREPO_FOUND FALSE) + endif(SYSREPO_INCLUDE_DIR AND SYSREPO_LIBRARY) + + set(SYSREPO_INCLUDE_DIRS ${SYSREPO_INCLUDE_DIR}) + set(SYSREPO_LIBRARIES ${SYSREPO_LIBRARY}) +endif() \ No newline at end of file diff --git a/cmake/Modules/FindSYSREPO.cmake b/cmake/Modules/FindSYSREPO.cmake deleted file mode 100644 index 3d6ece20..00000000 --- a/cmake/Modules/FindSYSREPO.cmake +++ /dev/null @@ -1,26 +0,0 @@ -# SYSREPO_FOUND - System has SYSREPO -# SYSREPO_INCLUDE_DIRS - The SYSREPO include directories -# SYSREPO_LIBRARIES - The libraries needed to use SYSREPO -# SYSREPO_DEFINITIONS - Compiler switches required for using SYSREPO - -find_package(PkgConfig) -pkg_check_modules(PC_SYSREPO QUIET sysrepo) -set(SYSREPO_DEFINITIONS ${PC_SYSREPO_CFLAGS_OTHER}) - -find_path(SYSREPO_INCLUDE_DIR sysrepo.h - HINTS ${PC_SYSREPO_INCLUDEDIR} ${PC_SYSREPO_INCLUDE_DIRS} - PATH_SUFFIXES sysrepo ) - -find_library(SYSREPO_LIBRARY NAMES sysrepo - HINTS ${PC_SYSREPO_LIBDIR} ${PC_SYSREPO_LIBRARY_DIRS} ) - -set(SYSREPO_LIBRARIES ${SYSREPO_LIBRARY} ) -set(SYSREPO_INCLUDE_DIRS ${SYSREPO_INCLUDE_DIR} ) - -include(FindPackageHandleStandardArgs) -# handle the QUIETLY and REQUIRED arguments and set SYSREPO_FOUND to TRUE -# if all listed variables are TRUE -find_package_handle_standard_args(sysrepo DEFAULT_MSG - SYSREPO_LIBRARY SYSREPO_INCLUDE_DIR) - -mark_as_advanced(SYSREPO_INCLUDE_DIR SYSREPO_LIBRARY ) diff --git a/src/interfaces/CMakeLists.txt b/src/interfaces/CMakeLists.txt new file mode 100644 index 00000000..a9b7e45f --- /dev/null +++ b/src/interfaces/CMakeLists.txt @@ -0,0 +1,89 @@ +cmake_minimum_required(VERSION 3.0) +project(sysrepo-plugin-interfaces C) + +set(PLUGIN_LIBRARY_NAME srplg-interfaces) + +include_directories( + ${CMAKE_SOURCE_DIR}/src/interfaces/src + ${CMAKE_SOURCE_DIR}/deps/uthash +) + +set(PLUGIN 0 CACHE BOOL "Build a plugin") + +set( + SOURCES + + src/plugin/startup/load.c + src/plugin/startup/store.c + src/plugin/subscription/change.c + src/plugin/subscription/operational.c + src/plugin/subscription/rpc.c + src/plugin/ly_tree.c + src/plugin/api/interfaces/check.c + src/plugin/api/interfaces/load.c + src/plugin/api/interfaces/store.c + src/plugin/api/interfaces/change.c + src/plugin/api/interfaces/interface/change.c + src/plugin.c +) + +# plugin library +add_library( + ${PLUGIN_LIBRARY_NAME} + STATIC + ${SOURCES} +) + +# link plugin library +target_link_libraries( + ${PLUGIN_LIBRARY_NAME} + + ${SYSREPO_LIBRARIES} + ${LIBYANG_LIBRARIES} + ${SRPC_LIBRARIES} +) + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMakeModules") +find_package(AUGYANG) + +if(PLUGIN) + # ignore plugin library and compile PROJECT_NAME as a module + add_library( + ${PROJECT_NAME} + MODULE ${SOURCES} + ) + target_link_libraries( + ${PROJECT_NAME} + ${SYSREPO_LIBRARIES} + ${LIBYANG_LIBRARIES} + ${SRPC_LIBRARIES} + ) +else() + add_executable( + ${PROJECT_NAME} + src/main.c + ) + target_link_libraries( + ${PROJECT_NAME} + + # link plugin library with executable + ${PLUGIN_LIBRARY_NAME} + + ${SYSREPO_LIBRARIES} + ${LIBYANG_LIBRARIES} + ${SRPC_LIBRARIES} + ) +endif() + +include_directories( + ${SYSREPO_INCLUDE_DIRS} + ${LIBYANG_INCLUDE_DIRS} + ${SRPC_INCLUDE_DIRS} +) + +# augyang support +if(AUGYANG_FOUND) + add_compile_definitions(AUGYANG) +else(AUGYANG_FOUND) + message(WARNING "AUGYANG not found - augeas support will be disabled") +endif() \ No newline at end of file diff --git a/src/interfaces/src/main.c b/src/interfaces/src/main.c new file mode 100644 index 00000000..a8ea03cf --- /dev/null +++ b/src/interfaces/src/main.c @@ -0,0 +1,58 @@ +#include +#include +#include + +#include "plugin.h" +#include "plugin/common.h" + +volatile int exit_application = 0; + +static void sigint_handler(__attribute__((unused)) int signum); + +int main(void) +{ + int error = SR_ERR_OK; + sr_conn_ctx_t* connection = NULL; + sr_session_ctx_t* session = NULL; + void* private_data = NULL; + + sr_log_stderr(SR_LL_INF); + + /* connect to sysrepo */ + error = sr_connect(SR_CONN_DEFAULT, &connection); + if (error) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_connect error (%d): %s", error, sr_strerror(error)); + goto out; + } + + error = sr_session_start(connection, SR_DS_RUNNING, &session); + if (error) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_session_start error (%d): %s", error, sr_strerror(error)); + goto out; + } + + error = sr_plugin_init_cb(session, &private_data); + if (error) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_plugin_init_cb error"); + goto out; + } + + /* loop until ctrl-c is pressed / SIGINT is received */ + signal(SIGINT, sigint_handler); + signal(SIGPIPE, SIG_IGN); + while (!exit_application) { + sleep(1); + } + +out: + sr_plugin_cleanup_cb(session, private_data); + sr_disconnect(connection); + + return error ? -1 : 0; +} + +static void sigint_handler(__attribute__((unused)) int signum) +{ + SRPLG_LOG_INF(PLUGIN_NAME, "Sigint called, exiting..."); + exit_application = 1; +} \ No newline at end of file diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c new file mode 100644 index 00000000..2964345e --- /dev/null +++ b/src/interfaces/src/plugin.c @@ -0,0 +1,242 @@ +#include "plugin.h" +#include "plugin/common.h" +#include "plugin/context.h" + +// startup +#include "plugin/startup/load.h" +#include "plugin/startup/store.h" + +// subscription +#include "plugin/subscription/change.h" +#include "plugin/subscription/operational.h" +#include "plugin/subscription/rpc.h" + +#include +#include +#include + +int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) +{ + int error = 0; + + bool empty_startup = false; + + // sysrepo + sr_session_ctx_t* startup_session = NULL; + sr_conn_ctx_t* connection = NULL; + sr_subscription_ctx_t* subscription = NULL; + + // plugin + interfaces_ctx_t* ctx = NULL; + + // init context + ctx = malloc(sizeof(*ctx)); + *ctx = (interfaces_ctx_t) { 0 }; + + *private_data = ctx; + + // module changes + srpc_module_change_t module_changes[] = { + { + INTERFACES_INTERFACES_INTERFACE_YANG_PATH, + interfaces_subscription_change_interfaces_interface, + }, + }; + + // operational getters + srpc_operational_t oper[] = { + { + INTERFACES_INTERFACES_INTERFACE_ADMIN_STATUS_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_admin_status, + }, + { + INTERFACES_INTERFACES_INTERFACE_OPER_STATUS_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_oper_status, + }, + { + INTERFACES_INTERFACES_INTERFACE_LAST_CHANGE_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_last_change, + }, + { + INTERFACES_INTERFACES_INTERFACE_IF_INDEX_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_if_index, + }, + { + INTERFACES_INTERFACES_INTERFACE_PHYS_ADDRESS_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_phys_address, + }, + { + INTERFACES_INTERFACES_INTERFACE_HIGHER_LAYER_IF_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_higher_layer_if, + }, + { + INTERFACES_INTERFACES_INTERFACE_LOWER_LAYER_IF_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_lower_layer_if, + }, + { + INTERFACES_INTERFACES_INTERFACE_SPEED_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_speed, + }, + { + INTERFACES_INTERFACES_INTERFACE_STATISTICS_DISCONTINUITY_TIME_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_statistics_discontinuity_time, + }, + { + INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_OCTETS_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_statistics_in_octets, + }, + { + INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_UNICAST_PKTS_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_statistics_in_unicast_pkts, + }, + { + INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_BROADCAST_PKTS_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_statistics_in_broadcast_pkts, + }, + { + INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_MULTICAST_PKTS_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_statistics_in_multicast_pkts, + }, + { + INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_DISCARDS_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_statistics_in_discards, + }, + { + INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_ERRORS_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_statistics_in_errors, + }, + { + INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_UNKNOWN_PROTOS_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_statistics_in_unknown_protos, + }, + { + INTERFACES_INTERFACES_INTERFACE_STATISTICS_OUT_OCTETS_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_statistics_out_octets, + }, + { + INTERFACES_INTERFACES_INTERFACE_STATISTICS_OUT_UNICAST_PKTS_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_statistics_out_unicast_pkts, + }, + { + INTERFACES_INTERFACES_INTERFACE_STATISTICS_OUT_BROADCAST_PKTS_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_statistics_out_broadcast_pkts, + }, + { + INTERFACES_INTERFACES_INTERFACE_STATISTICS_OUT_MULTICAST_PKTS_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_statistics_out_multicast_pkts, + }, + { + INTERFACES_INTERFACES_INTERFACE_STATISTICS_OUT_DISCARDS_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_statistics_out_discards, + }, + { + INTERFACES_INTERFACES_INTERFACE_STATISTICS_OUT_ERRORS_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_statistics_out_errors, + }, + { + INTERFACES_INTERFACES_INTERFACE_YANG_PATH, + interfaces_subscription_operational_interfaces_interface, + }, + }; + + connection = sr_session_get_connection(running_session); + error = sr_session_start(connection, SR_DS_STARTUP, &startup_session); + if (error) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_session_start() error (%d): %s", error, sr_strerror(error)); + goto error_out; + } + + ctx->startup_session = startup_session; + + error = srpc_check_empty_datastore(startup_session, INTERFACES_INTERFACES_INTERFACE_YANG_PATH, &empty_startup); + if (error) { + SRPLG_LOG_ERR(PLUGIN_NAME, "Failed checking datastore contents: %d", error); + goto error_out; + } + + if (empty_startup) { + SRPLG_LOG_INF(PLUGIN_NAME, "Startup datastore is empty"); + SRPLG_LOG_INF(PLUGIN_NAME, "Loading initial system data"); + error = interfaces_startup_load(ctx, startup_session); + if (error) { + SRPLG_LOG_ERR(PLUGIN_NAME, "Error loading initial data into the startup datastore... exiting"); + goto error_out; + } + + // copy contents of the startup session to the current running session + error = sr_copy_config(running_session, BASE_YANG_MODEL, SR_DS_STARTUP, 0); + if (error) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_copy_config() error (%d): %s", error, sr_strerror(error)); + goto error_out; + } + } else { + // make sure the data from startup DS is stored in the interfaces + SRPLG_LOG_INF(PLUGIN_NAME, "Startup datastore contains data"); + SRPLG_LOG_INF(PLUGIN_NAME, "Storing startup datastore data in the system"); + + error = interfaces_startup_store(ctx, startup_session); + if (error) { + SRPLG_LOG_ERR(PLUGIN_NAME, "Error applying initial data from startup datastore to the system... exiting"); + goto error_out; + } + + // copy contents of the startup session to the current running session + error = sr_copy_config(running_session, BASE_YANG_MODEL, SR_DS_STARTUP, 0); + if (error) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_copy_config() error (%d): %s", error, sr_strerror(error)); + goto error_out; + } + } + + // subscribe every module change + for (size_t i = 0; i < ARRAY_SIZE(module_changes); i++) { + const srpc_module_change_t* change = &module_changes[i]; + + // in case of work on a specific callback set it to NULL + if (change->cb) { + error = sr_module_change_subscribe(running_session, BASE_YANG_MODEL, change->path, change->cb, *private_data, 0, SR_SUBSCR_DEFAULT, &subscription); + if (error) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_module_change_subscribe() error for \"%s\" (%d): %s", change->path, error, sr_strerror(error)); + goto error_out; + } + } + } + + // subscribe every operational getter + for (size_t i = 0; i < ARRAY_SIZE(oper); i++) { + const srpc_operational_t* op = &oper[i]; + + // in case of work on a specific callback set it to NULL + if (op->cb) { + error = sr_oper_get_subscribe(running_session, BASE_YANG_MODEL, op->path, op->cb, NULL, SR_SUBSCR_DEFAULT, &subscription); + if (error) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_oper_get_subscribe() error (%d): %s", error, sr_strerror(error)); + goto error_out; + } + } + } + + goto out; + +error_out: + error = -1; + SRPLG_LOG_ERR(PLUGIN_NAME, "Error occured while initializing the plugin (%d)", error); + +out: + return error ? SR_ERR_CALLBACK_FAILED : SR_ERR_OK; +} + +void sr_plugin_cleanup_cb(sr_session_ctx_t* running_session, void* private_data) +{ + int error = 0; + + interfaces_ctx_t* ctx = (interfaces_ctx_t*)private_data; + + // save current running configuration into startup for next time when the plugin starts + error = sr_copy_config(ctx->startup_session, BASE_YANG_MODEL, SR_DS_RUNNING, 0); + if (error) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_copy_config() error (%d): %s", error, sr_strerror(error)); + } + + free(ctx); +} \ No newline at end of file diff --git a/src/interfaces/src/plugin.h b/src/interfaces/src/plugin.h new file mode 100644 index 00000000..72b7bc91 --- /dev/null +++ b/src/interfaces/src/plugin.h @@ -0,0 +1,9 @@ +#ifndef INTERFACES_PLUGIN_H +#define INTERFACES_PLUGIN_H + +#include + +int sr_plugin_init_cb(sr_session_ctx_t* session, void** private_data); +void sr_plugin_cleanup_cb(sr_session_ctx_t* session, void* private_data); + +#endif // INTERFACES_PLUGIN_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/api/interfaces/change.c b/src/interfaces/src/plugin/api/interfaces/change.c new file mode 100644 index 00000000..d17cc186 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/change.c @@ -0,0 +1,26 @@ +#include "change.h" +#include "plugin/common.h" + +#include + +int interfaces_change_interface(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} diff --git a/src/interfaces/src/plugin/api/interfaces/change.h b/src/interfaces/src/plugin/api/interfaces/change.h new file mode 100644 index 00000000..fb6fe90a --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/change.h @@ -0,0 +1,9 @@ +#ifndef INTERFACES_PLUGIN_API_INTERFACES_CHANGE_H +#define INTERFACES_PLUGIN_API_INTERFACES_CHANGE_H + +#include +#include + +int interfaces_change_interface(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); + +#endif // INTERFACES_PLUGIN_API_INTERFACES_CHANGE_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/api/interfaces/check.c b/src/interfaces/src/plugin/api/interfaces/check.c new file mode 100644 index 00000000..50cf1d88 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/check.c @@ -0,0 +1,7 @@ +#include "check.h" + +int interfaces_check_interface(interfaces_ctx_t* ctx, const UT_array* interface) +{ + int error = 0; + return error; +} diff --git a/src/interfaces/src/plugin/api/interfaces/check.h b/src/interfaces/src/plugin/api/interfaces/check.h new file mode 100644 index 00000000..883491bf --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/check.h @@ -0,0 +1,9 @@ +#ifndef INTERFACES_PLUGIN_API_INTERFACES_CHECK_H +#define INTERFACES_PLUGIN_API_INTERFACES_CHECK_H + +#include "plugin/context.h" +#include + +int interfaces_check_interface(interfaces_ctx_t* ctx, const UT_array* interface); + +#endif // INTERFACES_PLUGIN_API_INTERFACES_CHECK_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/api/interfaces/interface/change.c b/src/interfaces/src/plugin/api/interfaces/interface/change.c new file mode 100644 index 00000000..50a6aa29 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/change.c @@ -0,0 +1,114 @@ +#include "change.h" +#include "plugin/common.h" + +#include + +int interfaces_interface_change_link_up_down_trap_enable(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +int interfaces_interface_change_enabled(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +int interfaces_interface_change_type(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +int interfaces_interface_change_description(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +int interfaces_interface_change_name(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} diff --git a/src/interfaces/src/plugin/api/interfaces/interface/change.h b/src/interfaces/src/plugin/api/interfaces/interface/change.h new file mode 100644 index 00000000..f9aa1e90 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/change.h @@ -0,0 +1,13 @@ +#ifndef INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_CHANGE_H +#define INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_CHANGE_H + +#include +#include + +int interfaces_interface_change_link_up_down_trap_enable(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +int interfaces_interface_change_enabled(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +int interfaces_interface_change_type(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +int interfaces_interface_change_description(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +int interfaces_interface_change_name(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); + +#endif // INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_CHANGE_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c new file mode 100644 index 00000000..dbbb83d0 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -0,0 +1,7 @@ +#include "load.h" + +int interfaces_load_interface(interfaces_ctx_t* ctx, UT_array** interface) +{ + int error = 0; + return error; +} diff --git a/src/interfaces/src/plugin/api/interfaces/load.h b/src/interfaces/src/plugin/api/interfaces/load.h new file mode 100644 index 00000000..f27e12f0 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/load.h @@ -0,0 +1,9 @@ +#ifndef INTERFACES_PLUGIN_API_INTERFACES_LOAD_H +#define INTERFACES_PLUGIN_API_INTERFACES_LOAD_H + +#include "plugin/context.h" +#include + +int interfaces_load_interface(interfaces_ctx_t* ctx, UT_array** interface); + +#endif // INTERFACES_PLUGIN_API_INTERFACES_LOAD_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/api/interfaces/store.c b/src/interfaces/src/plugin/api/interfaces/store.c new file mode 100644 index 00000000..f848c5f8 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/store.c @@ -0,0 +1,7 @@ +#include "store.h" + +int interfaces_store_interface(interfaces_ctx_t* ctx, const UT_array* interface) +{ + int error = 0; + return error; +} diff --git a/src/interfaces/src/plugin/api/interfaces/store.h b/src/interfaces/src/plugin/api/interfaces/store.h new file mode 100644 index 00000000..b9fb91e3 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/store.h @@ -0,0 +1,9 @@ +#ifndef INTERFACES_PLUGIN_API_INTERFACES_STORE_H +#define INTERFACES_PLUGIN_API_INTERFACES_STORE_H + +#include "plugin/context.h" +#include + +int interfaces_store_interface(interfaces_ctx_t* ctx, const UT_array* interface); + +#endif // INTERFACES_PLUGIN_API_INTERFACES_STORE_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/common.h b/src/interfaces/src/plugin/common.h new file mode 100644 index 00000000..1c5e145e --- /dev/null +++ b/src/interfaces/src/plugin/common.h @@ -0,0 +1,68 @@ +#ifndef INTERFACES_PLUGIN_COMMON_H +#define INTERFACES_PLUGIN_COMMON_H + +#define PLUGIN_NAME "interfaces-plugin" + +#define BASE_YANG_MODEL "ietf-interfaces" + +#define INTERFACES_INTERFACES_STATE_INTERFACE_NAME_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_YANG_PATH "/name" +#define INTERFACES_INTERFACES_STATE_INTERFACE_TYPE_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_YANG_PATH "/type" +#define INTERFACES_INTERFACES_STATE_INTERFACE_ADMIN_STATUS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_YANG_PATH "/admin-status" +#define INTERFACES_INTERFACES_STATE_INTERFACE_OPER_STATUS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_YANG_PATH "/oper-status" +#define INTERFACES_INTERFACES_STATE_INTERFACE_LAST_CHANGE_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_YANG_PATH "/last-change" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IF_INDEX_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_YANG_PATH "/if-index" +#define INTERFACES_INTERFACES_STATE_INTERFACE_PHYS_ADDRESS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_YANG_PATH "/phys-address" +#define INTERFACES_INTERFACES_STATE_INTERFACE_HIGHER_LAYER_IF_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_YANG_PATH "/higher-layer-if" +#define INTERFACES_INTERFACES_STATE_INTERFACE_LOWER_LAYER_IF_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_YANG_PATH "/lower-layer-if" +#define INTERFACES_INTERFACES_STATE_INTERFACE_SPEED_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_YANG_PATH "/speed" +#define INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_DISCONTINUITY_TIME_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_YANG_PATH "/discontinuity-time" +#define INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_IN_OCTETS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_YANG_PATH "/in-octets" +#define INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_IN_UNICAST_PKTS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_YANG_PATH "/in-unicast-pkts" +#define INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_IN_BROADCAST_PKTS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_YANG_PATH "/in-broadcast-pkts" +#define INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_IN_MULTICAST_PKTS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_YANG_PATH "/in-multicast-pkts" +#define INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_IN_DISCARDS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_YANG_PATH "/in-discards" +#define INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_IN_ERRORS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_YANG_PATH "/in-errors" +#define INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_IN_UNKNOWN_PROTOS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_YANG_PATH "/in-unknown-protos" +#define INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_OUT_OCTETS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_YANG_PATH "/out-octets" +#define INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_OUT_UNICAST_PKTS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_YANG_PATH "/out-unicast-pkts" +#define INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_OUT_BROADCAST_PKTS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_YANG_PATH "/out-broadcast-pkts" +#define INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_OUT_MULTICAST_PKTS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_YANG_PATH "/out-multicast-pkts" +#define INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_OUT_DISCARDS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_YANG_PATH "/out-discards" +#define INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_OUT_ERRORS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_YANG_PATH "/out-errors" +#define INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_YANG_PATH "/statistics" +#define INTERFACES_INTERFACES_STATE_INTERFACE_YANG_PATH INTERFACES_INTERFACES_STATE_YANG_PATH "/interface" +#define INTERFACES_INTERFACES_STATE_YANG_PATH "/ietf-interfaces:interfaces-state" +#define INTERFACES_INTERFACES_INTERFACE_NAME_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/name" +#define INTERFACES_INTERFACES_INTERFACE_DESCRIPTION_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/description" +#define INTERFACES_INTERFACES_INTERFACE_TYPE_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/type" +#define INTERFACES_INTERFACES_INTERFACE_ENABLED_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/enabled" +#define INTERFACES_INTERFACES_INTERFACE_LINK_UP_DOWN_TRAP_ENABLE_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/link-up-down-trap-enable" +#define INTERFACES_INTERFACES_INTERFACE_ADMIN_STATUS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/admin-status" +#define INTERFACES_INTERFACES_INTERFACE_OPER_STATUS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/oper-status" +#define INTERFACES_INTERFACES_INTERFACE_LAST_CHANGE_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/last-change" +#define INTERFACES_INTERFACES_INTERFACE_IF_INDEX_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/if-index" +#define INTERFACES_INTERFACES_INTERFACE_PHYS_ADDRESS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/phys-address" +#define INTERFACES_INTERFACES_INTERFACE_HIGHER_LAYER_IF_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/higher-layer-if" +#define INTERFACES_INTERFACES_INTERFACE_LOWER_LAYER_IF_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/lower-layer-if" +#define INTERFACES_INTERFACES_INTERFACE_SPEED_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/speed" +#define INTERFACES_INTERFACES_INTERFACE_STATISTICS_DISCONTINUITY_TIME_YANG_PATH INTERFACES_INTERFACES_INTERFACE_STATISTICS_YANG_PATH "/discontinuity-time" +#define INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_OCTETS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_STATISTICS_YANG_PATH "/in-octets" +#define INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_UNICAST_PKTS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_STATISTICS_YANG_PATH "/in-unicast-pkts" +#define INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_BROADCAST_PKTS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_STATISTICS_YANG_PATH "/in-broadcast-pkts" +#define INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_MULTICAST_PKTS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_STATISTICS_YANG_PATH "/in-multicast-pkts" +#define INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_DISCARDS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_STATISTICS_YANG_PATH "/in-discards" +#define INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_ERRORS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_STATISTICS_YANG_PATH "/in-errors" +#define INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_UNKNOWN_PROTOS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_STATISTICS_YANG_PATH "/in-unknown-protos" +#define INTERFACES_INTERFACES_INTERFACE_STATISTICS_OUT_OCTETS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_STATISTICS_YANG_PATH "/out-octets" +#define INTERFACES_INTERFACES_INTERFACE_STATISTICS_OUT_UNICAST_PKTS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_STATISTICS_YANG_PATH "/out-unicast-pkts" +#define INTERFACES_INTERFACES_INTERFACE_STATISTICS_OUT_BROADCAST_PKTS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_STATISTICS_YANG_PATH "/out-broadcast-pkts" +#define INTERFACES_INTERFACES_INTERFACE_STATISTICS_OUT_MULTICAST_PKTS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_STATISTICS_YANG_PATH "/out-multicast-pkts" +#define INTERFACES_INTERFACES_INTERFACE_STATISTICS_OUT_DISCARDS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_STATISTICS_YANG_PATH "/out-discards" +#define INTERFACES_INTERFACES_INTERFACE_STATISTICS_OUT_ERRORS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_STATISTICS_YANG_PATH "/out-errors" +#define INTERFACES_INTERFACES_INTERFACE_STATISTICS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/statistics" +#define INTERFACES_INTERFACES_INTERFACE_YANG_PATH INTERFACES_INTERFACES_YANG_PATH "/interface" +#define INTERFACES_INTERFACES_YANG_PATH "/ietf-interfaces:interfaces" + +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) + +#endif // INTERFACES_PLUGIN_COMMON_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/context.h b/src/interfaces/src/plugin/context.h new file mode 100644 index 00000000..d705d8ef --- /dev/null +++ b/src/interfaces/src/plugin/context.h @@ -0,0 +1,13 @@ +#ifndef INTERFACES_PLUGIN_CONTEXT_H +#define INTERFACES_PLUGIN_CONTEXT_H + +#include "plugin/types.h" +#include + +typedef struct interfaces_ctx_s interfaces_ctx_t; + +struct interfaces_ctx_s { + sr_session_ctx_t* startup_session; +}; + +#endif // INTERFACES_PLUGIN_CONTEXT_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/ly_tree.c b/src/interfaces/src/plugin/ly_tree.c new file mode 100644 index 00000000..d25e85ff --- /dev/null +++ b/src/interfaces/src/plugin/ly_tree.c @@ -0,0 +1,291 @@ +#include "ly_tree.h" +#include "common.h" + +#include + +int interfaces_ly_tree_create_interfaces_state(const struct ly_ctx* ly_ctx, struct lyd_node** interfaces_state_node) +{ + return srpc_ly_tree_create_container(ly_ctx, NULL, interfaces_state_node, "interfaces-state"); +} + +int interfaces_ly_tree_create_interfaces_state_interface(const struct ly_ctx* ly_ctx, struct lyd_node* interfaces_state_node, struct lyd_node** interface_node, const char* name) +{ + // TODO: fix this for multiple keys with SRPC library + return srpc_ly_tree_create_list(ly_ctx, interfaces_state_node, interface_node, "interface", "name", name); +} + +int interfaces_ly_tree_create_interfaces_state_interface_statistics(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, struct lyd_node** statistics_node) +{ + return srpc_ly_tree_create_container(ly_ctx, interface_node, statistics_node, "statistics"); +} + +int interfaces_ly_tree_create_interfaces_state_interface_statistics_out_errors(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_errors) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "out-errors", out_errors); +} + +int interfaces_ly_tree_create_interfaces_state_interface_statistics_out_discards(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_discards) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "out-discards", out_discards); +} + +int interfaces_ly_tree_create_interfaces_state_interface_statistics_out_multicast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_multicast_pkts) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "out-multicast-pkts", out_multicast_pkts); +} + +int interfaces_ly_tree_create_interfaces_state_interface_statistics_out_broadcast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_broadcast_pkts) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "out-broadcast-pkts", out_broadcast_pkts); +} + +int interfaces_ly_tree_create_interfaces_state_interface_statistics_out_unicast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_unicast_pkts) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "out-unicast-pkts", out_unicast_pkts); +} + +int interfaces_ly_tree_create_interfaces_state_interface_statistics_out_octets(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_octets) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "out-octets", out_octets); +} + +int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_unknown_protos(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_unknown_protos) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "in-unknown-protos", in_unknown_protos); +} + +int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_errors(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_errors) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "in-errors", in_errors); +} + +int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_discards(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_discards) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "in-discards", in_discards); +} + +int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_multicast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_multicast_pkts) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "in-multicast-pkts", in_multicast_pkts); +} + +int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_broadcast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_broadcast_pkts) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "in-broadcast-pkts", in_broadcast_pkts); +} + +int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_unicast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_unicast_pkts) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "in-unicast-pkts", in_unicast_pkts); +} + +int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_octets(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_octets) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "in-octets", in_octets); +} + +int interfaces_ly_tree_create_interfaces_state_interface_statistics_discontinuity_time(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* discontinuity_time) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "discontinuity-time", discontinuity_time); +} + +int interfaces_ly_tree_create_interfaces_state_interface_speed(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* speed) +{ + return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "speed", speed); +} + +int interfaces_ly_tree_create_interfaces_state_interface_lower_layer_if(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* lower_layer_if) +{ + return srpc_ly_tree_append_leaf_list(ly_ctx, interface_node, NULL, "lower-layer-if", lower_layer_if); +} + +int interfaces_ly_tree_create_interfaces_state_interface_higher_layer_if(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* higher_layer_if) +{ + return srpc_ly_tree_append_leaf_list(ly_ctx, interface_node, NULL, "higher-layer-if", higher_layer_if); +} + +int interfaces_ly_tree_create_interfaces_state_interface_phys_address(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* phys_address) +{ + return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "phys-address", phys_address); +} + +int interfaces_ly_tree_create_interfaces_state_interface_if_index(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* if_index) +{ + return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "if-index", if_index); +} + +int interfaces_ly_tree_create_interfaces_state_interface_last_change(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* last_change) +{ + return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "last-change", last_change); +} + +int interfaces_ly_tree_create_interfaces_state_interface_oper_status(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* oper_status) +{ + return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "oper-status", oper_status); +} + +int interfaces_ly_tree_create_interfaces_state_interface_admin_status(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* admin_status) +{ + return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "admin-status", admin_status); +} + +int interfaces_ly_tree_create_interfaces_state_interface_type(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* type) +{ + return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "type", type); +} + +int interfaces_ly_tree_create_interfaces_state_interface_name(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* name) +{ + return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "name", name); +} + +int interfaces_ly_tree_create_interfaces(const struct ly_ctx* ly_ctx, struct lyd_node** interfaces_node) +{ + return srpc_ly_tree_create_container(ly_ctx, NULL, interfaces_node, "interfaces"); +} + +int interfaces_ly_tree_create_interfaces_interface(const struct ly_ctx* ly_ctx, struct lyd_node* interfaces_node, struct lyd_node** interface_node, const char* name) +{ + // TODO: fix this for multiple keys with SRPC library + return srpc_ly_tree_create_list(ly_ctx, interfaces_node, interface_node, "interface", "name", name); +} + +int interfaces_ly_tree_create_interfaces_interface_statistics(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, struct lyd_node** statistics_node) +{ + return srpc_ly_tree_create_container(ly_ctx, interface_node, statistics_node, "statistics"); +} + +int interfaces_ly_tree_create_interfaces_interface_statistics_out_errors(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_errors) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "out-errors", out_errors); +} + +int interfaces_ly_tree_create_interfaces_interface_statistics_out_discards(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_discards) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "out-discards", out_discards); +} + +int interfaces_ly_tree_create_interfaces_interface_statistics_out_multicast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_multicast_pkts) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "out-multicast-pkts", out_multicast_pkts); +} + +int interfaces_ly_tree_create_interfaces_interface_statistics_out_broadcast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_broadcast_pkts) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "out-broadcast-pkts", out_broadcast_pkts); +} + +int interfaces_ly_tree_create_interfaces_interface_statistics_out_unicast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_unicast_pkts) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "out-unicast-pkts", out_unicast_pkts); +} + +int interfaces_ly_tree_create_interfaces_interface_statistics_out_octets(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_octets) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "out-octets", out_octets); +} + +int interfaces_ly_tree_create_interfaces_interface_statistics_in_unknown_protos(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_unknown_protos) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "in-unknown-protos", in_unknown_protos); +} + +int interfaces_ly_tree_create_interfaces_interface_statistics_in_errors(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_errors) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "in-errors", in_errors); +} + +int interfaces_ly_tree_create_interfaces_interface_statistics_in_discards(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_discards) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "in-discards", in_discards); +} + +int interfaces_ly_tree_create_interfaces_interface_statistics_in_multicast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_multicast_pkts) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "in-multicast-pkts", in_multicast_pkts); +} + +int interfaces_ly_tree_create_interfaces_interface_statistics_in_broadcast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_broadcast_pkts) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "in-broadcast-pkts", in_broadcast_pkts); +} + +int interfaces_ly_tree_create_interfaces_interface_statistics_in_unicast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_unicast_pkts) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "in-unicast-pkts", in_unicast_pkts); +} + +int interfaces_ly_tree_create_interfaces_interface_statistics_in_octets(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_octets) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "in-octets", in_octets); +} + +int interfaces_ly_tree_create_interfaces_interface_statistics_discontinuity_time(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* discontinuity_time) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "discontinuity-time", discontinuity_time); +} + +int interfaces_ly_tree_create_interfaces_interface_speed(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* speed) +{ + return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "speed", speed); +} + +int interfaces_ly_tree_create_interfaces_interface_lower_layer_if(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* lower_layer_if) +{ + return srpc_ly_tree_append_leaf_list(ly_ctx, interface_node, NULL, "lower-layer-if", lower_layer_if); +} + +int interfaces_ly_tree_create_interfaces_interface_higher_layer_if(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* higher_layer_if) +{ + return srpc_ly_tree_append_leaf_list(ly_ctx, interface_node, NULL, "higher-layer-if", higher_layer_if); +} + +int interfaces_ly_tree_create_interfaces_interface_phys_address(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* phys_address) +{ + return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "phys-address", phys_address); +} + +int interfaces_ly_tree_create_interfaces_interface_if_index(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* if_index) +{ + return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "if-index", if_index); +} + +int interfaces_ly_tree_create_interfaces_interface_last_change(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* last_change) +{ + return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "last-change", last_change); +} + +int interfaces_ly_tree_create_interfaces_interface_oper_status(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* oper_status) +{ + return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "oper-status", oper_status); +} + +int interfaces_ly_tree_create_interfaces_interface_admin_status(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* admin_status) +{ + return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "admin-status", admin_status); +} + +int interfaces_ly_tree_create_interfaces_interface_link_up_down_trap_enable(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* link_up_down_trap_enable) +{ + return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "link-up-down-trap-enable", link_up_down_trap_enable); +} + +int interfaces_ly_tree_create_interfaces_interface_enabled(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* enabled) +{ + return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "enabled", enabled); +} + +int interfaces_ly_tree_create_interfaces_interface_type(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* type) +{ + return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "type", type); +} + +int interfaces_ly_tree_create_interfaces_interface_description(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* description) +{ + return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "description", description); +} + +int interfaces_ly_tree_create_interfaces_interface_name(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* name) +{ + return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "name", name); +} diff --git a/src/interfaces/src/plugin/ly_tree.h b/src/interfaces/src/plugin/ly_tree.h new file mode 100644 index 00000000..188c49d1 --- /dev/null +++ b/src/interfaces/src/plugin/ly_tree.h @@ -0,0 +1,64 @@ +#ifndef INTERFACES_PLUGIN_LY_TREE_H +#define INTERFACES_PLUGIN_LY_TREE_H + +#include + +int interfaces_ly_tree_create_interfaces_state(const struct ly_ctx* ly_ctx, struct lyd_node** interfaces_state_node); +int interfaces_ly_tree_create_interfaces_state_interface(const struct ly_ctx* ly_ctx, struct lyd_node* interfaces_state_node, struct lyd_node** interface_node, const char* name); +int interfaces_ly_tree_create_interfaces_state_interface_statistics(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, struct lyd_node** statistics_node); +int interfaces_ly_tree_create_interfaces_state_interface_statistics_out_errors(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_errors); +int interfaces_ly_tree_create_interfaces_state_interface_statistics_out_discards(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_discards); +int interfaces_ly_tree_create_interfaces_state_interface_statistics_out_multicast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_multicast_pkts); +int interfaces_ly_tree_create_interfaces_state_interface_statistics_out_broadcast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_broadcast_pkts); +int interfaces_ly_tree_create_interfaces_state_interface_statistics_out_unicast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_unicast_pkts); +int interfaces_ly_tree_create_interfaces_state_interface_statistics_out_octets(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_octets); +int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_unknown_protos(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_unknown_protos); +int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_errors(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_errors); +int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_discards(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_discards); +int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_multicast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_multicast_pkts); +int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_broadcast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_broadcast_pkts); +int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_unicast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_unicast_pkts); +int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_octets(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_octets); +int interfaces_ly_tree_create_interfaces_state_interface_statistics_discontinuity_time(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* discontinuity_time); +int interfaces_ly_tree_create_interfaces_state_interface_speed(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* speed); +int interfaces_ly_tree_create_interfaces_state_interface_lower_layer_if(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* lower_layer_if); +int interfaces_ly_tree_create_interfaces_state_interface_higher_layer_if(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* higher_layer_if); +int interfaces_ly_tree_create_interfaces_state_interface_phys_address(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* phys_address); +int interfaces_ly_tree_create_interfaces_state_interface_if_index(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* if_index); +int interfaces_ly_tree_create_interfaces_state_interface_last_change(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* last_change); +int interfaces_ly_tree_create_interfaces_state_interface_oper_status(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* oper_status); +int interfaces_ly_tree_create_interfaces_state_interface_admin_status(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* admin_status); +int interfaces_ly_tree_create_interfaces_state_interface_type(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* type); +int interfaces_ly_tree_create_interfaces_state_interface_name(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* name); +int interfaces_ly_tree_create_interfaces(const struct ly_ctx* ly_ctx, struct lyd_node** interfaces_node); +int interfaces_ly_tree_create_interfaces_interface(const struct ly_ctx* ly_ctx, struct lyd_node* interfaces_node, struct lyd_node** interface_node, const char* name); +int interfaces_ly_tree_create_interfaces_interface_statistics(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, struct lyd_node** statistics_node); +int interfaces_ly_tree_create_interfaces_interface_statistics_out_errors(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_errors); +int interfaces_ly_tree_create_interfaces_interface_statistics_out_discards(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_discards); +int interfaces_ly_tree_create_interfaces_interface_statistics_out_multicast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_multicast_pkts); +int interfaces_ly_tree_create_interfaces_interface_statistics_out_broadcast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_broadcast_pkts); +int interfaces_ly_tree_create_interfaces_interface_statistics_out_unicast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_unicast_pkts); +int interfaces_ly_tree_create_interfaces_interface_statistics_out_octets(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_octets); +int interfaces_ly_tree_create_interfaces_interface_statistics_in_unknown_protos(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_unknown_protos); +int interfaces_ly_tree_create_interfaces_interface_statistics_in_errors(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_errors); +int interfaces_ly_tree_create_interfaces_interface_statistics_in_discards(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_discards); +int interfaces_ly_tree_create_interfaces_interface_statistics_in_multicast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_multicast_pkts); +int interfaces_ly_tree_create_interfaces_interface_statistics_in_broadcast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_broadcast_pkts); +int interfaces_ly_tree_create_interfaces_interface_statistics_in_unicast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_unicast_pkts); +int interfaces_ly_tree_create_interfaces_interface_statistics_in_octets(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_octets); +int interfaces_ly_tree_create_interfaces_interface_statistics_discontinuity_time(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* discontinuity_time); +int interfaces_ly_tree_create_interfaces_interface_speed(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* speed); +int interfaces_ly_tree_create_interfaces_interface_lower_layer_if(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* lower_layer_if); +int interfaces_ly_tree_create_interfaces_interface_higher_layer_if(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* higher_layer_if); +int interfaces_ly_tree_create_interfaces_interface_phys_address(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* phys_address); +int interfaces_ly_tree_create_interfaces_interface_if_index(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* if_index); +int interfaces_ly_tree_create_interfaces_interface_last_change(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* last_change); +int interfaces_ly_tree_create_interfaces_interface_oper_status(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* oper_status); +int interfaces_ly_tree_create_interfaces_interface_admin_status(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* admin_status); +int interfaces_ly_tree_create_interfaces_interface_link_up_down_trap_enable(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* link_up_down_trap_enable); +int interfaces_ly_tree_create_interfaces_interface_enabled(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* enabled); +int interfaces_ly_tree_create_interfaces_interface_type(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* type); +int interfaces_ly_tree_create_interfaces_interface_description(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* description); +int interfaces_ly_tree_create_interfaces_interface_name(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* name); + +#endif // INTERFACES_PLUGIN_LY_TREE_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/startup/load.c b/src/interfaces/src/plugin/startup/load.c new file mode 100644 index 00000000..d58fb0f8 --- /dev/null +++ b/src/interfaces/src/plugin/startup/load.c @@ -0,0 +1,74 @@ +#include "load.h" +#include "plugin/common.h" + +#include +#include +#include + +static int interfaces_startup_load_interface(void* priv, sr_session_ctx_t* session, const struct ly_ctx* ly_ctx, struct lyd_node* parent_node); + +int interfaces_startup_load(interfaces_ctx_t* ctx, sr_session_ctx_t* session) +{ + int error = 0; + + const struct ly_ctx* ly_ctx = NULL; + struct lyd_node* root_node = NULL; + sr_conn_ctx_t* conn_ctx = NULL; + + srpc_startup_load_t load_values[] = { + { + "/ietf-interfaces:interfaces/interface[name='%s']", + interfaces_startup_load_interface, + }, + }; + + conn_ctx = sr_session_get_connection(session); + ly_ctx = sr_acquire_context(conn_ctx); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "Unable to get ly_ctx variable"); + goto error_out; + } + + // load system container info + // [LOAD ROOT NODE HERE] + goto out; + for (size_t i = 0; i < ARRAY_SIZE(load_values); i++) { + const srpc_startup_load_t* load = &load_values[i]; + + error = load->cb((void*)ctx, session, ly_ctx, root_node); + if (error) { + SRPLG_LOG_ERR(PLUGIN_NAME, "Node creation callback failed for value %s", load->name); + goto error_out; + } + } + + error = sr_edit_batch(session, root_node, "merge"); + if (error != SR_ERR_OK) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_edit_batch() error (%d): %s", error, sr_strerror(error)); + goto error_out; + } + + error = sr_apply_changes(session, 0); + if (error != 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_apply_changes() error (%d): %s", error, sr_strerror(error)); + goto error_out; + } + + goto out; + +error_out: + error = -1; + +out: + if (root_node) { + lyd_free_tree(root_node); + } + sr_release_context(conn_ctx); + return error; +} + +static int interfaces_startup_load_interface(void* priv, sr_session_ctx_t* session, const struct ly_ctx* ly_ctx, struct lyd_node* parent_node) +{ + int error = 0; + return error; +} diff --git a/src/interfaces/src/plugin/startup/load.h b/src/interfaces/src/plugin/startup/load.h new file mode 100644 index 00000000..89f3a89c --- /dev/null +++ b/src/interfaces/src/plugin/startup/load.h @@ -0,0 +1,8 @@ +#ifndef INTERFACES_PLUGIN_STARTUP_LOAD_H +#define INTERFACES_PLUGIN_STARTUP_LOAD_H + +#include "plugin/context.h" + +int interfaces_startup_load(interfaces_ctx_t* ctx, sr_session_ctx_t* session); + +#endif // INTERFACES_PLUGIN_STARTUP_LOAD_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/startup/store.c b/src/interfaces/src/plugin/startup/store.c new file mode 100644 index 00000000..80374035 --- /dev/null +++ b/src/interfaces/src/plugin/startup/store.c @@ -0,0 +1,55 @@ +#include "store.h" +#include "plugin/common.h" + +#include +#include +#include + +static int interfaces_startup_store_interface(void* priv, const struct lyd_node* parent_container); + +int interfaces_startup_store(interfaces_ctx_t* ctx, sr_session_ctx_t* session) +{ + int error = 0; + sr_data_t* subtree = NULL; + + error = sr_get_subtree(session, "[ENTER_ROOT_CONFIG_PATH]", 0, &subtree); + if (error) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_get_subtree() error (%d): %s", error, sr_strerror(error)); + goto error_out; + } + + srpc_startup_store_t store_values[] = { + { + "/ietf-interfaces:interfaces/interface[name='%s']", + interfaces_startup_store_interface, + }, + }; + + for (size_t i = 0; i < ARRAY_SIZE(store_values); i++) { + const srpc_startup_store_t* store = &store_values[i]; + + error = store->cb(ctx, subtree->tree); + if (error != 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "Startup store callback failed for value %s", store->name); + goto error_out; + } + } + + goto out; + +error_out: + error = -1; + +out: + if (subtree) { + sr_release_data(subtree); + } + + return error; +} + +static int interfaces_startup_store_interface(void* priv, const struct lyd_node* parent_container) +{ + int error = 0; + return error; +} diff --git a/src/interfaces/src/plugin/startup/store.h b/src/interfaces/src/plugin/startup/store.h new file mode 100644 index 00000000..7e5a9a65 --- /dev/null +++ b/src/interfaces/src/plugin/startup/store.h @@ -0,0 +1,8 @@ +#ifndef INTERFACES_PLUGIN_STARTUP_STORE_H +#define INTERFACES_PLUGIN_STARTUP_STORE_H + +#include "plugin/context.h" + +int interfaces_startup_store(interfaces_ctx_t* ctx, sr_session_ctx_t* session); + +#endif // INTERFACES_PLUGIN_STARTUP_STORE_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/subscription/change.c b/src/interfaces/src/plugin/subscription/change.c new file mode 100644 index 00000000..a7929078 --- /dev/null +++ b/src/interfaces/src/plugin/subscription/change.c @@ -0,0 +1,55 @@ +#include "change.h" +#include "plugin/common.h" +#include "plugin/context.h" + +#include +#include +#include + +// change API +#include "plugin/api/interfaces/change.h" +#include "plugin/api/interfaces/interface/change.h" + +int interfaces_subscription_change_interfaces_interface(sr_session_ctx_t* session, uint32_t subscription_id, const char* module_name, const char* xpath, sr_event_t event, uint32_t request_id, void* private_data) +{ + int error = SR_ERR_OK; + interfaces_ctx_t* ctx = (interfaces_ctx_t*)private_data; + + // sysrepo + sr_change_iter_t* changes_iterator = NULL; + sr_change_oper_t operation = SR_OP_CREATED; + const char *prev_value = NULL, *prev_list = NULL; + int prev_default; + + const char* node_name = NULL; + const char* node_value = NULL; + + // libyang + const struct lyd_node* node = NULL; + + if (event == SR_EV_ABORT) { + SRPLG_LOG_ERR(PLUGIN_NAME, "Aborting changes for %s", xpath); + goto error_out; + } else if (event == SR_EV_DONE) { + error = sr_copy_config(ctx->startup_session, BASE_YANG_MODEL, SR_DS_RUNNING, 0); + if (error) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_copy_config() error (%d): %s", error, sr_strerror(error)); + goto error_out; + } + } else if (event == SR_EV_CHANGE) { + // connect change API + error = srpc_iterate_changes(ctx, session, xpath, interfaces_change_interface); + if (error) { + SRPLG_LOG_ERR(PLUGIN_NAME, "srpc_iterate_changes() for interfaces_change_interface failed: %d", error); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} diff --git a/src/interfaces/src/plugin/subscription/change.h b/src/interfaces/src/plugin/subscription/change.h new file mode 100644 index 00000000..bfefa610 --- /dev/null +++ b/src/interfaces/src/plugin/subscription/change.h @@ -0,0 +1,8 @@ +#ifndef INTERFACES_PLUGIN_SUBSCRIPTION_CHANGE_H +#define INTERFACES_PLUGIN_SUBSCRIPTION_CHANGE_H + +#include + +int interfaces_subscription_change_interfaces_interface(sr_session_ctx_t* session, uint32_t subscription_id, const char* module_name, const char* xpath, sr_event_t event, uint32_t request_id, void* private_data); + +#endif // INTERFACES_PLUGIN_SUBSCRIPTION_CHANGE_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c new file mode 100644 index 00000000..4bfa1a1e --- /dev/null +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -0,0 +1,1065 @@ +#include "operational.h" +#include "plugin/common.h" +#include "plugin/context.h" + +#include +#include +#include + +int interfaces_subscription_operational_interfaces_interface_admin_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + SRPLG_LOG_INF(PLUGIN_NAME, "Operational XPath: %s", request_xpath); + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_oper_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_last_change(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_if_index(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_phys_address(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_higher_layer_if(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_lower_layer_if(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_speed(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_statistics_discontinuity_time(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_statistics_in_octets(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_statistics_in_unicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_statistics_in_broadcast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_statistics_in_multicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_statistics_in_discards(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_statistics_in_errors(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_statistics_in_unknown_protos(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_statistics_out_octets(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_statistics_out_unicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_statistics_out_broadcast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_statistics_out_multicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_statistics_out_discards(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_statistics_out_errors(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_state_interface_name(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_state_interface_type(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_state_interface_admin_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_state_interface_oper_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_state_interface_last_change(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_state_interface_if_index(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_state_interface_phys_address(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_state_interface_higher_layer_if(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_state_interface_lower_layer_if(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_state_interface_speed(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_state_interface_statistics_discontinuity_time(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_state_interface_statistics_in_octets(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_state_interface_statistics_in_unicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_state_interface_statistics_in_broadcast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_state_interface_statistics_in_multicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_state_interface_statistics_in_discards(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_state_interface_statistics_in_errors(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_state_interface_statistics_in_unknown_protos(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_state_interface_statistics_out_octets(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_state_interface_statistics_out_unicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_state_interface_statistics_out_broadcast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_state_interface_statistics_out_multicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_state_interface_statistics_out_discards(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_state_interface_statistics_out_errors(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_state_interface(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} diff --git a/src/interfaces/src/plugin/subscription/operational.h b/src/interfaces/src/plugin/subscription/operational.h new file mode 100644 index 00000000..0f8090f1 --- /dev/null +++ b/src/interfaces/src/plugin/subscription/operational.h @@ -0,0 +1,55 @@ +#ifndef INTERFACES_PLUGIN_SUBSCRIPTION_OPERATIONAL_H +#define INTERFACES_PLUGIN_SUBSCRIPTION_OPERATIONAL_H + +#include + +int interfaces_subscription_operational_interfaces_interface_admin_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_oper_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_last_change(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_if_index(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_phys_address(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_higher_layer_if(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_lower_layer_if(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_speed(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_statistics_discontinuity_time(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_statistics_in_octets(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_statistics_in_unicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_statistics_in_broadcast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_statistics_in_multicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_statistics_in_discards(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_statistics_in_errors(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_statistics_in_unknown_protos(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_statistics_out_octets(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_statistics_out_unicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_statistics_out_broadcast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_statistics_out_multicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_statistics_out_discards(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_statistics_out_errors(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_state_interface_name(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_state_interface_type(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_state_interface_admin_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_state_interface_oper_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_state_interface_last_change(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_state_interface_if_index(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_state_interface_phys_address(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_state_interface_higher_layer_if(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_state_interface_lower_layer_if(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_state_interface_speed(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_state_interface_statistics_discontinuity_time(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_state_interface_statistics_in_octets(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_state_interface_statistics_in_unicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_state_interface_statistics_in_broadcast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_state_interface_statistics_in_multicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_state_interface_statistics_in_discards(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_state_interface_statistics_in_errors(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_state_interface_statistics_in_unknown_protos(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_state_interface_statistics_out_octets(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_state_interface_statistics_out_unicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_state_interface_statistics_out_broadcast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_state_interface_statistics_out_multicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_state_interface_statistics_out_discards(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_state_interface_statistics_out_errors(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_state_interface(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); + +#endif // INTERFACES_PLUGIN_SUBSCRIPTION_OPERATIONAL_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/subscription/rpc.c b/src/interfaces/src/plugin/subscription/rpc.c new file mode 100644 index 00000000..03645e83 --- /dev/null +++ b/src/interfaces/src/plugin/subscription/rpc.c @@ -0,0 +1,7 @@ +#include "rpc.h" +#include "plugin/common.h" +#include "plugin/context.h" + +#include +#include +#include diff --git a/src/interfaces/src/plugin/subscription/rpc.h b/src/interfaces/src/plugin/subscription/rpc.h new file mode 100644 index 00000000..6afecbaa --- /dev/null +++ b/src/interfaces/src/plugin/subscription/rpc.h @@ -0,0 +1,6 @@ +#ifndef INTERFACES_PLUGIN_SUBSCRIPTION_RPC_H +#define INTERFACES_PLUGIN_SUBSCRIPTION_RPC_H + +#include + +#endif // INTERFACES_PLUGIN_SUBSCRIPTION_RPC_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/types.h b/src/interfaces/src/plugin/types.h new file mode 100644 index 00000000..3efa5a6e --- /dev/null +++ b/src/interfaces/src/plugin/types.h @@ -0,0 +1,35 @@ +#ifndef INTERFACES_PLUGIN_TYPES_H +#define INTERFACES_PLUGIN_TYPES_H + +#include +#include + +// typedefs +typedef enum interfaces_interfaces_interface_link_up_down_trap_enable interfaces_interfaces_interface_link_up_down_trap_enable_t; +typedef struct interfaces_interfaces_interface interfaces_interfaces_interface_t; +typedef struct interfaces_interfaces_interface_element interfaces_interfaces_interface_element_t; +typedef struct interfaces_interfaces interfaces_interfaces_t; + +enum interfaces_interfaces_interface_link_up_down_trap_enable { + interfaces_interfaces_interface_link_up_down_trap_enable_disabled, + interfaces_interfaces_interface_link_up_down_trap_enable_enabled, +}; + +struct interfaces_interfaces_interface { + char* name; + char* description; + char* type; + uint8_t enabled; + interfaces_interfaces_interface_link_up_down_trap_enable_t link_up_down_trap_enable; +}; + +struct interfaces_interfaces_interface_element { + interfaces_interfaces_interface_element_t* next; + interfaces_interfaces_interface_t interface; +}; + +struct interfaces_interfaces { + interfaces_interfaces_interface_element_t* interface; +}; + +#endif // INTERFACES_PLUGIN_TYPES_H \ No newline at end of file From eca66a0f9c86a70c8427dfbd82aeec767dc7e734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Thu, 11 Aug 2022 16:16:36 +0200 Subject: [PATCH 004/247] interfaces-plugin: remove unused operational callbacks --- .../src/plugin/subscription/operational.c | 552 +----------------- .../src/plugin/subscription/operational.h | 25 - 2 files changed, 1 insertion(+), 576 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 4bfa1a1e..23441d2f 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -512,554 +512,4 @@ int interfaces_subscription_operational_interfaces_interface(sr_session_ctx_t* s out: return error; -} - -int interfaces_subscription_operational_interfaces_state_interface_name(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - return error; -} - -int interfaces_subscription_operational_interfaces_state_interface_type(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - return error; -} - -int interfaces_subscription_operational_interfaces_state_interface_admin_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - return error; -} - -int interfaces_subscription_operational_interfaces_state_interface_oper_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - return error; -} - -int interfaces_subscription_operational_interfaces_state_interface_last_change(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - return error; -} - -int interfaces_subscription_operational_interfaces_state_interface_if_index(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - return error; -} - -int interfaces_subscription_operational_interfaces_state_interface_phys_address(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - return error; -} - -int interfaces_subscription_operational_interfaces_state_interface_higher_layer_if(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - return error; -} - -int interfaces_subscription_operational_interfaces_state_interface_lower_layer_if(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - return error; -} - -int interfaces_subscription_operational_interfaces_state_interface_speed(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - return error; -} - -int interfaces_subscription_operational_interfaces_state_interface_statistics_discontinuity_time(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - return error; -} - -int interfaces_subscription_operational_interfaces_state_interface_statistics_in_octets(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - return error; -} - -int interfaces_subscription_operational_interfaces_state_interface_statistics_in_unicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - return error; -} - -int interfaces_subscription_operational_interfaces_state_interface_statistics_in_broadcast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - return error; -} - -int interfaces_subscription_operational_interfaces_state_interface_statistics_in_multicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - return error; -} - -int interfaces_subscription_operational_interfaces_state_interface_statistics_in_discards(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - return error; -} - -int interfaces_subscription_operational_interfaces_state_interface_statistics_in_errors(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - return error; -} - -int interfaces_subscription_operational_interfaces_state_interface_statistics_in_unknown_protos(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - return error; -} - -int interfaces_subscription_operational_interfaces_state_interface_statistics_out_octets(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - return error; -} - -int interfaces_subscription_operational_interfaces_state_interface_statistics_out_unicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - return error; -} - -int interfaces_subscription_operational_interfaces_state_interface_statistics_out_broadcast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - return error; -} - -int interfaces_subscription_operational_interfaces_state_interface_statistics_out_multicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - return error; -} - -int interfaces_subscription_operational_interfaces_state_interface_statistics_out_discards(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - return error; -} - -int interfaces_subscription_operational_interfaces_state_interface_statistics_out_errors(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - return error; -} - -int interfaces_subscription_operational_interfaces_state_interface(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) -{ - int error = SR_ERR_OK; - const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } - - goto out; - -error_out: - error = SR_ERR_CALLBACK_FAILED; - -out: - return error; -} +} \ No newline at end of file diff --git a/src/interfaces/src/plugin/subscription/operational.h b/src/interfaces/src/plugin/subscription/operational.h index 0f8090f1..c20d908f 100644 --- a/src/interfaces/src/plugin/subscription/operational.h +++ b/src/interfaces/src/plugin/subscription/operational.h @@ -26,30 +26,5 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_mult int interfaces_subscription_operational_interfaces_interface_statistics_out_discards(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); int interfaces_subscription_operational_interfaces_interface_statistics_out_errors(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); int interfaces_subscription_operational_interfaces_interface(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); -int interfaces_subscription_operational_interfaces_state_interface_name(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); -int interfaces_subscription_operational_interfaces_state_interface_type(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); -int interfaces_subscription_operational_interfaces_state_interface_admin_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); -int interfaces_subscription_operational_interfaces_state_interface_oper_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); -int interfaces_subscription_operational_interfaces_state_interface_last_change(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); -int interfaces_subscription_operational_interfaces_state_interface_if_index(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); -int interfaces_subscription_operational_interfaces_state_interface_phys_address(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); -int interfaces_subscription_operational_interfaces_state_interface_higher_layer_if(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); -int interfaces_subscription_operational_interfaces_state_interface_lower_layer_if(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); -int interfaces_subscription_operational_interfaces_state_interface_speed(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); -int interfaces_subscription_operational_interfaces_state_interface_statistics_discontinuity_time(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); -int interfaces_subscription_operational_interfaces_state_interface_statistics_in_octets(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); -int interfaces_subscription_operational_interfaces_state_interface_statistics_in_unicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); -int interfaces_subscription_operational_interfaces_state_interface_statistics_in_broadcast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); -int interfaces_subscription_operational_interfaces_state_interface_statistics_in_multicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); -int interfaces_subscription_operational_interfaces_state_interface_statistics_in_discards(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); -int interfaces_subscription_operational_interfaces_state_interface_statistics_in_errors(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); -int interfaces_subscription_operational_interfaces_state_interface_statistics_in_unknown_protos(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); -int interfaces_subscription_operational_interfaces_state_interface_statistics_out_octets(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); -int interfaces_subscription_operational_interfaces_state_interface_statistics_out_unicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); -int interfaces_subscription_operational_interfaces_state_interface_statistics_out_broadcast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); -int interfaces_subscription_operational_interfaces_state_interface_statistics_out_multicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); -int interfaces_subscription_operational_interfaces_state_interface_statistics_out_discards(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); -int interfaces_subscription_operational_interfaces_state_interface_statistics_out_errors(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); -int interfaces_subscription_operational_interfaces_state_interface(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); #endif // INTERFACES_PLUGIN_SUBSCRIPTION_OPERATIONAL_H \ No newline at end of file From d4fb76b20c699700743b6d3b15d5029ce825df3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Thu, 11 Aug 2022 16:22:06 +0200 Subject: [PATCH 005/247] interfaces-plugin: link NETLINK library --- CMakeLists.txt | 3 +++ src/interfaces/CMakeLists.txt | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index a78c2fea..5d3180a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,10 +15,13 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMakeModules") find_package(SYSREPO REQUIRED) find_package(LIBYANG REQUIRED) find_package(SRPC REQUIRED) +find_package(NL REQUIRED) include_directories( ${SYSREPO_INCLUDE_DIRS} ${LIBYANG_INCLUDE_DIRS} + ${SRPC_INCLUDE_DIRS} + ${NL_INCLUDE_DIRS} ) option(INTERFACES_PLUGIN "Enable interfaces plugin" OFF) diff --git a/src/interfaces/CMakeLists.txt b/src/interfaces/CMakeLists.txt index a9b7e45f..e166733f 100644 --- a/src/interfaces/CMakeLists.txt +++ b/src/interfaces/CMakeLists.txt @@ -41,6 +41,7 @@ target_link_libraries( ${SYSREPO_LIBRARIES} ${LIBYANG_LIBRARIES} ${SRPC_LIBRARIES} + ${NL_LIBRARIES} ) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMakeModules") @@ -57,6 +58,7 @@ if(PLUGIN) ${SYSREPO_LIBRARIES} ${LIBYANG_LIBRARIES} ${SRPC_LIBRARIES} + ${NL_LIBRARIES} ) else() add_executable( @@ -72,6 +74,7 @@ else() ${SYSREPO_LIBRARIES} ${LIBYANG_LIBRARIES} ${SRPC_LIBRARIES} + ${NL_LIBRARIES} ) endif() @@ -79,6 +82,7 @@ include_directories( ${SYSREPO_INCLUDE_DIRS} ${LIBYANG_INCLUDE_DIRS} ${SRPC_INCLUDE_DIRS} + ${NL_INCLUDE_DIRS} ) # augyang support From c5e3973c15ab1fc689e01d5132d6a5b095c43abe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Thu, 11 Aug 2022 16:42:17 +0200 Subject: [PATCH 006/247] interfaces-plugin: remove unused ly_tree functions --- src/interfaces/src/plugin/ly_tree.c | 136 ---------------------------- src/interfaces/src/plugin/ly_tree.h | 27 ------ src/interfaces/src/plugin/types.h | 3 +- 3 files changed, 2 insertions(+), 164 deletions(-) diff --git a/src/interfaces/src/plugin/ly_tree.c b/src/interfaces/src/plugin/ly_tree.c index d25e85ff..6801f9c2 100644 --- a/src/interfaces/src/plugin/ly_tree.c +++ b/src/interfaces/src/plugin/ly_tree.c @@ -3,142 +3,6 @@ #include -int interfaces_ly_tree_create_interfaces_state(const struct ly_ctx* ly_ctx, struct lyd_node** interfaces_state_node) -{ - return srpc_ly_tree_create_container(ly_ctx, NULL, interfaces_state_node, "interfaces-state"); -} - -int interfaces_ly_tree_create_interfaces_state_interface(const struct ly_ctx* ly_ctx, struct lyd_node* interfaces_state_node, struct lyd_node** interface_node, const char* name) -{ - // TODO: fix this for multiple keys with SRPC library - return srpc_ly_tree_create_list(ly_ctx, interfaces_state_node, interface_node, "interface", "name", name); -} - -int interfaces_ly_tree_create_interfaces_state_interface_statistics(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, struct lyd_node** statistics_node) -{ - return srpc_ly_tree_create_container(ly_ctx, interface_node, statistics_node, "statistics"); -} - -int interfaces_ly_tree_create_interfaces_state_interface_statistics_out_errors(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_errors) -{ - return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "out-errors", out_errors); -} - -int interfaces_ly_tree_create_interfaces_state_interface_statistics_out_discards(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_discards) -{ - return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "out-discards", out_discards); -} - -int interfaces_ly_tree_create_interfaces_state_interface_statistics_out_multicast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_multicast_pkts) -{ - return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "out-multicast-pkts", out_multicast_pkts); -} - -int interfaces_ly_tree_create_interfaces_state_interface_statistics_out_broadcast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_broadcast_pkts) -{ - return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "out-broadcast-pkts", out_broadcast_pkts); -} - -int interfaces_ly_tree_create_interfaces_state_interface_statistics_out_unicast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_unicast_pkts) -{ - return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "out-unicast-pkts", out_unicast_pkts); -} - -int interfaces_ly_tree_create_interfaces_state_interface_statistics_out_octets(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_octets) -{ - return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "out-octets", out_octets); -} - -int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_unknown_protos(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_unknown_protos) -{ - return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "in-unknown-protos", in_unknown_protos); -} - -int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_errors(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_errors) -{ - return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "in-errors", in_errors); -} - -int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_discards(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_discards) -{ - return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "in-discards", in_discards); -} - -int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_multicast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_multicast_pkts) -{ - return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "in-multicast-pkts", in_multicast_pkts); -} - -int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_broadcast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_broadcast_pkts) -{ - return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "in-broadcast-pkts", in_broadcast_pkts); -} - -int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_unicast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_unicast_pkts) -{ - return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "in-unicast-pkts", in_unicast_pkts); -} - -int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_octets(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_octets) -{ - return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "in-octets", in_octets); -} - -int interfaces_ly_tree_create_interfaces_state_interface_statistics_discontinuity_time(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* discontinuity_time) -{ - return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "discontinuity-time", discontinuity_time); -} - -int interfaces_ly_tree_create_interfaces_state_interface_speed(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* speed) -{ - return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "speed", speed); -} - -int interfaces_ly_tree_create_interfaces_state_interface_lower_layer_if(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* lower_layer_if) -{ - return srpc_ly_tree_append_leaf_list(ly_ctx, interface_node, NULL, "lower-layer-if", lower_layer_if); -} - -int interfaces_ly_tree_create_interfaces_state_interface_higher_layer_if(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* higher_layer_if) -{ - return srpc_ly_tree_append_leaf_list(ly_ctx, interface_node, NULL, "higher-layer-if", higher_layer_if); -} - -int interfaces_ly_tree_create_interfaces_state_interface_phys_address(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* phys_address) -{ - return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "phys-address", phys_address); -} - -int interfaces_ly_tree_create_interfaces_state_interface_if_index(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* if_index) -{ - return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "if-index", if_index); -} - -int interfaces_ly_tree_create_interfaces_state_interface_last_change(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* last_change) -{ - return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "last-change", last_change); -} - -int interfaces_ly_tree_create_interfaces_state_interface_oper_status(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* oper_status) -{ - return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "oper-status", oper_status); -} - -int interfaces_ly_tree_create_interfaces_state_interface_admin_status(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* admin_status) -{ - return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "admin-status", admin_status); -} - -int interfaces_ly_tree_create_interfaces_state_interface_type(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* type) -{ - return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "type", type); -} - -int interfaces_ly_tree_create_interfaces_state_interface_name(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* name) -{ - return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "name", name); -} - int interfaces_ly_tree_create_interfaces(const struct ly_ctx* ly_ctx, struct lyd_node** interfaces_node) { return srpc_ly_tree_create_container(ly_ctx, NULL, interfaces_node, "interfaces"); diff --git a/src/interfaces/src/plugin/ly_tree.h b/src/interfaces/src/plugin/ly_tree.h index 188c49d1..f86d99af 100644 --- a/src/interfaces/src/plugin/ly_tree.h +++ b/src/interfaces/src/plugin/ly_tree.h @@ -3,33 +3,6 @@ #include -int interfaces_ly_tree_create_interfaces_state(const struct ly_ctx* ly_ctx, struct lyd_node** interfaces_state_node); -int interfaces_ly_tree_create_interfaces_state_interface(const struct ly_ctx* ly_ctx, struct lyd_node* interfaces_state_node, struct lyd_node** interface_node, const char* name); -int interfaces_ly_tree_create_interfaces_state_interface_statistics(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, struct lyd_node** statistics_node); -int interfaces_ly_tree_create_interfaces_state_interface_statistics_out_errors(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_errors); -int interfaces_ly_tree_create_interfaces_state_interface_statistics_out_discards(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_discards); -int interfaces_ly_tree_create_interfaces_state_interface_statistics_out_multicast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_multicast_pkts); -int interfaces_ly_tree_create_interfaces_state_interface_statistics_out_broadcast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_broadcast_pkts); -int interfaces_ly_tree_create_interfaces_state_interface_statistics_out_unicast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_unicast_pkts); -int interfaces_ly_tree_create_interfaces_state_interface_statistics_out_octets(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_octets); -int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_unknown_protos(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_unknown_protos); -int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_errors(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_errors); -int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_discards(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_discards); -int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_multicast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_multicast_pkts); -int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_broadcast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_broadcast_pkts); -int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_unicast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_unicast_pkts); -int interfaces_ly_tree_create_interfaces_state_interface_statistics_in_octets(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_octets); -int interfaces_ly_tree_create_interfaces_state_interface_statistics_discontinuity_time(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* discontinuity_time); -int interfaces_ly_tree_create_interfaces_state_interface_speed(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* speed); -int interfaces_ly_tree_create_interfaces_state_interface_lower_layer_if(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* lower_layer_if); -int interfaces_ly_tree_create_interfaces_state_interface_higher_layer_if(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* higher_layer_if); -int interfaces_ly_tree_create_interfaces_state_interface_phys_address(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* phys_address); -int interfaces_ly_tree_create_interfaces_state_interface_if_index(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* if_index); -int interfaces_ly_tree_create_interfaces_state_interface_last_change(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* last_change); -int interfaces_ly_tree_create_interfaces_state_interface_oper_status(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* oper_status); -int interfaces_ly_tree_create_interfaces_state_interface_admin_status(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* admin_status); -int interfaces_ly_tree_create_interfaces_state_interface_type(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* type); -int interfaces_ly_tree_create_interfaces_state_interface_name(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* name); int interfaces_ly_tree_create_interfaces(const struct ly_ctx* ly_ctx, struct lyd_node** interfaces_node); int interfaces_ly_tree_create_interfaces_interface(const struct ly_ctx* ly_ctx, struct lyd_node* interfaces_node, struct lyd_node** interface_node, const char* name); int interfaces_ly_tree_create_interfaces_interface_statistics(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, struct lyd_node** statistics_node); diff --git a/src/interfaces/src/plugin/types.h b/src/interfaces/src/plugin/types.h index 3efa5a6e..6b8ebda2 100644 --- a/src/interfaces/src/plugin/types.h +++ b/src/interfaces/src/plugin/types.h @@ -5,7 +5,6 @@ #include // typedefs -typedef enum interfaces_interfaces_interface_link_up_down_trap_enable interfaces_interfaces_interface_link_up_down_trap_enable_t; typedef struct interfaces_interfaces_interface interfaces_interfaces_interface_t; typedef struct interfaces_interfaces_interface_element interfaces_interfaces_interface_element_t; typedef struct interfaces_interfaces interfaces_interfaces_t; @@ -15,6 +14,8 @@ enum interfaces_interfaces_interface_link_up_down_trap_enable { interfaces_interfaces_interface_link_up_down_trap_enable_enabled, }; +typedef enum interfaces_interfaces_interface_link_up_down_trap_enable interfaces_interfaces_interface_link_up_down_trap_enable_t; + struct interfaces_interfaces_interface { char* name; char* description; From 22151fd1d73e0ecfd86683e232c1506020940cd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Thu, 11 Aug 2022 18:05:23 +0200 Subject: [PATCH 007/247] interfaces-plugin: implement operational interface list callback --- src/interfaces/src/plugin.c | 11 ++++- src/interfaces/src/plugin/context.h | 10 ++++ .../src/plugin/subscription/operational.c | 47 +++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index 2964345e..b45c588b 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -1,4 +1,5 @@ #include "plugin.h" +#include "netlink/socket.h" #include "plugin/common.h" #include "plugin/context.h" @@ -208,7 +209,7 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) // in case of work on a specific callback set it to NULL if (op->cb) { - error = sr_oper_get_subscribe(running_session, BASE_YANG_MODEL, op->path, op->cb, NULL, SR_SUBSCR_DEFAULT, &subscription); + error = sr_oper_get_subscribe(running_session, BASE_YANG_MODEL, op->path, op->cb, *private_data, SR_SUBSCR_DEFAULT, &subscription); if (error) { SRPLG_LOG_ERR(PLUGIN_NAME, "sr_oper_get_subscribe() error (%d): %s", error, sr_strerror(error)); goto error_out; @@ -238,5 +239,13 @@ void sr_plugin_cleanup_cb(sr_session_ctx_t* running_session, void* private_data) SRPLG_LOG_ERR(PLUGIN_NAME, "sr_copy_config() error (%d): %s", error, sr_strerror(error)); } + if (ctx->nl_ctx.link_cache) { + nl_cache_free(ctx->nl_ctx.link_cache); + } + + if (ctx->nl_ctx.socket) { + nl_socket_free(ctx->nl_ctx.socket); + } + free(ctx); } \ No newline at end of file diff --git a/src/interfaces/src/plugin/context.h b/src/interfaces/src/plugin/context.h index d705d8ef..7f6168ea 100644 --- a/src/interfaces/src/plugin/context.h +++ b/src/interfaces/src/plugin/context.h @@ -4,10 +4,20 @@ #include "plugin/types.h" #include +#include + +// typedefs +typedef struct interfaces_nl_ctx_s interfaces_nl_ctx_t; typedef struct interfaces_ctx_s interfaces_ctx_t; +struct interfaces_nl_ctx_s { + struct nl_sock* socket; + struct nl_cache* link_cache; +}; + struct interfaces_ctx_s { sr_session_ctx_t* startup_session; + interfaces_nl_ctx_t nl_ctx; }; #endif // INTERFACES_PLUGIN_CONTEXT_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 23441d2f..bc39510b 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -1,11 +1,18 @@ #include "operational.h" +#include "libyang/tree_data.h" +#include "netlink/cache.h" +#include "netlink/socket.h" #include "plugin/common.h" #include "plugin/context.h" +#include "plugin/ly_tree.h" +#include "srpc/common.h" #include #include #include +#include + int interfaces_subscription_operational_interfaces_interface_admin_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; @@ -496,6 +503,31 @@ int interfaces_subscription_operational_interfaces_interface(sr_session_ctx_t* s { int error = SR_ERR_OK; const struct ly_ctx* ly_ctx = NULL; + interfaces_ctx_t* ctx = private_data; + interfaces_nl_ctx_t* nl_ctx = &ctx->nl_ctx; + struct rtnl_link* link_iter = NULL; + + // libyang + struct lyd_node* interface_list_node = NULL; + + SRPLG_LOG_INF(PLUGIN_NAME, "Operational callback: %s", request_xpath); + + // setup nl socket + if (!nl_ctx->socket) { + // netlink + SRPC_SAFE_CALL_PTR(nl_ctx->socket, nl_socket_alloc(), error_out); + + // connect + SRPC_SAFE_CALL_ERR(error, nl_connect(nl_ctx->socket, NETLINK_ROUTE), error_out); + } + + // cache was already allocated - free existing cache + if (nl_ctx->link_cache) { + nl_cache_free(nl_ctx->link_cache); + } + + // allocate new link cache + SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(nl_ctx->socket, 0, &nl_ctx->link_cache), error_out); if (*parent == NULL) { ly_ctx = sr_acquire_context(sr_session_get_connection(session)); @@ -503,6 +535,20 @@ int interfaces_subscription_operational_interfaces_interface(sr_session_ctx_t* s SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); goto error_out; } + + // set parent to the interfaces container + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces(ly_ctx, parent), error_out); + } + + // iterate links and add them to the operational DS + link_iter = (struct rtnl_link*)nl_cache_get_first(nl_ctx->link_cache); + while (link_iter) { + SRPLG_LOG_INF(PLUGIN_NAME, "Interface %s", rtnl_link_get_name(link_iter)); + + // add interface + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface(ly_ctx, *parent, &interface_list_node, rtnl_link_get_name(link_iter)), error_out); + + link_iter = (struct rtnl_link*)nl_cache_get_next((struct nl_object*)link_iter); } goto out; @@ -511,5 +557,6 @@ int interfaces_subscription_operational_interfaces_interface(sr_session_ctx_t* s error = SR_ERR_CALLBACK_FAILED; out: + return error; } \ No newline at end of file From c8dd124345269b7537f77860ad1bdc0747bf5737 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Thu, 11 Aug 2022 18:30:42 +0200 Subject: [PATCH 008/247] interfaces-plugin: implement operational oper-status leaf callback --- .../src/plugin/subscription/operational.c | 79 ++++++++++++++++--- 1 file changed, 67 insertions(+), 12 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index bc39510b..e34d224b 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -6,20 +6,24 @@ #include "plugin/context.h" #include "plugin/ly_tree.h" #include "srpc/common.h" +#include "sysrepo_types.h" +#include #include #include #include +#include +#include #include +static int interfaces_extract_interface_name(sr_session_ctx_t* session, const char* xpath, char* buffer, size_t buffer_size); + int interfaces_subscription_operational_interfaces_interface_admin_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; const struct ly_ctx* ly_ctx = NULL; - SRPLG_LOG_INF(PLUGIN_NAME, "Operational XPath: %s", request_xpath); - if (*parent == NULL) { ly_ctx = sr_acquire_context(sr_session_get_connection(session)); if (ly_ctx == NULL) { @@ -41,14 +45,39 @@ int interfaces_subscription_operational_interfaces_interface_oper_status(sr_sess { int error = SR_ERR_OK; const struct ly_ctx* ly_ctx = NULL; - - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } + interfaces_ctx_t* ctx = private_data; + interfaces_nl_ctx_t* nl_ctx = &ctx->nl_ctx; + char interface_name_buffer[100] = { 0 }; + struct rtnl_link* link = NULL; + + const char* operstate_map[] = { + [IF_OPER_UNKNOWN] = "unknown", + [IF_OPER_NOTPRESENT] = "not-present", + [IF_OPER_DOWN] = "down", + [IF_OPER_LOWERLAYERDOWN] = "lower-layer-down", + [IF_OPER_TESTING] = "testing", + [IF_OPER_DORMANT] = "dormant", + [IF_OPER_UP] = "up", + }; + + // there needs to be an allocated link cache in memory + assert(ctx->nl_ctx.link_cache != NULL); + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "interface") == 0); + + // extract interface name + SRPC_SAFE_CALL_ERR(error, interfaces_extract_interface_name(session, request_xpath, interface_name_buffer, sizeof(interface_name_buffer)), error_out); + SRPLG_LOG_INF(PLUGIN_NAME, "Getting oper status for interface %s", interface_name_buffer); + + // get link by name + SRPC_SAFE_CALL_PTR(link, rtnl_link_get_by_name(nl_ctx->link_cache, interface_name_buffer), error_out); + + // get oper status + const uint8_t oper_status = rtnl_link_get_operstate(link); + const char* oper_status_str = operstate_map[oper_status]; + + // add oper-status node + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_oper_status(ly_ctx, *parent, oper_status_str), error_out); goto out; @@ -510,8 +539,6 @@ int interfaces_subscription_operational_interfaces_interface(sr_session_ctx_t* s // libyang struct lyd_node* interface_list_node = NULL; - SRPLG_LOG_INF(PLUGIN_NAME, "Operational callback: %s", request_xpath); - // setup nl socket if (!nl_ctx->socket) { // netlink @@ -558,5 +585,33 @@ int interfaces_subscription_operational_interfaces_interface(sr_session_ctx_t* s out: + return error; +} + +static int interfaces_extract_interface_name(sr_session_ctx_t* session, const char* xpath, char* buffer, size_t buffer_size) +{ + int error = 0; + + const char* name = NULL; + + sr_xpath_ctx_t xpath_ctx = { 0 }; + + // extract key + SRPC_SAFE_CALL_PTR(name, sr_xpath_key_value((char*)xpath, "interface", "name", &xpath_ctx), error_out); + + // store to buffer + error = snprintf(buffer, buffer_size, "%s", name); + if (error < 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed"); + goto error_out; + } + + error = 0; + goto out; + +error_out: + error = -1; + +out: return error; } \ No newline at end of file From 1e9db27a284f547b179111bcc94d14b985d163aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Thu, 11 Aug 2022 18:38:04 +0200 Subject: [PATCH 009/247] interfaces-plugin: implement operational if-index leaf callback --- .../src/plugin/subscription/operational.c | 54 ++++++++++++++++--- 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index e34d224b..dbb30799 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -44,10 +44,16 @@ int interfaces_subscription_operational_interfaces_interface_admin_status(sr_ses int interfaces_subscription_operational_interfaces_interface_oper_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + + // context const struct ly_ctx* ly_ctx = NULL; interfaces_ctx_t* ctx = private_data; interfaces_nl_ctx_t* nl_ctx = &ctx->nl_ctx; + + // buffers char interface_name_buffer[100] = { 0 }; + + // libnl struct rtnl_link* link = NULL; const char* operstate_map[] = { @@ -67,15 +73,18 @@ int interfaces_subscription_operational_interfaces_interface_oper_status(sr_sess // extract interface name SRPC_SAFE_CALL_ERR(error, interfaces_extract_interface_name(session, request_xpath, interface_name_buffer, sizeof(interface_name_buffer)), error_out); - SRPLG_LOG_INF(PLUGIN_NAME, "Getting oper status for interface %s", interface_name_buffer); // get link by name SRPC_SAFE_CALL_PTR(link, rtnl_link_get_by_name(nl_ctx->link_cache, interface_name_buffer), error_out); + SRPLG_LOG_INF(PLUGIN_NAME, "Getting oper-status(%s)", interface_name_buffer); + // get oper status const uint8_t oper_status = rtnl_link_get_operstate(link); const char* oper_status_str = operstate_map[oper_status]; + SRPLG_LOG_INF(PLUGIN_NAME, "oper-status(%s) = %s", interface_name_buffer, oper_status_str); + // add oper-status node SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_oper_status(ly_ctx, *parent, oper_status_str), error_out); @@ -113,16 +122,47 @@ int interfaces_subscription_operational_interfaces_interface_last_change(sr_sess int interfaces_subscription_operational_interfaces_interface_if_index(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + + // context const struct ly_ctx* ly_ctx = NULL; + interfaces_ctx_t* ctx = private_data; + interfaces_nl_ctx_t* nl_ctx = &ctx->nl_ctx; - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } + // buffers + char interface_name_buffer[100] = { 0 }; + char ifindex_buffer[100] = { 0 }; + + // libnl + struct rtnl_link* link = NULL; + + // there needs to be an allocated link cache in memory + assert(ctx->nl_ctx.link_cache != NULL); + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "interface") == 0); + + // extract interface name + SRPC_SAFE_CALL_ERR(error, interfaces_extract_interface_name(session, request_xpath, interface_name_buffer, sizeof(interface_name_buffer)), error_out); + + // get link by name + SRPC_SAFE_CALL_PTR(link, rtnl_link_get_by_name(nl_ctx->link_cache, interface_name_buffer), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "Getting if-index(%s)", interface_name_buffer); + + // get if-index + const int ifindex = rtnl_link_get_ifindex(link); + + error = snprintf(ifindex_buffer, sizeof(ifindex_buffer), "%d", ifindex); + if (error < 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); + goto error_out; } + SRPLG_LOG_INF(PLUGIN_NAME, "if-index(%s) = %s", interface_name_buffer, ifindex_buffer); + + // add ifindex node + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_if_index(ly_ctx, *parent, ifindex_buffer), error_out); + + error = 0; goto out; error_out: From 565596e88cbe9f3d42677d4637f8f016174eaf50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Thu, 11 Aug 2022 18:48:40 +0200 Subject: [PATCH 010/247] interfaces-plugin: implement operational phys-address leaf callback --- .../src/plugin/subscription/operational.c | 43 ++++++++++++++++--- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index dbb30799..f8ca2c75 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -1,5 +1,6 @@ #include "operational.h" #include "libyang/tree_data.h" +#include "netlink/addr.h" #include "netlink/cache.h" #include "netlink/socket.h" #include "plugin/common.h" @@ -175,16 +176,44 @@ int interfaces_subscription_operational_interfaces_interface_if_index(sr_session int interfaces_subscription_operational_interfaces_interface_phys_address(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; + + // context const struct ly_ctx* ly_ctx = NULL; + interfaces_ctx_t* ctx = private_data; + interfaces_nl_ctx_t* nl_ctx = &ctx->nl_ctx; - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } + // buffers + char interface_name_buffer[100] = { 0 }; + char phys_address_buffer[100] = { 0 }; + + // libnl + struct rtnl_link* link = NULL; + struct nl_addr* addr = NULL; + // there needs to be an allocated link cache in memory + assert(ctx->nl_ctx.link_cache != NULL); + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "interface") == 0); + + // extract interface name + SRPC_SAFE_CALL_ERR(error, interfaces_extract_interface_name(session, request_xpath, interface_name_buffer, sizeof(interface_name_buffer)), error_out); + + // get link by name + SRPC_SAFE_CALL_PTR(link, rtnl_link_get_by_name(nl_ctx->link_cache, interface_name_buffer), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "Getting phys-address(%s)", interface_name_buffer); + + // get phys-address + SRPC_SAFE_CALL_PTR(addr, rtnl_link_get_addr(link), error_out); + SRPC_SAFE_CALL_PTR(error_ptr, nl_addr2str(addr, phys_address_buffer, sizeof(phys_address_buffer)), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "phys-address(%s) = %s", interface_name_buffer, phys_address_buffer); + + // add phys-address node + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_phys_address(ly_ctx, *parent, phys_address_buffer), error_out); + + error = 0; goto out; error_out: From e3526e43c52d916cafba5cf4275ba679204e8fe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Thu, 11 Aug 2022 19:12:33 +0200 Subject: [PATCH 011/247] interfaces-plugin: implement operational speed leaf callback --- src/interfaces/src/plugin.c | 3 +- .../src/plugin/subscription/operational.c | 63 ++++++++++++++++--- 2 files changed, 55 insertions(+), 11 deletions(-) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index b45c588b..f8f7654b 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -1,4 +1,5 @@ #include "plugin.h" +#include "netlink/cache.h" #include "netlink/socket.h" #include "plugin/common.h" #include "plugin/context.h" @@ -240,7 +241,7 @@ void sr_plugin_cleanup_cb(sr_session_ctx_t* running_session, void* private_data) } if (ctx->nl_ctx.link_cache) { - nl_cache_free(ctx->nl_ctx.link_cache); + nl_cache_put(ctx->nl_ctx.link_cache); } if (ctx->nl_ctx.socket) { diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index f8ca2c75..f749a69c 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -2,6 +2,7 @@ #include "libyang/tree_data.h" #include "netlink/addr.h" #include "netlink/cache.h" +#include "netlink/route/tc.h" #include "netlink/socket.h" #include "plugin/common.h" #include "plugin/context.h" @@ -17,6 +18,7 @@ #include #include +#include static int interfaces_extract_interface_name(sr_session_ctx_t* session, const char* xpath, char* buffer, size_t buffer_size); @@ -270,22 +272,63 @@ int interfaces_subscription_operational_interfaces_interface_lower_layer_if(sr_s int interfaces_subscription_operational_interfaces_interface_speed(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + // void* error_ptr = NULL; + + // context const struct ly_ctx* ly_ctx = NULL; + interfaces_ctx_t* ctx = private_data; + interfaces_nl_ctx_t* nl_ctx = &ctx->nl_ctx; - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } + // buffers + char interface_name_buffer[100] = { 0 }; + char speed_buffer[100] = { 0 }; + + // libnl + struct rtnl_link* link = NULL; + struct rtnl_qdisc* qdisc = NULL; + struct rtnl_tc* tc = NULL; + + // there needs to be an allocated link cache in memory + assert(ctx->nl_ctx.link_cache != NULL); + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "interface") == 0); + + // extract interface name + SRPC_SAFE_CALL_ERR(error, interfaces_extract_interface_name(session, request_xpath, interface_name_buffer, sizeof(interface_name_buffer)), error_out); + + // get link by name + SRPC_SAFE_CALL_PTR(link, rtnl_link_get_by_name(nl_ctx->link_cache, interface_name_buffer), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "Getting speed(%s)", interface_name_buffer); + + qdisc = rtnl_qdisc_alloc(); + + // setup traffic control + tc = TC_CAST(qdisc); + rtnl_tc_set_link(tc, link); + + // get speed + const uint64_t speed = rtnl_tc_get_stat(tc, RTNL_TC_RATE_BPS); + error = snprintf(speed_buffer, sizeof(speed_buffer), "%lu", speed); + if (error < 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); + goto error_out; } + SRPLG_LOG_INF(PLUGIN_NAME, "speed(%s) = %s", interface_name_buffer, speed_buffer); + + // add phys-address node + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_speed(ly_ctx, *parent, speed_buffer), error_out); + + error = 0; goto out; error_out: error = SR_ERR_CALLBACK_FAILED; out: + rtnl_qdisc_put(qdisc); + return error; } @@ -619,12 +662,12 @@ int interfaces_subscription_operational_interfaces_interface(sr_session_ctx_t* s // cache was already allocated - free existing cache if (nl_ctx->link_cache) { - nl_cache_free(nl_ctx->link_cache); + nl_cache_refill(nl_ctx->socket, nl_ctx->link_cache); + } else { + // allocate new link cache + SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(nl_ctx->socket, 0, &nl_ctx->link_cache), error_out); } - // allocate new link cache - SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(nl_ctx->socket, 0, &nl_ctx->link_cache), error_out); - if (*parent == NULL) { ly_ctx = sr_acquire_context(sr_session_get_connection(session)); if (ly_ctx == NULL) { From d7cb1408b588edb43e4fba75589d81dc3ac68033 Mon Sep 17 00:00:00 2001 From: agardijan Date: Thu, 11 Aug 2022 19:14:27 +0200 Subject: [PATCH 012/247] interfaces-plugin: initial store startup refactor --- src/interfaces/src/plugin/startup/store.c | 46 ++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin/startup/store.c b/src/interfaces/src/plugin/startup/store.c index 80374035..f2994113 100644 --- a/src/interfaces/src/plugin/startup/store.c +++ b/src/interfaces/src/plugin/startup/store.c @@ -1,5 +1,6 @@ #include "store.h" #include "plugin/common.h" +#include "utarray.h" #include #include @@ -12,7 +13,7 @@ int interfaces_startup_store(interfaces_ctx_t* ctx, sr_session_ctx_t* session) int error = 0; sr_data_t* subtree = NULL; - error = sr_get_subtree(session, "[ENTER_ROOT_CONFIG_PATH]", 0, &subtree); + error = sr_get_subtree(session, INTERFACES_INTERFACES_CONTAINER_YANG_PATH, 0, &subtree); if (error) { SRPLG_LOG_ERR(PLUGIN_NAME, "sr_get_subtree() error (%d): %s", error, sr_strerror(error)); goto error_out; @@ -51,5 +52,48 @@ int interfaces_startup_store(interfaces_ctx_t* ctx, sr_session_ctx_t* session) static int interfaces_startup_store_interface(void* priv, const struct lyd_node* parent_container) { int error = 0; + interfaces_ctx_t *ctx = (interfaces_ctx_t *) priv; + srpc_check_status_t check_status = srpc_check_status_none; + UT_array *interface_array = NULL; + + struct lyd_node *interfaces_node = srpc_ly_tree_get_child_leaf(parent_container, "interfaces"); + if (interfaces_node == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "srpc_ly_tree_get_child_leaf returned NULL for 'interfaces'"); + goto error_out; + } + + SRPLG_LOG_INF(PLUGIN_NAME, "Checking interface array"); + check_status = interfaces_check_interface(ctx, interface_array); + + switch (check_status) { + case srpc_check_status_none: + SRPLG_LOG_ERR(PLUGIN_NAME, "Error loading current interface array"); + goto error_out; + case srpc_check_status_error: + SRPLG_LOG_ERR(PLUGIN_NAME, "Error loading current interface array"); + goto error_out; + case srpc_check_status_non_existant: + SRPLG_LOG_INF(PLUGIN_NAME, "Storing interface array"); + + error = interfaces_store_interface(ctx, interface_array); + if (error) { + SRPLG_LOG_ERR(PLUGIN_NAME, "interfaces_store_interface() failed (%d)", error); + goto error_out; + } + break; + case srpc_check_status_equal: + SRPLG_LOG_ERR(PLUGIN_NAME, "Startup interface array is already applied on the system"); + break; + case srpc_check_status_partial: + /* should not be returned - treat as an error */ + SRPLG_LOG_ERR(PLUGIN_NAME, "Error loading current interface array"); + goto error_out; + } + + goto out; + +error_out: + error = -1; +out: return error; } From fc9be8b6a64fb392d6fa645a3a047a18596396b9 Mon Sep 17 00:00:00 2001 From: agardijan Date: Thu, 11 Aug 2022 19:14:37 +0200 Subject: [PATCH 013/247] interfaces-plugin: initial load startup refactor --- src/interfaces/src/plugin/startup/load.c | 37 ++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/src/interfaces/src/plugin/startup/load.c b/src/interfaces/src/plugin/startup/load.c index d58fb0f8..c5ee35f4 100644 --- a/src/interfaces/src/plugin/startup/load.c +++ b/src/interfaces/src/plugin/startup/load.c @@ -1,5 +1,7 @@ #include "load.h" #include "plugin/common.h" +#include "plugin/ly_tree.h" +#include "utarray.h" #include #include @@ -29,9 +31,12 @@ int interfaces_startup_load(interfaces_ctx_t* ctx, sr_session_ctx_t* session) goto error_out; } - // load system container info - // [LOAD ROOT NODE HERE] - goto out; + error = interfaces_ly_tree_create_interfaces(ly_ctx, &root_node); + if (error != 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "Unable to create ly root tree container"); + goto error_out; + } + for (size_t i = 0; i < ARRAY_SIZE(load_values); i++) { const srpc_startup_load_t* load = &load_values[i]; @@ -42,6 +47,11 @@ int interfaces_startup_load(interfaces_ctx_t* ctx, sr_session_ctx_t* session) } } +/* enable or disable storing into startup, use for testing */ +#define INTERFACES_PLUGIN_LOAD_STARTUP +/* disable for now */ +#undef INTERFACES_PLUGIN_LOAD_STARTUP +#ifdef INTERFACES_PLUGIN_LOAD_STARTUP error = sr_edit_batch(session, root_node, "merge"); if (error != SR_ERR_OK) { SRPLG_LOG_ERR(PLUGIN_NAME, "sr_edit_batch() error (%d): %s", error, sr_strerror(error)); @@ -53,6 +63,7 @@ int interfaces_startup_load(interfaces_ctx_t* ctx, sr_session_ctx_t* session) SRPLG_LOG_ERR(PLUGIN_NAME, "sr_apply_changes() error (%d): %s", error, sr_strerror(error)); goto error_out; } +#endif goto out; @@ -70,5 +81,25 @@ int interfaces_startup_load(interfaces_ctx_t* ctx, sr_session_ctx_t* session) static int interfaces_startup_load_interface(void* priv, sr_session_ctx_t* session, const struct ly_ctx* ly_ctx, struct lyd_node* parent_node) { int error = 0; + interfaces_ctx_t *ctx = (interfaces_ctx_t *) priv; + UT_array *interface_array = NULL; + + error = interfaces_load_interface(ly_ctx, &interface_array); + if (error) { + SRPLG_LOG_ERR(PLUGIN_NAME, "interfaces_load_interface() error (%d)", error); + goto error_out; + } + + error = interfaces_ly_tree_create_interfaces(ly_ctx, &parent_node); + if (error) { + SRPLG_LOG_ERR(PLUGIN_NAME, "interfaces_ly_tree_create_interfaces() error (%d)", error); + goto error_out; + } + + goto out; + +error_out: + error = -1; +out: return error; } From 413d03cfb694c508dae4dca6fe157cfc4128fe3e Mon Sep 17 00:00:00 2001 From: agardijan Date: Thu, 11 Aug 2022 19:15:29 +0200 Subject: [PATCH 014/247] interfaces-plugin: add interfaces containter yang path --- src/interfaces/src/plugin/common.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin/common.h b/src/interfaces/src/plugin/common.h index 1c5e145e..baed80d5 100644 --- a/src/interfaces/src/plugin/common.h +++ b/src/interfaces/src/plugin/common.h @@ -5,6 +5,8 @@ #define BASE_YANG_MODEL "ietf-interfaces" +#define INTERFACES_INTERFACES_CONTAINER_YANG_PATH "/" BASE_YANG_MODEL ":interfaces" + #define INTERFACES_INTERFACES_STATE_INTERFACE_NAME_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_YANG_PATH "/name" #define INTERFACES_INTERFACES_STATE_INTERFACE_TYPE_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_YANG_PATH "/type" #define INTERFACES_INTERFACES_STATE_INTERFACE_ADMIN_STATUS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_YANG_PATH "/admin-status" @@ -65,4 +67,4 @@ #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) -#endif // INTERFACES_PLUGIN_COMMON_H \ No newline at end of file +#endif // INTERFACES_PLUGIN_COMMON_H From 4ee79846b8c4afbffbdcdb8c27b20ae9256e336e Mon Sep 17 00:00:00 2001 From: agardijan Date: Fri, 12 Aug 2022 14:12:03 +0200 Subject: [PATCH 015/247] interfaces-plugin: use linked lists with interfaces --- src/interfaces/src/plugin/api/interfaces/load.c | 2 +- src/interfaces/src/plugin/api/interfaces/load.h | 4 ++-- src/interfaces/src/plugin/api/interfaces/store.c | 2 +- src/interfaces/src/plugin/api/interfaces/store.h | 4 ++-- src/interfaces/src/plugin/startup/load.c | 6 +++--- src/interfaces/src/plugin/startup/store.c | 12 ++++++------ 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index dbbb83d0..00b00147 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -1,6 +1,6 @@ #include "load.h" -int interfaces_load_interface(interfaces_ctx_t* ctx, UT_array** interface) +int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interfaces_interface_element_t** interface) { int error = 0; return error; diff --git a/src/interfaces/src/plugin/api/interfaces/load.h b/src/interfaces/src/plugin/api/interfaces/load.h index f27e12f0..e93df333 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.h +++ b/src/interfaces/src/plugin/api/interfaces/load.h @@ -4,6 +4,6 @@ #include "plugin/context.h" #include -int interfaces_load_interface(interfaces_ctx_t* ctx, UT_array** interface); +int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interfaces_interface_element_t** interface); -#endif // INTERFACES_PLUGIN_API_INTERFACES_LOAD_H \ No newline at end of file +#endif // INTERFACES_PLUGIN_API_INTERFACES_LOAD_H diff --git a/src/interfaces/src/plugin/api/interfaces/store.c b/src/interfaces/src/plugin/api/interfaces/store.c index f848c5f8..06dc1977 100644 --- a/src/interfaces/src/plugin/api/interfaces/store.c +++ b/src/interfaces/src/plugin/api/interfaces/store.c @@ -1,6 +1,6 @@ #include "store.h" -int interfaces_store_interface(interfaces_ctx_t* ctx, const UT_array* interface) +int interfaces_store_interface(interfaces_ctx_t* ctx, const interfaces_interfaces_interface_element_t* interface) { int error = 0; return error; diff --git a/src/interfaces/src/plugin/api/interfaces/store.h b/src/interfaces/src/plugin/api/interfaces/store.h index b9fb91e3..c2612553 100644 --- a/src/interfaces/src/plugin/api/interfaces/store.h +++ b/src/interfaces/src/plugin/api/interfaces/store.h @@ -4,6 +4,6 @@ #include "plugin/context.h" #include -int interfaces_store_interface(interfaces_ctx_t* ctx, const UT_array* interface); +int interfaces_store_interface(interfaces_ctx_t* ctx, const interfaces_interfaces_interface_element_t* interface); -#endif // INTERFACES_PLUGIN_API_INTERFACES_STORE_H \ No newline at end of file +#endif // INTERFACES_PLUGIN_API_INTERFACES_STORE_H diff --git a/src/interfaces/src/plugin/startup/load.c b/src/interfaces/src/plugin/startup/load.c index c5ee35f4..3a09efbc 100644 --- a/src/interfaces/src/plugin/startup/load.c +++ b/src/interfaces/src/plugin/startup/load.c @@ -1,7 +1,7 @@ #include "load.h" #include "plugin/common.h" #include "plugin/ly_tree.h" -#include "utarray.h" +#include "utlist.h" #include #include @@ -82,9 +82,9 @@ static int interfaces_startup_load_interface(void* priv, sr_session_ctx_t* sessi { int error = 0; interfaces_ctx_t *ctx = (interfaces_ctx_t *) priv; - UT_array *interface_array = NULL; + interfaces_interfaces_interface_element_t *interface_head = NULL; - error = interfaces_load_interface(ly_ctx, &interface_array); + error = interfaces_load_interface(ly_ctx, &interface_head); if (error) { SRPLG_LOG_ERR(PLUGIN_NAME, "interfaces_load_interface() error (%d)", error); goto error_out; diff --git a/src/interfaces/src/plugin/startup/store.c b/src/interfaces/src/plugin/startup/store.c index f2994113..0df2aeb9 100644 --- a/src/interfaces/src/plugin/startup/store.c +++ b/src/interfaces/src/plugin/startup/store.c @@ -1,6 +1,6 @@ #include "store.h" #include "plugin/common.h" -#include "utarray.h" +#include "utlist.h" #include #include @@ -54,7 +54,7 @@ static int interfaces_startup_store_interface(void* priv, const struct lyd_node* int error = 0; interfaces_ctx_t *ctx = (interfaces_ctx_t *) priv; srpc_check_status_t check_status = srpc_check_status_none; - UT_array *interface_array = NULL; + interfaces_interfaces_interface_element_t *interface_head = NULL; struct lyd_node *interfaces_node = srpc_ly_tree_get_child_leaf(parent_container, "interfaces"); if (interfaces_node == NULL) { @@ -62,12 +62,12 @@ static int interfaces_startup_store_interface(void* priv, const struct lyd_node* goto error_out; } - SRPLG_LOG_INF(PLUGIN_NAME, "Checking interface array"); - check_status = interfaces_check_interface(ctx, interface_array); + SRPLG_LOG_INF(PLUGIN_NAME, "Checking interface list"); + check_status = interfaces_check_interface(ctx, interface_head); switch (check_status) { case srpc_check_status_none: - SRPLG_LOG_ERR(PLUGIN_NAME, "Error loading current interface array"); + SRPLG_LOG_ERR(PLUGIN_NAME, "Error loading current interface list"); goto error_out; case srpc_check_status_error: SRPLG_LOG_ERR(PLUGIN_NAME, "Error loading current interface array"); @@ -75,7 +75,7 @@ static int interfaces_startup_store_interface(void* priv, const struct lyd_node* case srpc_check_status_non_existant: SRPLG_LOG_INF(PLUGIN_NAME, "Storing interface array"); - error = interfaces_store_interface(ctx, interface_array); + error = interfaces_store_interface(ctx, interface_head); if (error) { SRPLG_LOG_ERR(PLUGIN_NAME, "interfaces_store_interface() failed (%d)", error); goto error_out; From 2c5527a260271db641d16aa31025f7aa5d848c42 Mon Sep 17 00:00:00 2001 From: agardijan Date: Fri, 12 Aug 2022 14:17:26 +0200 Subject: [PATCH 016/247] interfaces-plugin: utarray not needed, utlist dep in api --- src/interfaces/src/plugin/api/interfaces/load.c | 1 + src/interfaces/src/plugin/api/interfaces/store.c | 1 + src/interfaces/src/plugin/startup/load.c | 1 - src/interfaces/src/plugin/startup/store.c | 1 - 4 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index 00b00147..cd646b03 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -1,4 +1,5 @@ #include "load.h" +#include "utlist.h" int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interfaces_interface_element_t** interface) { diff --git a/src/interfaces/src/plugin/api/interfaces/store.c b/src/interfaces/src/plugin/api/interfaces/store.c index 06dc1977..7bf50e0c 100644 --- a/src/interfaces/src/plugin/api/interfaces/store.c +++ b/src/interfaces/src/plugin/api/interfaces/store.c @@ -1,4 +1,5 @@ #include "store.h" +#include "utlist.h" int interfaces_store_interface(interfaces_ctx_t* ctx, const interfaces_interfaces_interface_element_t* interface) { diff --git a/src/interfaces/src/plugin/startup/load.c b/src/interfaces/src/plugin/startup/load.c index 3a09efbc..6e1f1fbf 100644 --- a/src/interfaces/src/plugin/startup/load.c +++ b/src/interfaces/src/plugin/startup/load.c @@ -1,7 +1,6 @@ #include "load.h" #include "plugin/common.h" #include "plugin/ly_tree.h" -#include "utlist.h" #include #include diff --git a/src/interfaces/src/plugin/startup/store.c b/src/interfaces/src/plugin/startup/store.c index 0df2aeb9..7a60d8b7 100644 --- a/src/interfaces/src/plugin/startup/store.c +++ b/src/interfaces/src/plugin/startup/store.c @@ -1,6 +1,5 @@ #include "store.h" #include "plugin/common.h" -#include "utlist.h" #include #include From 801c9d22ecadb7885a5f0bcab7abe158ad4dc804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 15 Aug 2022 20:53:37 +0200 Subject: [PATCH 017/247] interfaces-plugin: add helper link getter --- .../src/plugin/subscription/operational.c | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index f749a69c..8e1cefca 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -20,6 +20,7 @@ #include #include +static struct rtnl_link* interfaces_get_current_link(interfaces_ctx_t* ctx, sr_session_ctx_t* session, const char* xpath); static int interfaces_extract_interface_name(sr_session_ctx_t* session, const char* xpath, char* buffer, size_t buffer_size); int interfaces_subscription_operational_interfaces_interface_admin_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) @@ -700,6 +701,33 @@ int interfaces_subscription_operational_interfaces_interface(sr_session_ctx_t* s return error; } +static struct rtnl_link* interfaces_get_current_link(interfaces_ctx_t* ctx, sr_session_ctx_t* session, const char* xpath) +{ + int error = 0; + + const interfaces_nl_ctx_t* nl_ctx = &ctx->nl_ctx; + + // buffers + char interface_name_buffer[100] = { 0 }; + + // libnl + struct rtnl_link* link = NULL; + + // there needs to be an allocated link cache in memory + assert(ctx->nl_ctx.link_cache != NULL); + + // extract interface name + SRPC_SAFE_CALL_ERR(error, interfaces_extract_interface_name(session, xpath, interface_name_buffer, sizeof(interface_name_buffer)), error_out); + + // get link by name + SRPC_SAFE_CALL_PTR(link, rtnl_link_get_by_name(nl_ctx->link_cache, interface_name_buffer), error_out); + + return link; + +error_out: + return NULL; +} + static int interfaces_extract_interface_name(sr_session_ctx_t* session, const char* xpath, char* buffer, size_t buffer_size) { int error = 0; From 91348ff86cb46c08b601fbcd2e49fced22572f5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 15 Aug 2022 21:02:11 +0200 Subject: [PATCH 018/247] interfaces-plugin: add augmented nodes API --- src/interfaces/CMakeLists.txt | 4 + src/interfaces/src/plugin.c | 28 ++++ .../interface/carrier-delay/change.c | 48 ++++++ .../interface/carrier-delay/change.h | 10 ++ .../plugin/api/interfaces/interface/change.c | 66 ++++++++ .../plugin/api/interfaces/interface/change.h | 3 + .../interfaces/interface/dampening/change.c | 92 +++++++++++ .../interfaces/interface/dampening/change.h | 12 ++ .../dot1q-vlan/outer-tag/change.c | 48 ++++++ .../dot1q-vlan/outer-tag/change.h | 10 ++ .../dot1q-vlan/second-tag/change.c | 48 ++++++ .../dot1q-vlan/second-tag/change.h | 10 ++ src/interfaces/src/plugin/common.h | 26 +++ src/interfaces/src/plugin/ly_tree.c | 135 +++++++++++++++ src/interfaces/src/plugin/ly_tree.h | 26 +++ .../src/plugin/subscription/operational.c | 154 ++++++++++++++++++ .../src/plugin/subscription/operational.h | 7 + src/interfaces/src/plugin/types.h | 43 +++++ 18 files changed, 770 insertions(+) create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/carrier-delay/change.c create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/carrier-delay/change.h create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/dampening/change.c create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/dampening/change.h create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/outer-tag/change.c create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/outer-tag/change.h create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/second-tag/change.c create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/second-tag/change.h diff --git a/src/interfaces/CMakeLists.txt b/src/interfaces/CMakeLists.txt index e166733f..2fa6fcdc 100644 --- a/src/interfaces/CMakeLists.txt +++ b/src/interfaces/CMakeLists.txt @@ -24,6 +24,10 @@ set( src/plugin/api/interfaces/store.c src/plugin/api/interfaces/change.c src/plugin/api/interfaces/interface/change.c + src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/second-tag/change.c + src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/outer-tag/change.c + src/plugin/api/interfaces/interface/dampening/change.c + src/plugin/api/interfaces/interface/carrier-delay/change.c src/plugin.c ) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index f8f7654b..5a89075f 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -135,6 +135,34 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) INTERFACES_INTERFACES_INTERFACE_STATISTICS_OUT_ERRORS_YANG_PATH, interfaces_subscription_operational_interfaces_interface_statistics_out_errors, }, + { + INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_DISCARD_UNKNOWN_ENCAPS_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_statistics_in_discard_unknown_encaps, + }, + { + INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_CARRIER_TRANSITIONS_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_carrier_delay_carrier_transitions, + }, + { + INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_TIMER_RUNNING_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_carrier_delay_timer_running, + }, + { + INTERFACES_INTERFACES_INTERFACE_DAMPENING_PENALTY_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_dampening_penalty, + }, + { + INTERFACES_INTERFACES_INTERFACE_DAMPENING_SUPPRESSED_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_dampening_suppressed, + }, + { + INTERFACES_INTERFACES_INTERFACE_DAMPENING_TIME_REMAINING_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_dampening_time_remaining, + }, + { + INTERFACES_INTERFACES_INTERFACE_FORWARDING_MODE_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_forwarding_mode, + }, { INTERFACES_INTERFACES_INTERFACE_YANG_PATH, interfaces_subscription_operational_interfaces_interface, diff --git a/src/interfaces/src/plugin/api/interfaces/interface/carrier-delay/change.c b/src/interfaces/src/plugin/api/interfaces/interface/carrier-delay/change.c new file mode 100644 index 00000000..0160254f --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/carrier-delay/change.c @@ -0,0 +1,48 @@ +#include "change.h" +#include "plugin/common.h" + +#include + +int interfaces_interface_carrier_delay_change_up(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +int interfaces_interface_carrier_delay_change_down(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} diff --git a/src/interfaces/src/plugin/api/interfaces/interface/carrier-delay/change.h b/src/interfaces/src/plugin/api/interfaces/interface/carrier-delay/change.h new file mode 100644 index 00000000..94faedb6 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/carrier-delay/change.h @@ -0,0 +1,10 @@ +#ifndef INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_CARRIER_DELAY_CHANGE_H +#define INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_CARRIER_DELAY_CHANGE_H + +#include +#include + +int interfaces_interface_carrier_delay_change_up(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +int interfaces_interface_carrier_delay_change_down(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); + +#endif // INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_CARRIER_DELAY_CHANGE_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/api/interfaces/interface/change.c b/src/interfaces/src/plugin/api/interfaces/interface/change.c index 50a6aa29..6e77f6dd 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/change.c @@ -3,6 +3,72 @@ #include +int interfaces_interface_change_parent_interface(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +int interfaces_interface_change_max_frame_size(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +int interfaces_interface_change_loopback(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + int interfaces_interface_change_link_up_down_trap_enable(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) { int error = 0; diff --git a/src/interfaces/src/plugin/api/interfaces/interface/change.h b/src/interfaces/src/plugin/api/interfaces/interface/change.h index f9aa1e90..531a0a4c 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/change.h +++ b/src/interfaces/src/plugin/api/interfaces/interface/change.h @@ -4,6 +4,9 @@ #include #include +int interfaces_interface_change_parent_interface(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +int interfaces_interface_change_max_frame_size(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +int interfaces_interface_change_loopback(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); int interfaces_interface_change_link_up_down_trap_enable(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); int interfaces_interface_change_enabled(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); int interfaces_interface_change_type(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); diff --git a/src/interfaces/src/plugin/api/interfaces/interface/dampening/change.c b/src/interfaces/src/plugin/api/interfaces/interface/dampening/change.c new file mode 100644 index 00000000..1d19c74e --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/dampening/change.c @@ -0,0 +1,92 @@ +#include "change.h" +#include "plugin/common.h" + +#include + +int interfaces_interface_dampening_change_max_suppress_time(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +int interfaces_interface_dampening_change_suppress(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +int interfaces_interface_dampening_change_reuse(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +int interfaces_interface_dampening_change_half_life(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} diff --git a/src/interfaces/src/plugin/api/interfaces/interface/dampening/change.h b/src/interfaces/src/plugin/api/interfaces/interface/dampening/change.h new file mode 100644 index 00000000..22e7a76b --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/dampening/change.h @@ -0,0 +1,12 @@ +#ifndef INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_DAMPENING_CHANGE_H +#define INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_DAMPENING_CHANGE_H + +#include +#include + +int interfaces_interface_dampening_change_max_suppress_time(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +int interfaces_interface_dampening_change_suppress(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +int interfaces_interface_dampening_change_reuse(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +int interfaces_interface_dampening_change_half_life(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); + +#endif // INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_DAMPENING_CHANGE_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/outer-tag/change.c b/src/interfaces/src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/outer-tag/change.c new file mode 100644 index 00000000..bf909c58 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/outer-tag/change.c @@ -0,0 +1,48 @@ +#include "change.h" +#include "plugin/common.h" + +#include + +int interfaces_interface_encapsulation_dot1q_vlan_outer_tag_change_vlan_id(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +int interfaces_interface_encapsulation_dot1q_vlan_outer_tag_change_tag_type(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} diff --git a/src/interfaces/src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/outer-tag/change.h b/src/interfaces/src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/outer-tag/change.h new file mode 100644 index 00000000..7966fa9f --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/outer-tag/change.h @@ -0,0 +1,10 @@ +#ifndef INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_ENCAPSULATION_DOT1Q_VLAN_OUTER_TAG_CHANGE_H +#define INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_ENCAPSULATION_DOT1Q_VLAN_OUTER_TAG_CHANGE_H + +#include +#include + +int interfaces_interface_encapsulation_dot1q_vlan_outer_tag_change_vlan_id(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +int interfaces_interface_encapsulation_dot1q_vlan_outer_tag_change_tag_type(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); + +#endif // INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_ENCAPSULATION_DOT1Q_VLAN_OUTER_TAG_CHANGE_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/second-tag/change.c b/src/interfaces/src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/second-tag/change.c new file mode 100644 index 00000000..5feeccb6 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/second-tag/change.c @@ -0,0 +1,48 @@ +#include "change.h" +#include "plugin/common.h" + +#include + +int interfaces_interface_encapsulation_dot1q_vlan_second_tag_change_vlan_id(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +int interfaces_interface_encapsulation_dot1q_vlan_second_tag_change_tag_type(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} diff --git a/src/interfaces/src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/second-tag/change.h b/src/interfaces/src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/second-tag/change.h new file mode 100644 index 00000000..57be5706 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/second-tag/change.h @@ -0,0 +1,10 @@ +#ifndef INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_ENCAPSULATION_DOT1Q_VLAN_SECOND_TAG_CHANGE_H +#define INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_ENCAPSULATION_DOT1Q_VLAN_SECOND_TAG_CHANGE_H + +#include +#include + +int interfaces_interface_encapsulation_dot1q_vlan_second_tag_change_vlan_id(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +int interfaces_interface_encapsulation_dot1q_vlan_second_tag_change_tag_type(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); + +#endif // INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_ENCAPSULATION_DOT1Q_VLAN_SECOND_TAG_CHANGE_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/common.h b/src/interfaces/src/plugin/common.h index 1c5e145e..b1c9089d 100644 --- a/src/interfaces/src/plugin/common.h +++ b/src/interfaces/src/plugin/common.h @@ -59,7 +59,33 @@ #define INTERFACES_INTERFACES_INTERFACE_STATISTICS_OUT_MULTICAST_PKTS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_STATISTICS_YANG_PATH "/out-multicast-pkts" #define INTERFACES_INTERFACES_INTERFACE_STATISTICS_OUT_DISCARDS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_STATISTICS_YANG_PATH "/out-discards" #define INTERFACES_INTERFACES_INTERFACE_STATISTICS_OUT_ERRORS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_STATISTICS_YANG_PATH "/out-errors" +#define INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_DISCARD_UNKNOWN_ENCAPS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_STATISTICS_YANG_PATH "/in-discard-unknown-encaps" #define INTERFACES_INTERFACES_INTERFACE_STATISTICS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/statistics" +#define INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_DOWN_YANG_PATH INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_YANG_PATH "/down" +#define INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_UP_YANG_PATH INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_YANG_PATH "/up" +#define INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_CARRIER_TRANSITIONS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_YANG_PATH "/carrier-transitions" +#define INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_TIMER_RUNNING_YANG_PATH INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_YANG_PATH "/timer-running" +#define INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/carrier-delay" +#define INTERFACES_INTERFACES_INTERFACE_DAMPENING_HALF_LIFE_YANG_PATH INTERFACES_INTERFACES_INTERFACE_DAMPENING_YANG_PATH "/half-life" +#define INTERFACES_INTERFACES_INTERFACE_DAMPENING_REUSE_YANG_PATH INTERFACES_INTERFACES_INTERFACE_DAMPENING_YANG_PATH "/reuse" +#define INTERFACES_INTERFACES_INTERFACE_DAMPENING_SUPPRESS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_DAMPENING_YANG_PATH "/suppress" +#define INTERFACES_INTERFACES_INTERFACE_DAMPENING_MAX_SUPPRESS_TIME_YANG_PATH INTERFACES_INTERFACES_INTERFACE_DAMPENING_YANG_PATH "/max-suppress-time" +#define INTERFACES_INTERFACES_INTERFACE_DAMPENING_PENALTY_YANG_PATH INTERFACES_INTERFACES_INTERFACE_DAMPENING_YANG_PATH "/penalty" +#define INTERFACES_INTERFACES_INTERFACE_DAMPENING_SUPPRESSED_YANG_PATH INTERFACES_INTERFACES_INTERFACE_DAMPENING_YANG_PATH "/suppressed" +#define INTERFACES_INTERFACES_INTERFACE_DAMPENING_TIME_REMAINING_YANG_PATH INTERFACES_INTERFACES_INTERFACE_DAMPENING_YANG_PATH "/time-remaining" +#define INTERFACES_INTERFACES_INTERFACE_DAMPENING_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/dampening" +#define INTERFACES_INTERFACES_INTERFACE_ENCAPSULATION_DOT1Q_VLAN_OUTER_TAG_TAG_TYPE_YANG_PATH INTERFACES_INTERFACES_INTERFACE_ENCAPSULATION_DOT1Q_VLAN_OUTER_TAG_YANG_PATH "/tag-type" +#define INTERFACES_INTERFACES_INTERFACE_ENCAPSULATION_DOT1Q_VLAN_OUTER_TAG_VLAN_ID_YANG_PATH INTERFACES_INTERFACES_INTERFACE_ENCAPSULATION_DOT1Q_VLAN_OUTER_TAG_YANG_PATH "/vlan-id" +#define INTERFACES_INTERFACES_INTERFACE_ENCAPSULATION_DOT1Q_VLAN_OUTER_TAG_YANG_PATH INTERFACES_INTERFACES_INTERFACE_ENCAPSULATION_DOT1Q_VLAN_YANG_PATH "/outer-tag" +#define INTERFACES_INTERFACES_INTERFACE_ENCAPSULATION_DOT1Q_VLAN_SECOND_TAG_TAG_TYPE_YANG_PATH INTERFACES_INTERFACES_INTERFACE_ENCAPSULATION_DOT1Q_VLAN_SECOND_TAG_YANG_PATH "/tag-type" +#define INTERFACES_INTERFACES_INTERFACE_ENCAPSULATION_DOT1Q_VLAN_SECOND_TAG_VLAN_ID_YANG_PATH INTERFACES_INTERFACES_INTERFACE_ENCAPSULATION_DOT1Q_VLAN_SECOND_TAG_YANG_PATH "/vlan-id" +#define INTERFACES_INTERFACES_INTERFACE_ENCAPSULATION_DOT1Q_VLAN_SECOND_TAG_YANG_PATH INTERFACES_INTERFACES_INTERFACE_ENCAPSULATION_DOT1Q_VLAN_YANG_PATH "/second-tag" +#define INTERFACES_INTERFACES_INTERFACE_ENCAPSULATION_DOT1Q_VLAN_YANG_PATH INTERFACES_INTERFACES_INTERFACE_ENCAPSULATION_YANG_PATH "/dot1q-vlan" +#define INTERFACES_INTERFACES_INTERFACE_ENCAPSULATION_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/encapsulation" +#define INTERFACES_INTERFACES_INTERFACE_LOOPBACK_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/loopback" +#define INTERFACES_INTERFACES_INTERFACE_MAX_FRAME_SIZE_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/max-frame-size" +#define INTERFACES_INTERFACES_INTERFACE_FORWARDING_MODE_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/forwarding-mode" +#define INTERFACES_INTERFACES_INTERFACE_PARENT_INTERFACE_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/parent-interface" #define INTERFACES_INTERFACES_INTERFACE_YANG_PATH INTERFACES_INTERFACES_YANG_PATH "/interface" #define INTERFACES_INTERFACES_YANG_PATH "/ietf-interfaces:interfaces" diff --git a/src/interfaces/src/plugin/ly_tree.c b/src/interfaces/src/plugin/ly_tree.c index 6801f9c2..9afe3cc6 100644 --- a/src/interfaces/src/plugin/ly_tree.c +++ b/src/interfaces/src/plugin/ly_tree.c @@ -3,6 +3,11 @@ #include +int interfaces_ly_tree_create_interfaces_state_interface_name(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* name) +{ + return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "name", name); +} + int interfaces_ly_tree_create_interfaces(const struct ly_ctx* ly_ctx, struct lyd_node** interfaces_node) { return srpc_ly_tree_create_container(ly_ctx, NULL, interfaces_node, "interfaces"); @@ -14,11 +19,141 @@ int interfaces_ly_tree_create_interfaces_interface(const struct ly_ctx* ly_ctx, return srpc_ly_tree_create_list(ly_ctx, interfaces_node, interface_node, "interface", "name", name); } +int interfaces_ly_tree_create_interfaces_interface_parent_interface(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* parent_interface) +{ + return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "parent-interface", parent_interface); +} + +int interfaces_ly_tree_create_interfaces_interface_forwarding_mode(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* forwarding_mode) +{ + return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "forwarding-mode", forwarding_mode); +} + +int interfaces_ly_tree_create_interfaces_interface_max_frame_size(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* max_frame_size) +{ + return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "max-frame-size", max_frame_size); +} + +int interfaces_ly_tree_create_interfaces_interface_loopback(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* loopback) +{ + return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "loopback", loopback); +} + +int interfaces_ly_tree_create_interfaces_interface_encapsulation(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, struct lyd_node** encapsulation_node) +{ + return srpc_ly_tree_create_container(ly_ctx, interface_node, encapsulation_node, "encapsulation"); +} + +int interfaces_ly_tree_create_interfaces_interface_encapsulation_dot1q_vlan(const struct ly_ctx* ly_ctx, struct lyd_node* encapsulation_node, struct lyd_node** dot1q_vlan_node) +{ + return srpc_ly_tree_create_container(ly_ctx, encapsulation_node, dot1q_vlan_node, "dot1q-vlan"); +} + +int interfaces_ly_tree_create_interfaces_interface_encapsulation_dot1q_vlan_second_tag(const struct ly_ctx* ly_ctx, struct lyd_node* dot1q_vlan_node, struct lyd_node** second_tag_node) +{ + return srpc_ly_tree_create_container(ly_ctx, dot1q_vlan_node, second_tag_node, "second-tag"); +} + +int interfaces_ly_tree_create_interfaces_interface_encapsulation_dot1q_vlan_second_tag_vlan_id(const struct ly_ctx* ly_ctx, struct lyd_node* second_tag_node, const char* vlan_id) +{ + return srpc_ly_tree_create_leaf(ly_ctx, second_tag_node, NULL, "vlan-id", vlan_id); +} + +int interfaces_ly_tree_create_interfaces_interface_encapsulation_dot1q_vlan_second_tag_tag_type(const struct ly_ctx* ly_ctx, struct lyd_node* second_tag_node, const char* tag_type) +{ + return srpc_ly_tree_create_leaf(ly_ctx, second_tag_node, NULL, "tag-type", tag_type); +} + +int interfaces_ly_tree_create_interfaces_interface_encapsulation_dot1q_vlan_outer_tag(const struct ly_ctx* ly_ctx, struct lyd_node* dot1q_vlan_node, struct lyd_node** outer_tag_node) +{ + return srpc_ly_tree_create_container(ly_ctx, dot1q_vlan_node, outer_tag_node, "outer-tag"); +} + +int interfaces_ly_tree_create_interfaces_interface_encapsulation_dot1q_vlan_outer_tag_vlan_id(const struct ly_ctx* ly_ctx, struct lyd_node* outer_tag_node, const char* vlan_id) +{ + return srpc_ly_tree_create_leaf(ly_ctx, outer_tag_node, NULL, "vlan-id", vlan_id); +} + +int interfaces_ly_tree_create_interfaces_interface_encapsulation_dot1q_vlan_outer_tag_tag_type(const struct ly_ctx* ly_ctx, struct lyd_node* outer_tag_node, const char* tag_type) +{ + return srpc_ly_tree_create_leaf(ly_ctx, outer_tag_node, NULL, "tag-type", tag_type); +} + +int interfaces_ly_tree_create_interfaces_interface_dampening(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, struct lyd_node** dampening_node) +{ + return srpc_ly_tree_create_container(ly_ctx, interface_node, dampening_node, "dampening"); +} + +int interfaces_ly_tree_create_interfaces_interface_dampening_time_remaining(const struct ly_ctx* ly_ctx, struct lyd_node* dampening_node, const char* time_remaining) +{ + return srpc_ly_tree_create_leaf(ly_ctx, dampening_node, NULL, "time-remaining", time_remaining); +} + +int interfaces_ly_tree_create_interfaces_interface_dampening_suppressed(const struct ly_ctx* ly_ctx, struct lyd_node* dampening_node, const char* suppressed) +{ + return srpc_ly_tree_create_leaf(ly_ctx, dampening_node, NULL, "suppressed", suppressed); +} + +int interfaces_ly_tree_create_interfaces_interface_dampening_penalty(const struct ly_ctx* ly_ctx, struct lyd_node* dampening_node, const char* penalty) +{ + return srpc_ly_tree_create_leaf(ly_ctx, dampening_node, NULL, "penalty", penalty); +} + +int interfaces_ly_tree_create_interfaces_interface_dampening_max_suppress_time(const struct ly_ctx* ly_ctx, struct lyd_node* dampening_node, const char* max_suppress_time) +{ + return srpc_ly_tree_create_leaf(ly_ctx, dampening_node, NULL, "max-suppress-time", max_suppress_time); +} + +int interfaces_ly_tree_create_interfaces_interface_dampening_suppress(const struct ly_ctx* ly_ctx, struct lyd_node* dampening_node, const char* suppress) +{ + return srpc_ly_tree_create_leaf(ly_ctx, dampening_node, NULL, "suppress", suppress); +} + +int interfaces_ly_tree_create_interfaces_interface_dampening_reuse(const struct ly_ctx* ly_ctx, struct lyd_node* dampening_node, const char* reuse) +{ + return srpc_ly_tree_create_leaf(ly_ctx, dampening_node, NULL, "reuse", reuse); +} + +int interfaces_ly_tree_create_interfaces_interface_dampening_half_life(const struct ly_ctx* ly_ctx, struct lyd_node* dampening_node, const char* half_life) +{ + return srpc_ly_tree_create_leaf(ly_ctx, dampening_node, NULL, "half-life", half_life); +} + +int interfaces_ly_tree_create_interfaces_interface_carrier_delay(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, struct lyd_node** carrier_delay_node) +{ + return srpc_ly_tree_create_container(ly_ctx, interface_node, carrier_delay_node, "carrier-delay"); +} + +int interfaces_ly_tree_create_interfaces_interface_carrier_delay_timer_running(const struct ly_ctx* ly_ctx, struct lyd_node* carrier_delay_node, const char* timer_running) +{ + return srpc_ly_tree_create_leaf(ly_ctx, carrier_delay_node, NULL, "timer-running", timer_running); +} + +int interfaces_ly_tree_create_interfaces_interface_carrier_delay_carrier_transitions(const struct ly_ctx* ly_ctx, struct lyd_node* carrier_delay_node, const char* carrier_transitions) +{ + return srpc_ly_tree_create_leaf(ly_ctx, carrier_delay_node, NULL, "carrier-transitions", carrier_transitions); +} + +int interfaces_ly_tree_create_interfaces_interface_carrier_delay_up(const struct ly_ctx* ly_ctx, struct lyd_node* carrier_delay_node, const char* up) +{ + return srpc_ly_tree_create_leaf(ly_ctx, carrier_delay_node, NULL, "up", up); +} + +int interfaces_ly_tree_create_interfaces_interface_carrier_delay_down(const struct ly_ctx* ly_ctx, struct lyd_node* carrier_delay_node, const char* down) +{ + return srpc_ly_tree_create_leaf(ly_ctx, carrier_delay_node, NULL, "down", down); +} + int interfaces_ly_tree_create_interfaces_interface_statistics(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, struct lyd_node** statistics_node) { return srpc_ly_tree_create_container(ly_ctx, interface_node, statistics_node, "statistics"); } +int interfaces_ly_tree_create_interfaces_interface_statistics_in_discard_unknown_encaps(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_discard_unknown_encaps) +{ + return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "in-discard-unknown-encaps", in_discard_unknown_encaps); +} + int interfaces_ly_tree_create_interfaces_interface_statistics_out_errors(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_errors) { return srpc_ly_tree_create_leaf(ly_ctx, statistics_node, NULL, "out-errors", out_errors); diff --git a/src/interfaces/src/plugin/ly_tree.h b/src/interfaces/src/plugin/ly_tree.h index f86d99af..f14b0ffd 100644 --- a/src/interfaces/src/plugin/ly_tree.h +++ b/src/interfaces/src/plugin/ly_tree.h @@ -5,7 +5,33 @@ int interfaces_ly_tree_create_interfaces(const struct ly_ctx* ly_ctx, struct lyd_node** interfaces_node); int interfaces_ly_tree_create_interfaces_interface(const struct ly_ctx* ly_ctx, struct lyd_node* interfaces_node, struct lyd_node** interface_node, const char* name); +int interfaces_ly_tree_create_interfaces_interface_parent_interface(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* parent_interface); +int interfaces_ly_tree_create_interfaces_interface_forwarding_mode(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* forwarding_mode); +int interfaces_ly_tree_create_interfaces_interface_max_frame_size(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* max_frame_size); +int interfaces_ly_tree_create_interfaces_interface_loopback(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* loopback); +int interfaces_ly_tree_create_interfaces_interface_encapsulation(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, struct lyd_node** encapsulation_node); +int interfaces_ly_tree_create_interfaces_interface_encapsulation_dot1q_vlan(const struct ly_ctx* ly_ctx, struct lyd_node* encapsulation_node, struct lyd_node** dot1q_vlan_node); +int interfaces_ly_tree_create_interfaces_interface_encapsulation_dot1q_vlan_second_tag(const struct ly_ctx* ly_ctx, struct lyd_node* dot1q_vlan_node, struct lyd_node** second_tag_node); +int interfaces_ly_tree_create_interfaces_interface_encapsulation_dot1q_vlan_second_tag_vlan_id(const struct ly_ctx* ly_ctx, struct lyd_node* second_tag_node, const char* vlan_id); +int interfaces_ly_tree_create_interfaces_interface_encapsulation_dot1q_vlan_second_tag_tag_type(const struct ly_ctx* ly_ctx, struct lyd_node* second_tag_node, const char* tag_type); +int interfaces_ly_tree_create_interfaces_interface_encapsulation_dot1q_vlan_outer_tag(const struct ly_ctx* ly_ctx, struct lyd_node* dot1q_vlan_node, struct lyd_node** outer_tag_node); +int interfaces_ly_tree_create_interfaces_interface_encapsulation_dot1q_vlan_outer_tag_vlan_id(const struct ly_ctx* ly_ctx, struct lyd_node* outer_tag_node, const char* vlan_id); +int interfaces_ly_tree_create_interfaces_interface_encapsulation_dot1q_vlan_outer_tag_tag_type(const struct ly_ctx* ly_ctx, struct lyd_node* outer_tag_node, const char* tag_type); +int interfaces_ly_tree_create_interfaces_interface_dampening(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, struct lyd_node** dampening_node); +int interfaces_ly_tree_create_interfaces_interface_dampening_time_remaining(const struct ly_ctx* ly_ctx, struct lyd_node* dampening_node, const char* time_remaining); +int interfaces_ly_tree_create_interfaces_interface_dampening_suppressed(const struct ly_ctx* ly_ctx, struct lyd_node* dampening_node, const char* suppressed); +int interfaces_ly_tree_create_interfaces_interface_dampening_penalty(const struct ly_ctx* ly_ctx, struct lyd_node* dampening_node, const char* penalty); +int interfaces_ly_tree_create_interfaces_interface_dampening_max_suppress_time(const struct ly_ctx* ly_ctx, struct lyd_node* dampening_node, const char* max_suppress_time); +int interfaces_ly_tree_create_interfaces_interface_dampening_suppress(const struct ly_ctx* ly_ctx, struct lyd_node* dampening_node, const char* suppress); +int interfaces_ly_tree_create_interfaces_interface_dampening_reuse(const struct ly_ctx* ly_ctx, struct lyd_node* dampening_node, const char* reuse); +int interfaces_ly_tree_create_interfaces_interface_dampening_half_life(const struct ly_ctx* ly_ctx, struct lyd_node* dampening_node, const char* half_life); +int interfaces_ly_tree_create_interfaces_interface_carrier_delay(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, struct lyd_node** carrier_delay_node); +int interfaces_ly_tree_create_interfaces_interface_carrier_delay_timer_running(const struct ly_ctx* ly_ctx, struct lyd_node* carrier_delay_node, const char* timer_running); +int interfaces_ly_tree_create_interfaces_interface_carrier_delay_carrier_transitions(const struct ly_ctx* ly_ctx, struct lyd_node* carrier_delay_node, const char* carrier_transitions); +int interfaces_ly_tree_create_interfaces_interface_carrier_delay_up(const struct ly_ctx* ly_ctx, struct lyd_node* carrier_delay_node, const char* up); +int interfaces_ly_tree_create_interfaces_interface_carrier_delay_down(const struct ly_ctx* ly_ctx, struct lyd_node* carrier_delay_node, const char* down); int interfaces_ly_tree_create_interfaces_interface_statistics(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, struct lyd_node** statistics_node); +int interfaces_ly_tree_create_interfaces_interface_statistics_in_discard_unknown_encaps(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* in_discard_unknown_encaps); int interfaces_ly_tree_create_interfaces_interface_statistics_out_errors(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_errors); int interfaces_ly_tree_create_interfaces_interface_statistics_out_discards(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_discards); int interfaces_ly_tree_create_interfaces_interface_statistics_out_multicast_pkts(const struct ly_ctx* ly_ctx, struct lyd_node* statistics_node, const char* out_multicast_pkts); diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index f749a69c..db0e82c8 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -640,6 +640,160 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_erro return error; } +int interfaces_subscription_operational_interfaces_interface_statistics_in_discard_unknown_encaps(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_carrier_delay_carrier_transitions(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_carrier_delay_timer_running(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_dampening_penalty(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_dampening_suppressed(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_dampening_time_remaining(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_forwarding_mode(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + int interfaces_subscription_operational_interfaces_interface(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; diff --git a/src/interfaces/src/plugin/subscription/operational.h b/src/interfaces/src/plugin/subscription/operational.h index c20d908f..8c8c4a29 100644 --- a/src/interfaces/src/plugin/subscription/operational.h +++ b/src/interfaces/src/plugin/subscription/operational.h @@ -25,6 +25,13 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_broa int interfaces_subscription_operational_interfaces_interface_statistics_out_multicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); int interfaces_subscription_operational_interfaces_interface_statistics_out_discards(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); int interfaces_subscription_operational_interfaces_interface_statistics_out_errors(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_statistics_in_discard_unknown_encaps(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_carrier_delay_carrier_transitions(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_carrier_delay_timer_running(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_dampening_penalty(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_dampening_suppressed(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_dampening_time_remaining(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_forwarding_mode(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); int interfaces_subscription_operational_interfaces_interface(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); #endif // INTERFACES_PLUGIN_SUBSCRIPTION_OPERATIONAL_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/types.h b/src/interfaces/src/plugin/types.h index 6b8ebda2..fbb877ec 100644 --- a/src/interfaces/src/plugin/types.h +++ b/src/interfaces/src/plugin/types.h @@ -5,6 +5,12 @@ #include // typedefs +typedef struct interfaces_interfaces_interface_carrier_delay interfaces_interfaces_interface_carrier_delay_t; +typedef struct interfaces_interfaces_interface_dampening interfaces_interfaces_interface_dampening_t; +typedef struct interfaces_interfaces_interface_encapsulation_dot1q_vlan_outer_tag interfaces_interfaces_interface_encapsulation_dot1q_vlan_outer_tag_t; +typedef struct interfaces_interfaces_interface_encapsulation_dot1q_vlan_second_tag interfaces_interfaces_interface_encapsulation_dot1q_vlan_second_tag_t; +typedef struct interfaces_interfaces_interface_encapsulation_dot1q_vlan interfaces_interfaces_interface_encapsulation_dot1q_vlan_t; +typedef struct interfaces_interfaces_interface_encapsulation interfaces_interfaces_interface_encapsulation_t; typedef struct interfaces_interfaces_interface interfaces_interfaces_interface_t; typedef struct interfaces_interfaces_interface_element interfaces_interfaces_interface_element_t; typedef struct interfaces_interfaces interfaces_interfaces_t; @@ -16,12 +22,49 @@ enum interfaces_interfaces_interface_link_up_down_trap_enable { typedef enum interfaces_interfaces_interface_link_up_down_trap_enable interfaces_interfaces_interface_link_up_down_trap_enable_t; +struct interfaces_interfaces_interface_carrier_delay { + uint32_t down; + uint32_t up; +}; + +struct interfaces_interfaces_interface_dampening { + uint32_t half_life; + uint32_t reuse; + uint32_t suppress; + uint32_t max_suppress_time; +}; + +struct interfaces_interfaces_interface_encapsulation_dot1q_vlan_outer_tag { + char* tag_type; + uint16_t vlan_id; +}; + +struct interfaces_interfaces_interface_encapsulation_dot1q_vlan_second_tag { + char* tag_type; + uint16_t vlan_id; +}; + +struct interfaces_interfaces_interface_encapsulation_dot1q_vlan { + interfaces_interfaces_interface_encapsulation_dot1q_vlan_outer_tag_t outer_tag; + interfaces_interfaces_interface_encapsulation_dot1q_vlan_second_tag_t second_tag; +}; + +struct interfaces_interfaces_interface_encapsulation { + interfaces_interfaces_interface_encapsulation_dot1q_vlan_t dot1q_vlan; +}; + struct interfaces_interfaces_interface { char* name; char* description; char* type; uint8_t enabled; interfaces_interfaces_interface_link_up_down_trap_enable_t link_up_down_trap_enable; + interfaces_interfaces_interface_carrier_delay_t carrier_delay; + interfaces_interfaces_interface_dampening_t dampening; + interfaces_interfaces_interface_encapsulation_t encapsulation; + char* loopback; + uint32_t max_frame_size; + char* parent_interface; }; struct interfaces_interfaces_interface_element { From a7d00b43d0f5b8502750c3a051bb84153bc72e4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 15 Aug 2022 21:06:42 +0200 Subject: [PATCH 019/247] interfaces-plugin: comment invalid operational paths for now --- src/interfaces/src/plugin.c | 56 ++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index 5a89075f..a5c5b0a1 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -135,34 +135,34 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) INTERFACES_INTERFACES_INTERFACE_STATISTICS_OUT_ERRORS_YANG_PATH, interfaces_subscription_operational_interfaces_interface_statistics_out_errors, }, - { - INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_DISCARD_UNKNOWN_ENCAPS_YANG_PATH, - interfaces_subscription_operational_interfaces_interface_statistics_in_discard_unknown_encaps, - }, - { - INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_CARRIER_TRANSITIONS_YANG_PATH, - interfaces_subscription_operational_interfaces_interface_carrier_delay_carrier_transitions, - }, - { - INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_TIMER_RUNNING_YANG_PATH, - interfaces_subscription_operational_interfaces_interface_carrier_delay_timer_running, - }, - { - INTERFACES_INTERFACES_INTERFACE_DAMPENING_PENALTY_YANG_PATH, - interfaces_subscription_operational_interfaces_interface_dampening_penalty, - }, - { - INTERFACES_INTERFACES_INTERFACE_DAMPENING_SUPPRESSED_YANG_PATH, - interfaces_subscription_operational_interfaces_interface_dampening_suppressed, - }, - { - INTERFACES_INTERFACES_INTERFACE_DAMPENING_TIME_REMAINING_YANG_PATH, - interfaces_subscription_operational_interfaces_interface_dampening_time_remaining, - }, - { - INTERFACES_INTERFACES_INTERFACE_FORWARDING_MODE_YANG_PATH, - interfaces_subscription_operational_interfaces_interface_forwarding_mode, - }, + // { + // INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_DISCARD_UNKNOWN_ENCAPS_YANG_PATH, + // interfaces_subscription_operational_interfaces_interface_statistics_in_discard_unknown_encaps, + // }, + // { + // INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_CARRIER_TRANSITIONS_YANG_PATH, + // interfaces_subscription_operational_interfaces_interface_carrier_delay_carrier_transitions, + // }, + // { + // INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_TIMER_RUNNING_YANG_PATH, + // interfaces_subscription_operational_interfaces_interface_carrier_delay_timer_running, + // }, + // { + // INTERFACES_INTERFACES_INTERFACE_DAMPENING_PENALTY_YANG_PATH, + // interfaces_subscription_operational_interfaces_interface_dampening_penalty, + // }, + // { + // INTERFACES_INTERFACES_INTERFACE_DAMPENING_SUPPRESSED_YANG_PATH, + // interfaces_subscription_operational_interfaces_interface_dampening_suppressed, + // }, + // { + // INTERFACES_INTERFACES_INTERFACE_DAMPENING_TIME_REMAINING_YANG_PATH, + // interfaces_subscription_operational_interfaces_interface_dampening_time_remaining, + // }, + // { + // INTERFACES_INTERFACES_INTERFACE_FORWARDING_MODE_YANG_PATH, + // interfaces_subscription_operational_interfaces_interface_forwarding_mode, + // }, { INTERFACES_INTERFACES_INTERFACE_YANG_PATH, interfaces_subscription_operational_interfaces_interface, From a035d530e6a48ad0c70a50a045523cf108b07711 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Wed, 17 Aug 2022 17:36:57 +0200 Subject: [PATCH 020/247] interfaces-plugin: simplify getting link by name --- .../src/plugin/subscription/operational.c | 60 ++++--------------- 1 file changed, 13 insertions(+), 47 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 82d26254..6e64c6e5 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -52,10 +52,6 @@ int interfaces_subscription_operational_interfaces_interface_oper_status(sr_sess // context const struct ly_ctx* ly_ctx = NULL; interfaces_ctx_t* ctx = private_data; - interfaces_nl_ctx_t* nl_ctx = &ctx->nl_ctx; - - // buffers - char interface_name_buffer[100] = { 0 }; // libnl struct rtnl_link* link = NULL; @@ -71,23 +67,17 @@ int interfaces_subscription_operational_interfaces_interface_oper_status(sr_sess }; // there needs to be an allocated link cache in memory - assert(ctx->nl_ctx.link_cache != NULL); assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "interface") == 0); - // extract interface name - SRPC_SAFE_CALL_ERR(error, interfaces_extract_interface_name(session, request_xpath, interface_name_buffer, sizeof(interface_name_buffer)), error_out); - - // get link by name - SRPC_SAFE_CALL_PTR(link, rtnl_link_get_by_name(nl_ctx->link_cache, interface_name_buffer), error_out); - - SRPLG_LOG_INF(PLUGIN_NAME, "Getting oper-status(%s)", interface_name_buffer); + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); // get oper status const uint8_t oper_status = rtnl_link_get_operstate(link); const char* oper_status_str = operstate_map[oper_status]; - SRPLG_LOG_INF(PLUGIN_NAME, "oper-status(%s) = %s", interface_name_buffer, oper_status_str); + SRPLG_LOG_INF(PLUGIN_NAME, "oper-status(%s) = %s", rtnl_link_get_name(link), oper_status_str); // add oper-status node SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_oper_status(ly_ctx, *parent, oper_status_str), error_out); @@ -130,27 +120,19 @@ int interfaces_subscription_operational_interfaces_interface_if_index(sr_session // context const struct ly_ctx* ly_ctx = NULL; interfaces_ctx_t* ctx = private_data; - interfaces_nl_ctx_t* nl_ctx = &ctx->nl_ctx; // buffers - char interface_name_buffer[100] = { 0 }; char ifindex_buffer[100] = { 0 }; // libnl struct rtnl_link* link = NULL; // there needs to be an allocated link cache in memory - assert(ctx->nl_ctx.link_cache != NULL); assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "interface") == 0); - // extract interface name - SRPC_SAFE_CALL_ERR(error, interfaces_extract_interface_name(session, request_xpath, interface_name_buffer, sizeof(interface_name_buffer)), error_out); - - // get link by name - SRPC_SAFE_CALL_PTR(link, rtnl_link_get_by_name(nl_ctx->link_cache, interface_name_buffer), error_out); - - SRPLG_LOG_INF(PLUGIN_NAME, "Getting if-index(%s)", interface_name_buffer); + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); // get if-index const int ifindex = rtnl_link_get_ifindex(link); @@ -161,7 +143,7 @@ int interfaces_subscription_operational_interfaces_interface_if_index(sr_session goto error_out; } - SRPLG_LOG_INF(PLUGIN_NAME, "if-index(%s) = %s", interface_name_buffer, ifindex_buffer); + SRPLG_LOG_INF(PLUGIN_NAME, "if-index(%s) = %s", rtnl_link_get_name(link), ifindex_buffer); // add ifindex node SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_if_index(ly_ctx, *parent, ifindex_buffer), error_out); @@ -184,10 +166,8 @@ int interfaces_subscription_operational_interfaces_interface_phys_address(sr_ses // context const struct ly_ctx* ly_ctx = NULL; interfaces_ctx_t* ctx = private_data; - interfaces_nl_ctx_t* nl_ctx = &ctx->nl_ctx; // buffers - char interface_name_buffer[100] = { 0 }; char phys_address_buffer[100] = { 0 }; // libnl @@ -195,23 +175,17 @@ int interfaces_subscription_operational_interfaces_interface_phys_address(sr_ses struct nl_addr* addr = NULL; // there needs to be an allocated link cache in memory - assert(ctx->nl_ctx.link_cache != NULL); assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "interface") == 0); - // extract interface name - SRPC_SAFE_CALL_ERR(error, interfaces_extract_interface_name(session, request_xpath, interface_name_buffer, sizeof(interface_name_buffer)), error_out); - - // get link by name - SRPC_SAFE_CALL_PTR(link, rtnl_link_get_by_name(nl_ctx->link_cache, interface_name_buffer), error_out); - - SRPLG_LOG_INF(PLUGIN_NAME, "Getting phys-address(%s)", interface_name_buffer); + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); // get phys-address SRPC_SAFE_CALL_PTR(addr, rtnl_link_get_addr(link), error_out); SRPC_SAFE_CALL_PTR(error_ptr, nl_addr2str(addr, phys_address_buffer, sizeof(phys_address_buffer)), error_out); - SRPLG_LOG_INF(PLUGIN_NAME, "phys-address(%s) = %s", interface_name_buffer, phys_address_buffer); + SRPLG_LOG_INF(PLUGIN_NAME, "phys-address(%s) = %s", rtnl_link_get_name(link), phys_address_buffer); // add phys-address node SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_phys_address(ly_ctx, *parent, phys_address_buffer), error_out); @@ -278,10 +252,8 @@ int interfaces_subscription_operational_interfaces_interface_speed(sr_session_ct // context const struct ly_ctx* ly_ctx = NULL; interfaces_ctx_t* ctx = private_data; - interfaces_nl_ctx_t* nl_ctx = &ctx->nl_ctx; // buffers - char interface_name_buffer[100] = { 0 }; char speed_buffer[100] = { 0 }; // libnl @@ -290,17 +262,11 @@ int interfaces_subscription_operational_interfaces_interface_speed(sr_session_ct struct rtnl_tc* tc = NULL; // there needs to be an allocated link cache in memory - assert(ctx->nl_ctx.link_cache != NULL); assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "interface") == 0); - // extract interface name - SRPC_SAFE_CALL_ERR(error, interfaces_extract_interface_name(session, request_xpath, interface_name_buffer, sizeof(interface_name_buffer)), error_out); - - // get link by name - SRPC_SAFE_CALL_PTR(link, rtnl_link_get_by_name(nl_ctx->link_cache, interface_name_buffer), error_out); - - SRPLG_LOG_INF(PLUGIN_NAME, "Getting speed(%s)", interface_name_buffer); + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); qdisc = rtnl_qdisc_alloc(); @@ -316,7 +282,7 @@ int interfaces_subscription_operational_interfaces_interface_speed(sr_session_ct goto error_out; } - SRPLG_LOG_INF(PLUGIN_NAME, "speed(%s) = %s", interface_name_buffer, speed_buffer); + SRPLG_LOG_INF(PLUGIN_NAME, "speed(%s) = %s", rtnl_link_get_name(link), speed_buffer); // add phys-address node SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_speed(ly_ctx, *parent, speed_buffer), error_out); @@ -868,7 +834,7 @@ static struct rtnl_link* interfaces_get_current_link(interfaces_ctx_t* ctx, sr_s struct rtnl_link* link = NULL; // there needs to be an allocated link cache in memory - assert(ctx->nl_ctx.link_cache != NULL); + assert(nl_ctx->link_cache != NULL); // extract interface name SRPC_SAFE_CALL_ERR(error, interfaces_extract_interface_name(session, xpath, interface_name_buffer, sizeof(interface_name_buffer)), error_out); From f27755be89b1c9b67f42e37de363d976f0c63be2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Wed, 17 Aug 2022 18:11:05 +0200 Subject: [PATCH 021/247] interfaces-plugin: implement operational packet stats --- .../src/plugin/subscription/operational.c | 139 +++++++++++++++--- 1 file changed, 115 insertions(+), 24 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 6e64c6e5..398715b9 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -324,16 +324,38 @@ int interfaces_subscription_operational_interfaces_interface_statistics_disconti int interfaces_subscription_operational_interfaces_interface_statistics_in_octets(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + + // context const struct ly_ctx* ly_ctx = NULL; + interfaces_ctx_t* ctx = private_data; - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } + // buffers + char in_octets_buffer[100] = { 0 }; + + // libnl + struct rtnl_link* link = NULL; + + // there needs to be an allocated link cache in memory + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + + // get in-octets + const uint64_t in_octets = rtnl_link_get_stat(link, RTNL_LINK_RX_BYTES); + + error = snprintf(in_octets_buffer, sizeof(in_octets_buffer), "%lu", in_octets); + if (error < 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); + goto error_out; } + SRPLG_LOG_INF(PLUGIN_NAME, "in-octets(%s) = %s", rtnl_link_get_name(link), in_octets_buffer); + + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_in_octets(ly_ctx, *parent, in_octets_buffer), error_out); + + error = 0; goto out; error_out: @@ -346,16 +368,41 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_octet int interfaces_subscription_operational_interfaces_interface_statistics_in_unicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + + // context const struct ly_ctx* ly_ctx = NULL; + interfaces_ctx_t* ctx = private_data; - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } + // buffers + char in_unicast_pkts_buffer[100] = { 0 }; + + // libnl + struct rtnl_link* link = NULL; + + // there needs to be an allocated link cache in memory + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + + // get in-octets + const uint64_t in_pkts = rtnl_link_get_stat(link, RTNL_LINK_RX_PACKETS); + const uint64_t in_broadcast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_INBCASTPKTS); + const uint64_t in_multicast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_INMCASTPKTS); + const uint64_t in_unicast_pkts = in_pkts - in_broadcast_pkts - in_multicast_pkts; + + error = snprintf(in_unicast_pkts_buffer, sizeof(in_unicast_pkts_buffer), "%lu", in_unicast_pkts); + if (error < 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); + goto error_out; } + SRPLG_LOG_INF(PLUGIN_NAME, "in-octets(%s) = %s", rtnl_link_get_name(link), in_unicast_pkts_buffer); + + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_in_unicast_pkts(ly_ctx, *parent, in_unicast_pkts_buffer), error_out); + + error = 0; goto out; error_out: @@ -368,16 +415,38 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_unica int interfaces_subscription_operational_interfaces_interface_statistics_in_broadcast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + + // context const struct ly_ctx* ly_ctx = NULL; + interfaces_ctx_t* ctx = private_data; - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } + // buffers + char in_broadcast_pkts_buffer[100] = { 0 }; + + // libnl + struct rtnl_link* link = NULL; + + // there needs to be an allocated link cache in memory + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + + // get in-octets + const uint64_t in_broadcast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_INBCASTPKTS); + + error = snprintf(in_broadcast_pkts_buffer, sizeof(in_broadcast_pkts_buffer), "%lu", in_broadcast_pkts); + if (error < 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); + goto error_out; } + SRPLG_LOG_INF(PLUGIN_NAME, "in-octets(%s) = %s", rtnl_link_get_name(link), in_broadcast_pkts_buffer); + + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_in_broadcast_pkts(ly_ctx, *parent, in_broadcast_pkts_buffer), error_out); + + error = 0; goto out; error_out: @@ -390,16 +459,38 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_broad int interfaces_subscription_operational_interfaces_interface_statistics_in_multicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + + // context const struct ly_ctx* ly_ctx = NULL; + interfaces_ctx_t* ctx = private_data; - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } + // buffers + char in_multicast_pkts_buffer[100] = { 0 }; + + // libnl + struct rtnl_link* link = NULL; + + // there needs to be an allocated link cache in memory + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + + // get in-octets + const uint64_t in_multicast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_INMCASTPKTS); + + error = snprintf(in_multicast_pkts_buffer, sizeof(in_multicast_pkts_buffer), "%lu", in_multicast_pkts); + if (error < 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); + goto error_out; } + SRPLG_LOG_INF(PLUGIN_NAME, "in-octets(%s) = %s", rtnl_link_get_name(link), in_multicast_pkts_buffer); + + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_in_multicast_pkts(ly_ctx, *parent, in_multicast_pkts_buffer), error_out); + + error = 0; goto out; error_out: From 0020eb83979543d01900d06550377678f667d4e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Wed, 17 Aug 2022 18:11:18 +0200 Subject: [PATCH 022/247] interfaces-plugin: implement in-discards leaf --- .../src/plugin/subscription/operational.c | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 398715b9..bce0ffe5 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -503,16 +503,38 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_multi int interfaces_subscription_operational_interfaces_interface_statistics_in_discards(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + + // context const struct ly_ctx* ly_ctx = NULL; + interfaces_ctx_t* ctx = private_data; - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } + // buffers + char in_multicast_pkts_buffer[100] = { 0 }; + + // libnl + struct rtnl_link* link = NULL; + + // there needs to be an allocated link cache in memory + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + + // get in-octets + const uint64_t in_multicast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_INMCASTPKTS); + + error = snprintf(in_multicast_pkts_buffer, sizeof(in_multicast_pkts_buffer), "%lu", in_multicast_pkts); + if (error < 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); + goto error_out; } + SRPLG_LOG_INF(PLUGIN_NAME, "in-octets(%s) = %s", rtnl_link_get_name(link), in_multicast_pkts_buffer); + + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_in_multicast_pkts(ly_ctx, *parent, in_multicast_pkts_buffer), error_out); + + error = 0; goto out; error_out: From cce5a5e5bb20bb6dfa0d4cc562529e5cb5c7b112 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Wed, 17 Aug 2022 18:12:21 +0200 Subject: [PATCH 023/247] interfaces-plugin: fix in-discards leaf --- .../src/plugin/subscription/operational.c | 44 ++++++++++++++----- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index bce0ffe5..13cb56c0 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -509,7 +509,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_disca interfaces_ctx_t* ctx = private_data; // buffers - char in_multicast_pkts_buffer[100] = { 0 }; + char in_discards_buffer[100] = { 0 }; // libnl struct rtnl_link* link = NULL; @@ -522,17 +522,17 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_disca SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); // get in-octets - const uint64_t in_multicast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_INMCASTPKTS); + const uint64_t in_discards = rtnl_link_get_stat(link, RTNL_LINK_RX_DROPPED); - error = snprintf(in_multicast_pkts_buffer, sizeof(in_multicast_pkts_buffer), "%lu", in_multicast_pkts); + error = snprintf(in_discards_buffer, sizeof(in_discards_buffer), "%lu", in_discards); if (error < 0) { SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); goto error_out; } - SRPLG_LOG_INF(PLUGIN_NAME, "in-octets(%s) = %s", rtnl_link_get_name(link), in_multicast_pkts_buffer); + SRPLG_LOG_INF(PLUGIN_NAME, "in-octets(%s) = %s", rtnl_link_get_name(link), in_discards_buffer); - SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_in_multicast_pkts(ly_ctx, *parent, in_multicast_pkts_buffer), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_in_multicast_pkts(ly_ctx, *parent, in_discards_buffer), error_out); error = 0; goto out; @@ -547,16 +547,38 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_disca int interfaces_subscription_operational_interfaces_interface_statistics_in_errors(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + + // context const struct ly_ctx* ly_ctx = NULL; + interfaces_ctx_t* ctx = private_data; - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } + // buffers + char in_multicast_pkts_buffer[100] = { 0 }; + + // libnl + struct rtnl_link* link = NULL; + + // there needs to be an allocated link cache in memory + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + + // get in-octets + const uint64_t in_multicast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_INMCASTPKTS); + + error = snprintf(in_multicast_pkts_buffer, sizeof(in_multicast_pkts_buffer), "%lu", in_multicast_pkts); + if (error < 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); + goto error_out; } + SRPLG_LOG_INF(PLUGIN_NAME, "in-octets(%s) = %s", rtnl_link_get_name(link), in_multicast_pkts_buffer); + + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_in_multicast_pkts(ly_ctx, *parent, in_multicast_pkts_buffer), error_out); + + error = 0; goto out; error_out: From 5d760d17f889725b6c030ca843b4bcab2a143642 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Wed, 17 Aug 2022 18:14:11 +0200 Subject: [PATCH 024/247] interfaces-plugin: fix in-errors leaf --- .../src/plugin/subscription/operational.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 13cb56c0..2be589a8 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -398,7 +398,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_unica goto error_out; } - SRPLG_LOG_INF(PLUGIN_NAME, "in-octets(%s) = %s", rtnl_link_get_name(link), in_unicast_pkts_buffer); + SRPLG_LOG_INF(PLUGIN_NAME, "in-unicast-pkts(%s) = %s", rtnl_link_get_name(link), in_unicast_pkts_buffer); SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_in_unicast_pkts(ly_ctx, *parent, in_unicast_pkts_buffer), error_out); @@ -442,7 +442,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_broad goto error_out; } - SRPLG_LOG_INF(PLUGIN_NAME, "in-octets(%s) = %s", rtnl_link_get_name(link), in_broadcast_pkts_buffer); + SRPLG_LOG_INF(PLUGIN_NAME, "in-broadcast-pkts(%s) = %s", rtnl_link_get_name(link), in_broadcast_pkts_buffer); SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_in_broadcast_pkts(ly_ctx, *parent, in_broadcast_pkts_buffer), error_out); @@ -486,7 +486,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_multi goto error_out; } - SRPLG_LOG_INF(PLUGIN_NAME, "in-octets(%s) = %s", rtnl_link_get_name(link), in_multicast_pkts_buffer); + SRPLG_LOG_INF(PLUGIN_NAME, "in-multicast-pkts(%s) = %s", rtnl_link_get_name(link), in_multicast_pkts_buffer); SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_in_multicast_pkts(ly_ctx, *parent, in_multicast_pkts_buffer), error_out); @@ -530,7 +530,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_disca goto error_out; } - SRPLG_LOG_INF(PLUGIN_NAME, "in-octets(%s) = %s", rtnl_link_get_name(link), in_discards_buffer); + SRPLG_LOG_INF(PLUGIN_NAME, "in-discards(%s) = %s", rtnl_link_get_name(link), in_discards_buffer); SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_in_multicast_pkts(ly_ctx, *parent, in_discards_buffer), error_out); @@ -553,7 +553,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_error interfaces_ctx_t* ctx = private_data; // buffers - char in_multicast_pkts_buffer[100] = { 0 }; + char in_errors_buffer[100] = { 0 }; // libnl struct rtnl_link* link = NULL; @@ -566,17 +566,17 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_error SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); // get in-octets - const uint64_t in_multicast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_INMCASTPKTS); + const uint64_t in_errors = rtnl_link_get_stat(link, RTNL_LINK_RX_ERRORS); - error = snprintf(in_multicast_pkts_buffer, sizeof(in_multicast_pkts_buffer), "%lu", in_multicast_pkts); + error = snprintf(in_errors_buffer, sizeof(in_errors_buffer), "%lu", in_errors); if (error < 0) { SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); goto error_out; } - SRPLG_LOG_INF(PLUGIN_NAME, "in-octets(%s) = %s", rtnl_link_get_name(link), in_multicast_pkts_buffer); + SRPLG_LOG_INF(PLUGIN_NAME, "in-errors(%s) = %s", rtnl_link_get_name(link), in_errors_buffer); - SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_in_multicast_pkts(ly_ctx, *parent, in_multicast_pkts_buffer), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_in_multicast_pkts(ly_ctx, *parent, in_errors_buffer), error_out); error = 0; goto out; From 63141474af778842714e15ec888f90ef1e57a993 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Wed, 17 Aug 2022 18:18:53 +0200 Subject: [PATCH 025/247] interfaces-plugin: fix in-discards, in-errors and in-unknown-protos operational leafs --- .../src/plugin/subscription/operational.c | 46 ++++++++++++++----- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 2be589a8..6823d3da 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -522,9 +522,9 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_disca SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); // get in-octets - const uint64_t in_discards = rtnl_link_get_stat(link, RTNL_LINK_RX_DROPPED); + const uint32_t in_discards = (uint32_t)rtnl_link_get_stat(link, RTNL_LINK_RX_DROPPED); - error = snprintf(in_discards_buffer, sizeof(in_discards_buffer), "%lu", in_discards); + error = snprintf(in_discards_buffer, sizeof(in_discards_buffer), "%u", in_discards); if (error < 0) { SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); goto error_out; @@ -532,7 +532,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_disca SRPLG_LOG_INF(PLUGIN_NAME, "in-discards(%s) = %s", rtnl_link_get_name(link), in_discards_buffer); - SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_in_multicast_pkts(ly_ctx, *parent, in_discards_buffer), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_in_discards(ly_ctx, *parent, in_discards_buffer), error_out); error = 0; goto out; @@ -566,9 +566,9 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_error SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); // get in-octets - const uint64_t in_errors = rtnl_link_get_stat(link, RTNL_LINK_RX_ERRORS); + const uint32_t in_errors = (uint32_t)rtnl_link_get_stat(link, RTNL_LINK_RX_ERRORS); - error = snprintf(in_errors_buffer, sizeof(in_errors_buffer), "%lu", in_errors); + error = snprintf(in_errors_buffer, sizeof(in_errors_buffer), "%u", in_errors); if (error < 0) { SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); goto error_out; @@ -576,7 +576,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_error SRPLG_LOG_INF(PLUGIN_NAME, "in-errors(%s) = %s", rtnl_link_get_name(link), in_errors_buffer); - SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_in_multicast_pkts(ly_ctx, *parent, in_errors_buffer), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_in_errors(ly_ctx, *parent, in_errors_buffer), error_out); error = 0; goto out; @@ -591,16 +591,38 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_error int interfaces_subscription_operational_interfaces_interface_statistics_in_unknown_protos(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + + // context const struct ly_ctx* ly_ctx = NULL; + interfaces_ctx_t* ctx = private_data; - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } + // buffers + char in_unknown_protos_buffer[100] = { 0 }; + + // libnl + struct rtnl_link* link = NULL; + + // there needs to be an allocated link cache in memory + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + + // get in-octets + const uint32_t in_unknown_protos = (uint32_t)rtnl_link_get_stat(link, RTNL_LINK_IP6_INUNKNOWNPROTOS); + + error = snprintf(in_unknown_protos_buffer, sizeof(in_unknown_protos_buffer), "%u", in_unknown_protos); + if (error < 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); + goto error_out; } + SRPLG_LOG_INF(PLUGIN_NAME, "in-unknown-protos(%s) = %s", rtnl_link_get_name(link), in_unknown_protos_buffer); + + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_in_unknown_protos(ly_ctx, *parent, in_unknown_protos_buffer), error_out); + + error = 0; goto out; error_out: From 7b7ab95e2225804fde03007b81a42ccc74550a96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Wed, 17 Aug 2022 18:21:49 +0200 Subject: [PATCH 026/247] interfaces-plugin: implement out-octets operational leaf --- .../src/plugin/subscription/operational.c | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 6823d3da..29ec68c5 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -635,16 +635,38 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_unkno int interfaces_subscription_operational_interfaces_interface_statistics_out_octets(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + + // context const struct ly_ctx* ly_ctx = NULL; + interfaces_ctx_t* ctx = private_data; - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } + // buffers + char out_octets_buffer[100] = { 0 }; + + // libnl + struct rtnl_link* link = NULL; + + // there needs to be an allocated link cache in memory + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + + // get in-octets + const uint64_t out_octets = rtnl_link_get_stat(link, RTNL_LINK_TX_BYTES); + + error = snprintf(out_octets_buffer, sizeof(out_octets_buffer), "%lu", out_octets); + if (error < 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); + goto error_out; } + SRPLG_LOG_INF(PLUGIN_NAME, "out-octets(%s) = %s", rtnl_link_get_name(link), out_octets_buffer); + + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_out_octets(ly_ctx, *parent, out_octets_buffer), error_out); + + error = 0; goto out; error_out: From 7a14db9233d28448525a4711e58a803717211504 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Wed, 17 Aug 2022 18:27:59 +0200 Subject: [PATCH 027/247] interfaces-plugin: implement out unicast, broadcast and multicast operational leafs --- .../src/plugin/subscription/operational.c | 110 +++++++++++++----- 1 file changed, 84 insertions(+), 26 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 29ec68c5..1a8e85de 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -342,7 +342,6 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_octet // get link SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); - // get in-octets const uint64_t in_octets = rtnl_link_get_stat(link, RTNL_LINK_RX_BYTES); error = snprintf(in_octets_buffer, sizeof(in_octets_buffer), "%lu", in_octets); @@ -386,7 +385,6 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_unica // get link SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); - // get in-octets const uint64_t in_pkts = rtnl_link_get_stat(link, RTNL_LINK_RX_PACKETS); const uint64_t in_broadcast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_INBCASTPKTS); const uint64_t in_multicast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_INMCASTPKTS); @@ -433,7 +431,6 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_broad // get link SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); - // get in-octets const uint64_t in_broadcast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_INBCASTPKTS); error = snprintf(in_broadcast_pkts_buffer, sizeof(in_broadcast_pkts_buffer), "%lu", in_broadcast_pkts); @@ -477,7 +474,6 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_multi // get link SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); - // get in-octets const uint64_t in_multicast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_INMCASTPKTS); error = snprintf(in_multicast_pkts_buffer, sizeof(in_multicast_pkts_buffer), "%lu", in_multicast_pkts); @@ -521,7 +517,6 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_disca // get link SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); - // get in-octets const uint32_t in_discards = (uint32_t)rtnl_link_get_stat(link, RTNL_LINK_RX_DROPPED); error = snprintf(in_discards_buffer, sizeof(in_discards_buffer), "%u", in_discards); @@ -565,7 +560,6 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_error // get link SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); - // get in-octets const uint32_t in_errors = (uint32_t)rtnl_link_get_stat(link, RTNL_LINK_RX_ERRORS); error = snprintf(in_errors_buffer, sizeof(in_errors_buffer), "%u", in_errors); @@ -609,7 +603,6 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_unkno // get link SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); - // get in-octets const uint32_t in_unknown_protos = (uint32_t)rtnl_link_get_stat(link, RTNL_LINK_IP6_INUNKNOWNPROTOS); error = snprintf(in_unknown_protos_buffer, sizeof(in_unknown_protos_buffer), "%u", in_unknown_protos); @@ -653,7 +646,6 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_octe // get link SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); - // get in-octets const uint64_t out_octets = rtnl_link_get_stat(link, RTNL_LINK_TX_BYTES); error = snprintf(out_octets_buffer, sizeof(out_octets_buffer), "%lu", out_octets); @@ -679,16 +671,40 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_octe int interfaces_subscription_operational_interfaces_interface_statistics_out_unicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + + // context const struct ly_ctx* ly_ctx = NULL; + interfaces_ctx_t* ctx = private_data; - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } + // buffers + char out_unicast_pkts_buffer[100] = { 0 }; + + // libnl + struct rtnl_link* link = NULL; + + // there needs to be an allocated link cache in memory + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + + const uint64_t out_pkts = rtnl_link_get_stat(link, RTNL_LINK_TX_PACKETS); + const uint64_t out_broadcast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_OUTBCASTPKTS); + const uint64_t out_multicast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_OUTMCASTPKTS); + const uint64_t out_unicast_pkts = out_pkts - out_broadcast_pkts - out_multicast_pkts; + + error = snprintf(out_unicast_pkts_buffer, sizeof(out_unicast_pkts_buffer), "%lu", out_unicast_pkts); + if (error < 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); + goto error_out; } + SRPLG_LOG_INF(PLUGIN_NAME, "out-unicast-pkts(%s) = %s", rtnl_link_get_name(link), out_unicast_pkts_buffer); + + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_out_unicast_pkts(ly_ctx, *parent, out_unicast_pkts_buffer), error_out); + + error = 0; goto out; error_out: @@ -701,16 +717,37 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_unic int interfaces_subscription_operational_interfaces_interface_statistics_out_broadcast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + + // context const struct ly_ctx* ly_ctx = NULL; + interfaces_ctx_t* ctx = private_data; - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } + // buffers + char out_broadcast_pkts_buffer[100] = { 0 }; + + // libnl + struct rtnl_link* link = NULL; + + // there needs to be an allocated link cache in memory + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + + const uint64_t out_broadcast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_OUTBCASTPKTS); + + error = snprintf(out_broadcast_pkts_buffer, sizeof(out_broadcast_pkts_buffer), "%lu", out_broadcast_pkts); + if (error < 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); + goto error_out; } + SRPLG_LOG_INF(PLUGIN_NAME, "out-broadcast-pkts(%s) = %s", rtnl_link_get_name(link), out_broadcast_pkts_buffer); + + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_out_broadcast_pkts(ly_ctx, *parent, out_broadcast_pkts_buffer), error_out); + + error = 0; goto out; error_out: @@ -723,16 +760,37 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_broa int interfaces_subscription_operational_interfaces_interface_statistics_out_multicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + + // context const struct ly_ctx* ly_ctx = NULL; + interfaces_ctx_t* ctx = private_data; - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } + // buffers + char out_multicast_pkts_buffer[100] = { 0 }; + + // libnl + struct rtnl_link* link = NULL; + + // there needs to be an allocated link cache in memory + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + + const uint64_t out_multicast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_OUTMCASTPKTS); + + error = snprintf(out_multicast_pkts_buffer, sizeof(out_multicast_pkts_buffer), "%lu", out_multicast_pkts); + if (error < 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); + goto error_out; } + SRPLG_LOG_INF(PLUGIN_NAME, "out-multicast-pkts(%s) = %s", rtnl_link_get_name(link), out_multicast_pkts_buffer); + + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_out_multicast_pkts(ly_ctx, *parent, out_multicast_pkts_buffer), error_out); + + error = 0; goto out; error_out: From 4c848617c854f6a8d702d820962173e0b9becc4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Wed, 17 Aug 2022 18:30:11 +0200 Subject: [PATCH 028/247] interfaces-plugin: implement out-discards operational leafs --- .../src/plugin/subscription/operational.c | 33 +++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 1a8e85de..9aff347e 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -803,16 +803,37 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_mult int interfaces_subscription_operational_interfaces_interface_statistics_out_discards(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + + // context const struct ly_ctx* ly_ctx = NULL; + interfaces_ctx_t* ctx = private_data; - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } + // buffers + char out_discards_buffer[100] = { 0 }; + + // libnl + struct rtnl_link* link = NULL; + + // there needs to be an allocated link cache in memory + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + + const uint64_t out_discards = rtnl_link_get_stat(link, RTNL_LINK_TX_DROPPED); + + error = snprintf(out_discards_buffer, sizeof(out_discards_buffer), "%lu", out_discards); + if (error < 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); + goto error_out; } + SRPLG_LOG_INF(PLUGIN_NAME, "out-discards(%s) = %s", rtnl_link_get_name(link), out_discards_buffer); + + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_out_discards(ly_ctx, *parent, out_discards_buffer), error_out); + + error = 0; goto out; error_out: From 3b455fac62d750d11aebb20f4c2fb11d6e84940f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Wed, 17 Aug 2022 18:31:08 +0200 Subject: [PATCH 029/247] interfaces-plugin: implement out-errors operational leafs --- .../src/plugin/subscription/operational.c | 33 +++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 9aff347e..3af31baa 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -846,16 +846,37 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_disc int interfaces_subscription_operational_interfaces_interface_statistics_out_errors(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + + // context const struct ly_ctx* ly_ctx = NULL; + interfaces_ctx_t* ctx = private_data; - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } + // buffers + char out_errors_buffer[100] = { 0 }; + + // libnl + struct rtnl_link* link = NULL; + + // there needs to be an allocated link cache in memory + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + + const uint64_t out_errors = rtnl_link_get_stat(link, RTNL_LINK_TX_DROPPED); + + error = snprintf(out_errors_buffer, sizeof(out_errors_buffer), "%lu", out_errors); + if (error < 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); + goto error_out; } + SRPLG_LOG_INF(PLUGIN_NAME, "out-errors(%s) = %s", rtnl_link_get_name(link), out_errors_buffer); + + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_out_errors(ly_ctx, *parent, out_errors_buffer), error_out); + + error = 0; goto out; error_out: From 948c2a46476b5e29fd5890ce26687655f8110d24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Wed, 17 Aug 2022 18:41:50 +0200 Subject: [PATCH 030/247] interfaces-plugin: implement higher-layer-if operational leaf --- .../src/plugin/subscription/operational.c | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 3af31baa..b01c85e5 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -203,16 +203,39 @@ int interfaces_subscription_operational_interfaces_interface_phys_address(sr_ses int interfaces_subscription_operational_interfaces_interface_higher_layer_if(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + + // context const struct ly_ctx* ly_ctx = NULL; + interfaces_ctx_t* ctx = private_data; + interfaces_nl_ctx_t* nl_ctx = &ctx->nl_ctx; - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } + // libnl + struct rtnl_link* link = NULL; + struct rtnl_link* master_link = NULL; + struct nl_addr* addr = NULL; + + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "interface") == 0); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + + // get phys-address + SRPC_SAFE_CALL_PTR(addr, rtnl_link_get_addr(link), error_out); + + int master_if_index = rtnl_link_get_master(link); + while (master_if_index) { + master_link = rtnl_link_get(nl_ctx->link_cache, master_if_index); + const char* master_name = rtnl_link_get_name(master_link); + + // add higher-layer-if + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_higher_layer_if(ly_ctx, *parent, master_name), error_out); + + // go one layer higher + master_if_index = rtnl_link_get_master(master_link); } + error = 0; goto out; error_out: From bb39a401fa41af86a449cd11b7ef363cd0355922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Wed, 17 Aug 2022 18:42:55 +0200 Subject: [PATCH 031/247] interfaces-plugin: log higher-layer-if operational leaf --- src/interfaces/src/plugin/subscription/operational.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index b01c85e5..decdefb5 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -228,6 +228,8 @@ int interfaces_subscription_operational_interfaces_interface_higher_layer_if(sr_ master_link = rtnl_link_get(nl_ctx->link_cache, master_if_index); const char* master_name = rtnl_link_get_name(master_link); + SRPLG_LOG_INF(PLUGIN_NAME, "higher-layer-if(%s) = %s", rtnl_link_get_name(link), master_name); + // add higher-layer-if SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_higher_layer_if(ly_ctx, *parent, master_name), error_out); From d3f9e748174d3a2f2e380228381f218e44ed2021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Wed, 17 Aug 2022 22:01:05 +0200 Subject: [PATCH 032/247] interfaces-plugin: enable all if-extensions features --- src/interfaces/src/plugin.c | 56 ++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index a5c5b0a1..5a89075f 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -135,34 +135,34 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) INTERFACES_INTERFACES_INTERFACE_STATISTICS_OUT_ERRORS_YANG_PATH, interfaces_subscription_operational_interfaces_interface_statistics_out_errors, }, - // { - // INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_DISCARD_UNKNOWN_ENCAPS_YANG_PATH, - // interfaces_subscription_operational_interfaces_interface_statistics_in_discard_unknown_encaps, - // }, - // { - // INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_CARRIER_TRANSITIONS_YANG_PATH, - // interfaces_subscription_operational_interfaces_interface_carrier_delay_carrier_transitions, - // }, - // { - // INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_TIMER_RUNNING_YANG_PATH, - // interfaces_subscription_operational_interfaces_interface_carrier_delay_timer_running, - // }, - // { - // INTERFACES_INTERFACES_INTERFACE_DAMPENING_PENALTY_YANG_PATH, - // interfaces_subscription_operational_interfaces_interface_dampening_penalty, - // }, - // { - // INTERFACES_INTERFACES_INTERFACE_DAMPENING_SUPPRESSED_YANG_PATH, - // interfaces_subscription_operational_interfaces_interface_dampening_suppressed, - // }, - // { - // INTERFACES_INTERFACES_INTERFACE_DAMPENING_TIME_REMAINING_YANG_PATH, - // interfaces_subscription_operational_interfaces_interface_dampening_time_remaining, - // }, - // { - // INTERFACES_INTERFACES_INTERFACE_FORWARDING_MODE_YANG_PATH, - // interfaces_subscription_operational_interfaces_interface_forwarding_mode, - // }, + { + INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_DISCARD_UNKNOWN_ENCAPS_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_statistics_in_discard_unknown_encaps, + }, + { + INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_CARRIER_TRANSITIONS_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_carrier_delay_carrier_transitions, + }, + { + INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_TIMER_RUNNING_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_carrier_delay_timer_running, + }, + { + INTERFACES_INTERFACES_INTERFACE_DAMPENING_PENALTY_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_dampening_penalty, + }, + { + INTERFACES_INTERFACES_INTERFACE_DAMPENING_SUPPRESSED_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_dampening_suppressed, + }, + { + INTERFACES_INTERFACES_INTERFACE_DAMPENING_TIME_REMAINING_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_dampening_time_remaining, + }, + { + INTERFACES_INTERFACES_INTERFACE_FORWARDING_MODE_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_forwarding_mode, + }, { INTERFACES_INTERFACES_INTERFACE_YANG_PATH, interfaces_subscription_operational_interfaces_interface, From 0d0f47e5df70ab94578a1103e4660ccc8118e563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Wed, 17 Aug 2022 22:36:14 +0200 Subject: [PATCH 033/247] interfaces-plugin: log enabled features --- src/interfaces/src/plugin.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index 5a89075f..289f4958 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -37,6 +37,21 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) *private_data = ctx; + // log status of features + const char* ietf_interfaces_features[] = { + "arbitrary-names", + "pre-provisioning", + "if-mib", + }; + + const char* ietf_if_extensions_features[] = { + "carrier-delay", + "dampening", + "loopback", + "max-frame-size", + "sub-interfaces", + }; + // module changes srpc_module_change_t module_changes[] = { { @@ -169,6 +184,28 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) }, }; + SRPLG_LOG_INF(PLUGIN_NAME, "Checking ietf-interfaces YANG module used features:"); + + for (size_t i = 0; i < ARRAY_SIZE(ietf_interfaces_features); i++) { + const char* feature = ietf_interfaces_features[i]; + bool enabled = false; + + SRPC_SAFE_CALL_ERR(error, srpc_check_feature_status(running_session, "ietf-interfaces", feature, &enabled), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "ietf-interfaces feature \"%s\" status = %s", feature, enabled ? "enabled" : "disabled"); + } + + SRPLG_LOG_INF(PLUGIN_NAME, "Checking ietf-if-extensions YANG module used features:"); + + for (size_t i = 0; i < ARRAY_SIZE(ietf_if_extensions_features); i++) { + const char* feature = ietf_if_extensions_features[i]; + bool enabled = false; + + SRPC_SAFE_CALL_ERR(error, srpc_check_feature_status(running_session, "ietf-if-extensions", feature, &enabled), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "ietf-if-extensions feature \"%s\" status = %s", feature, enabled ? "enabled" : "disabled"); + } + connection = sr_session_get_connection(running_session); error = sr_session_start(connection, SR_DS_STARTUP, &startup_session); if (error) { From 36c84d2d18a7d156612e28f51f0c5dcc6114f677 Mon Sep 17 00:00:00 2001 From: agardijan Date: Sun, 21 Aug 2022 15:55:22 +0200 Subject: [PATCH 034/247] interfaces-plugin: add interface hash table api --- .../src/plugin/api/interfaces/if_data.c | 143 ++++++++++++++++++ .../src/plugin/api/interfaces/if_data.h | 35 +++++ 2 files changed, 178 insertions(+) create mode 100644 src/interfaces/src/plugin/api/interfaces/if_data.c create mode 100644 src/interfaces/src/plugin/api/interfaces/if_data.h diff --git a/src/interfaces/src/plugin/api/interfaces/if_data.c b/src/interfaces/src/plugin/api/interfaces/if_data.c new file mode 100644 index 00000000..6c7d4443 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/if_data.c @@ -0,0 +1,143 @@ +#include "if_data.h" +#include "utils/memory.h" + +void +if_data_init(interfaces_interfaces_interface_element_t* interface) +{ + /* TODO: init all struct members */ + interface->name = NULL; + interface->description = NULL; + interface->type = NULL; + interface->enabled = 0; +} + +void +if_data_ht_root_init(interface_ht_element_t **if_root) +{ + /* uthash root node has to be initialized to NULL */ + *root = NULL; +} + +interface_ht_element_t * +if_data_ht_get_by_name(interface_ht_element_t *if_root, char *name) +{ + interface_ht_element_t *elem = NULL; + HASH_FIND_STR(if_root, name, elem); + return elem; +} + +void +if_data_ht_set_name(interfaces_interfaces_interface_element_t *interface, char *name) +{ + interface->name = xstrdup(name); +} + +int +if_data_ht_add(interface_ht_element_t *if_root, char *name) +{ + interface_ht_element_t *tmp = NULL, *elem = NULL; + int rc = 0; + + HASH_FIND_STR(if_root, name, tmp); + if (tmp != NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "interface with name key: %s already exists in hash table", name); + goto error_out; + } + + elem = (interface_ht_element_t *) xmalloc(sizeof elem); + if_data_init(&elem->interface); + if_data_ht_set_name(&elem->interface) + + /* since name is char *, *_KEYPTR has to be used instead of *_STR */ + HASH_ADD_KEYPTR(hh, if_root, elem->interface.name, sizeof(elem->interface.name), elem); + + goto out; +error_out: + rc = -1; +out: + return rc; +} + +int +if_data_ht_set_description(interface_ht_element_t *if_root, char *name, char *description) +{ + interface_ht_element_t *elem = NULL; + int rc = 0; + + elem = if_data_ht_get_by_name(if_root, name); + if (elem == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "interface with name key: %s non-existant in hash table", name); + goto error_out; + } + + if (elem->interface.description != NULL) { + FREE_SAFE(elem->interface.description); + } + elem->interface.description = xstrdup(description); + if (elem->interface.description == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "couldn't copy description: %s", description); + goto error_out; + } + + goto out; +error_out: + rc = -1; +out: + return rc; +} + +int +if_data_ht_set_type(interface_ht_element_t *if_root, char *name, char *type) +{ + interface_ht_element_t *elem = NULL; + int rc = 0; + + elem = if_data_ht_get_by_name(if_root, name); + if (elem == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "interface with name key: %s non-existant in hash table", name); + goto error_out; + } + + if (elem->interface.type != NULL) { + FREE_SAFE(elem->interface.type); + } + elem->interface.type = xstrdup(type); + if (elem->interface.type == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "couldn't copy type: %s", type); + goto error_out; + } + + goto out; +error_out: + rc = -1; +out: + return rc; +} + +void +if_data_ht_if_free(interfaces_interfaces_interface_element_t *interface) +{ + /* TODO: free other struct members as needed */ + if (interface->name) { + FREE_SAFE(interface->name); + } + if (interface->description) { + FREE_SAFE(interface->description); + } + if (interface->type) { + FREE_SAFE(interface->type); + } +} + +void +if_data_ht_free(interface_ht_element_t *if_root) +{ + interface_ht_element_t tmp = NULL, elem = NULL; + + HASH_ITER(hh, if_root, elem, tmp) { + HASH_DEL(if_root, elem); + if_data_ht_if_free(&elem->interface); + FREE_SAFE(elem); + } +} + diff --git a/src/interfaces/src/plugin/api/interfaces/if_data.h b/src/interfaces/src/plugin/api/interfaces/if_data.h new file mode 100644 index 00000000..eb826c1b --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/if_data.h @@ -0,0 +1,35 @@ +#ifndef IF_DATA_H +#define IF_DATA_H + +#include + +#include "plugin/types.h" + +void +if_data_init(interfaces_interfaces_interface_element_t* interface); + +void +if_data_ht_root_init(interface_ht_element_t **if_root); + +interface_ht_element_t * +if_data_ht_get_by_name(interface_ht_element_t *if_root, char *name); + +void +if_data_ht_set_name(interfaces_interfaces_interface_element_t *interface, char *name); + +int +if_data_ht_add(interface_ht_element_t *if_root, char *name); + +int +if_data_ht_set_description(interface_ht_element_t *if_root, char *name, char *description); + +int +if_data_ht_set_type(interface_ht_element_t *if_root, char *name, char *type); + +void +if_data_ht_if_free(interfaces_interfaces_interface_element_t *interface); + +void +if_data_ht_free(interface_ht_element_t *if_root); + +#endif /* IF_DATA_H */ From 9566b4b8061a689748462e755730c384af7933e2 Mon Sep 17 00:00:00 2001 From: agardijan Date: Sun, 21 Aug 2022 15:56:14 +0200 Subject: [PATCH 035/247] interfaces-plugin: add interface hash table node struct --- src/interfaces/src/plugin/types.h | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin/types.h b/src/interfaces/src/plugin/types.h index fbb877ec..bc3ea72b 100644 --- a/src/interfaces/src/plugin/types.h +++ b/src/interfaces/src/plugin/types.h @@ -4,6 +4,8 @@ #include #include +#include + // typedefs typedef struct interfaces_interfaces_interface_carrier_delay interfaces_interfaces_interface_carrier_delay_t; typedef struct interfaces_interfaces_interface_dampening interfaces_interfaces_interface_dampening_t; @@ -14,6 +16,7 @@ typedef struct interfaces_interfaces_interface_encapsulation interfaces_interfac typedef struct interfaces_interfaces_interface interfaces_interfaces_interface_t; typedef struct interfaces_interfaces_interface_element interfaces_interfaces_interface_element_t; typedef struct interfaces_interfaces interfaces_interfaces_t; +typedef struct interface_ht_element interface_ht_element_t; enum interfaces_interfaces_interface_link_up_down_trap_enable { interfaces_interfaces_interface_link_up_down_trap_enable_disabled, @@ -72,8 +75,18 @@ struct interfaces_interfaces_interface_element { interfaces_interfaces_interface_t interface; }; +/* + * - interface hash table element + * - used due to interface name indexing + */ +struct interface_ht_element { + interfaces_interfaces_interface_t interface; + /* makes the structure hashable */ + UT_hash_handle hh; +}; + struct interfaces_interfaces { interfaces_interfaces_interface_element_t* interface; }; -#endif // INTERFACES_PLUGIN_TYPES_H \ No newline at end of file +#endif // INTERFACES_PLUGIN_TYPES_H From cbea543e710b0b0aae5147093c7049fc2d107b1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 22 Aug 2022 10:52:46 +0200 Subject: [PATCH 036/247] interfaces-plugin: use new SRPC API to load enabled features on plugin init --- src/interfaces/src/plugin.c | 47 +++++++++---------------------------- 1 file changed, 11 insertions(+), 36 deletions(-) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index 289f4958..87cc45a6 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -12,6 +12,9 @@ #include "plugin/subscription/change.h" #include "plugin/subscription/operational.h" #include "plugin/subscription/rpc.h" +#include "srpc/common.h" +#include "srpc/feature_status.h" +#include "srpc/types.h" #include #include @@ -27,6 +30,8 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) sr_session_ctx_t* startup_session = NULL; sr_conn_ctx_t* connection = NULL; sr_subscription_ctx_t* subscription = NULL; + srpc_feature_status_t* ietf_interfaces_features = NULL; + srpc_feature_status_t* ietf_if_extensions_features = NULL; // plugin interfaces_ctx_t* ctx = NULL; @@ -37,20 +42,9 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) *private_data = ctx; - // log status of features - const char* ietf_interfaces_features[] = { - "arbitrary-names", - "pre-provisioning", - "if-mib", - }; - - const char* ietf_if_extensions_features[] = { - "carrier-delay", - "dampening", - "loopback", - "max-frame-size", - "sub-interfaces", - }; + // load enabled features from modules in sysrepo + SRPC_SAFE_CALL_ERR(error, srpc_feature_status_hash_load(&ietf_interfaces_features, running_session, "ietf-interfaces"), error_out); + SRPC_SAFE_CALL_ERR(error, srpc_feature_status_hash_load(&ietf_if_extensions_features, running_session, "ietf-if-extensions"), error_out); // module changes srpc_module_change_t module_changes[] = { @@ -184,28 +178,6 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) }, }; - SRPLG_LOG_INF(PLUGIN_NAME, "Checking ietf-interfaces YANG module used features:"); - - for (size_t i = 0; i < ARRAY_SIZE(ietf_interfaces_features); i++) { - const char* feature = ietf_interfaces_features[i]; - bool enabled = false; - - SRPC_SAFE_CALL_ERR(error, srpc_check_feature_status(running_session, "ietf-interfaces", feature, &enabled), error_out); - - SRPLG_LOG_INF(PLUGIN_NAME, "ietf-interfaces feature \"%s\" status = %s", feature, enabled ? "enabled" : "disabled"); - } - - SRPLG_LOG_INF(PLUGIN_NAME, "Checking ietf-if-extensions YANG module used features:"); - - for (size_t i = 0; i < ARRAY_SIZE(ietf_if_extensions_features); i++) { - const char* feature = ietf_if_extensions_features[i]; - bool enabled = false; - - SRPC_SAFE_CALL_ERR(error, srpc_check_feature_status(running_session, "ietf-if-extensions", feature, &enabled), error_out); - - SRPLG_LOG_INF(PLUGIN_NAME, "ietf-if-extensions feature \"%s\" status = %s", feature, enabled ? "enabled" : "disabled"); - } - connection = sr_session_get_connection(running_session); error = sr_session_start(connection, SR_DS_STARTUP, &startup_session); if (error) { @@ -290,6 +262,9 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) SRPLG_LOG_ERR(PLUGIN_NAME, "Error occured while initializing the plugin (%d)", error); out: + srpc_feature_status_hash_free(&ietf_interfaces_features); + srpc_feature_status_hash_free(&ietf_if_extensions_features); + return error ? SR_ERR_CALLBACK_FAILED : SR_ERR_OK; } From 697928380c81035a18e18c19ed31d5db88402a8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 22 Aug 2022 17:32:12 +0200 Subject: [PATCH 037/247] interfaces-plugin: initialize feature status hash using SRPC API --- src/interfaces/src/plugin.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index 87cc45a6..5dd9809b 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -42,6 +42,10 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) *private_data = ctx; + // initialize feature status hashes + ietf_interfaces_features = srpc_feature_status_hash_new(); + ietf_if_extensions_features = srpc_feature_status_hash_new(); + // load enabled features from modules in sysrepo SRPC_SAFE_CALL_ERR(error, srpc_feature_status_hash_load(&ietf_interfaces_features, running_session, "ietf-interfaces"), error_out); SRPC_SAFE_CALL_ERR(error, srpc_feature_status_hash_load(&ietf_if_extensions_features, running_session, "ietf-if-extensions"), error_out); From 7210baba5f1d61c310f3a8f0d343c4f46d50565b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 22 Aug 2022 18:31:32 +0200 Subject: [PATCH 038/247] interfaces-plugin: remove unused variable --- src/interfaces/src/plugin/subscription/operational.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index decdefb5..93f919f0 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -212,7 +212,6 @@ int interfaces_subscription_operational_interfaces_interface_higher_layer_if(sr_ // libnl struct rtnl_link* link = NULL; struct rtnl_link* master_link = NULL; - struct nl_addr* addr = NULL; assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "interface") == 0); @@ -220,9 +219,6 @@ int interfaces_subscription_operational_interfaces_interface_higher_layer_if(sr_ // get link SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); - // get phys-address - SRPC_SAFE_CALL_PTR(addr, rtnl_link_get_addr(link), error_out); - int master_if_index = rtnl_link_get_master(link); while (master_if_index) { master_link = rtnl_link_get(nl_ctx->link_cache, master_if_index); From 65ecf2566d3f60022689f7a6a6580db1d50b5568 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 22 Aug 2022 18:45:31 +0200 Subject: [PATCH 039/247] interfaces-plugin: implement lower-layer-if operational leaf list --- .../src/plugin/subscription/operational.c | 46 +++++++++++++++++-- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 93f919f0..71362663 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -2,6 +2,7 @@ #include "libyang/tree_data.h" #include "netlink/addr.h" #include "netlink/cache.h" +#include "netlink/object.h" #include "netlink/route/tc.h" #include "netlink/socket.h" #include "plugin/common.h" @@ -246,16 +247,51 @@ int interfaces_subscription_operational_interfaces_interface_higher_layer_if(sr_ int interfaces_subscription_operational_interfaces_interface_lower_layer_if(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + + // context const struct ly_ctx* ly_ctx = NULL; + interfaces_ctx_t* ctx = private_data; + interfaces_nl_ctx_t* nl_ctx = &ctx->nl_ctx; - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; + // libnl + struct rtnl_link* link = NULL; + struct rtnl_link* master_link = NULL; + + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "interface") == 0); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + + // iterate over all links and check for ones which have a master equal to the current link + struct nl_cache* link_cache = nl_ctx->link_cache; + struct rtnl_link* link_iter = (struct rtnl_link*)nl_cache_get_first(link_cache); + + while (link_iter) { + int master_if_index = rtnl_link_get_master(link); + while (master_if_index) { + master_link = rtnl_link_get(nl_ctx->link_cache, master_if_index); + const char* master_name = rtnl_link_get_name(master_link); + + if (!strcmp(master_name, rtnl_link_get_name(link))) { + // current link is the higher layer interface of the iterated link + SRPLG_LOG_INF(PLUGIN_NAME, "lower-layer-if(%s) = %s", rtnl_link_get_name(link), rtnl_link_get_name(link_iter)); + + // add lower-layer-if + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_lower_layer_if(ly_ctx, *parent, rtnl_link_get_name(link_iter)), error_out); + + // found in the master list - continue checking other interfaces + break; + } + + // go one layer higher + master_if_index = rtnl_link_get_master(master_link); } + + link_iter = (struct rtnl_link*)nl_cache_get_next((struct nl_object*)link_iter); } + error = 0; goto out; error_out: From 9d67aea2b63e78fd4c424f793de8d39d1c2a45b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 22 Aug 2022 19:09:02 +0200 Subject: [PATCH 040/247] interfaces-plugin: implement discontinuity-time statistics operational leaf --- .../src/plugin/subscription/operational.c | 61 ++++++++++++++++--- 1 file changed, 54 insertions(+), 7 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 71362663..9745519d 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -20,9 +20,11 @@ #include #include #include +#include static struct rtnl_link* interfaces_get_current_link(interfaces_ctx_t* ctx, sr_session_ctx_t* session, const char* xpath); static int interfaces_extract_interface_name(sr_session_ctx_t* session, const char* xpath, char* buffer, size_t buffer_size); +static int interfaces_get_system_boot_time(char* buffer, size_t buffer_size); int interfaces_subscription_operational_interfaces_interface_admin_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { @@ -359,16 +361,32 @@ int interfaces_subscription_operational_interfaces_interface_speed(sr_session_ct int interfaces_subscription_operational_interfaces_interface_statistics_discontinuity_time(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + + // context const struct ly_ctx* ly_ctx = NULL; + interfaces_ctx_t* ctx = private_data; - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } - } + // buffers + char discontinuity_time_buffer[100] = { 0 }; + + // libnl + struct rtnl_link* link = NULL; + + // there needs to be an allocated link cache in memory + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + + // get boot time as discontinuity time + SRPC_SAFE_CALL_ERR(error, interfaces_get_system_boot_time(discontinuity_time_buffer, sizeof(discontinuity_time_buffer)), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "discontinuity-time(%s) = %s", rtnl_link_get_name(link), discontinuity_time_buffer); + + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics_discontinuity_time(ly_ctx, *parent, discontinuity_time_buffer), error_out); + + error = 0; goto out; error_out: @@ -1210,4 +1228,33 @@ static int interfaces_extract_interface_name(sr_session_ctx_t* session, const ch out: return error; +} + +static int interfaces_get_system_boot_time(char* buffer, size_t buffer_size) +{ + time_t now = 0; + struct tm* ts = { 0 }; + struct sysinfo s_info = { 0 }; + time_t uptime_seconds = 0; + + now = time(NULL); + + ts = localtime(&now); + if (ts == NULL) + return -1; + + if (sysinfo(&s_info) != 0) + return -1; + + uptime_seconds = s_info.uptime; + + time_t diff = now - uptime_seconds; + + ts = localtime(&diff); + if (ts == NULL) + return -1; + + strftime(buffer, buffer_size, "%FT%TZ", ts); + + return 0; } \ No newline at end of file From ab4d5e8cc41ee504ebb27d2ecc76ca0e4f068347 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 23 Aug 2022 13:45:10 +0200 Subject: [PATCH 041/247] interfaces-plugin: add interfaces state data structure --- src/interfaces/CMakeLists.txt | 1 + .../plugin/data/interfaces/interface/state.c | 53 +++++++++++++++++++ .../plugin/data/interfaces/interface/state.h | 11 ++++ src/interfaces/src/plugin/types.h | 10 ++++ 4 files changed, 75 insertions(+) create mode 100644 src/interfaces/src/plugin/data/interfaces/interface/state.c create mode 100644 src/interfaces/src/plugin/data/interfaces/interface/state.h diff --git a/src/interfaces/CMakeLists.txt b/src/interfaces/CMakeLists.txt index 2fa6fcdc..61d179b9 100644 --- a/src/interfaces/CMakeLists.txt +++ b/src/interfaces/CMakeLists.txt @@ -28,6 +28,7 @@ set( src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/outer-tag/change.c src/plugin/api/interfaces/interface/dampening/change.c src/plugin/api/interfaces/interface/carrier-delay/change.c + src/plugin/data/interfaces/interface/state.c src/plugin.c ) diff --git a/src/interfaces/src/plugin/data/interfaces/interface/state.c b/src/interfaces/src/plugin/data/interfaces/interface/state.c new file mode 100644 index 00000000..56c20eac --- /dev/null +++ b/src/interfaces/src/plugin/data/interfaces/interface/state.c @@ -0,0 +1,53 @@ +#include "state.h" +#include "src/uthash.h" + +interfaces_interface_state_t* interfaces_interface_state_hash_new(void) +{ + return NULL; +} + +int interfaces_interface_state_hash_add(interfaces_interface_state_t** state_hash, const char* name, const uint8_t state, const time_t time) +{ + interfaces_interface_state_t* new_state = malloc(sizeof(interfaces_interface_state_t)); + + if (!new_state) { + return -1; + } + + new_state->name = strdup(name); + if (!new_state->name) { + return -2; + } + + new_state->state = state; + new_state->last_change = time; + + HASH_ADD_STR(*state_hash, name, new_state); + + return 0; +} + +interfaces_interface_state_t* interfaces_interface_state_hash_get(const interfaces_interface_state_t* state_hash, const char* name) +{ + interfaces_interface_state_t* state = NULL; + + HASH_FIND_STR(state_hash, name, state); + + return state; +} + +void interfaces_interface_state_hash_free(interfaces_interface_state_t** state_hash) +{ + interfaces_interface_state_t *current = NULL, *tmp = NULL; + + HASH_ITER(hh, *state_hash, current, tmp) + { + HASH_DEL(*state_hash, current); + + // free data + free((char*)current->name); + + // free allocated struct + free(current); + } +} diff --git a/src/interfaces/src/plugin/data/interfaces/interface/state.h b/src/interfaces/src/plugin/data/interfaces/interface/state.h new file mode 100644 index 00000000..f4738a75 --- /dev/null +++ b/src/interfaces/src/plugin/data/interfaces/interface/state.h @@ -0,0 +1,11 @@ +#ifndef INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_STATE_H +#define INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_STATE_H + +#include "plugin/types.h" + +interfaces_interface_state_t* interfaces_interface_state_hash_new(void); +int interfaces_interface_state_hash_add(interfaces_interface_state_t** state_hash, const char* name, const uint8_t state, const time_t time); +interfaces_interface_state_t* interfaces_interface_state_hash_get(const interfaces_interface_state_t* state_hash, const char* name); +void interfaces_interface_state_hash_free(interfaces_interface_state_t** state_hash); + +#endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_STATE_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/types.h b/src/interfaces/src/plugin/types.h index fbb877ec..eb2c27bd 100644 --- a/src/interfaces/src/plugin/types.h +++ b/src/interfaces/src/plugin/types.h @@ -3,6 +3,8 @@ #include #include +#include +#include // typedefs typedef struct interfaces_interfaces_interface_carrier_delay interfaces_interfaces_interface_carrier_delay_t; @@ -14,6 +16,7 @@ typedef struct interfaces_interfaces_interface_encapsulation interfaces_interfac typedef struct interfaces_interfaces_interface interfaces_interfaces_interface_t; typedef struct interfaces_interfaces_interface_element interfaces_interfaces_interface_element_t; typedef struct interfaces_interfaces interfaces_interfaces_t; +typedef struct interfaces_interface_state_s interfaces_interface_state_t; enum interfaces_interfaces_interface_link_up_down_trap_enable { interfaces_interfaces_interface_link_up_down_trap_enable_disabled, @@ -76,4 +79,11 @@ struct interfaces_interfaces { interfaces_interfaces_interface_element_t* interface; }; +struct interfaces_interface_state_s { + char* name; // key + uint8_t state; + time_t last_change; + UT_hash_handle hh; +}; + #endif // INTERFACES_PLUGIN_TYPES_H \ No newline at end of file From c611bf7bab91c8e5b36fddd424549b0e689ee0e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 23 Aug 2022 16:27:57 +0200 Subject: [PATCH 042/247] interfaces-plugin: add interfaces state context to the main context --- src/interfaces/src/plugin.c | 12 ++++++++++++ src/interfaces/src/plugin/context.h | 9 +++++++++ 2 files changed, 21 insertions(+) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index 5dd9809b..3cc64c1e 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -20,6 +20,8 @@ #include #include +static int interfaces_init_state_changes_tracking(interfaces_state_changes_ctx_t* ctx); + int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) { int error = 0; @@ -259,6 +261,9 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) } } + // tracking oper-status changes for interfaces + SRPC_SAFE_CALL_ERR(error, interfaces_init_state_changes_tracking(&ctx->state_ctx), error_out); + goto out; error_out: @@ -293,4 +298,11 @@ void sr_plugin_cleanup_cb(sr_session_ctx_t* running_session, void* private_data) } free(ctx); +} + +static int interfaces_init_state_changes_tracking(interfaces_state_changes_ctx_t* ctx) +{ + // setup threads to check every link state and write timestamps of changes + int error = 0; + return error; } \ No newline at end of file diff --git a/src/interfaces/src/plugin/context.h b/src/interfaces/src/plugin/context.h index 7f6168ea..314be0dc 100644 --- a/src/interfaces/src/plugin/context.h +++ b/src/interfaces/src/plugin/context.h @@ -1,6 +1,7 @@ #ifndef INTERFACES_PLUGIN_CONTEXT_H #define INTERFACES_PLUGIN_CONTEXT_H +#include "netlink/cache.h" #include "plugin/types.h" #include @@ -9,6 +10,13 @@ // typedefs typedef struct interfaces_nl_ctx_s interfaces_nl_ctx_t; typedef struct interfaces_ctx_s interfaces_ctx_t; +typedef struct interfaces_state_changes_ctx_s interfaces_state_changes_ctx_t; + +struct interfaces_state_changes_ctx_s { + struct nl_sock* socket; + struct nl_cache* link_cache; + struct nl_cache_mngr* link_cache_manager; +}; struct interfaces_nl_ctx_s { struct nl_sock* socket; @@ -18,6 +26,7 @@ struct interfaces_nl_ctx_s { struct interfaces_ctx_s { sr_session_ctx_t* startup_session; interfaces_nl_ctx_t nl_ctx; + interfaces_state_changes_ctx_t state_ctx; }; #endif // INTERFACES_PLUGIN_CONTEXT_H \ No newline at end of file From 4f0c5d5af30f93fbc587e83942fab397b254d236 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 23 Aug 2022 17:11:22 +0200 Subject: [PATCH 043/247] interfaces-plugin: refactor interface state changes tracking --- CMakeModules/FindPTHREAD.cmake | 24 ++++++++ src/interfaces/CMakeLists.txt | 16 +++++- src/interfaces/src/plugin.c | 86 ++++++++++++++++++++++++++++- src/interfaces/src/plugin/context.h | 5 ++ 4 files changed, 127 insertions(+), 4 deletions(-) create mode 100644 CMakeModules/FindPTHREAD.cmake diff --git a/CMakeModules/FindPTHREAD.cmake b/CMakeModules/FindPTHREAD.cmake new file mode 100644 index 00000000..edf8ab1d --- /dev/null +++ b/CMakeModules/FindPTHREAD.cmake @@ -0,0 +1,24 @@ +if(PTHREAD_LIBRARIES AND PTHREAD_INCLUDE_DIRS) + set(PTHREAD_FOUND TRUE) +else() + find_path( + PTHREAD_INCLUDE_DIR + NAMES pthread.h + PATHS /usr/include /usr/local/include /opt/local/include /sw/include ${CMAKE_INCLUDE_PATH} ${CMAKE_INSTALL_PREFIX}/include + ) + + find_library( + PTHREAD_LIBRARY + NAMES pthread + PATHS /usr/lib /usr/lib64 /usr/local/lib /usr/local/lib64 /opt/local/lib /sw/lib ${CMAKE_LIBRARY_PATH} ${CMAKE_INSTALL_PREFIX}/lib + ) + + if(PTHREAD_INCLUDE_DIR AND PTHREAD_LIBRARY) + set(PTHREAD_FOUND TRUE) + else(PTHREAD_INCLUDE_DIR AND PTHREAD_LIBRARY) + set(PTHREAD_FOUND FALSE) + endif(PTHREAD_INCLUDE_DIR AND PTHREAD_LIBRARY) + + set(PTHREAD_INCLUDE_DIRS ${PTHREAD_INCLUDE_DIR}) + set(PTHREAD_LIBRARIES ${PTHREAD_LIBRARY}) +endif() \ No newline at end of file diff --git a/src/interfaces/CMakeLists.txt b/src/interfaces/CMakeLists.txt index 61d179b9..30931710 100644 --- a/src/interfaces/CMakeLists.txt +++ b/src/interfaces/CMakeLists.txt @@ -9,6 +9,7 @@ include_directories( ) set(PLUGIN 0 CACHE BOOL "Build a plugin") +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMakeModules") set( SOURCES @@ -32,6 +33,14 @@ set( src/plugin.c ) +# packages +find_package(AUGYANG) +find_package(PTHREAD REQUIRED) +find_package(LIBYANG REQUIRED) +find_package(SYSREPO REQUIRED) +find_package(SRPC REQUIRED) +find_package(NL REQUIRED) + # plugin library add_library( ${PLUGIN_LIBRARY_NAME} @@ -47,11 +56,9 @@ target_link_libraries( ${LIBYANG_LIBRARIES} ${SRPC_LIBRARIES} ${NL_LIBRARIES} + ${PTHREAD_LIBRARIES} ) -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMakeModules") -find_package(AUGYANG) - if(PLUGIN) # ignore plugin library and compile PROJECT_NAME as a module add_library( @@ -64,6 +71,7 @@ if(PLUGIN) ${LIBYANG_LIBRARIES} ${SRPC_LIBRARIES} ${NL_LIBRARIES} + ${PTHREAD_LIBRARIES} ) else() add_executable( @@ -80,6 +88,7 @@ else() ${LIBYANG_LIBRARIES} ${SRPC_LIBRARIES} ${NL_LIBRARIES} + ${PTHREAD_LIBRARIES} ) endif() @@ -88,6 +97,7 @@ include_directories( ${LIBYANG_INCLUDE_DIRS} ${SRPC_INCLUDE_DIRS} ${NL_INCLUDE_DIRS} + ${PTHREAD_INCLUDE_DIRS} ) # augyang support diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index 3cc64c1e..6cc6aa1d 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -1,10 +1,12 @@ #include "plugin.h" #include "netlink/cache.h" +#include "netlink/route/link.h" #include "netlink/socket.h" #include "plugin/common.h" #include "plugin/context.h" // startup +#include "plugin/data/interfaces/interface/state.h" #include "plugin/startup/load.h" #include "plugin/startup/store.h" @@ -17,10 +19,13 @@ #include "srpc/types.h" #include +#include #include #include static int interfaces_init_state_changes_tracking(interfaces_state_changes_ctx_t* ctx); +static void interfaces_link_cache_change_cb(struct nl_cache* cache, struct nl_object* obj, int val, void* arg); +static void* interfaces_link_manager_thread_cb(void* data); int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) { @@ -302,7 +307,86 @@ void sr_plugin_cleanup_cb(sr_session_ctx_t* running_session, void* private_data) static int interfaces_init_state_changes_tracking(interfaces_state_changes_ctx_t* ctx) { - // setup threads to check every link state and write timestamps of changes int error = 0; + struct rtnl_link* link = NULL; + pthread_attr_t attr; + + ctx->state_hash = interfaces_interface_state_hash_new(); + + SRPC_SAFE_CALL_PTR(ctx->socket, nl_socket_alloc(), error_out); + + // connect and get all links + SRPC_SAFE_CALL_ERR(error, nl_connect(ctx->socket, NETLINK_ROUTE), error_out); + SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(ctx->socket, AF_UNSPEC, &ctx->link_cache), error_out); + + link = (struct rtnl_link*)nl_cache_get_first(ctx->link_cache); + + while (link != NULL) { + // create hash entries + const uint8_t oper_state = rtnl_link_get_operstate(link); + const time_t current_time = time(NULL); + const char* link_name = rtnl_link_get_name(link); + + // add entry to the hash table + SRPC_SAFE_CALL_ERR(error, interfaces_interface_state_hash_add(&ctx->state_hash, link_name, oper_state, current_time), error_out); + + link = (struct rtnl_link*)nl_cache_get_next((struct nl_object*)link); + } + + // setup cache manager + SRPC_SAFE_CALL_ERR(error, nl_cache_mngr_alloc(NULL, NETLINK_ROUTE, 0, &ctx->link_cache_manager), error_out); + SRPC_SAFE_CALL_ERR(error, nl_cache_mngr_add(ctx->link_cache_manager, "route/link", interfaces_link_cache_change_cb, ctx, &ctx->link_cache), error_out); + + // setup detatched thread for sending change signals to the cache manager + SRPC_SAFE_CALL_ERR(error, pthread_attr_init(&attr), error_out); + SRPC_SAFE_CALL_ERR(error, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED), error_out); + SRPC_SAFE_CALL_ERR(error, pthread_create(&ctx->manager_thread, &attr, interfaces_link_manager_thread_cb, ctx), error_out); + + goto out; + +error_out: + error = -1; + +out: + return error; +} + +static void interfaces_link_cache_change_cb(struct nl_cache* cache, struct nl_object* obj, int val, void* arg) +{ + interfaces_state_changes_ctx_t* ctx = arg; + + struct rtnl_link* link = NULL; + + SRPLG_LOG_INF(PLUGIN_NAME, "Entered callback function for handling link cache changes"); + + link = (struct rtnl_link*)nl_cache_get_first(cache); + + while (link != NULL) { + const char* link_name = rtnl_link_get_name(link); + interfaces_interface_state_t* state = interfaces_interface_state_hash_get(ctx->state_hash, link_name); + const uint8_t oper_state = rtnl_link_get_operstate(link); + + if (state) { + if (oper_state != state->state) { + SRPLG_LOG_INF(PLUGIN_NAME, "Interface %s changed oper-state from %d to %d", link_name, state->state, oper_state); + state->state = oper_state; + state->last_change = time(NULL); + } + } + + link = (struct rtnl_link*)nl_cache_get_next((struct nl_object*)link); + } +} + +static void* interfaces_link_manager_thread_cb(void* data) +{ + interfaces_state_changes_ctx_t* ctx = data; + + do { + nl_cache_mngr_data_ready(ctx->link_cache_manager); + sleep(1); + } while (1); + + return NULL; } \ No newline at end of file diff --git a/src/interfaces/src/plugin/context.h b/src/interfaces/src/plugin/context.h index 314be0dc..eb169218 100644 --- a/src/interfaces/src/plugin/context.h +++ b/src/interfaces/src/plugin/context.h @@ -13,9 +13,14 @@ typedef struct interfaces_ctx_s interfaces_ctx_t; typedef struct interfaces_state_changes_ctx_s interfaces_state_changes_ctx_t; struct interfaces_state_changes_ctx_s { + // libnl data struct nl_sock* socket; struct nl_cache* link_cache; struct nl_cache_mngr* link_cache_manager; + pthread_t manager_thread; + + // main hash DS for storing state info + interfaces_interface_state_t* state_hash; }; struct interfaces_nl_ctx_s { From cd805918e948ee68f0fd5e36032ce4b644a5f245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 23 Aug 2022 17:19:49 +0200 Subject: [PATCH 044/247] interfaces-plugin: free allocated data for interface state changes tracking --- src/interfaces/src/plugin.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index 6cc6aa1d..c4cf747b 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -302,6 +302,22 @@ void sr_plugin_cleanup_cb(sr_session_ctx_t* running_session, void* private_data) nl_socket_free(ctx->nl_ctx.socket); } + if (ctx->state_ctx.link_cache) { + nl_cache_put(ctx->state_ctx.link_cache); + } + + if (ctx->state_ctx.socket) { + nl_socket_free(ctx->state_ctx.socket); + } + + if (ctx->state_ctx.link_cache_manager) { + nl_cache_mngr_free(ctx->state_ctx.link_cache_manager); + } + + if (ctx->state_ctx.state_hash) { + interfaces_interface_state_hash_free(&ctx->state_ctx.state_hash); + } + free(ctx); } From 9397b0a9ba384fbc38570fd4c88369f95d0b4af1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 23 Aug 2022 17:45:21 +0200 Subject: [PATCH 045/247] interfaces-plugin: add mutex for synchronization of state changes data --- src/interfaces/src/plugin.c | 18 +++++++++++++++--- src/interfaces/src/plugin/context.h | 4 ++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index c4cf747b..b933c06c 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -302,9 +302,7 @@ void sr_plugin_cleanup_cb(sr_session_ctx_t* running_session, void* private_data) nl_socket_free(ctx->nl_ctx.socket); } - if (ctx->state_ctx.link_cache) { - nl_cache_put(ctx->state_ctx.link_cache); - } + pthread_mutex_lock(&ctx->state_ctx.state_hash_mutex); if (ctx->state_ctx.socket) { nl_socket_free(ctx->state_ctx.socket); @@ -318,6 +316,8 @@ void sr_plugin_cleanup_cb(sr_session_ctx_t* running_session, void* private_data) interfaces_interface_state_hash_free(&ctx->state_ctx.state_hash); } + pthread_mutex_unlock(&ctx->state_ctx.state_hash_mutex); + free(ctx); } @@ -327,14 +327,19 @@ static int interfaces_init_state_changes_tracking(interfaces_state_changes_ctx_t struct rtnl_link* link = NULL; pthread_attr_t attr; + // init hash ctx->state_hash = interfaces_interface_state_hash_new(); + // init libnl data SRPC_SAFE_CALL_PTR(ctx->socket, nl_socket_alloc(), error_out); // connect and get all links SRPC_SAFE_CALL_ERR(error, nl_connect(ctx->socket, NETLINK_ROUTE), error_out); SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(ctx->socket, AF_UNSPEC, &ctx->link_cache), error_out); + // init hash mutex + SRPC_SAFE_CALL_ERR(error, pthread_mutex_init(&ctx->state_hash_mutex, NULL), error_out); + link = (struct rtnl_link*)nl_cache_get_first(ctx->link_cache); while (link != NULL) { @@ -372,6 +377,10 @@ static void interfaces_link_cache_change_cb(struct nl_cache* cache, struct nl_ob { interfaces_state_changes_ctx_t* ctx = arg; + // block further access using mutex + + pthread_mutex_lock(&ctx->state_hash_mutex); + struct rtnl_link* link = NULL; SRPLG_LOG_INF(PLUGIN_NAME, "Entered callback function for handling link cache changes"); @@ -393,6 +402,9 @@ static void interfaces_link_cache_change_cb(struct nl_cache* cache, struct nl_ob link = (struct rtnl_link*)nl_cache_get_next((struct nl_object*)link); } + + // unlock further access to the state hash + pthread_mutex_unlock(&ctx->state_hash_mutex); } static void* interfaces_link_manager_thread_cb(void* data) diff --git a/src/interfaces/src/plugin/context.h b/src/interfaces/src/plugin/context.h index eb169218..bdd70b2f 100644 --- a/src/interfaces/src/plugin/context.h +++ b/src/interfaces/src/plugin/context.h @@ -3,6 +3,7 @@ #include "netlink/cache.h" #include "plugin/types.h" +#include #include #include @@ -21,6 +22,9 @@ struct interfaces_state_changes_ctx_s { // main hash DS for storing state info interfaces_interface_state_t* state_hash; + + // mutex for accessing state hash data + pthread_mutex_t state_hash_mutex; }; struct interfaces_nl_ctx_s { From d1c120ff27bffce3df48dc44c9bac805e6207bc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 23 Aug 2022 18:00:38 +0200 Subject: [PATCH 046/247] interfaces-plugin: implement last-change operational leaf --- src/interfaces/src/plugin.c | 8 +++- .../src/plugin/subscription/operational.c | 47 ++++++++++++++++--- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index b933c06c..d84d2580 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -376,6 +376,8 @@ static int interfaces_init_state_changes_tracking(interfaces_state_changes_ctx_t static void interfaces_link_cache_change_cb(struct nl_cache* cache, struct nl_object* obj, int val, void* arg) { interfaces_state_changes_ctx_t* ctx = arg; + char time_buffer[100] = { 0 }; + struct tm* last_change = NULL; // block further access using mutex @@ -394,7 +396,11 @@ static void interfaces_link_cache_change_cb(struct nl_cache* cache, struct nl_ob if (state) { if (oper_state != state->state) { - SRPLG_LOG_INF(PLUGIN_NAME, "Interface %s changed oper-state from %d to %d", link_name, state->state, oper_state); + const time_t current = time(NULL); + last_change = localtime(¤t); + strftime(time_buffer, sizeof(time_buffer), "%FT%TZ", last_change); + + SRPLG_LOG_INF(PLUGIN_NAME, "Interface %s changed oper-state from %d to %d at %s", link_name, state->state, oper_state, time_buffer); state->state = oper_state; state->last_change = time(NULL); } diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 9745519d..994bd585 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -7,12 +7,15 @@ #include "netlink/socket.h" #include "plugin/common.h" #include "plugin/context.h" +#include "plugin/data/interfaces/interface/state.h" #include "plugin/ly_tree.h" +#include "plugin/types.h" #include "srpc/common.h" #include "sysrepo_types.h" #include #include +#include #include #include #include @@ -97,16 +100,48 @@ int interfaces_subscription_operational_interfaces_interface_oper_status(sr_sess int interfaces_subscription_operational_interfaces_interface_last_change(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + + // context const struct ly_ctx* ly_ctx = NULL; + interfaces_ctx_t* ctx = private_data; + interfaces_state_changes_ctx_t* state_ctx = &ctx->state_ctx; + interfaces_interface_state_t* state = NULL; - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } + // libnl + struct rtnl_link* link = NULL; + + // buffers + char last_change_buffer[100] = { 0 }; + + // there needs to be an allocated link cache in memory + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "interface") == 0); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + + // synchronization + pthread_mutex_lock(&state_ctx->state_hash_mutex); + + // get last change + SRPC_SAFE_CALL_PTR(state, interfaces_interface_state_hash_get(state_ctx->state_hash, rtnl_link_get_name(link)), error_out); + + const time_t last_change = state->last_change; + struct tm* last_change_tm = localtime(&last_change); + + size_t written = strftime(last_change_buffer, sizeof(last_change_buffer), "%FT%TZ", last_change_tm); + if (written == 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "strftime() failed"); + goto error_out; } + SRPLG_LOG_INF(PLUGIN_NAME, "last-change(%s) = %s", rtnl_link_get_name(link), last_change_buffer); + + // add oper-status node + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_last_change(ly_ctx, *parent, last_change_buffer), error_out); + + pthread_mutex_unlock(&state_ctx->state_hash_mutex); + goto out; error_out: From a8abd270e2cbc7c7d078c03d19a0c3f168707f6b Mon Sep 17 00:00:00 2001 From: agardijan Date: Wed, 24 Aug 2022 10:22:41 +0200 Subject: [PATCH 047/247] interfaces-plugin: change name prefix for consistency --- .../src/plugin/api/interfaces/if_data.c | 24 +++++++++---------- .../src/plugin/api/interfaces/if_data.h | 16 ++++++------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/if_data.c b/src/interfaces/src/plugin/api/interfaces/if_data.c index 6c7d4443..ec77ba40 100644 --- a/src/interfaces/src/plugin/api/interfaces/if_data.c +++ b/src/interfaces/src/plugin/api/interfaces/if_data.c @@ -12,14 +12,14 @@ if_data_init(interfaces_interfaces_interface_element_t* interface) } void -if_data_ht_root_init(interface_ht_element_t **if_root) +interfaces_data_ht_root_init(interface_ht_element_t **if_root) { /* uthash root node has to be initialized to NULL */ *root = NULL; } interface_ht_element_t * -if_data_ht_get_by_name(interface_ht_element_t *if_root, char *name) +interfaces_data_ht_get_by_name(interface_ht_element_t *if_root, char *name) { interface_ht_element_t *elem = NULL; HASH_FIND_STR(if_root, name, elem); @@ -27,13 +27,13 @@ if_data_ht_get_by_name(interface_ht_element_t *if_root, char *name) } void -if_data_ht_set_name(interfaces_interfaces_interface_element_t *interface, char *name) +interfaces_data_ht_set_name(interfaces_interfaces_interface_element_t *interface, char *name) { interface->name = xstrdup(name); } int -if_data_ht_add(interface_ht_element_t *if_root, char *name) +interfaces_data_ht_add(interface_ht_element_t *if_root, char *name) { interface_ht_element_t *tmp = NULL, *elem = NULL; int rc = 0; @@ -46,7 +46,7 @@ if_data_ht_add(interface_ht_element_t *if_root, char *name) elem = (interface_ht_element_t *) xmalloc(sizeof elem); if_data_init(&elem->interface); - if_data_ht_set_name(&elem->interface) + interfaces_data_ht_set_name(&elem->interface) /* since name is char *, *_KEYPTR has to be used instead of *_STR */ HASH_ADD_KEYPTR(hh, if_root, elem->interface.name, sizeof(elem->interface.name), elem); @@ -59,12 +59,12 @@ if_data_ht_add(interface_ht_element_t *if_root, char *name) } int -if_data_ht_set_description(interface_ht_element_t *if_root, char *name, char *description) +interfaces_data_ht_set_description(interface_ht_element_t *if_root, char *name, char *description) { interface_ht_element_t *elem = NULL; int rc = 0; - elem = if_data_ht_get_by_name(if_root, name); + elem = interfaces_data_ht_get_by_name(if_root, name); if (elem == NULL) { SRPLG_LOG_ERR(PLUGIN_NAME, "interface with name key: %s non-existant in hash table", name); goto error_out; @@ -87,12 +87,12 @@ if_data_ht_set_description(interface_ht_element_t *if_root, char *name, char *de } int -if_data_ht_set_type(interface_ht_element_t *if_root, char *name, char *type) +interfaces_data_ht_set_type(interface_ht_element_t *if_root, char *name, char *type) { interface_ht_element_t *elem = NULL; int rc = 0; - elem = if_data_ht_get_by_name(if_root, name); + elem = interfaces_data_ht_get_by_name(if_root, name); if (elem == NULL) { SRPLG_LOG_ERR(PLUGIN_NAME, "interface with name key: %s non-existant in hash table", name); goto error_out; @@ -115,7 +115,7 @@ if_data_ht_set_type(interface_ht_element_t *if_root, char *name, char *type) } void -if_data_ht_if_free(interfaces_interfaces_interface_element_t *interface) +interfaces_data_ht_if_free(interfaces_interfaces_interface_element_t *interface) { /* TODO: free other struct members as needed */ if (interface->name) { @@ -130,13 +130,13 @@ if_data_ht_if_free(interfaces_interfaces_interface_element_t *interface) } void -if_data_ht_free(interface_ht_element_t *if_root) +interfaces_data_ht_free(interface_ht_element_t *if_root) { interface_ht_element_t tmp = NULL, elem = NULL; HASH_ITER(hh, if_root, elem, tmp) { HASH_DEL(if_root, elem); - if_data_ht_if_free(&elem->interface); + interfaces_data_ht_if_free(&elem->interface); FREE_SAFE(elem); } } diff --git a/src/interfaces/src/plugin/api/interfaces/if_data.h b/src/interfaces/src/plugin/api/interfaces/if_data.h index eb826c1b..2be6a5b2 100644 --- a/src/interfaces/src/plugin/api/interfaces/if_data.h +++ b/src/interfaces/src/plugin/api/interfaces/if_data.h @@ -9,27 +9,27 @@ void if_data_init(interfaces_interfaces_interface_element_t* interface); void -if_data_ht_root_init(interface_ht_element_t **if_root); +interfaces_data_ht_root_init(interface_ht_element_t **if_root); interface_ht_element_t * -if_data_ht_get_by_name(interface_ht_element_t *if_root, char *name); +interfaces_data_ht_get_by_name(interface_ht_element_t *if_root, char *name); void -if_data_ht_set_name(interfaces_interfaces_interface_element_t *interface, char *name); +interfaces_data_ht_set_name(interfaces_interfaces_interface_element_t *interface, char *name); int -if_data_ht_add(interface_ht_element_t *if_root, char *name); +interfaces_data_ht_add(interface_ht_element_t *if_root, char *name); int -if_data_ht_set_description(interface_ht_element_t *if_root, char *name, char *description); +interfaces_data_ht_set_description(interface_ht_element_t *if_root, char *name, char *description); int -if_data_ht_set_type(interface_ht_element_t *if_root, char *name, char *type); +interfaces_data_ht_set_type(interface_ht_element_t *if_root, char *name, char *type); void -if_data_ht_if_free(interfaces_interfaces_interface_element_t *interface); +interfaces_data_ht_if_free(interfaces_interfaces_interface_element_t *interface); void -if_data_ht_free(interface_ht_element_t *if_root); +interfaces_data_ht_free(interface_ht_element_t *if_root); #endif /* IF_DATA_H */ From bd154ca67e7b749da68618e52cdbd0e24e17019f Mon Sep 17 00:00:00 2001 From: agardijan Date: Mon, 5 Sep 2022 16:09:49 +0200 Subject: [PATCH 048/247] interfaces-plugin: rename interfaces hash, add cmake sources --- src/interfaces/CMakeLists.txt | 4 +++- src/interfaces/src/plugin/{api/interfaces => data}/if_data.c | 0 src/interfaces/src/plugin/{api/interfaces => data}/if_data.h | 0 3 files changed, 3 insertions(+), 1 deletion(-) rename src/interfaces/src/plugin/{api/interfaces => data}/if_data.c (100%) rename src/interfaces/src/plugin/{api/interfaces => data}/if_data.h (100%) diff --git a/src/interfaces/CMakeLists.txt b/src/interfaces/CMakeLists.txt index 2fa6fcdc..43331fa4 100644 --- a/src/interfaces/CMakeLists.txt +++ b/src/interfaces/CMakeLists.txt @@ -19,6 +19,7 @@ set( src/plugin/subscription/operational.c src/plugin/subscription/rpc.c src/plugin/ly_tree.c + src/plugin/data/interface.c src/plugin/api/interfaces/check.c src/plugin/api/interfaces/load.c src/plugin/api/interfaces/store.c @@ -29,6 +30,7 @@ set( src/plugin/api/interfaces/interface/dampening/change.c src/plugin/api/interfaces/interface/carrier-delay/change.c src/plugin.c + ${CMAKE_SOURCE_DIR}/src/utils/memory.c ) # plugin library @@ -94,4 +96,4 @@ if(AUGYANG_FOUND) add_compile_definitions(AUGYANG) else(AUGYANG_FOUND) message(WARNING "AUGYANG not found - augeas support will be disabled") -endif() \ No newline at end of file +endif() diff --git a/src/interfaces/src/plugin/api/interfaces/if_data.c b/src/interfaces/src/plugin/data/if_data.c similarity index 100% rename from src/interfaces/src/plugin/api/interfaces/if_data.c rename to src/interfaces/src/plugin/data/if_data.c diff --git a/src/interfaces/src/plugin/api/interfaces/if_data.h b/src/interfaces/src/plugin/data/if_data.h similarity index 100% rename from src/interfaces/src/plugin/api/interfaces/if_data.h rename to src/interfaces/src/plugin/data/if_data.h From 8b08504c74d9ddd852bfd6c776f3f52969db7c61 Mon Sep 17 00:00:00 2001 From: agardijan Date: Mon, 5 Sep 2022 16:15:58 +0200 Subject: [PATCH 049/247] interfaces-plugin: fix build errors --- .../plugin/data/{if_data.c => interface.c} | 95 ++++++++++++++++--- .../plugin/data/{if_data.h => interface.h} | 16 +++- 2 files changed, 92 insertions(+), 19 deletions(-) rename src/interfaces/src/plugin/data/{if_data.c => interface.c} (58%) rename src/interfaces/src/plugin/data/{if_data.h => interface.h} (58%) diff --git a/src/interfaces/src/plugin/data/if_data.c b/src/interfaces/src/plugin/data/interface.c similarity index 58% rename from src/interfaces/src/plugin/data/if_data.c rename to src/interfaces/src/plugin/data/interface.c index ec77ba40..18eb53f6 100644 --- a/src/interfaces/src/plugin/data/if_data.c +++ b/src/interfaces/src/plugin/data/interface.c @@ -1,21 +1,26 @@ -#include "if_data.h" +#include "interface.h" +#include "plugin/common.h" #include "utils/memory.h" +#include + void -if_data_init(interfaces_interfaces_interface_element_t* interface) +interfaces_data_ht_root_init(interface_ht_element_t **if_root) +{ + /* uthash root node has to be initialized to NULL */ + *if_root = NULL; +} + +static void +interfaces_data_init(interfaces_interfaces_interface_t* interface) { /* TODO: init all struct members */ interface->name = NULL; interface->description = NULL; interface->type = NULL; interface->enabled = 0; -} - -void -interfaces_data_ht_root_init(interface_ht_element_t **if_root) -{ - /* uthash root node has to be initialized to NULL */ - *root = NULL; + interface->loopback = NULL; + interface->parent_interface = NULL; } interface_ht_element_t * @@ -27,7 +32,7 @@ interfaces_data_ht_get_by_name(interface_ht_element_t *if_root, char *name) } void -interfaces_data_ht_set_name(interfaces_interfaces_interface_element_t *interface, char *name) +interfaces_data_ht_set_name(interfaces_interfaces_interface_t *interface, char *name) { interface->name = xstrdup(name); } @@ -45,8 +50,8 @@ interfaces_data_ht_add(interface_ht_element_t *if_root, char *name) } elem = (interface_ht_element_t *) xmalloc(sizeof elem); - if_data_init(&elem->interface); - interfaces_data_ht_set_name(&elem->interface) + interfaces_data_init(&elem->interface); + interfaces_data_ht_set_name(&elem->interface, name); /* since name is char *, *_KEYPTR has to be used instead of *_STR */ HASH_ADD_KEYPTR(hh, if_root, elem->interface.name, sizeof(elem->interface.name), elem); @@ -114,8 +119,64 @@ interfaces_data_ht_set_type(interface_ht_element_t *if_root, char *name, char *t return rc; } +int +interfaces_data_ht_set_loopback(interface_ht_element_t *if_root, char *name, char *loopback) +{ + interface_ht_element_t *elem = NULL; + int rc = 0; + + elem = interfaces_data_ht_get_by_name(if_root, name); + if (elem == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "interface with name key: %s non-existant in hash table", name); + goto error_out; + } + + if (elem->interface.loopback != NULL) { + FREE_SAFE(elem->interface.loopback); + } + elem->interface.loopback = xstrdup(loopback); + if (elem->interface.loopback == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "couldn't copy loopback: %s", loopback); + goto error_out; + } + + goto out; +error_out: + rc = -1; +out: + return rc; +} + +int +interfaces_data_ht_set_parent_interface(interface_ht_element_t *if_root, char *name, char *parent_interface) +{ + interface_ht_element_t *elem = NULL; + int rc = 0; + + elem = interfaces_data_ht_get_by_name(if_root, name); + if (elem == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "interface with name key: %s non-existant in hash table", name); + goto error_out; + } + + if (elem->interface.parent_interface != NULL) { + FREE_SAFE(elem->interface.parent_interface); + } + elem->interface.parent_interface = xstrdup(parent_interface); + if (elem->interface.parent_interface == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "couldn't copy parent interface: %s", parent_interface); + goto error_out; + } + + goto out; +error_out: + rc = -1; +out: + return rc; +} + void -interfaces_data_ht_if_free(interfaces_interfaces_interface_element_t *interface) +interfaces_data_ht_if_free(interfaces_interfaces_interface_t *interface) { /* TODO: free other struct members as needed */ if (interface->name) { @@ -127,12 +188,18 @@ interfaces_data_ht_if_free(interfaces_interfaces_interface_element_t *interface) if (interface->type) { FREE_SAFE(interface->type); } + if (interface->loopback) { + FREE_SAFE(interface->loopback); + } + if (interface->parent_interface) { + FREE_SAFE(interface->parent_interface); + } } void interfaces_data_ht_free(interface_ht_element_t *if_root) { - interface_ht_element_t tmp = NULL, elem = NULL; + interface_ht_element_t *tmp = NULL, *elem = NULL; HASH_ITER(hh, if_root, elem, tmp) { HASH_DEL(if_root, elem); diff --git a/src/interfaces/src/plugin/data/if_data.h b/src/interfaces/src/plugin/data/interface.h similarity index 58% rename from src/interfaces/src/plugin/data/if_data.h rename to src/interfaces/src/plugin/data/interface.h index 2be6a5b2..351119ee 100644 --- a/src/interfaces/src/plugin/data/if_data.h +++ b/src/interfaces/src/plugin/data/interface.h @@ -5,17 +5,17 @@ #include "plugin/types.h" -void -if_data_init(interfaces_interfaces_interface_element_t* interface); - void interfaces_data_ht_root_init(interface_ht_element_t **if_root); +static void +interfaces_data_init(interfaces_interfaces_interface_t* interface); + interface_ht_element_t * interfaces_data_ht_get_by_name(interface_ht_element_t *if_root, char *name); void -interfaces_data_ht_set_name(interfaces_interfaces_interface_element_t *interface, char *name); +interfaces_data_ht_set_name(interfaces_interfaces_interface_t *interface, char *name); int interfaces_data_ht_add(interface_ht_element_t *if_root, char *name); @@ -26,8 +26,14 @@ interfaces_data_ht_set_description(interface_ht_element_t *if_root, char *name, int interfaces_data_ht_set_type(interface_ht_element_t *if_root, char *name, char *type); +int +interfaces_data_ht_set_loopback(interface_ht_element_t *if_root, char *name, char *loopback); + +int +interfaces_data_ht_set_parent_interface(interface_ht_element_t *if_root, char *name, char *parent_interface); + void -interfaces_data_ht_if_free(interfaces_interfaces_interface_element_t *interface); +interfaces_data_ht_if_free(interfaces_interfaces_interface_t *interface); void interfaces_data_ht_free(interface_ht_element_t *if_root); From a1c43cf6d0dd91b925f8ae3740894c994ab92c2b Mon Sep 17 00:00:00 2001 From: agardijan Date: Mon, 5 Sep 2022 18:27:22 +0200 Subject: [PATCH 050/247] interfaces-plugin: add interfaces list yang path --- src/interfaces/src/plugin/common.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/interfaces/src/plugin/common.h b/src/interfaces/src/plugin/common.h index b2416533..8fb3b73a 100644 --- a/src/interfaces/src/plugin/common.h +++ b/src/interfaces/src/plugin/common.h @@ -6,6 +6,7 @@ #define BASE_YANG_MODEL "ietf-interfaces" #define INTERFACES_INTERFACES_CONTAINER_YANG_PATH "/" BASE_YANG_MODEL ":interfaces" +#define INTERFACES_INTERFACES_LIST_YANG_PATH INTERFACES_INTERFACES_CONTAINER_YANG_PATH "/interface" #define INTERFACES_INTERFACES_STATE_INTERFACE_NAME_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_YANG_PATH "/name" #define INTERFACES_INTERFACES_STATE_INTERFACE_TYPE_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_YANG_PATH "/type" From 01321d67cde67825919b9a5d558696ea94dbe4dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 6 Sep 2022 13:49:16 +0200 Subject: [PATCH 051/247] interfaces-plugin: setup changes handling --- examples/test_config.xml | 12 +++++ .../src/plugin/api/interfaces/change.c | 54 +++++++++++++++---- .../src/plugin/api/interfaces/change.h | 2 + .../plugin/api/interfaces/interface/change.c | 16 +++--- src/interfaces/src/plugin/context.h | 7 +++ .../src/plugin/subscription/change.c | 16 +----- 6 files changed, 74 insertions(+), 33 deletions(-) create mode 100644 examples/test_config.xml diff --git a/examples/test_config.xml b/examples/test_config.xml new file mode 100644 index 00000000..952cdd5f --- /dev/null +++ b/examples/test_config.xml @@ -0,0 +1,12 @@ + + + + if0 + Test Interface + ianaift:other + + \ No newline at end of file diff --git a/src/interfaces/src/plugin/api/interfaces/change.c b/src/interfaces/src/plugin/api/interfaces/change.c index d17cc186..2dedcfca 100644 --- a/src/interfaces/src/plugin/api/interfaces/change.c +++ b/src/interfaces/src/plugin/api/interfaces/change.c @@ -1,26 +1,58 @@ #include "change.h" #include "plugin/common.h" +#include "plugin/context.h" +#include "interface/change.h" + +#include #include +int interfaces_change_interface_init(void* priv) +{ + int error = 0; + interfaces_ctx_t* ctx = (interfaces_ctx_t*)priv; + (void)ctx; + + SRPLG_LOG_INF(PLUGIN_NAME, "Initializing context data for interface changes"); + + return error; +} + int interfaces_change_interface(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) { int error = 0; + int rc = 0; + + interfaces_ctx_t* ctx = (interfaces_ctx_t*)priv; + + char xpath_buffer[PATH_MAX] = { 0 }; + char change_xpath_buffer[PATH_MAX] = { 0 }; const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + // get node xpath + lyd_path(change_ctx->node, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)); + + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d, Node XPath: %s", node_name, change_ctx->previous_value, node_value, change_ctx->operation, xpath_buffer); + + // name + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/name", xpath_buffer), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_change_name, NULL, NULL), error_out); + + // description + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/description", xpath_buffer), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_change_description, NULL, NULL), error_out); - switch (change_ctx->operation) { - case SR_OP_CREATED: - break; - case SR_OP_MODIFIED: - break; - case SR_OP_DELETED: - break; - case SR_OP_MOVED: - break; - } + goto out; +error_out: + error = -1; + +out: return error; } + +void interfaces_change_interface_free(void* priv) +{ + SRPLG_LOG_INF(PLUGIN_NAME, "Freeing context data for interface changes"); +} diff --git a/src/interfaces/src/plugin/api/interfaces/change.h b/src/interfaces/src/plugin/api/interfaces/change.h index fb6fe90a..c8e4247e 100644 --- a/src/interfaces/src/plugin/api/interfaces/change.h +++ b/src/interfaces/src/plugin/api/interfaces/change.h @@ -4,6 +4,8 @@ #include #include +int interfaces_change_interface_init(void* priv); int interfaces_change_interface(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +void interfaces_change_interface_free(void* priv); #endif // INTERFACES_PLUGIN_API_INTERFACES_CHANGE_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/api/interfaces/interface/change.c b/src/interfaces/src/plugin/api/interfaces/interface/change.c index 6e77f6dd..08360e46 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/change.c @@ -9,7 +9,7 @@ int interfaces_interface_change_parent_interface(void* priv, sr_session_ctx_t* s const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -31,7 +31,7 @@ int interfaces_interface_change_max_frame_size(void* priv, sr_session_ctx_t* ses const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -53,7 +53,7 @@ int interfaces_interface_change_loopback(void* priv, sr_session_ctx_t* session, const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -75,7 +75,7 @@ int interfaces_interface_change_link_up_down_trap_enable(void* priv, sr_session_ const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -97,7 +97,7 @@ int interfaces_interface_change_enabled(void* priv, sr_session_ctx_t* session, c const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -119,7 +119,7 @@ int interfaces_interface_change_type(void* priv, sr_session_ctx_t* session, cons const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -141,7 +141,7 @@ int interfaces_interface_change_description(void* priv, sr_session_ctx_t* sessio const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -163,7 +163,7 @@ int interfaces_interface_change_name(void* priv, sr_session_ctx_t* session, cons const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: diff --git a/src/interfaces/src/plugin/context.h b/src/interfaces/src/plugin/context.h index bdd70b2f..8d5fe8f4 100644 --- a/src/interfaces/src/plugin/context.h +++ b/src/interfaces/src/plugin/context.h @@ -12,6 +12,7 @@ typedef struct interfaces_nl_ctx_s interfaces_nl_ctx_t; typedef struct interfaces_ctx_s interfaces_ctx_t; typedef struct interfaces_state_changes_ctx_s interfaces_state_changes_ctx_t; +typedef struct interfaces_mod_changes_ctx_s interfaces_mod_changes_ctx_t; struct interfaces_state_changes_ctx_s { // libnl data @@ -27,6 +28,11 @@ struct interfaces_state_changes_ctx_s { pthread_mutex_t state_hash_mutex; }; +struct interfaces_mod_changes_ctx_s { + struct nl_sock* socket; + struct nl_cache* link_cache; +}; + struct interfaces_nl_ctx_s { struct nl_sock* socket; struct nl_cache* link_cache; @@ -36,6 +42,7 @@ struct interfaces_ctx_s { sr_session_ctx_t* startup_session; interfaces_nl_ctx_t nl_ctx; interfaces_state_changes_ctx_t state_ctx; + interfaces_mod_changes_ctx_t mod_ctx; }; #endif // INTERFACES_PLUGIN_CONTEXT_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/subscription/change.c b/src/interfaces/src/plugin/subscription/change.c index a7929078..e5edb597 100644 --- a/src/interfaces/src/plugin/subscription/change.c +++ b/src/interfaces/src/plugin/subscription/change.c @@ -15,18 +15,6 @@ int interfaces_subscription_change_interfaces_interface(sr_session_ctx_t* sessio int error = SR_ERR_OK; interfaces_ctx_t* ctx = (interfaces_ctx_t*)private_data; - // sysrepo - sr_change_iter_t* changes_iterator = NULL; - sr_change_oper_t operation = SR_OP_CREATED; - const char *prev_value = NULL, *prev_list = NULL; - int prev_default; - - const char* node_name = NULL; - const char* node_value = NULL; - - // libyang - const struct lyd_node* node = NULL; - if (event == SR_EV_ABORT) { SRPLG_LOG_ERR(PLUGIN_NAME, "Aborting changes for %s", xpath); goto error_out; @@ -38,7 +26,7 @@ int interfaces_subscription_change_interfaces_interface(sr_session_ctx_t* sessio } } else if (event == SR_EV_CHANGE) { // connect change API - error = srpc_iterate_changes(ctx, session, xpath, interfaces_change_interface); + error = srpc_iterate_changes(ctx, session, xpath, interfaces_change_interface, interfaces_change_interface_init, interfaces_change_interface_free); if (error) { SRPLG_LOG_ERR(PLUGIN_NAME, "srpc_iterate_changes() for interfaces_change_interface failed: %d", error); goto error_out; @@ -51,5 +39,5 @@ int interfaces_subscription_change_interfaces_interface(sr_session_ctx_t* sessio error = SR_ERR_CALLBACK_FAILED; out: - return error; + return SR_ERR_CALLBACK_FAILED; } From 343c136299d9bc3631029e1b559b42d0288d6e8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 6 Sep 2022 13:52:48 +0200 Subject: [PATCH 052/247] interfaces-plugin: add all previous leaf callbacks --- examples/test_config.xml | 1 + src/interfaces/src/plugin/api/interfaces/change.c | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/examples/test_config.xml b/examples/test_config.xml index 952cdd5f..166e3410 100644 --- a/examples/test_config.xml +++ b/examples/test_config.xml @@ -8,5 +8,6 @@ if0 Test Interface ianaift:other + true \ No newline at end of file diff --git a/src/interfaces/src/plugin/api/interfaces/change.c b/src/interfaces/src/plugin/api/interfaces/change.c index 2dedcfca..554c0c5f 100644 --- a/src/interfaces/src/plugin/api/interfaces/change.c +++ b/src/interfaces/src/plugin/api/interfaces/change.c @@ -43,6 +43,18 @@ int interfaces_change_interface(void* priv, sr_session_ctx_t* session, const srp SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/description", xpath_buffer), error_out); SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_change_description, NULL, NULL), error_out); + // type + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/type", xpath_buffer), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_change_type, NULL, NULL), error_out); + + // enabled + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/enabled", xpath_buffer), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_change_enabled, NULL, NULL), error_out); + + // link-up-down-trap-enable + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/link-up-down-trap-enable", xpath_buffer), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_change_link_up_down_trap_enable, NULL, NULL), error_out); + goto out; error_out: From f3cd82edc6ecc37ae80644bc3283019c68cb898e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 6 Sep 2022 15:12:22 +0200 Subject: [PATCH 053/247] interfaces-plugin: initialize needed changes data before calling change callbacks --- .../src/plugin/api/interfaces/change.c | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin/api/interfaces/change.c b/src/interfaces/src/plugin/api/interfaces/change.c index 554c0c5f..54fdd1fe 100644 --- a/src/interfaces/src/plugin/api/interfaces/change.c +++ b/src/interfaces/src/plugin/api/interfaces/change.c @@ -11,10 +11,26 @@ int interfaces_change_interface_init(void* priv) { int error = 0; interfaces_ctx_t* ctx = (interfaces_ctx_t*)priv; - (void)ctx; + interfaces_mod_changes_ctx_t* mod_ctx = &ctx->mod_ctx; SRPLG_LOG_INF(PLUGIN_NAME, "Initializing context data for interface changes"); + // allocate socket + SRPC_SAFE_CALL_PTR(mod_ctx->socket, nl_socket_alloc(), error_out); + + // connect + SRPC_SAFE_CALL_ERR(error, nl_connect(mod_ctx->socket, NETLINK_ROUTE), error_out); + + // allocate link cache + SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(mod_ctx->socket, 0, &mod_ctx->link_cache), error_out); + + goto out; + +error_out: + error = -1; + +out: + return error; } @@ -66,5 +82,18 @@ int interfaces_change_interface(void* priv, sr_session_ctx_t* session, const srp void interfaces_change_interface_free(void* priv) { + interfaces_ctx_t* ctx = (interfaces_ctx_t*)priv; + interfaces_mod_changes_ctx_t* mod_ctx = &ctx->mod_ctx; + SRPLG_LOG_INF(PLUGIN_NAME, "Freeing context data for interface changes"); + + if (mod_ctx->link_cache) { + nl_cache_put(ctx->nl_ctx.link_cache); + } + if (mod_ctx->socket) { + nl_socket_free(ctx->nl_ctx.socket); + } + + // set to NULL + ctx->mod_ctx = (interfaces_mod_changes_ctx_t) { 0 }; } From dfcf09dc243905683d8072b33c387a707527fae0 Mon Sep 17 00:00:00 2001 From: agardijan Date: Tue, 6 Sep 2022 15:34:39 +0200 Subject: [PATCH 054/247] unit-tests: add initial interfaces unit tests template --- tests/interfaces/interfaces_utest.c | 59 +++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 tests/interfaces/interfaces_utest.c diff --git a/tests/interfaces/interfaces_utest.c b/tests/interfaces/interfaces_utest.c new file mode 100644 index 00000000..ad5affb7 --- /dev/null +++ b/tests/interfaces/interfaces_utest.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include +#include +#include + +/* load api */ +#include "plugin/api/interfaces/load.h" + +/* init functionality */ +static int setup(void **state); +static int teardown(void **state); + +/* tests */ + +/* load */ +static void test_correct_load_interface(void **state); + +int main(void) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_correct_load_interface), + }; + + return cmocka_run_group_tests(tests, setup, teardown); +} + +static int setup(void **state) +{ + interfaces_ctx_t *ctx = malloc(sizeof(interfaces_ctx_t)); + if (!ctx) { + return -1; + } + + *ctx = (interfaces_ctx_t){0}; + *state = ctx; + + return 0; +} + +static int teardown(void **state) +{ + if (*state) { + free(*state); + } + + return 0; +} + +static void test_correct_load_interface(void **state) +{ + interfaces_ctx_t *ctx = *state; + int rc = 0; + + assert_int_equal(rc, 0); +} + From 5ca6c64cbdd473910fff30bd8fa52987865139c9 Mon Sep 17 00:00:00 2001 From: agardijan Date: Tue, 6 Sep 2022 15:36:09 +0200 Subject: [PATCH 055/247] unit-tests: split builds per plugin target --- tests/Tests.cmake | 20 ++------------------ tests/interfaces/CMakeLists.txt | 22 ++++++++++++++++++++++ tests/routing/CMakeLists.txt | 22 ++++++++++++++++++++++ 3 files changed, 46 insertions(+), 18 deletions(-) create mode 100644 tests/interfaces/CMakeLists.txt create mode 100644 tests/routing/CMakeLists.txt diff --git a/tests/Tests.cmake b/tests/Tests.cmake index fca00a16..cdeac767 100644 --- a/tests/Tests.cmake +++ b/tests/Tests.cmake @@ -1,18 +1,2 @@ - -# routing_utest -add_executable( - "routing_utest" - - "tests/routing/routing_utest.c" -) -target_link_libraries( - "routing_utest" - - ${CMOCKA_LIBRARIES} - ${SYSREPO_LIBRARIES} - ${LIBYANG_LIBRARIES} -) -add_test( - NAME routing_utest - COMMAND routing_utest -) \ No newline at end of file +add_subdirectory(${CMAKE_SOURCE_DIR}/tests/interfaces) +add_subdirectory(${CMAKE_SOURCE_DIR}/tests/routing) diff --git a/tests/interfaces/CMakeLists.txt b/tests/interfaces/CMakeLists.txt new file mode 100644 index 00000000..023b11f3 --- /dev/null +++ b/tests/interfaces/CMakeLists.txt @@ -0,0 +1,22 @@ +set(INTERFACES_UTEST_NAME "interfaces_utest") + +add_executable( + ${INTERFACES_UTEST_NAME} + + "interfaces_utest.c" +) +target_include_directories( + ${INTERFACES_UTEST_NAME} + PUBLIC ${CMAKE_SOURCE_DIR}/src/interfaces/src +) +target_link_libraries( + ${INTERFACES_UTEST_NAME} + + ${CMOCKA_LIBRARIES} + ${SYSREPO_LIBRARIES} + ${LIBYANG_LIBRARIES} +) +add_test( + NAME ${INTERFACES_UTEST_NAME} + COMMAND interfaces_utest +) diff --git a/tests/routing/CMakeLists.txt b/tests/routing/CMakeLists.txt new file mode 100644 index 00000000..0a9303f0 --- /dev/null +++ b/tests/routing/CMakeLists.txt @@ -0,0 +1,22 @@ +set(ROUTING_UTEST_NAME "routing_utest") + +add_executable( + ${ROUTING_UTEST_NAME} + + "routing_utest.c" +) +target_include_directories( + ${ROUTING_UTEST_NAME} + PUBLIC ${CMAKE_SOURCE_DIR}/src/routing/src +) +target_link_libraries( + ${ROUTING_UTEST_NAME} + + ${CMOCKA_LIBRARIES} + ${SYSREPO_LIBRARIES} + ${LIBYANG_LIBRARIES} +) +add_test( + NAME ${ROUTING_UTEST_NAME} + COMMAND routing_utest +) From a03bc13b7dc7635ff4186f7fc855cce0ff923373 Mon Sep 17 00:00:00 2001 From: agardijan Date: Tue, 6 Sep 2022 16:05:39 +0200 Subject: [PATCH 056/247] unit-tests: switch to xmalloc, FREE_SAFE --- tests/interfaces/CMakeLists.txt | 7 +++++++ tests/interfaces/interfaces_utest.c | 7 +++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/interfaces/CMakeLists.txt b/tests/interfaces/CMakeLists.txt index 023b11f3..ad2c002b 100644 --- a/tests/interfaces/CMakeLists.txt +++ b/tests/interfaces/CMakeLists.txt @@ -1,4 +1,5 @@ set(INTERFACES_UTEST_NAME "interfaces_utest") +set(UTILS_MEMORY_LIBRARY_NAME "utils_memory") add_executable( ${INTERFACES_UTEST_NAME} @@ -9,12 +10,18 @@ target_include_directories( ${INTERFACES_UTEST_NAME} PUBLIC ${CMAKE_SOURCE_DIR}/src/interfaces/src ) +add_library( + ${UTILS_MEMORY_LIBRARY_NAME} + STATIC + ${CMAKE_SOURCE_DIR}/src/utils/memory.c +) target_link_libraries( ${INTERFACES_UTEST_NAME} ${CMOCKA_LIBRARIES} ${SYSREPO_LIBRARIES} ${LIBYANG_LIBRARIES} + ${UTILS_MEMORY_LIBRARY_NAME} ) add_test( NAME ${INTERFACES_UTEST_NAME} diff --git a/tests/interfaces/interfaces_utest.c b/tests/interfaces/interfaces_utest.c index ad5affb7..2b3ff80f 100644 --- a/tests/interfaces/interfaces_utest.c +++ b/tests/interfaces/interfaces_utest.c @@ -6,6 +6,9 @@ #include #include +/* xmalloc, FREE_SAFE */ +#include "utils/memory.h" + /* load api */ #include "plugin/api/interfaces/load.h" @@ -29,7 +32,7 @@ int main(void) static int setup(void **state) { - interfaces_ctx_t *ctx = malloc(sizeof(interfaces_ctx_t)); + interfaces_ctx_t *ctx = xmalloc(sizeof(interfaces_ctx_t)); if (!ctx) { return -1; } @@ -43,7 +46,7 @@ static int setup(void **state) static int teardown(void **state) { if (*state) { - free(*state); + FREE_SAFE(*state); } return 0; From 51065c89de51979486d4e1bbde5da63ad628723f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 6 Sep 2022 18:23:16 +0200 Subject: [PATCH 057/247] interfaces-plugin: implement interface name change API --- .../src/plugin/api/interfaces/change.c | 2 +- .../plugin/api/interfaces/interface/change.c | 36 ++++++++++++++++++- .../src/plugin/subscription/operational.c | 2 +- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/change.c b/src/interfaces/src/plugin/api/interfaces/change.c index 54fdd1fe..bbaca468 100644 --- a/src/interfaces/src/plugin/api/interfaces/change.c +++ b/src/interfaces/src/plugin/api/interfaces/change.c @@ -22,7 +22,7 @@ int interfaces_change_interface_init(void* priv) SRPC_SAFE_CALL_ERR(error, nl_connect(mod_ctx->socket, NETLINK_ROUTE), error_out); // allocate link cache - SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(mod_ctx->socket, 0, &mod_ctx->link_cache), error_out); + SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(mod_ctx->socket, AF_UNSPEC, &mod_ctx->link_cache), error_out); goto out; diff --git a/src/interfaces/src/plugin/api/interfaces/interface/change.c b/src/interfaces/src/plugin/api/interfaces/interface/change.c index 08360e46..bab91740 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/change.c @@ -1,5 +1,7 @@ #include "change.h" +#include "netlink/route/link.h" #include "plugin/common.h" +#include "plugin/context.h" #include @@ -160,6 +162,12 @@ int interfaces_interface_change_description(void* priv, sr_session_ctx_t* sessio int interfaces_interface_change_name(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) { int error = 0; + + interfaces_ctx_t* ctx = (interfaces_ctx_t*)priv; + interfaces_mod_changes_ctx_t* mod_ctx = &ctx->mod_ctx; + struct rtnl_link* new_link = NULL; + struct rtnl_link* old_link = NULL; + const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); @@ -167,14 +175,40 @@ int interfaces_interface_change_name(void* priv, sr_session_ctx_t* session, cons switch (change_ctx->operation) { case SR_OP_CREATED: + old_link = rtnl_link_get_by_name(mod_ctx->link_cache, node_value); + + // add a new link if such a link doesn't exist + if (!old_link) { + // create a new link + SRPC_SAFE_CALL_PTR(new_link, rtnl_link_alloc(), error_out); + + // setup link and add it to the system + rtnl_link_set_name(new_link, node_value); + + SRPC_SAFE_CALL_ERR(error, rtnl_link_add(mod_ctx->socket, new_link, 0), error_out); + } break; case SR_OP_MODIFIED: - break; + // name cannot be modified - only deleted and created again + goto error_out; case SR_OP_DELETED: + // get link and delete it + SRPC_SAFE_CALL_PTR(old_link, rtnl_link_get_by_name(mod_ctx->link_cache, change_ctx->previous_value), error_out); + + SRPC_SAFE_CALL_ERR(error, rtnl_link_delete(mod_ctx->socket, old_link), error_out); break; case SR_OP_MOVED: break; } + // if all succeeded - refresh link cache for changes + SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(mod_ctx->socket, AF_UNSPEC, &mod_ctx->link_cache), error_out); + + goto out; + +error_out: + error = -1; + +out: return error; } diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 994bd585..b241942b 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -1175,7 +1175,7 @@ int interfaces_subscription_operational_interfaces_interface(sr_session_ctx_t* s nl_cache_refill(nl_ctx->socket, nl_ctx->link_cache); } else { // allocate new link cache - SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(nl_ctx->socket, 0, &nl_ctx->link_cache), error_out); + SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(nl_ctx->socket, AF_UNSPEC, &nl_ctx->link_cache), error_out); } if (*parent == NULL) { From c4e40a08b0cff5bf7987dc4979ba506065cf3f38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 6 Sep 2022 18:50:09 +0200 Subject: [PATCH 058/247] interfaces-plugin: implement interface type change API --- .../plugin/api/interfaces/interface/change.c | 101 +++++++++++++++++- .../src/plugin/subscription/change.c | 2 +- 2 files changed, 101 insertions(+), 2 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/change.c b/src/interfaces/src/plugin/api/interfaces/interface/change.c index bab91740..80a9f522 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/change.c @@ -2,9 +2,12 @@ #include "netlink/route/link.h" #include "plugin/common.h" #include "plugin/context.h" +#include "sysrepo/xpath.h" #include +static int interfacecs_interface_extract_name(sr_session_ctx_t* session, const struct lyd_node* node, char* name_buffer, size_t buffer_size); + int interfaces_interface_change_parent_interface(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) { int error = 0; @@ -118,22 +121,89 @@ int interfaces_interface_change_enabled(void* priv, sr_session_ctx_t* session, c int interfaces_interface_change_type(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) { int error = 0; + + char interface_name_buffer[256] = { 0 }; + + interfaces_ctx_t* ctx = (interfaces_ctx_t*)priv; + interfaces_mod_changes_ctx_t* mod_ctx = &ctx->mod_ctx; + struct rtnl_link* current_link = NULL; + struct rtnl_link* request_link = NULL; + bool type_set = false; + + struct { + const char* yang_type; + const char* type; + } type_pairs[] = { + { + "iana-if-type:ethernetCsmacd", + "eth", + }, + { + "iana-if-type:softwareLoopback", + "lo", + }, + { + "iana-if-type:l2vlan", + "vlan", + }, + { + "iana-if-type:other", + "dummy", + }, + }; + const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + // get interface name + SRPC_SAFE_CALL_ERR(error, interfacecs_interface_extract_name(session, change_ctx->node, interface_name_buffer, sizeof(interface_name_buffer)), error_out); + + // get link by name + SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->link_cache, interface_name_buffer), error_out); + switch (change_ctx->operation) { case SR_OP_CREATED: - break; case SR_OP_MODIFIED: + request_link = rtnl_link_alloc(); + + // set name + rtnl_link_set_name(request_link, interface_name_buffer); + + // set type + for (size_t i = 0; i < ARRAY_SIZE(type_pairs); i++) { + if (!strcmp(node_value, type_pairs[i].yang_type)) { + rtnl_link_set_type(request_link, type_pairs[i].type); + type_set = true; + break; + } + } + + if (!type_set) { + SRPLG_LOG_ERR(PLUGIN_NAME, "Unsupported interface type (%s)", node_value); + goto error_out; + } + + // apply changes + SRPC_SAFE_CALL_ERR(error, rtnl_link_change(mod_ctx->socket, current_link, request_link, 0), error_out); break; case SR_OP_DELETED: + // unsupported - type is necessarry break; case SR_OP_MOVED: break; } + // if all succeeded - refresh link cache for changes + SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(mod_ctx->socket, AF_UNSPEC, &mod_ctx->link_cache), error_out); + + goto out; + +error_out: + error = -1; + +out: return error; } @@ -212,3 +282,32 @@ int interfaces_interface_change_name(void* priv, sr_session_ctx_t* session, cons out: return error; } + +static int interfacecs_interface_extract_name(sr_session_ctx_t* session, const struct lyd_node* node, char* name_buffer, size_t buffer_size) +{ + int error = 0; + int rc = 0; + void* error_ptr = NULL; + + const char* name = NULL; + + sr_xpath_ctx_t xpath_ctx = { 0 }; + char path_buffer[PATH_MAX] = { 0 }; + + // get node full path + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(node, LYD_PATH_STD, path_buffer, sizeof(path_buffer)), error_out); + + // extract key + SRPC_SAFE_CALL_PTR(name, sr_xpath_key_value(path_buffer, "interface", "name", &xpath_ctx), error_out); + + // store to buffer + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(name_buffer, buffer_size, "%s", name), error_out); + + goto out; + +error_out: + error = -1; + +out: + return error; +} \ No newline at end of file diff --git a/src/interfaces/src/plugin/subscription/change.c b/src/interfaces/src/plugin/subscription/change.c index e5edb597..4ff86fb8 100644 --- a/src/interfaces/src/plugin/subscription/change.c +++ b/src/interfaces/src/plugin/subscription/change.c @@ -39,5 +39,5 @@ int interfaces_subscription_change_interfaces_interface(sr_session_ctx_t* sessio error = SR_ERR_CALLBACK_FAILED; out: - return SR_ERR_CALLBACK_FAILED; + return error; } From 473f62aee7530c0610912d93e22477abbceae882 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 6 Sep 2022 18:55:17 +0200 Subject: [PATCH 059/247] interfaces-plugin: implement interface enabled leaf change API --- .../plugin/api/interfaces/interface/change.c | 49 ++++++++++++++++--- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/change.c b/src/interfaces/src/plugin/api/interfaces/interface/change.c index 80a9f522..a1759f24 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/change.c @@ -4,6 +4,7 @@ #include "plugin/context.h" #include "sysrepo/xpath.h" +#include #include static int interfacecs_interface_extract_name(sr_session_ctx_t* session, const struct lyd_node* node, char* name_buffer, size_t buffer_size); @@ -99,22 +100,57 @@ int interfaces_interface_change_link_up_down_trap_enable(void* priv, sr_session_ int interfaces_interface_change_enabled(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) { int error = 0; + + char interface_name_buffer[256] = { 0 }; + + interfaces_ctx_t* ctx = (interfaces_ctx_t*)priv; + interfaces_mod_changes_ctx_t* mod_ctx = &ctx->mod_ctx; + struct rtnl_link* current_link = NULL; + struct rtnl_link* request_link = NULL; + const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + // get interface name + SRPC_SAFE_CALL_ERR(error, interfacecs_interface_extract_name(session, change_ctx->node, interface_name_buffer, sizeof(interface_name_buffer)), error_out); + + // get link by name + SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->link_cache, interface_name_buffer), error_out); + + // create request link + SRPC_SAFE_CALL_PTR(request_link, rtnl_link_alloc(), error_out); + + // set name + rtnl_link_set_name(request_link, interface_name_buffer); + switch (change_ctx->operation) { case SR_OP_CREATED: - break; case SR_OP_MODIFIED: + // set operstate + rtnl_link_set_operstate(request_link, (strcmp(node_value, "true") == 0) ? IF_OPER_UP : IF_OPER_DOWN); break; case SR_OP_DELETED: + // treat as set to up - default value + rtnl_link_set_operstate(request_link, IF_OPER_UP); break; case SR_OP_MOVED: break; } + // apply changes + SRPC_SAFE_CALL_ERR(error, rtnl_link_change(mod_ctx->socket, current_link, request_link, 0), error_out); + + // if all succeeded - refresh link cache for changes + SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(mod_ctx->socket, AF_UNSPEC, &mod_ctx->link_cache), error_out); + + goto out; + +error_out: + error = -1; + +out: return error; } @@ -163,14 +199,15 @@ int interfaces_interface_change_type(void* priv, sr_session_ctx_t* session, cons // get link by name SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->link_cache, interface_name_buffer), error_out); + // create request link + SRPC_SAFE_CALL_PTR(request_link, rtnl_link_alloc(), error_out); + + // set name + rtnl_link_set_name(request_link, interface_name_buffer); + switch (change_ctx->operation) { case SR_OP_CREATED: case SR_OP_MODIFIED: - request_link = rtnl_link_alloc(); - - // set name - rtnl_link_set_name(request_link, interface_name_buffer); - // set type for (size_t i = 0; i < ARRAY_SIZE(type_pairs); i++) { if (!strcmp(node_value, type_pairs[i].yang_type)) { From ed1e72a6496e2a341c040d46f7f12a8306bfa41b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Wed, 7 Sep 2022 15:05:48 +0200 Subject: [PATCH 060/247] interfaces-plugin: fix link creation --- examples/test_config.xml | 2 +- .../src/plugin/api/interfaces/interface/change.c | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/examples/test_config.xml b/examples/test_config.xml index 166e3410..12eff8c4 100644 --- a/examples/test_config.xml +++ b/examples/test_config.xml @@ -5,7 +5,7 @@ xmlns:if-ext="urn:ietf:params:xml:ns:yang:ietf-if-extensions"> - if0 + test_if Test Interface ianaift:other true diff --git a/src/interfaces/src/plugin/api/interfaces/interface/change.c b/src/interfaces/src/plugin/api/interfaces/interface/change.c index a1759f24..b6a40824 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/change.c @@ -1,12 +1,16 @@ #include "change.h" +#include "netlink/errno.h" #include "netlink/route/link.h" #include "plugin/common.h" #include "plugin/context.h" #include "sysrepo/xpath.h" #include +#include #include +#include + static int interfacecs_interface_extract_name(sr_session_ctx_t* session, const struct lyd_node* node, char* name_buffer, size_t buffer_size); int interfaces_interface_change_parent_interface(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) @@ -172,7 +176,7 @@ int interfaces_interface_change_type(void* priv, sr_session_ctx_t* session, cons } type_pairs[] = { { "iana-if-type:ethernetCsmacd", - "eth", + "veth", }, { "iana-if-type:softwareLoopback", @@ -292,7 +296,10 @@ int interfaces_interface_change_name(void* priv, sr_session_ctx_t* session, cons // setup link and add it to the system rtnl_link_set_name(new_link, node_value); - SRPC_SAFE_CALL_ERR(error, rtnl_link_add(mod_ctx->socket, new_link, 0), error_out); + // set temp as initial type + SRPC_SAFE_CALL_ERR(error, rtnl_link_set_type(new_link, "dummy"), error_out); + + SRPC_SAFE_CALL_ERR(error, rtnl_link_add(mod_ctx->socket, new_link, NLM_F_CREATE), error_out); } break; case SR_OP_MODIFIED: @@ -314,6 +321,9 @@ int interfaces_interface_change_name(void* priv, sr_session_ctx_t* session, cons goto out; error_out: + if (error < 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "nl_geterror(): %d = %s", error, nl_geterror(error)); + } error = -1; out: From 25735b61cf110a25fb44c5dc088bb8ea9214d518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jurica=20Kule=C5=A1?= Date: Fri, 9 Sep 2022 11:24:47 +0200 Subject: [PATCH 061/247] sysrepo-plugin-interfaces: set operational getters to correct value --- src/interfaces/src/plugin.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index d84d2580..9fa7910f 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -68,8 +68,9 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) // operational getters srpc_operational_t oper[] = { { + //depends on if-mib feature INTERFACES_INTERFACES_INTERFACE_ADMIN_STATUS_YANG_PATH, - interfaces_subscription_operational_interfaces_interface_admin_status, + srpc_feature_status_hash_check(ietf_interfaces_features, "if-mib")? interfaces_subscription_operational_interfaces_interface_admin_status: NULL, }, { INTERFACES_INTERFACES_INTERFACE_OPER_STATUS_YANG_PATH, @@ -80,8 +81,9 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) interfaces_subscription_operational_interfaces_interface_last_change, }, { + //depends on if-mib feature INTERFACES_INTERFACES_INTERFACE_IF_INDEX_YANG_PATH, - interfaces_subscription_operational_interfaces_interface_if_index, + srpc_feature_status_hash_check(ietf_interfaces_features, "if-mib")? interfaces_subscription_operational_interfaces_interface_if_index: NULL, }, { INTERFACES_INTERFACES_INTERFACE_PHYS_ADDRESS_YANG_PATH, @@ -160,24 +162,29 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) interfaces_subscription_operational_interfaces_interface_statistics_in_discard_unknown_encaps, }, { + //depends on carrier-delay feature INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_CARRIER_TRANSITIONS_YANG_PATH, - interfaces_subscription_operational_interfaces_interface_carrier_delay_carrier_transitions, + srpc_feature_status_hash_check(ietf_if_extensions_features, "carrier-delay")? interfaces_subscription_operational_interfaces_interface_carrier_delay_carrier_transitions: NULL, }, { + //depends on carrier-delay feature INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_TIMER_RUNNING_YANG_PATH, - interfaces_subscription_operational_interfaces_interface_carrier_delay_timer_running, + srpc_feature_status_hash_check(ietf_if_extensions_features, "carrier-delay")? interfaces_subscription_operational_interfaces_interface_carrier_delay_timer_running: NULL, }, { + //depends on dampening feature INTERFACES_INTERFACES_INTERFACE_DAMPENING_PENALTY_YANG_PATH, - interfaces_subscription_operational_interfaces_interface_dampening_penalty, + srpc_feature_status_hash_check(ietf_if_extensions_features, "dampening")? interfaces_subscription_operational_interfaces_interface_dampening_penalty: NULL, }, { + //depends on dampening feature INTERFACES_INTERFACES_INTERFACE_DAMPENING_SUPPRESSED_YANG_PATH, - interfaces_subscription_operational_interfaces_interface_dampening_suppressed, + srpc_feature_status_hash_check(ietf_if_extensions_features, "dampening")? interfaces_subscription_operational_interfaces_interface_dampening_suppressed: NULL, }, { + //depends on dampening feature INTERFACES_INTERFACES_INTERFACE_DAMPENING_TIME_REMAINING_YANG_PATH, - interfaces_subscription_operational_interfaces_interface_dampening_time_remaining, + srpc_feature_status_hash_check(ietf_if_extensions_features, "dampening")? interfaces_subscription_operational_interfaces_interface_dampening_time_remaining: NULL, }, { INTERFACES_INTERFACES_INTERFACE_FORWARDING_MODE_YANG_PATH, From e2aae7ea9dd0544bc9e4f1f23ef3ef35bcab0677 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Fri, 9 Sep 2022 17:05:34 +0200 Subject: [PATCH 062/247] interfaces-plugin: fix enabled leaf --- src/interfaces/src/plugin.c | 10 ++-- .../src/plugin/api/interfaces/change.c | 12 ++--- .../plugin/api/interfaces/interface/change.c | 48 ++++++++++++------- .../src/plugin/subscription/change.c | 27 ++++++++--- 4 files changed, 62 insertions(+), 35 deletions(-) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index d84d2580..da760226 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -224,11 +224,11 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) SRPLG_LOG_INF(PLUGIN_NAME, "Startup datastore contains data"); SRPLG_LOG_INF(PLUGIN_NAME, "Storing startup datastore data in the system"); - error = interfaces_startup_store(ctx, startup_session); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "Error applying initial data from startup datastore to the system... exiting"); - goto error_out; - } + // error = interfaces_startup_store(ctx, startup_session); + // if (error) { + // SRPLG_LOG_ERR(PLUGIN_NAME, "Error applying initial data from startup datastore to the system... exiting"); + // goto error_out; + // } // copy contents of the startup session to the current running session error = sr_copy_config(running_session, BASE_YANG_MODEL, SR_DS_STARTUP, 0); diff --git a/src/interfaces/src/plugin/api/interfaces/change.c b/src/interfaces/src/plugin/api/interfaces/change.c index bbaca468..97901fd7 100644 --- a/src/interfaces/src/plugin/api/interfaces/change.c +++ b/src/interfaces/src/plugin/api/interfaces/change.c @@ -49,27 +49,27 @@ int interfaces_change_interface(void* priv, sr_session_ctx_t* session, const srp // get node xpath lyd_path(change_ctx->node, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)); - SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d, Node XPath: %s", node_name, change_ctx->previous_value, node_value, change_ctx->operation, xpath_buffer); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s; Value: %s; Operation: %d, Node XPath: %s", node_name, change_ctx->previous_value, node_value, change_ctx->operation, xpath_buffer); // name SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/name", xpath_buffer), error_out); - SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_change_name, NULL, NULL), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_change_name, interfaces_change_interface_init, interfaces_change_interface_free), error_out); // description SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/description", xpath_buffer), error_out); - SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_change_description, NULL, NULL), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_change_description, interfaces_change_interface_init, interfaces_change_interface_free), error_out); // type SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/type", xpath_buffer), error_out); - SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_change_type, NULL, NULL), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_change_type, interfaces_change_interface_init, interfaces_change_interface_free), error_out); // enabled SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/enabled", xpath_buffer), error_out); - SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_change_enabled, NULL, NULL), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_change_enabled, interfaces_change_interface_init, interfaces_change_interface_free), error_out); // link-up-down-trap-enable SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/link-up-down-trap-enable", xpath_buffer), error_out); - SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_change_link_up_down_trap_enable, NULL, NULL), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_change_link_up_down_trap_enable, interfaces_change_interface_init, interfaces_change_interface_free), error_out); goto out; diff --git a/src/interfaces/src/plugin/api/interfaces/interface/change.c b/src/interfaces/src/plugin/api/interfaces/interface/change.c index b6a40824..8d48a3cb 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/change.c @@ -6,6 +6,7 @@ #include "sysrepo/xpath.h" #include +#include #include #include @@ -19,7 +20,7 @@ int interfaces_interface_change_parent_interface(void* priv, sr_session_ctx_t* s const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s; Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -41,7 +42,7 @@ int interfaces_interface_change_max_frame_size(void* priv, sr_session_ctx_t* ses const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s; Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -63,7 +64,7 @@ int interfaces_interface_change_loopback(void* priv, sr_session_ctx_t* session, const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s; Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -85,7 +86,7 @@ int interfaces_interface_change_link_up_down_trap_enable(void* priv, sr_session_ const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s; Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -115,11 +116,13 @@ int interfaces_interface_change_enabled(void* priv, sr_session_ctx_t* session, c const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s; Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); // get interface name SRPC_SAFE_CALL_ERR(error, interfacecs_interface_extract_name(session, change_ctx->node, interface_name_buffer, sizeof(interface_name_buffer)), error_out); + SRPLG_LOG_INF(PLUGIN_NAME, "Working with interface %s", interface_name_buffer); + // get link by name SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->link_cache, interface_name_buffer), error_out); @@ -128,33 +131,48 @@ int interfaces_interface_change_enabled(void* priv, sr_session_ctx_t* session, c // set name rtnl_link_set_name(request_link, interface_name_buffer); + rtnl_link_set_type(request_link, rtnl_link_get_type(current_link)); switch (change_ctx->operation) { case SR_OP_CREATED: case SR_OP_MODIFIED: // set operstate + rtnl_link_set_flags(request_link, (strcmp(node_value, "true") == 0) ? (unsigned int)rtnl_link_str2flags("up") : (unsigned int)rtnl_link_str2flags("down")); rtnl_link_set_operstate(request_link, (strcmp(node_value, "true") == 0) ? IF_OPER_UP : IF_OPER_DOWN); break; case SR_OP_DELETED: // treat as set to up - default value + rtnl_link_set_flags(request_link, (unsigned int)rtnl_link_str2flags("up")); rtnl_link_set_operstate(request_link, IF_OPER_UP); break; case SR_OP_MOVED: break; } - // apply changes - SRPC_SAFE_CALL_ERR(error, rtnl_link_change(mod_ctx->socket, current_link, request_link, 0), error_out); + SRPLG_LOG_INF(PLUGIN_NAME, "Current link status: %d", rtnl_link_get_operstate(current_link)); + SRPLG_LOG_INF(PLUGIN_NAME, "Changed link status: %d", rtnl_link_get_operstate(request_link)); - // if all succeeded - refresh link cache for changes - SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(mod_ctx->socket, AF_UNSPEC, &mod_ctx->link_cache), error_out); + // error = rtnl_link_change(mod_ctx->socket, current_link, request_link, NLM_F_REPLACE); + // if (error) { + // SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_change() error (%d) : %s", error, nl_geterror(error)); + // goto error_out; + // } + + // apply changes + SRPC_SAFE_CALL_ERR(error, rtnl_link_change(mod_ctx->socket, current_link, request_link, NLM_F_REPLACE), error_out); goto out; error_out: + if (error < 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "nl_geterror(): %s", nl_geterror(error)); + } error = -1; out: + // free request link + rtnl_link_put(request_link); + return error; } @@ -195,7 +213,7 @@ int interfaces_interface_change_type(void* priv, sr_session_ctx_t* session, cons const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s; Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); // get interface name SRPC_SAFE_CALL_ERR(error, interfacecs_interface_extract_name(session, change_ctx->node, interface_name_buffer, sizeof(interface_name_buffer)), error_out); @@ -236,9 +254,6 @@ int interfaces_interface_change_type(void* priv, sr_session_ctx_t* session, cons break; } - // if all succeeded - refresh link cache for changes - SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(mod_ctx->socket, AF_UNSPEC, &mod_ctx->link_cache), error_out); - goto out; error_out: @@ -254,7 +269,7 @@ int interfaces_interface_change_description(void* priv, sr_session_ctx_t* sessio const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s; Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -282,7 +297,7 @@ int interfaces_interface_change_name(void* priv, sr_session_ctx_t* session, cons const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s; Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -315,9 +330,6 @@ int interfaces_interface_change_name(void* priv, sr_session_ctx_t* session, cons break; } - // if all succeeded - refresh link cache for changes - SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(mod_ctx->socket, AF_UNSPEC, &mod_ctx->link_cache), error_out); - goto out; error_out: diff --git a/src/interfaces/src/plugin/subscription/change.c b/src/interfaces/src/plugin/subscription/change.c index 4ff86fb8..616397e8 100644 --- a/src/interfaces/src/plugin/subscription/change.c +++ b/src/interfaces/src/plugin/subscription/change.c @@ -14,6 +14,8 @@ int interfaces_subscription_change_interfaces_interface(sr_session_ctx_t* sessio { int error = SR_ERR_OK; interfaces_ctx_t* ctx = (interfaces_ctx_t*)private_data; + char change_xpath_buffer[PATH_MAX] = { 0 }; + int rc = 0; if (event == SR_EV_ABORT) { SRPLG_LOG_ERR(PLUGIN_NAME, "Aborting changes for %s", xpath); @@ -25,12 +27,25 @@ int interfaces_subscription_change_interfaces_interface(sr_session_ctx_t* sessio goto error_out; } } else if (event == SR_EV_CHANGE) { - // connect change API - error = srpc_iterate_changes(ctx, session, xpath, interfaces_change_interface, interfaces_change_interface_init, interfaces_change_interface_free); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "srpc_iterate_changes() for interfaces_change_interface failed: %d", error); - goto error_out; - } + // name + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/name", xpath), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_change_name, interfaces_change_interface_init, interfaces_change_interface_free), error_out); + + // description + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/description", xpath), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_change_description, interfaces_change_interface_init, interfaces_change_interface_free), error_out); + + // type + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/type", xpath), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_change_type, interfaces_change_interface_init, interfaces_change_interface_free), error_out); + + // enabled + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/enabled", xpath), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_change_enabled, interfaces_change_interface_init, interfaces_change_interface_free), error_out); + + // link-up-down-trap-enable + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/link-up-down-trap-enable", xpath), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_change_link_up_down_trap_enable, interfaces_change_interface_init, interfaces_change_interface_free), error_out); } goto out; From 15693989b013094f09b7c7b2450d6edf9ceeb4d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Fri, 9 Sep 2022 17:09:25 +0200 Subject: [PATCH 063/247] interfaces-plugin: unset needed flags on enabled leaf change --- src/interfaces/src/plugin/api/interfaces/interface/change.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/change.c b/src/interfaces/src/plugin/api/interfaces/interface/change.c index 8d48a3cb..0752050b 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/change.c @@ -138,6 +138,7 @@ int interfaces_interface_change_enabled(void* priv, sr_session_ctx_t* session, c case SR_OP_MODIFIED: // set operstate rtnl_link_set_flags(request_link, (strcmp(node_value, "true") == 0) ? (unsigned int)rtnl_link_str2flags("up") : (unsigned int)rtnl_link_str2flags("down")); + rtnl_link_unset_flags(request_link, (strcmp(node_value, "true") == 0) ? (unsigned int)rtnl_link_str2flags("down") : (unsigned int)rtnl_link_str2flags("up")); rtnl_link_set_operstate(request_link, (strcmp(node_value, "true") == 0) ? IF_OPER_UP : IF_OPER_DOWN); break; case SR_OP_DELETED: From 45a97d5f944051f04ee74bdc8085d0a3a510cd8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Fri, 9 Sep 2022 17:10:16 +0200 Subject: [PATCH 064/247] interfaces-plugin: remove unused code --- .../src/plugin/api/interfaces/interface/change.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/change.c b/src/interfaces/src/plugin/api/interfaces/interface/change.c index 0752050b..2d3db614 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/change.c @@ -153,12 +153,6 @@ int interfaces_interface_change_enabled(void* priv, sr_session_ctx_t* session, c SRPLG_LOG_INF(PLUGIN_NAME, "Current link status: %d", rtnl_link_get_operstate(current_link)); SRPLG_LOG_INF(PLUGIN_NAME, "Changed link status: %d", rtnl_link_get_operstate(request_link)); - // error = rtnl_link_change(mod_ctx->socket, current_link, request_link, NLM_F_REPLACE); - // if (error) { - // SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_change() error (%d) : %s", error, nl_geterror(error)); - // goto error_out; - // } - // apply changes SRPC_SAFE_CALL_ERR(error, rtnl_link_change(mod_ctx->socket, current_link, request_link, NLM_F_REPLACE), error_out); @@ -241,7 +235,7 @@ int interfaces_interface_change_type(void* priv, sr_session_ctx_t* session, cons } if (!type_set) { - SRPLG_LOG_ERR(PLUGIN_NAME, "Unsupported interface type (%s)", node_value); + SRPLG_LOG_ERR(PLUGIN_NAME, "Unsupported interface type %s", node_value); goto error_out; } From 30f23e5b05ad838cb0feadb5806d1ccb3c85bcc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Fri, 9 Sep 2022 18:32:23 +0200 Subject: [PATCH 065/247] interfaces-plugin: fix link data delete changes --- examples/test_config.xml | 9 ++- .../plugin/api/interfaces/interface/change.c | 79 +++++++++++-------- .../src/plugin/subscription/operational.c | 4 +- 3 files changed, 57 insertions(+), 35 deletions(-) diff --git a/examples/test_config.xml b/examples/test_config.xml index 12eff8c4..74a734be 100644 --- a/examples/test_config.xml +++ b/examples/test_config.xml @@ -8,6 +8,13 @@ test_if Test Interface ianaift:other - true + false + + + + if0 + Test Interface + ianaift:other + false \ No newline at end of file diff --git a/src/interfaces/src/plugin/api/interfaces/interface/change.c b/src/interfaces/src/plugin/api/interfaces/interface/change.c index 2d3db614..fb8eaff5 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/change.c @@ -121,41 +121,55 @@ int interfaces_interface_change_enabled(void* priv, sr_session_ctx_t* session, c // get interface name SRPC_SAFE_CALL_ERR(error, interfacecs_interface_extract_name(session, change_ctx->node, interface_name_buffer, sizeof(interface_name_buffer)), error_out); - SRPLG_LOG_INF(PLUGIN_NAME, "Working with interface %s", interface_name_buffer); - - // get link by name - SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->link_cache, interface_name_buffer), error_out); - - // create request link - SRPC_SAFE_CALL_PTR(request_link, rtnl_link_alloc(), error_out); - - // set name - rtnl_link_set_name(request_link, interface_name_buffer); - rtnl_link_set_type(request_link, rtnl_link_get_type(current_link)); - switch (change_ctx->operation) { case SR_OP_CREATED: case SR_OP_MODIFIED: + // get link by name + SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->link_cache, interface_name_buffer), error_out); + + // create request link + SRPC_SAFE_CALL_PTR(request_link, rtnl_link_alloc(), error_out); + + // set name + rtnl_link_set_name(request_link, interface_name_buffer); + rtnl_link_set_type(request_link, rtnl_link_get_type(current_link)); // set operstate rtnl_link_set_flags(request_link, (strcmp(node_value, "true") == 0) ? (unsigned int)rtnl_link_str2flags("up") : (unsigned int)rtnl_link_str2flags("down")); rtnl_link_unset_flags(request_link, (strcmp(node_value, "true") == 0) ? (unsigned int)rtnl_link_str2flags("down") : (unsigned int)rtnl_link_str2flags("up")); rtnl_link_set_operstate(request_link, (strcmp(node_value, "true") == 0) ? IF_OPER_UP : IF_OPER_DOWN); + + SRPLG_LOG_INF(PLUGIN_NAME, "Current link status: %d", rtnl_link_get_operstate(current_link)); + SRPLG_LOG_INF(PLUGIN_NAME, "Changed link status: %d", rtnl_link_get_operstate(request_link)); + + // apply changes + SRPC_SAFE_CALL_ERR(error, rtnl_link_change(mod_ctx->socket, current_link, request_link, NLM_F_REPLACE), error_out); break; case SR_OP_DELETED: + // get link by name + // goto out if this function fails - if the link has completely been deleted, no need to delete enabled leaf + SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->link_cache, interface_name_buffer), out); + + // create request link + SRPC_SAFE_CALL_PTR(request_link, rtnl_link_alloc(), error_out); + + // set name + rtnl_link_set_name(request_link, interface_name_buffer); + rtnl_link_set_type(request_link, rtnl_link_get_type(current_link)); + // treat as set to up - default value rtnl_link_set_flags(request_link, (unsigned int)rtnl_link_str2flags("up")); rtnl_link_set_operstate(request_link, IF_OPER_UP); + + SRPLG_LOG_INF(PLUGIN_NAME, "Current link status: %d", rtnl_link_get_operstate(current_link)); + SRPLG_LOG_INF(PLUGIN_NAME, "Changed link status: %d", rtnl_link_get_operstate(request_link)); + + // apply changes + SRPC_SAFE_CALL_ERR(error, rtnl_link_change(mod_ctx->socket, current_link, request_link, NLM_F_REPLACE), error_out); break; case SR_OP_MOVED: break; } - SRPLG_LOG_INF(PLUGIN_NAME, "Current link status: %d", rtnl_link_get_operstate(current_link)); - SRPLG_LOG_INF(PLUGIN_NAME, "Changed link status: %d", rtnl_link_get_operstate(request_link)); - - // apply changes - SRPC_SAFE_CALL_ERR(error, rtnl_link_change(mod_ctx->socket, current_link, request_link, NLM_F_REPLACE), error_out); - goto out; error_out: @@ -165,8 +179,9 @@ int interfaces_interface_change_enabled(void* priv, sr_session_ctx_t* session, c error = -1; out: - // free request link - rtnl_link_put(request_link); + if (request_link) { + rtnl_link_put(request_link); + } return error; } @@ -210,21 +225,21 @@ int interfaces_interface_change_type(void* priv, sr_session_ctx_t* session, cons SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s; Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); - // get interface name - SRPC_SAFE_CALL_ERR(error, interfacecs_interface_extract_name(session, change_ctx->node, interface_name_buffer, sizeof(interface_name_buffer)), error_out); + switch (change_ctx->operation) { + case SR_OP_CREATED: + case SR_OP_MODIFIED: + // get interface name + SRPC_SAFE_CALL_ERR(error, interfacecs_interface_extract_name(session, change_ctx->node, interface_name_buffer, sizeof(interface_name_buffer)), error_out); - // get link by name - SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->link_cache, interface_name_buffer), error_out); + // get link by name + SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->link_cache, interface_name_buffer), error_out); - // create request link - SRPC_SAFE_CALL_PTR(request_link, rtnl_link_alloc(), error_out); + // create request link + SRPC_SAFE_CALL_PTR(request_link, rtnl_link_alloc(), error_out); - // set name - rtnl_link_set_name(request_link, interface_name_buffer); + // set name + rtnl_link_set_name(request_link, interface_name_buffer); - switch (change_ctx->operation) { - case SR_OP_CREATED: - case SR_OP_MODIFIED: // set type for (size_t i = 0; i < ARRAY_SIZE(type_pairs); i++) { if (!strcmp(node_value, type_pairs[i].yang_type)) { @@ -317,7 +332,7 @@ int interfaces_interface_change_name(void* priv, sr_session_ctx_t* session, cons goto error_out; case SR_OP_DELETED: // get link and delete it - SRPC_SAFE_CALL_PTR(old_link, rtnl_link_get_by_name(mod_ctx->link_cache, change_ctx->previous_value), error_out); + SRPC_SAFE_CALL_PTR(old_link, rtnl_link_get_by_name(mod_ctx->link_cache, node_value), error_out); SRPC_SAFE_CALL_ERR(error, rtnl_link_delete(mod_ctx->socket, old_link), error_out); break; diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index b241942b..7ec5662e 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -140,14 +140,14 @@ int interfaces_subscription_operational_interfaces_interface_last_change(sr_sess // add oper-status node SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_last_change(ly_ctx, *parent, last_change_buffer), error_out); - pthread_mutex_unlock(&state_ctx->state_hash_mutex); - goto out; error_out: error = SR_ERR_CALLBACK_FAILED; out: + pthread_mutex_unlock(&state_ctx->state_hash_mutex); + return error; } From 3f8d8a8f3c0a30e8d18ddad7e2ebe60250b7b12f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Fri, 9 Sep 2022 18:37:13 +0200 Subject: [PATCH 066/247] interfaces-plugin: add a newly created link to the state data hash --- src/interfaces/src/plugin.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index da760226..7c8d4526 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -404,6 +404,15 @@ static void interfaces_link_cache_change_cb(struct nl_cache* cache, struct nl_ob state->state = oper_state; state->last_change = time(NULL); } + } else { + // new link has been added - add new data to the hash + const time_t current_time = time(NULL); + + // add entry to the hash table + int rc = interfaces_interface_state_hash_add(&ctx->state_hash, link_name, oper_state, current_time); + if (rc) { + SRPLG_LOG_ERR(PLUGIN_NAME, "Unable to add new interface %s to the interface hash"); + } } link = (struct rtnl_link*)nl_cache_get_next((struct nl_object*)link); From 603e33609cef8e3270589765c6b5ec09ee051378 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Fri, 9 Sep 2022 18:49:47 +0200 Subject: [PATCH 067/247] interfaces-plugin: fix interface xpath usage for operational speed leaf --- .../src/plugin/subscription/operational.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 7ec5662e..391c49e4 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -154,6 +154,7 @@ int interfaces_subscription_operational_interfaces_interface_last_change(sr_sess int interfaces_subscription_operational_interfaces_interface_if_index(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; // context const struct ly_ctx* ly_ctx = NULL; @@ -161,6 +162,7 @@ int interfaces_subscription_operational_interfaces_interface_if_index(sr_session // buffers char ifindex_buffer[100] = { 0 }; + char xpath_buffer[PATH_MAX] = { 0 }; // libnl struct rtnl_link* link = NULL; @@ -169,6 +171,9 @@ int interfaces_subscription_operational_interfaces_interface_if_index(sr_session assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "interface") == 0); + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + // get link SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); @@ -341,7 +346,7 @@ int interfaces_subscription_operational_interfaces_interface_lower_layer_if(sr_s int interfaces_subscription_operational_interfaces_interface_speed(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; - // void* error_ptr = NULL; + void* error_ptr = NULL; // context const struct ly_ctx* ly_ctx = NULL; @@ -349,6 +354,7 @@ int interfaces_subscription_operational_interfaces_interface_speed(sr_session_ct // buffers char speed_buffer[100] = { 0 }; + char xpath_buffer[PATH_MAX] = { 0 }; // libnl struct rtnl_link* link = NULL; @@ -359,8 +365,11 @@ int interfaces_subscription_operational_interfaces_interface_speed(sr_session_ct assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "interface") == 0); + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + // get link - SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); qdisc = rtnl_qdisc_alloc(); From 8ba8d0343e8ea18b2465f54458ecb29cb1e81572 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Fri, 9 Sep 2022 19:22:43 +0200 Subject: [PATCH 068/247] interfaces-plugin: fix interface xpath usage for operational lower-layer-if leaf-list --- src/interfaces/src/plugin/subscription/operational.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 391c49e4..353d431e 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -289,12 +289,15 @@ int interfaces_subscription_operational_interfaces_interface_higher_layer_if(sr_ int interfaces_subscription_operational_interfaces_interface_lower_layer_if(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; // context const struct ly_ctx* ly_ctx = NULL; interfaces_ctx_t* ctx = private_data; interfaces_nl_ctx_t* nl_ctx = &ctx->nl_ctx; + char xpath_buffer[PATH_MAX] = { 0 }; + // libnl struct rtnl_link* link = NULL; struct rtnl_link* master_link = NULL; @@ -302,8 +305,11 @@ int interfaces_subscription_operational_interfaces_interface_lower_layer_if(sr_s assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "interface") == 0); + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + // get link - SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); // iterate over all links and check for ones which have a master equal to the current link struct nl_cache* link_cache = nl_ctx->link_cache; From bef89b72d046f19cc0a22a63ce343556f9f70dff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Fri, 9 Sep 2022 19:23:10 +0200 Subject: [PATCH 069/247] interfaces-plugin: fix interface xpath usage for operational higher-layer-if leaf-list --- src/interfaces/src/plugin/subscription/operational.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 353d431e..0afda0a7 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -246,12 +246,15 @@ int interfaces_subscription_operational_interfaces_interface_phys_address(sr_ses int interfaces_subscription_operational_interfaces_interface_higher_layer_if(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; // context const struct ly_ctx* ly_ctx = NULL; interfaces_ctx_t* ctx = private_data; interfaces_nl_ctx_t* nl_ctx = &ctx->nl_ctx; + char xpath_buffer[PATH_MAX] = { 0 }; + // libnl struct rtnl_link* link = NULL; struct rtnl_link* master_link = NULL; @@ -259,8 +262,11 @@ int interfaces_subscription_operational_interfaces_interface_higher_layer_if(sr_ assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "interface") == 0); + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + // get link - SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); int master_if_index = rtnl_link_get_master(link); while (master_if_index) { From f75ca93792c6d9d31ae7c5add8aab8b95f9e6561 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Fri, 9 Sep 2022 19:24:27 +0200 Subject: [PATCH 070/247] interfaces-plugin: fix interface xpath usage for operational last-change leaf --- .../src/plugin/subscription/operational.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 0afda0a7..b23978b7 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -100,6 +100,7 @@ int interfaces_subscription_operational_interfaces_interface_oper_status(sr_sess int interfaces_subscription_operational_interfaces_interface_last_change(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; // context const struct ly_ctx* ly_ctx = NULL; @@ -112,13 +113,17 @@ int interfaces_subscription_operational_interfaces_interface_last_change(sr_sess // buffers char last_change_buffer[100] = { 0 }; + char xpath_buffer[PATH_MAX] = { 0 }; // there needs to be an allocated link cache in memory assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "interface") == 0); + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + // get link - SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); // synchronization pthread_mutex_lock(&state_ctx->state_hash_mutex); @@ -212,6 +217,7 @@ int interfaces_subscription_operational_interfaces_interface_phys_address(sr_ses // buffers char phys_address_buffer[100] = { 0 }; + char xpath_buffer[PATH_MAX] = { 0 }; // libnl struct rtnl_link* link = NULL; @@ -221,8 +227,11 @@ int interfaces_subscription_operational_interfaces_interface_phys_address(sr_ses assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "interface") == 0); + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + // get link - SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); // get phys-address SRPC_SAFE_CALL_PTR(addr, rtnl_link_get_addr(link), error_out); From aafc2d4559ea80a7774b0e7a81a68d8f44bf38f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Fri, 9 Sep 2022 19:25:03 +0200 Subject: [PATCH 071/247] interfaces-plugin: fix interface xpath usage for operational oper-status leaf --- src/interfaces/src/plugin/subscription/operational.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index b23978b7..9dc822ea 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -54,6 +54,7 @@ int interfaces_subscription_operational_interfaces_interface_admin_status(sr_ses int interfaces_subscription_operational_interfaces_interface_oper_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; // context const struct ly_ctx* ly_ctx = NULL; @@ -62,6 +63,8 @@ int interfaces_subscription_operational_interfaces_interface_oper_status(sr_sess // libnl struct rtnl_link* link = NULL; + char xpath_buffer[PATH_MAX] = { 0 }; + const char* operstate_map[] = { [IF_OPER_UNKNOWN] = "unknown", [IF_OPER_NOTPRESENT] = "not-present", @@ -76,8 +79,11 @@ int interfaces_subscription_operational_interfaces_interface_oper_status(sr_sess assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "interface") == 0); + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + // get link - SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); // get oper status const uint8_t oper_status = rtnl_link_get_operstate(link); From bc08b5ea313fef8fadc4eb4725ef9b9e644c9eb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Fri, 9 Sep 2022 19:33:34 +0200 Subject: [PATCH 072/247] interfaces-plugin: fix interface xpath usage for operational statistics container --- .../src/plugin/subscription/operational.c | 109 +++++++++++++++--- 1 file changed, 94 insertions(+), 15 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 9dc822ea..ae7952c5 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -32,6 +32,7 @@ static int interfaces_get_system_boot_time(char* buffer, size_t buffer_size); int interfaces_subscription_operational_interfaces_interface_admin_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; const struct ly_ctx* ly_ctx = NULL; if (*parent == NULL) { @@ -186,7 +187,7 @@ int interfaces_subscription_operational_interfaces_interface_if_index(sr_session SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); // get link - SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); // get if-index const int ifindex = rtnl_link_get_ifindex(link); @@ -432,6 +433,7 @@ int interfaces_subscription_operational_interfaces_interface_speed(sr_session_ct int interfaces_subscription_operational_interfaces_interface_statistics_discontinuity_time(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; // context const struct ly_ctx* ly_ctx = NULL; @@ -439,6 +441,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_disconti // buffers char discontinuity_time_buffer[100] = { 0 }; + char xpath_buffer[PATH_MAX] = { 0 }; // libnl struct rtnl_link* link = NULL; @@ -447,8 +450,11 @@ int interfaces_subscription_operational_interfaces_interface_statistics_disconti assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + // get link - SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); // get boot time as discontinuity time SRPC_SAFE_CALL_ERR(error, interfaces_get_system_boot_time(discontinuity_time_buffer, sizeof(discontinuity_time_buffer)), error_out); @@ -470,6 +476,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_disconti int interfaces_subscription_operational_interfaces_interface_statistics_in_octets(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; // context const struct ly_ctx* ly_ctx = NULL; @@ -477,6 +484,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_octet // buffers char in_octets_buffer[100] = { 0 }; + char xpath_buffer[PATH_MAX] = { 0 }; // libnl struct rtnl_link* link = NULL; @@ -485,8 +493,11 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_octet assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + // get link - SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); const uint64_t in_octets = rtnl_link_get_stat(link, RTNL_LINK_RX_BYTES); @@ -513,6 +524,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_octet int interfaces_subscription_operational_interfaces_interface_statistics_in_unicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; // context const struct ly_ctx* ly_ctx = NULL; @@ -520,6 +532,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_unica // buffers char in_unicast_pkts_buffer[100] = { 0 }; + char xpath_buffer[PATH_MAX] = { 0 }; // libnl struct rtnl_link* link = NULL; @@ -528,8 +541,11 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_unica assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + // get link - SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); const uint64_t in_pkts = rtnl_link_get_stat(link, RTNL_LINK_RX_PACKETS); const uint64_t in_broadcast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_INBCASTPKTS); @@ -559,6 +575,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_unica int interfaces_subscription_operational_interfaces_interface_statistics_in_broadcast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; // context const struct ly_ctx* ly_ctx = NULL; @@ -566,6 +583,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_broad // buffers char in_broadcast_pkts_buffer[100] = { 0 }; + char xpath_buffer[PATH_MAX] = { 0 }; // libnl struct rtnl_link* link = NULL; @@ -574,8 +592,11 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_broad assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + // get link - SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); const uint64_t in_broadcast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_INBCASTPKTS); @@ -602,6 +623,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_broad int interfaces_subscription_operational_interfaces_interface_statistics_in_multicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; // context const struct ly_ctx* ly_ctx = NULL; @@ -609,6 +631,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_multi // buffers char in_multicast_pkts_buffer[100] = { 0 }; + char xpath_buffer[PATH_MAX] = { 0 }; // libnl struct rtnl_link* link = NULL; @@ -617,8 +640,11 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_multi assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + // get link - SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); const uint64_t in_multicast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_INMCASTPKTS); @@ -645,6 +671,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_multi int interfaces_subscription_operational_interfaces_interface_statistics_in_discards(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; // context const struct ly_ctx* ly_ctx = NULL; @@ -652,6 +679,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_disca // buffers char in_discards_buffer[100] = { 0 }; + char xpath_buffer[PATH_MAX] = { 0 }; // libnl struct rtnl_link* link = NULL; @@ -660,8 +688,11 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_disca assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + // get link - SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); const uint32_t in_discards = (uint32_t)rtnl_link_get_stat(link, RTNL_LINK_RX_DROPPED); @@ -688,6 +719,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_disca int interfaces_subscription_operational_interfaces_interface_statistics_in_errors(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; // context const struct ly_ctx* ly_ctx = NULL; @@ -695,6 +727,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_error // buffers char in_errors_buffer[100] = { 0 }; + char xpath_buffer[PATH_MAX] = { 0 }; // libnl struct rtnl_link* link = NULL; @@ -703,8 +736,11 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_error assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + // get link - SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); const uint32_t in_errors = (uint32_t)rtnl_link_get_stat(link, RTNL_LINK_RX_ERRORS); @@ -731,6 +767,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_error int interfaces_subscription_operational_interfaces_interface_statistics_in_unknown_protos(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; // context const struct ly_ctx* ly_ctx = NULL; @@ -738,6 +775,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_unkno // buffers char in_unknown_protos_buffer[100] = { 0 }; + char xpath_buffer[PATH_MAX] = { 0 }; // libnl struct rtnl_link* link = NULL; @@ -746,8 +784,11 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_unkno assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + // get link - SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); const uint32_t in_unknown_protos = (uint32_t)rtnl_link_get_stat(link, RTNL_LINK_IP6_INUNKNOWNPROTOS); @@ -774,6 +815,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_unkno int interfaces_subscription_operational_interfaces_interface_statistics_out_octets(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; // context const struct ly_ctx* ly_ctx = NULL; @@ -781,6 +823,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_octe // buffers char out_octets_buffer[100] = { 0 }; + char xpath_buffer[PATH_MAX] = { 0 }; // libnl struct rtnl_link* link = NULL; @@ -789,8 +832,11 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_octe assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + // get link - SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); const uint64_t out_octets = rtnl_link_get_stat(link, RTNL_LINK_TX_BYTES); @@ -817,6 +863,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_octe int interfaces_subscription_operational_interfaces_interface_statistics_out_unicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; // context const struct ly_ctx* ly_ctx = NULL; @@ -824,6 +871,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_unic // buffers char out_unicast_pkts_buffer[100] = { 0 }; + char xpath_buffer[PATH_MAX] = { 0 }; // libnl struct rtnl_link* link = NULL; @@ -832,8 +880,11 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_unic assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + // get link - SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); const uint64_t out_pkts = rtnl_link_get_stat(link, RTNL_LINK_TX_PACKETS); const uint64_t out_broadcast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_OUTBCASTPKTS); @@ -863,6 +914,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_unic int interfaces_subscription_operational_interfaces_interface_statistics_out_broadcast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; // context const struct ly_ctx* ly_ctx = NULL; @@ -870,6 +922,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_broa // buffers char out_broadcast_pkts_buffer[100] = { 0 }; + char xpath_buffer[PATH_MAX] = { 0 }; // libnl struct rtnl_link* link = NULL; @@ -878,8 +931,11 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_broa assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + // get link - SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); const uint64_t out_broadcast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_OUTBCASTPKTS); @@ -906,6 +962,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_broa int interfaces_subscription_operational_interfaces_interface_statistics_out_multicast_pkts(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; // context const struct ly_ctx* ly_ctx = NULL; @@ -913,6 +970,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_mult // buffers char out_multicast_pkts_buffer[100] = { 0 }; + char xpath_buffer[PATH_MAX] = { 0 }; // libnl struct rtnl_link* link = NULL; @@ -921,8 +979,11 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_mult assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + // get link - SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); const uint64_t out_multicast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_OUTMCASTPKTS); @@ -949,6 +1010,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_mult int interfaces_subscription_operational_interfaces_interface_statistics_out_discards(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; // context const struct ly_ctx* ly_ctx = NULL; @@ -956,6 +1018,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_disc // buffers char out_discards_buffer[100] = { 0 }; + char xpath_buffer[PATH_MAX] = { 0 }; // libnl struct rtnl_link* link = NULL; @@ -964,8 +1027,11 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_disc assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + // get link - SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); const uint64_t out_discards = rtnl_link_get_stat(link, RTNL_LINK_TX_DROPPED); @@ -992,6 +1058,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_disc int interfaces_subscription_operational_interfaces_interface_statistics_out_errors(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; // context const struct ly_ctx* ly_ctx = NULL; @@ -999,6 +1066,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_erro // buffers char out_errors_buffer[100] = { 0 }; + char xpath_buffer[PATH_MAX] = { 0 }; // libnl struct rtnl_link* link = NULL; @@ -1007,8 +1075,11 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_erro assert(*parent != NULL); assert(strcmp(LYD_NAME(*parent), "statistics") == 0); + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + // get link - SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, request_xpath), error_out); + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); const uint64_t out_errors = rtnl_link_get_stat(link, RTNL_LINK_TX_DROPPED); @@ -1035,6 +1106,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_erro int interfaces_subscription_operational_interfaces_interface_statistics_in_discard_unknown_encaps(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; const struct ly_ctx* ly_ctx = NULL; if (*parent == NULL) { @@ -1057,6 +1129,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_disca int interfaces_subscription_operational_interfaces_interface_carrier_delay_carrier_transitions(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; const struct ly_ctx* ly_ctx = NULL; if (*parent == NULL) { @@ -1079,6 +1152,7 @@ int interfaces_subscription_operational_interfaces_interface_carrier_delay_carri int interfaces_subscription_operational_interfaces_interface_carrier_delay_timer_running(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; const struct ly_ctx* ly_ctx = NULL; if (*parent == NULL) { @@ -1101,6 +1175,7 @@ int interfaces_subscription_operational_interfaces_interface_carrier_delay_timer int interfaces_subscription_operational_interfaces_interface_dampening_penalty(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; const struct ly_ctx* ly_ctx = NULL; if (*parent == NULL) { @@ -1123,6 +1198,7 @@ int interfaces_subscription_operational_interfaces_interface_dampening_penalty(s int interfaces_subscription_operational_interfaces_interface_dampening_suppressed(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; const struct ly_ctx* ly_ctx = NULL; if (*parent == NULL) { @@ -1145,6 +1221,7 @@ int interfaces_subscription_operational_interfaces_interface_dampening_suppresse int interfaces_subscription_operational_interfaces_interface_dampening_time_remaining(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; const struct ly_ctx* ly_ctx = NULL; if (*parent == NULL) { @@ -1167,6 +1244,7 @@ int interfaces_subscription_operational_interfaces_interface_dampening_time_rema int interfaces_subscription_operational_interfaces_interface_forwarding_mode(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; const struct ly_ctx* ly_ctx = NULL; if (*parent == NULL) { @@ -1189,6 +1267,7 @@ int interfaces_subscription_operational_interfaces_interface_forwarding_mode(sr_ int interfaces_subscription_operational_interfaces_interface(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; const struct ly_ctx* ly_ctx = NULL; interfaces_ctx_t* ctx = private_data; interfaces_nl_ctx_t* nl_ctx = &ctx->nl_ctx; From 80d7a493644566e7df958c70473b1aff31cc92cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Fri, 9 Sep 2022 19:40:59 +0200 Subject: [PATCH 073/247] interfaces-plugin: improve logging for the link change callback --- src/interfaces/src/plugin.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index 7c8d4526..79532bed 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -378,6 +378,7 @@ static void interfaces_link_cache_change_cb(struct nl_cache* cache, struct nl_ob interfaces_state_changes_ctx_t* ctx = arg; char time_buffer[100] = { 0 }; struct tm* last_change = NULL; + time_t current = 0; // block further access using mutex @@ -395,8 +396,9 @@ static void interfaces_link_cache_change_cb(struct nl_cache* cache, struct nl_ob const uint8_t oper_state = rtnl_link_get_operstate(link); if (state) { + SRPLG_LOG_INF(PLUGIN_NAME, "State for interface %s already exists - updating last change", link_name); if (oper_state != state->state) { - const time_t current = time(NULL); + current = time(NULL); last_change = localtime(¤t); strftime(time_buffer, sizeof(time_buffer), "%FT%TZ", last_change); @@ -405,14 +407,19 @@ static void interfaces_link_cache_change_cb(struct nl_cache* cache, struct nl_ob state->last_change = time(NULL); } } else { + SRPLG_LOG_INF(PLUGIN_NAME, "State for interface %s doesn\'t exist - creating a new entry in the state data hash table", link_name); // new link has been added - add new data to the hash - const time_t current_time = time(NULL); + current = time(NULL); + last_change = localtime(¤t); // add entry to the hash table - int rc = interfaces_interface_state_hash_add(&ctx->state_hash, link_name, oper_state, current_time); + int rc = interfaces_interface_state_hash_add(&ctx->state_hash, link_name, oper_state, current); if (rc) { SRPLG_LOG_ERR(PLUGIN_NAME, "Unable to add new interface %s to the interface hash"); } + + strftime(time_buffer, sizeof(time_buffer), "%FT%TZ", last_change); + SRPLG_LOG_INF(PLUGIN_NAME, "Interface %s added to the state data hash: state = %d, time = %s", link_name, oper_state, time_buffer); } link = (struct rtnl_link*)nl_cache_get_next((struct nl_object*)link); From 4e1942d6d54e188d4d7b582ad1067cbc5ec0b12b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Fri, 9 Sep 2022 20:09:46 +0200 Subject: [PATCH 074/247] interfaces-plugin: fix check API --- .../src/plugin/api/interfaces/check.c | 6 +- .../src/plugin/api/interfaces/check.h | 4 +- src/interfaces/src/plugin/data/interface.h | 33 ++++------ src/interfaces/src/plugin/startup/load.c | 12 ++-- src/interfaces/src/plugin/startup/store.c | 63 ++++++++++--------- 5 files changed, 58 insertions(+), 60 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/check.c b/src/interfaces/src/plugin/api/interfaces/check.c index 50cf1d88..c738224b 100644 --- a/src/interfaces/src/plugin/api/interfaces/check.c +++ b/src/interfaces/src/plugin/api/interfaces/check.c @@ -1,7 +1,7 @@ #include "check.h" -int interfaces_check_interface(interfaces_ctx_t* ctx, const UT_array* interface) +srpc_check_status_t interfaces_check_interface(interfaces_ctx_t* ctx, const UT_array* interface) { - int error = 0; - return error; + srpc_check_status_t status = srpc_check_status_none; + return status; } diff --git a/src/interfaces/src/plugin/api/interfaces/check.h b/src/interfaces/src/plugin/api/interfaces/check.h index 883491bf..324295cd 100644 --- a/src/interfaces/src/plugin/api/interfaces/check.h +++ b/src/interfaces/src/plugin/api/interfaces/check.h @@ -4,6 +4,8 @@ #include "plugin/context.h" #include -int interfaces_check_interface(interfaces_ctx_t* ctx, const UT_array* interface); +#include + +srpc_check_status_t interfaces_check_interface(interfaces_ctx_t* ctx, const UT_array* interface); #endif // INTERFACES_PLUGIN_API_INTERFACES_CHECK_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/data/interface.h b/src/interfaces/src/plugin/data/interface.h index 351119ee..fb7d15c4 100644 --- a/src/interfaces/src/plugin/data/interface.h +++ b/src/interfaces/src/plugin/data/interface.h @@ -5,37 +5,28 @@ #include "plugin/types.h" -void -interfaces_data_ht_root_init(interface_ht_element_t **if_root); +void interfaces_data_ht_root_init(interface_ht_element_t** if_root); -static void +static void interfaces_data_init(interfaces_interfaces_interface_t* interface); -interface_ht_element_t * -interfaces_data_ht_get_by_name(interface_ht_element_t *if_root, char *name); +interface_ht_element_t* +interfaces_data_ht_get_by_name(interface_ht_element_t* if_root, char* name); -void -interfaces_data_ht_set_name(interfaces_interfaces_interface_t *interface, char *name); +void interfaces_data_ht_set_name(interfaces_interfaces_interface_t* interface, char* name); -int -interfaces_data_ht_add(interface_ht_element_t *if_root, char *name); +int interfaces_data_ht_add(interface_ht_element_t* if_root, char* name); -int -interfaces_data_ht_set_description(interface_ht_element_t *if_root, char *name, char *description); +int interfaces_data_ht_set_description(interface_ht_element_t* if_root, char* name, char* description); -int -interfaces_data_ht_set_type(interface_ht_element_t *if_root, char *name, char *type); +int interfaces_data_ht_set_type(interface_ht_element_t* if_root, char* name, char* type); -int -interfaces_data_ht_set_loopback(interface_ht_element_t *if_root, char *name, char *loopback); +int interfaces_data_ht_set_loopback(interface_ht_element_t* if_root, char* name, char* loopback); -int -interfaces_data_ht_set_parent_interface(interface_ht_element_t *if_root, char *name, char *parent_interface); +int interfaces_data_ht_set_parent_interface(interface_ht_element_t* if_root, char* name, char* parent_interface); -void -interfaces_data_ht_if_free(interfaces_interfaces_interface_t *interface); +void interfaces_data_ht_if_free(interfaces_interfaces_interface_t* interface); -void -interfaces_data_ht_free(interface_ht_element_t *if_root); +void interfaces_data_ht_free(interface_ht_element_t* if_root); #endif /* IF_DATA_H */ diff --git a/src/interfaces/src/plugin/startup/load.c b/src/interfaces/src/plugin/startup/load.c index 6e1f1fbf..c1d5b840 100644 --- a/src/interfaces/src/plugin/startup/load.c +++ b/src/interfaces/src/plugin/startup/load.c @@ -2,6 +2,8 @@ #include "plugin/common.h" #include "plugin/ly_tree.h" +#include "plugin/api/interfaces/load.h" + #include #include #include @@ -49,8 +51,8 @@ int interfaces_startup_load(interfaces_ctx_t* ctx, sr_session_ctx_t* session) /* enable or disable storing into startup, use for testing */ #define INTERFACES_PLUGIN_LOAD_STARTUP /* disable for now */ -#undef INTERFACES_PLUGIN_LOAD_STARTUP -#ifdef INTERFACES_PLUGIN_LOAD_STARTUP +#undef INTERFACES_PLUGIN_LOAD_STARTUP +#ifdef INTERFACES_PLUGIN_LOAD_STARTUP error = sr_edit_batch(session, root_node, "merge"); if (error != SR_ERR_OK) { SRPLG_LOG_ERR(PLUGIN_NAME, "sr_edit_batch() error (%d): %s", error, sr_strerror(error)); @@ -80,10 +82,10 @@ int interfaces_startup_load(interfaces_ctx_t* ctx, sr_session_ctx_t* session) static int interfaces_startup_load_interface(void* priv, sr_session_ctx_t* session, const struct ly_ctx* ly_ctx, struct lyd_node* parent_node) { int error = 0; - interfaces_ctx_t *ctx = (interfaces_ctx_t *) priv; - interfaces_interfaces_interface_element_t *interface_head = NULL; + interfaces_ctx_t* ctx = (interfaces_ctx_t*)priv; + interfaces_interfaces_interface_element_t* interface_head = NULL; - error = interfaces_load_interface(ly_ctx, &interface_head); + error = interfaces_load_interface(ctx, &interface_head); if (error) { SRPLG_LOG_ERR(PLUGIN_NAME, "interfaces_load_interface() error (%d)", error); goto error_out; diff --git a/src/interfaces/src/plugin/startup/store.c b/src/interfaces/src/plugin/startup/store.c index 7a60d8b7..0837a39a 100644 --- a/src/interfaces/src/plugin/startup/store.c +++ b/src/interfaces/src/plugin/startup/store.c @@ -1,6 +1,9 @@ #include "store.h" #include "plugin/common.h" +#include "plugin/api/interfaces/check.h" +#include "plugin/api/interfaces/store.h" + #include #include #include @@ -51,43 +54,43 @@ int interfaces_startup_store(interfaces_ctx_t* ctx, sr_session_ctx_t* session) static int interfaces_startup_store_interface(void* priv, const struct lyd_node* parent_container) { int error = 0; - interfaces_ctx_t *ctx = (interfaces_ctx_t *) priv; - srpc_check_status_t check_status = srpc_check_status_none; - interfaces_interfaces_interface_element_t *interface_head = NULL; + interfaces_ctx_t* ctx = (interfaces_ctx_t*)priv; + srpc_check_status_t check_status = srpc_check_status_none; + interfaces_interfaces_interface_element_t* interface_head = NULL; - struct lyd_node *interfaces_node = srpc_ly_tree_get_child_leaf(parent_container, "interfaces"); + struct lyd_node* interfaces_node = srpc_ly_tree_get_child_leaf(parent_container, "interfaces"); if (interfaces_node == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "srpc_ly_tree_get_child_leaf returned NULL for 'interfaces'"); - goto error_out; + SRPLG_LOG_ERR(PLUGIN_NAME, "srpc_ly_tree_get_child_leaf returned NULL for 'interfaces'"); + goto error_out; } SRPLG_LOG_INF(PLUGIN_NAME, "Checking interface list"); - check_status = interfaces_check_interface(ctx, interface_head); + // check_status = interfaces_check_interface(ctx, interface_head); switch (check_status) { - case srpc_check_status_none: - SRPLG_LOG_ERR(PLUGIN_NAME, "Error loading current interface list"); - goto error_out; - case srpc_check_status_error: - SRPLG_LOG_ERR(PLUGIN_NAME, "Error loading current interface array"); - goto error_out; - case srpc_check_status_non_existant: - SRPLG_LOG_INF(PLUGIN_NAME, "Storing interface array"); - - error = interfaces_store_interface(ctx, interface_head); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "interfaces_store_interface() failed (%d)", error); - goto error_out; - } - break; - case srpc_check_status_equal: - SRPLG_LOG_ERR(PLUGIN_NAME, "Startup interface array is already applied on the system"); - break; - case srpc_check_status_partial: - /* should not be returned - treat as an error */ - SRPLG_LOG_ERR(PLUGIN_NAME, "Error loading current interface array"); - goto error_out; - } + case srpc_check_status_none: + SRPLG_LOG_ERR(PLUGIN_NAME, "Error loading current interface list"); + goto error_out; + case srpc_check_status_error: + SRPLG_LOG_ERR(PLUGIN_NAME, "Error loading current interface array"); + goto error_out; + case srpc_check_status_non_existant: + SRPLG_LOG_INF(PLUGIN_NAME, "Storing interface array"); + + error = interfaces_store_interface(ctx, interface_head); + if (error) { + SRPLG_LOG_ERR(PLUGIN_NAME, "interfaces_store_interface() failed (%d)", error); + goto error_out; + } + break; + case srpc_check_status_equal: + SRPLG_LOG_ERR(PLUGIN_NAME, "Startup interface array is already applied on the system"); + break; + case srpc_check_status_partial: + /* should not be returned - treat as an error */ + SRPLG_LOG_ERR(PLUGIN_NAME, "Error loading current interface array"); + goto error_out; + } goto out; From 2c11183ff25c1a15b7cdfad8d44d0820ce977be2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 12 Sep 2022 16:12:44 +0200 Subject: [PATCH 075/247] interfaces-plugin: refactor interfaces hash API --- src/interfaces/CMakeLists.txt | 2 +- .../plugin/data/interfaces/interface/hash.c | 203 ++++++++++++++++++ .../plugin/data/interfaces/interface/hash.h | 33 +++ src/interfaces/src/plugin/types.h | 10 +- 4 files changed, 245 insertions(+), 3 deletions(-) create mode 100644 src/interfaces/src/plugin/data/interfaces/interface/hash.c create mode 100644 src/interfaces/src/plugin/data/interfaces/interface/hash.h diff --git a/src/interfaces/CMakeLists.txt b/src/interfaces/CMakeLists.txt index c09a4f55..6aa88ebd 100644 --- a/src/interfaces/CMakeLists.txt +++ b/src/interfaces/CMakeLists.txt @@ -20,7 +20,6 @@ set( src/plugin/subscription/operational.c src/plugin/subscription/rpc.c src/plugin/ly_tree.c - src/plugin/data/interface.c src/plugin/api/interfaces/check.c src/plugin/api/interfaces/load.c src/plugin/api/interfaces/store.c @@ -31,6 +30,7 @@ set( src/plugin/api/interfaces/interface/dampening/change.c src/plugin/api/interfaces/interface/carrier-delay/change.c src/plugin/data/interfaces/interface/state.c + src/plugin/data/interfaces/interface/hash.c src/plugin.c ${CMAKE_SOURCE_DIR}/src/utils/memory.c ) diff --git a/src/interfaces/src/plugin/data/interfaces/interface/hash.c b/src/interfaces/src/plugin/data/interfaces/interface/hash.c new file mode 100644 index 00000000..269cacbd --- /dev/null +++ b/src/interfaces/src/plugin/data/interfaces/interface/hash.c @@ -0,0 +1,203 @@ +#include "hash.h" + +interfaces_interface_hash_element_t* interfaces_interface_hash_new(void) +{ + return NULL; +} + +int interfaces_interface_hash_add_element(interfaces_interface_hash_element_t** hash, interfaces_interface_hash_element_t* new_element) +{ + interfaces_interface_hash_element_t* found_element = NULL; + + HASH_FIND_STR(*hash, new_element->interface.name, found_element); + + // element already exists + if (found_element != NULL) { + return -1; + } + + // element not found - add new element to the hash + HASH_ADD_KEYPTR(hh, *hash, new_element->interface.name, sizeof(new_element->interface.name), new_element); + + return 0; +} + +interfaces_interface_hash_element_t* interfaces_interface_hash_get_element(interfaces_interface_hash_element_t** hash, const char* name) +{ + interfaces_interface_hash_element_t* found_element = NULL; + + HASH_FIND_STR(*hash, name, found_element); + + return found_element; +} + +void interfaces_interface_hash_free(interfaces_interface_hash_element_t** hash) +{ + interfaces_interface_hash_element_t *tmp = NULL, *element = NULL; + + HASH_ITER(hh, *hash, element, tmp) + { + HASH_DEL(*hash, element); + interfaces_interface_hash_element_free(&element); + } +} + +interfaces_interface_hash_element_t* interfaces_interface_hash_element_new(void) +{ + interfaces_interface_hash_element_t* new_element = NULL; + + new_element = malloc(sizeof(interfaces_interface_hash_element_t)); + if (!new_element) + return NULL; + + // NULL all fields + new_element->interface = (interfaces_interfaces_interface_t) { 0 }; + + return new_element; +} + +int interfaces_interface_hash_element_set_name(interfaces_interface_hash_element_t** el, const char* name) +{ + if ((*el)->interface.name) { + free((*el)->interface.name); + (*el)->interface.name = NULL; + } + + if (name) { + (*el)->interface.name = strdup(name); + return (*el)->interface.name == NULL; + } + + return 0; +} + +int interfaces_interface_hash_element_set_description(interfaces_interface_hash_element_t** el, const char* description) +{ + if ((*el)->interface.description) { + free((*el)->interface.description); + (*el)->interface.description = NULL; + } + + if (description) { + (*el)->interface.description = strdup(description); + return (*el)->interface.description == NULL; + } + + return 0; +} + +int interfaces_interface_hash_element_set_type(interfaces_interface_hash_element_t** el, const char* type) +{ + if ((*el)->interface.type) { + free((*el)->interface.type); + (*el)->interface.type = NULL; + } + + if (type) { + (*el)->interface.type = strdup(type); + return (*el)->interface.type == NULL; + } + + return 0; +} + +int interfaces_interface_hash_element_set_enabled(interfaces_interface_hash_element_t** el, uint8_t enabled) +{ + (*el)->interface.enabled = enabled; + + return 0; +} + +int interfaces_interface_hash_element_set_link_up_down_trap_enable(interfaces_interface_hash_element_t** el, interfaces_interfaces_interface_link_up_down_trap_enable_t link_up_down_trap_enable) +{ + (*el)->interface.link_up_down_trap_enable = link_up_down_trap_enable; + return 0; +} + +int interfaces_interface_hash_element_set_carrier_delay(interfaces_interface_hash_element_t** el, interfaces_interfaces_interface_carrier_delay_t carrier_delay) +{ + (*el)->interface.carrier_delay = carrier_delay; + return 0; +} + +int interfaces_interface_hash_element_set_dampening(interfaces_interface_hash_element_t** el, interfaces_interfaces_interface_dampening_t dampening) +{ + (*el)->interface.dampening = dampening; + return 0; +} + +int interfaces_interface_hash_element_set_encapsulation(interfaces_interface_hash_element_t** el, interfaces_interfaces_interface_encapsulation_t encapsulation) +{ + (*el)->interface.encapsulation = encapsulation; + return 0; +} + +int interfaces_interface_hash_element_set_loopback(interfaces_interface_hash_element_t** el, const char* loopback) +{ + if ((*el)->interface.loopback) { + free((*el)->interface.loopback); + (*el)->interface.loopback = NULL; + } + + if (loopback) { + (*el)->interface.loopback = strdup(loopback); + return (*el)->interface.loopback == NULL; + } + + return 0; +} + +int interfaces_interface_hash_element_set_max_frame_size(interfaces_interface_hash_element_t** el, uint32_t max_frame_size) +{ + (*el)->interface.max_frame_size = max_frame_size; + return 0; +} + +int interfaces_interface_hash_element_set_parent_interface(interfaces_interface_hash_element_t** el, const char* parent_interface) +{ + if ((*el)->interface.parent_interface) { + free((*el)->interface.parent_interface); + (*el)->interface.parent_interface = NULL; + } + + if (parent_interface) { + (*el)->interface.parent_interface = strdup(parent_interface); + return (*el)->interface.parent_interface == NULL; + } + + return 0; +} + +void interfaces_interface_hash_element_free(interfaces_interface_hash_element_t** el) +{ + if (*el) { + // name + if ((*el)->interface.name) { + free((*el)->interface.name); + } + + // description + if ((*el)->interface.description) { + free((*el)->interface.description); + } + + // type + if ((*el)->interface.type) { + free((*el)->interface.type); + } + + // loopback + if ((*el)->interface.loopback) { + free((*el)->interface.loopback); + } + + // parent-interface + if ((*el)->interface.parent_interface) { + free((*el)->interface.parent_interface); + } + + // element data + free(*el); + *el = NULL; + } +} diff --git a/src/interfaces/src/plugin/data/interfaces/interface/hash.h b/src/interfaces/src/plugin/data/interfaces/interface/hash.h new file mode 100644 index 00000000..ef2e0812 --- /dev/null +++ b/src/interfaces/src/plugin/data/interfaces/interface/hash.h @@ -0,0 +1,33 @@ +#ifndef INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_HASH_H +#define INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_HASH_H + +#include "plugin/types.h" + +/* + Hash table operations +*/ + +interfaces_interface_hash_element_t* interfaces_interface_hash_new(void); +int interfaces_interface_hash_add_element(interfaces_interface_hash_element_t** hash, interfaces_interface_hash_element_t* new_element); +interfaces_interface_hash_element_t* interfaces_interface_hash_get_element(interfaces_interface_hash_element_t** hash, const char* name); +void interfaces_interface_hash_free(interfaces_interface_hash_element_t** hash); + +/* + Element operations +*/ + +interfaces_interface_hash_element_t* interfaces_interface_hash_element_new(void); +int interfaces_interface_hash_element_set_name(interfaces_interface_hash_element_t** el, const char* name); +int interfaces_interface_hash_element_set_description(interfaces_interface_hash_element_t** el, const char* description); +int interfaces_interface_hash_element_set_type(interfaces_interface_hash_element_t** el, const char* type); +int interfaces_interface_hash_element_set_enabled(interfaces_interface_hash_element_t** el, uint8_t enabled); +int interfaces_interface_hash_element_set_link_up_down_trap_enable(interfaces_interface_hash_element_t** el, interfaces_interfaces_interface_link_up_down_trap_enable_t link_up_down_trap_enable); +int interfaces_interface_hash_element_set_carrier_delay(interfaces_interface_hash_element_t** el, interfaces_interfaces_interface_carrier_delay_t carrier_delay); +int interfaces_interface_hash_element_set_dampening(interfaces_interface_hash_element_t** el, interfaces_interfaces_interface_dampening_t dampening); +int interfaces_interface_hash_element_set_encapsulation(interfaces_interface_hash_element_t** el, interfaces_interfaces_interface_encapsulation_t encapsulation); +int interfaces_interface_hash_element_set_loopback(interfaces_interface_hash_element_t** el, const char* loopback); +int interfaces_interface_hash_element_set_max_frame_size(interfaces_interface_hash_element_t** el, uint32_t max_frame_size); +int interfaces_interface_hash_element_set_parent_interface(interfaces_interface_hash_element_t** el, const char* parent_interface); +void interfaces_interface_hash_element_free(interfaces_interface_hash_element_t** el); + +#endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_HASH_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/types.h b/src/interfaces/src/plugin/types.h index 0480cea3..a8ecbff4 100644 --- a/src/interfaces/src/plugin/types.h +++ b/src/interfaces/src/plugin/types.h @@ -19,7 +19,8 @@ typedef struct interfaces_interfaces_interface interfaces_interfaces_interface_t typedef struct interfaces_interfaces_interface_element interfaces_interfaces_interface_element_t; typedef struct interfaces_interfaces interfaces_interfaces_t; typedef struct interface_ht_element interface_ht_element_t; -typedef struct interfaces_interface_state_s interfaces_interface_state_t; +typedef struct interfaces_interface_state interfaces_interface_state_t; +typedef struct interfaces_interface_hash_element interfaces_interface_hash_element_t; enum interfaces_interfaces_interface_link_up_down_trap_enable { interfaces_interfaces_interface_link_up_down_trap_enable_disabled, @@ -92,11 +93,16 @@ struct interfaces_interfaces { interfaces_interfaces_interface_element_t* interface; }; -struct interfaces_interface_state_s { +struct interfaces_interface_state { char* name; // key uint8_t state; time_t last_change; UT_hash_handle hh; }; +struct interfaces_interface_hash_element { + interfaces_interfaces_interface_t interface; + UT_hash_handle hh; +}; + #endif // INTERFACES_PLUGIN_TYPES_H From 10641a4afd26cf722643074325ab67d92b0d03dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 12 Sep 2022 16:14:08 +0200 Subject: [PATCH 076/247] interfaces-plugin: separate CMake plugin parts --- src/interfaces/CMakeLists.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/interfaces/CMakeLists.txt b/src/interfaces/CMakeLists.txt index 6aa88ebd..97eae79f 100644 --- a/src/interfaces/CMakeLists.txt +++ b/src/interfaces/CMakeLists.txt @@ -14,12 +14,19 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMakeModules") set( SOURCES + # startup src/plugin/startup/load.c src/plugin/startup/store.c + + # subscription src/plugin/subscription/change.c src/plugin/subscription/operational.c src/plugin/subscription/rpc.c + + # ly_tree src/plugin/ly_tree.c + + # API src/plugin/api/interfaces/check.c src/plugin/api/interfaces/load.c src/plugin/api/interfaces/store.c @@ -29,8 +36,12 @@ set( src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/outer-tag/change.c src/plugin/api/interfaces/interface/dampening/change.c src/plugin/api/interfaces/interface/carrier-delay/change.c + + # data src/plugin/data/interfaces/interface/state.c src/plugin/data/interfaces/interface/hash.c + + # main files src/plugin.c ${CMAKE_SOURCE_DIR}/src/utils/memory.c ) From e0e71d7f9b7ad0814bc3114827f863b8f40bdb00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 12 Sep 2022 17:39:14 +0200 Subject: [PATCH 077/247] interfaces-plugin: refactor interface state hash API --- src/interfaces/CMakeLists.txt | 2 +- src/interfaces/src/plugin.c | 55 ++++++++--- src/interfaces/src/plugin/context.h | 2 +- .../plugin/data/interfaces/interface/state.c | 53 ----------- .../plugin/data/interfaces/interface/state.h | 11 --- .../data/interfaces/interface/state_hash.c | 94 +++++++++++++++++++ .../data/interfaces/interface/state_hash.h | 25 +++++ .../src/plugin/subscription/operational.c | 8 +- src/interfaces/src/plugin/types.h | 5 + 9 files changed, 170 insertions(+), 85 deletions(-) delete mode 100644 src/interfaces/src/plugin/data/interfaces/interface/state.c delete mode 100644 src/interfaces/src/plugin/data/interfaces/interface/state.h create mode 100644 src/interfaces/src/plugin/data/interfaces/interface/state_hash.c create mode 100644 src/interfaces/src/plugin/data/interfaces/interface/state_hash.h diff --git a/src/interfaces/CMakeLists.txt b/src/interfaces/CMakeLists.txt index 97eae79f..40470f87 100644 --- a/src/interfaces/CMakeLists.txt +++ b/src/interfaces/CMakeLists.txt @@ -38,7 +38,7 @@ set( src/plugin/api/interfaces/interface/carrier-delay/change.c # data - src/plugin/data/interfaces/interface/state.c + src/plugin/data/interfaces/interface/state_hash.c src/plugin/data/interfaces/interface/hash.c # main files diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index 79532bed..0bc4a527 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -6,7 +6,7 @@ #include "plugin/context.h" // startup -#include "plugin/data/interfaces/interface/state.h" +#include "plugin/data/interfaces/interface/state_hash.h" #include "plugin/startup/load.h" #include "plugin/startup/store.h" @@ -326,6 +326,7 @@ static int interfaces_init_state_changes_tracking(interfaces_state_changes_ctx_t int error = 0; struct rtnl_link* link = NULL; pthread_attr_t attr; + interfaces_interface_state_hash_element_t* new_element = NULL; // init hash ctx->state_hash = interfaces_interface_state_hash_new(); @@ -348,8 +349,16 @@ static int interfaces_init_state_changes_tracking(interfaces_state_changes_ctx_t const time_t current_time = time(NULL); const char* link_name = rtnl_link_get_name(link); + // create new state element + SRPC_SAFE_CALL_PTR(new_element, interfaces_interface_state_hash_element_new(), error_out); + + // set element data + SRPC_SAFE_CALL_ERR(error, interfaces_interface_state_hash_element_set_name(&new_element, link_name), error_out); + interfaces_interface_state_hash_element_set_state(&new_element, oper_state); + interfaces_interface_state_hash_element_set_last_change(&new_element, current_time); + // add entry to the hash table - SRPC_SAFE_CALL_ERR(error, interfaces_interface_state_hash_add(&ctx->state_hash, link_name, oper_state, current_time), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_state_hash_add(&ctx->state_hash, new_element), error_out); link = (struct rtnl_link*)nl_cache_get_next((struct nl_object*)link); } @@ -379,6 +388,8 @@ static void interfaces_link_cache_change_cb(struct nl_cache* cache, struct nl_ob char time_buffer[100] = { 0 }; struct tm* last_change = NULL; time_t current = 0; + interfaces_interface_state_hash_element_t* new_element = NULL; + int rc = 0; // block further access using mutex @@ -392,19 +403,21 @@ static void interfaces_link_cache_change_cb(struct nl_cache* cache, struct nl_ob while (link != NULL) { const char* link_name = rtnl_link_get_name(link); - interfaces_interface_state_t* state = interfaces_interface_state_hash_get(ctx->state_hash, link_name); + interfaces_interface_state_hash_element_t* state_element = interfaces_interface_state_hash_get(ctx->state_hash, link_name); const uint8_t oper_state = rtnl_link_get_operstate(link); - if (state) { + if (state_element) { SRPLG_LOG_INF(PLUGIN_NAME, "State for interface %s already exists - updating last change", link_name); - if (oper_state != state->state) { + if (oper_state != state_element->state.state) { current = time(NULL); last_change = localtime(¤t); strftime(time_buffer, sizeof(time_buffer), "%FT%TZ", last_change); - SRPLG_LOG_INF(PLUGIN_NAME, "Interface %s changed oper-state from %d to %d at %s", link_name, state->state, oper_state, time_buffer); - state->state = oper_state; - state->last_change = time(NULL); + SRPLG_LOG_INF(PLUGIN_NAME, "Interface %s changed oper-state from %d to %d at %s", link_name, state_element->state.state, oper_state, time_buffer); + + // update state info + interfaces_interface_state_hash_element_set_state(&state_element, oper_state); + interfaces_interface_state_hash_element_set_last_change(&state_element, time(NULL)); } } else { SRPLG_LOG_INF(PLUGIN_NAME, "State for interface %s doesn\'t exist - creating a new entry in the state data hash table", link_name); @@ -412,14 +425,26 @@ static void interfaces_link_cache_change_cb(struct nl_cache* cache, struct nl_ob current = time(NULL); last_change = localtime(¤t); - // add entry to the hash table - int rc = interfaces_interface_state_hash_add(&ctx->state_hash, link_name, oper_state, current); - if (rc) { - SRPLG_LOG_ERR(PLUGIN_NAME, "Unable to add new interface %s to the interface hash"); + // create new state element + new_element = interfaces_interface_state_hash_element_new(); + if (!new_element) { + SRPLG_LOG_ERR(PLUGIN_NAME, "Unable to create new hash element for interface %s", link_name); + } else { + rc = interfaces_interface_state_hash_element_set_name(&new_element, link_name); + if (rc) { + SRPLG_LOG_ERR(PLUGIN_NAME, "Error setting interface name for a newly created hash element for interface %s", link_name); + } else { + interfaces_interface_state_hash_element_set_state(&new_element, oper_state); + interfaces_interface_state_hash_element_set_last_change(&new_element, current); + rc = interfaces_interface_state_hash_add(&ctx->state_hash, new_element); + if (rc) { + SRPLG_LOG_ERR(PLUGIN_NAME, "Unable to add new interface %s to the interface hash"); + } else { + strftime(time_buffer, sizeof(time_buffer), "%FT%TZ", last_change); + SRPLG_LOG_INF(PLUGIN_NAME, "Interface %s added to the state data hash: state = %d, time = %s", link_name, oper_state, time_buffer); + } + } } - - strftime(time_buffer, sizeof(time_buffer), "%FT%TZ", last_change); - SRPLG_LOG_INF(PLUGIN_NAME, "Interface %s added to the state data hash: state = %d, time = %s", link_name, oper_state, time_buffer); } link = (struct rtnl_link*)nl_cache_get_next((struct nl_object*)link); diff --git a/src/interfaces/src/plugin/context.h b/src/interfaces/src/plugin/context.h index 8d5fe8f4..c66e45b9 100644 --- a/src/interfaces/src/plugin/context.h +++ b/src/interfaces/src/plugin/context.h @@ -22,7 +22,7 @@ struct interfaces_state_changes_ctx_s { pthread_t manager_thread; // main hash DS for storing state info - interfaces_interface_state_t* state_hash; + interfaces_interface_state_hash_element_t* state_hash; // mutex for accessing state hash data pthread_mutex_t state_hash_mutex; diff --git a/src/interfaces/src/plugin/data/interfaces/interface/state.c b/src/interfaces/src/plugin/data/interfaces/interface/state.c deleted file mode 100644 index 56c20eac..00000000 --- a/src/interfaces/src/plugin/data/interfaces/interface/state.c +++ /dev/null @@ -1,53 +0,0 @@ -#include "state.h" -#include "src/uthash.h" - -interfaces_interface_state_t* interfaces_interface_state_hash_new(void) -{ - return NULL; -} - -int interfaces_interface_state_hash_add(interfaces_interface_state_t** state_hash, const char* name, const uint8_t state, const time_t time) -{ - interfaces_interface_state_t* new_state = malloc(sizeof(interfaces_interface_state_t)); - - if (!new_state) { - return -1; - } - - new_state->name = strdup(name); - if (!new_state->name) { - return -2; - } - - new_state->state = state; - new_state->last_change = time; - - HASH_ADD_STR(*state_hash, name, new_state); - - return 0; -} - -interfaces_interface_state_t* interfaces_interface_state_hash_get(const interfaces_interface_state_t* state_hash, const char* name) -{ - interfaces_interface_state_t* state = NULL; - - HASH_FIND_STR(state_hash, name, state); - - return state; -} - -void interfaces_interface_state_hash_free(interfaces_interface_state_t** state_hash) -{ - interfaces_interface_state_t *current = NULL, *tmp = NULL; - - HASH_ITER(hh, *state_hash, current, tmp) - { - HASH_DEL(*state_hash, current); - - // free data - free((char*)current->name); - - // free allocated struct - free(current); - } -} diff --git a/src/interfaces/src/plugin/data/interfaces/interface/state.h b/src/interfaces/src/plugin/data/interfaces/interface/state.h deleted file mode 100644 index f4738a75..00000000 --- a/src/interfaces/src/plugin/data/interfaces/interface/state.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_STATE_H -#define INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_STATE_H - -#include "plugin/types.h" - -interfaces_interface_state_t* interfaces_interface_state_hash_new(void); -int interfaces_interface_state_hash_add(interfaces_interface_state_t** state_hash, const char* name, const uint8_t state, const time_t time); -interfaces_interface_state_t* interfaces_interface_state_hash_get(const interfaces_interface_state_t* state_hash, const char* name); -void interfaces_interface_state_hash_free(interfaces_interface_state_t** state_hash); - -#endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_STATE_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/data/interfaces/interface/state_hash.c b/src/interfaces/src/plugin/data/interfaces/interface/state_hash.c new file mode 100644 index 00000000..e70b5d19 --- /dev/null +++ b/src/interfaces/src/plugin/data/interfaces/interface/state_hash.c @@ -0,0 +1,94 @@ +#include "state_hash.h" +#include "src/uthash.h" + +interfaces_interface_state_hash_element_t* interfaces_interface_state_hash_new(void) +{ + return NULL; +} + +int interfaces_interface_state_hash_add(interfaces_interface_state_hash_element_t** state_hash, interfaces_interface_state_hash_element_t* new_element) +{ + interfaces_interface_state_hash_element_t* found_element = NULL; + + HASH_FIND_STR(*state_hash, new_element->state.name, found_element); + + // element already exists + if (found_element != NULL) { + return -1; + } + + // element not found - add new element to the hash + HASH_ADD_KEYPTR(hh, *state_hash, new_element->state.name, strlen(new_element->state.name), new_element); + + return 0; +} + +interfaces_interface_state_hash_element_t* interfaces_interface_state_hash_get(const interfaces_interface_state_hash_element_t* state_hash, const char* name) +{ + interfaces_interface_state_hash_element_t* state = NULL; + + HASH_FIND_STR(state_hash, name, state); + + return state; +} + +void interfaces_interface_state_hash_free(interfaces_interface_state_hash_element_t** state_hash) +{ + interfaces_interface_state_hash_element_t *current = NULL, *tmp = NULL; + + HASH_ITER(hh, *state_hash, current, tmp) + { + HASH_DEL(*state_hash, current); + + interfaces_interface_state_hash_element_free(¤t); + } +} + +interfaces_interface_state_hash_element_t* interfaces_interface_state_hash_element_new(void) +{ + interfaces_interface_state_hash_element_t* new_element = NULL; + + new_element = malloc(sizeof(interfaces_interface_state_hash_element_t)); + if (!new_element) { + return NULL; + } + + new_element->state = (interfaces_interface_state_t) { 0 }; + + return new_element; +} + +int interfaces_interface_state_hash_element_set_name(interfaces_interface_state_hash_element_t** el, const char* name) +{ + if ((*el)->state.name) { + free((*el)->state.name); + (*el)->state.name = NULL; + } + + if (name) { + (*el)->state.name = strdup(name); + return (*el)->state.name == NULL; + } + + return 0; +} + +void interfaces_interface_state_hash_element_set_state(interfaces_interface_state_hash_element_t** el, const uint8_t state) +{ + (*el)->state.state = state; +} + +void interfaces_interface_state_hash_element_set_last_change(interfaces_interface_state_hash_element_t** el, const time_t last_change) +{ + (*el)->state.last_change = last_change; +} + +void interfaces_interface_state_hash_element_free(interfaces_interface_state_hash_element_t** el) +{ + if (*el) { + free((*el)->state.name); + + free(*el); + *el = NULL; + } +} diff --git a/src/interfaces/src/plugin/data/interfaces/interface/state_hash.h b/src/interfaces/src/plugin/data/interfaces/interface/state_hash.h new file mode 100644 index 00000000..8ee785e7 --- /dev/null +++ b/src/interfaces/src/plugin/data/interfaces/interface/state_hash.h @@ -0,0 +1,25 @@ +#ifndef INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_STATE_H +#define INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_STATE_H + +#include "plugin/types.h" + +/* + Hash table operations +*/ + +interfaces_interface_state_hash_element_t* interfaces_interface_state_hash_new(void); +int interfaces_interface_state_hash_add(interfaces_interface_state_hash_element_t** state_hash, interfaces_interface_state_hash_element_t* new_element); +interfaces_interface_state_hash_element_t* interfaces_interface_state_hash_get(const interfaces_interface_state_hash_element_t* state_hash, const char* name); +void interfaces_interface_state_hash_free(interfaces_interface_state_hash_element_t** state_hash); + +/* + Element operations +*/ + +interfaces_interface_state_hash_element_t* interfaces_interface_state_hash_element_new(void); +int interfaces_interface_state_hash_element_set_name(interfaces_interface_state_hash_element_t** el, const char* name); +void interfaces_interface_state_hash_element_set_state(interfaces_interface_state_hash_element_t** el, const uint8_t state); +void interfaces_interface_state_hash_element_set_last_change(interfaces_interface_state_hash_element_t** el, const time_t last_change); +void interfaces_interface_state_hash_element_free(interfaces_interface_state_hash_element_t** el); + +#endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_STATE_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index ae7952c5..c80a4008 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -7,7 +7,7 @@ #include "netlink/socket.h" #include "plugin/common.h" #include "plugin/context.h" -#include "plugin/data/interfaces/interface/state.h" +#include "plugin/data/interfaces/interface/state_hash.h" #include "plugin/ly_tree.h" #include "plugin/types.h" #include "srpc/common.h" @@ -113,7 +113,7 @@ int interfaces_subscription_operational_interfaces_interface_last_change(sr_sess const struct ly_ctx* ly_ctx = NULL; interfaces_ctx_t* ctx = private_data; interfaces_state_changes_ctx_t* state_ctx = &ctx->state_ctx; - interfaces_interface_state_t* state = NULL; + interfaces_interface_state_hash_element_t* state_element = NULL; // libnl struct rtnl_link* link = NULL; @@ -136,9 +136,9 @@ int interfaces_subscription_operational_interfaces_interface_last_change(sr_sess pthread_mutex_lock(&state_ctx->state_hash_mutex); // get last change - SRPC_SAFE_CALL_PTR(state, interfaces_interface_state_hash_get(state_ctx->state_hash, rtnl_link_get_name(link)), error_out); + SRPC_SAFE_CALL_PTR(state_element, interfaces_interface_state_hash_get(state_ctx->state_hash, rtnl_link_get_name(link)), error_out); - const time_t last_change = state->last_change; + const time_t last_change = state_element->state.last_change; struct tm* last_change_tm = localtime(&last_change); size_t written = strftime(last_change_buffer, sizeof(last_change_buffer), "%FT%TZ", last_change_tm); diff --git a/src/interfaces/src/plugin/types.h b/src/interfaces/src/plugin/types.h index a8ecbff4..02a3e9c8 100644 --- a/src/interfaces/src/plugin/types.h +++ b/src/interfaces/src/plugin/types.h @@ -20,6 +20,7 @@ typedef struct interfaces_interfaces_interface_element interfaces_interfaces_int typedef struct interfaces_interfaces interfaces_interfaces_t; typedef struct interface_ht_element interface_ht_element_t; typedef struct interfaces_interface_state interfaces_interface_state_t; +typedef struct interfaces_interface_state_hash_element interfaces_interface_state_hash_element_t; typedef struct interfaces_interface_hash_element interfaces_interface_hash_element_t; enum interfaces_interfaces_interface_link_up_down_trap_enable { @@ -97,6 +98,10 @@ struct interfaces_interface_state { char* name; // key uint8_t state; time_t last_change; +}; + +struct interfaces_interface_state_hash_element { + interfaces_interface_state_t state; UT_hash_handle hh; }; From b20f3e6790038c934c02fb47049d8981cd3f3da7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 12 Sep 2022 18:07:00 +0200 Subject: [PATCH 078/247] interfaces-plugin: fix hash element key length --- src/interfaces/src/plugin/data/interfaces/interface/hash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin/data/interfaces/interface/hash.c b/src/interfaces/src/plugin/data/interfaces/interface/hash.c index 269cacbd..17f77de6 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/hash.c +++ b/src/interfaces/src/plugin/data/interfaces/interface/hash.c @@ -17,7 +17,7 @@ int interfaces_interface_hash_add_element(interfaces_interface_hash_element_t** } // element not found - add new element to the hash - HASH_ADD_KEYPTR(hh, *hash, new_element->interface.name, sizeof(new_element->interface.name), new_element); + HASH_ADD_KEYPTR(hh, *hash, new_element->interface.name, strlen(new_element->interface.name), new_element); return 0; } From 2d9ef2eb259b6a92a0c37bfa49db07ce7ca27d64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 12 Sep 2022 18:20:15 +0200 Subject: [PATCH 079/247] interfaces-plugin: fix all APIs to use latest interface hash data structure --- src/interfaces/src/plugin/api/interfaces/check.c | 2 +- src/interfaces/src/plugin/api/interfaces/check.h | 2 +- src/interfaces/src/plugin/api/interfaces/load.c | 2 +- src/interfaces/src/plugin/api/interfaces/load.h | 2 +- src/interfaces/src/plugin/api/interfaces/store.c | 2 +- src/interfaces/src/plugin/api/interfaces/store.h | 2 +- src/interfaces/src/plugin/startup/load.c | 2 +- src/interfaces/src/plugin/startup/store.c | 4 ++-- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/check.c b/src/interfaces/src/plugin/api/interfaces/check.c index c738224b..460ed924 100644 --- a/src/interfaces/src/plugin/api/interfaces/check.c +++ b/src/interfaces/src/plugin/api/interfaces/check.c @@ -1,6 +1,6 @@ #include "check.h" -srpc_check_status_t interfaces_check_interface(interfaces_ctx_t* ctx, const UT_array* interface) +srpc_check_status_t interfaces_check_interface(interfaces_ctx_t* ctx, const interfaces_interface_hash_element_t* if_hash) { srpc_check_status_t status = srpc_check_status_none; return status; diff --git a/src/interfaces/src/plugin/api/interfaces/check.h b/src/interfaces/src/plugin/api/interfaces/check.h index 324295cd..4d8fc646 100644 --- a/src/interfaces/src/plugin/api/interfaces/check.h +++ b/src/interfaces/src/plugin/api/interfaces/check.h @@ -6,6 +6,6 @@ #include -srpc_check_status_t interfaces_check_interface(interfaces_ctx_t* ctx, const UT_array* interface); +srpc_check_status_t interfaces_check_interface(interfaces_ctx_t* ctx, const interfaces_interface_hash_element_t* if_hash); #endif // INTERFACES_PLUGIN_API_INTERFACES_CHECK_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index cd646b03..4da8e9d4 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -1,7 +1,7 @@ #include "load.h" #include "utlist.h" -int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interfaces_interface_element_t** interface) +int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** if_hash) { int error = 0; return error; diff --git a/src/interfaces/src/plugin/api/interfaces/load.h b/src/interfaces/src/plugin/api/interfaces/load.h index e93df333..3f50aa44 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.h +++ b/src/interfaces/src/plugin/api/interfaces/load.h @@ -4,6 +4,6 @@ #include "plugin/context.h" #include -int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interfaces_interface_element_t** interface); +int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** if_hash); #endif // INTERFACES_PLUGIN_API_INTERFACES_LOAD_H diff --git a/src/interfaces/src/plugin/api/interfaces/store.c b/src/interfaces/src/plugin/api/interfaces/store.c index 7bf50e0c..a665ce5e 100644 --- a/src/interfaces/src/plugin/api/interfaces/store.c +++ b/src/interfaces/src/plugin/api/interfaces/store.c @@ -1,7 +1,7 @@ #include "store.h" #include "utlist.h" -int interfaces_store_interface(interfaces_ctx_t* ctx, const interfaces_interfaces_interface_element_t* interface) +int interfaces_store_interface(interfaces_ctx_t* ctx, const interfaces_interface_hash_element_t* if_hash) { int error = 0; return error; diff --git a/src/interfaces/src/plugin/api/interfaces/store.h b/src/interfaces/src/plugin/api/interfaces/store.h index c2612553..ced145b6 100644 --- a/src/interfaces/src/plugin/api/interfaces/store.h +++ b/src/interfaces/src/plugin/api/interfaces/store.h @@ -4,6 +4,6 @@ #include "plugin/context.h" #include -int interfaces_store_interface(interfaces_ctx_t* ctx, const interfaces_interfaces_interface_element_t* interface); +int interfaces_store_interface(interfaces_ctx_t* ctx, const interfaces_interface_hash_element_t* if_hash); #endif // INTERFACES_PLUGIN_API_INTERFACES_STORE_H diff --git a/src/interfaces/src/plugin/startup/load.c b/src/interfaces/src/plugin/startup/load.c index c1d5b840..61b9cc1d 100644 --- a/src/interfaces/src/plugin/startup/load.c +++ b/src/interfaces/src/plugin/startup/load.c @@ -83,7 +83,7 @@ static int interfaces_startup_load_interface(void* priv, sr_session_ctx_t* sessi { int error = 0; interfaces_ctx_t* ctx = (interfaces_ctx_t*)priv; - interfaces_interfaces_interface_element_t* interface_head = NULL; + interfaces_interface_hash_element_t* interface_head = NULL; error = interfaces_load_interface(ctx, &interface_head); if (error) { diff --git a/src/interfaces/src/plugin/startup/store.c b/src/interfaces/src/plugin/startup/store.c index 0837a39a..a0c18247 100644 --- a/src/interfaces/src/plugin/startup/store.c +++ b/src/interfaces/src/plugin/startup/store.c @@ -56,7 +56,7 @@ static int interfaces_startup_store_interface(void* priv, const struct lyd_node* int error = 0; interfaces_ctx_t* ctx = (interfaces_ctx_t*)priv; srpc_check_status_t check_status = srpc_check_status_none; - interfaces_interfaces_interface_element_t* interface_head = NULL; + interfaces_interface_hash_element_t* interface_head = NULL; struct lyd_node* interfaces_node = srpc_ly_tree_get_child_leaf(parent_container, "interfaces"); if (interfaces_node == NULL) { @@ -65,7 +65,7 @@ static int interfaces_startup_store_interface(void* priv, const struct lyd_node* } SRPLG_LOG_INF(PLUGIN_NAME, "Checking interface list"); - // check_status = interfaces_check_interface(ctx, interface_head); + check_status = interfaces_check_interface(ctx, interface_head); switch (check_status) { case srpc_check_status_none: From 2b1b6e241b3c41acbc9fcb37bba8a4aaf1e28855 Mon Sep 17 00:00:00 2001 From: agardijan Date: Wed, 14 Sep 2022 11:12:32 +0200 Subject: [PATCH 080/247] interfaces-plugin: add interface status - enabled enum --- src/interfaces/src/plugin/types.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/interfaces/src/plugin/types.h b/src/interfaces/src/plugin/types.h index 0480cea3..420ba8ad 100644 --- a/src/interfaces/src/plugin/types.h +++ b/src/interfaces/src/plugin/types.h @@ -21,6 +21,11 @@ typedef struct interfaces_interfaces interfaces_interfaces_t; typedef struct interface_ht_element interface_ht_element_t; typedef struct interfaces_interface_state_s interfaces_interface_state_t; +enum interfaces_interfaces_interface_enable { + interfaces_interfaces_interface_enable_disabled, + interfaces_interfaces_interface_enable_enabled, +}; + enum interfaces_interfaces_interface_link_up_down_trap_enable { interfaces_interfaces_interface_link_up_down_trap_enable_disabled, interfaces_interfaces_interface_link_up_down_trap_enable_enabled, From 16ed7fae95c34c277d27884e5d8f90163ca0c5b3 Mon Sep 17 00:00:00 2001 From: agardijan Date: Wed, 14 Sep 2022 11:41:51 +0200 Subject: [PATCH 081/247] interfaces-plugin: add max interface name length --- src/interfaces/src/plugin/common.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/interfaces/src/plugin/common.h b/src/interfaces/src/plugin/common.h index 8fb3b73a..37a50d3c 100644 --- a/src/interfaces/src/plugin/common.h +++ b/src/interfaces/src/plugin/common.h @@ -94,4 +94,6 @@ #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) +#define MAX_IF_NAME_LEN IFNAMSIZ // 16 bytes + #endif // INTERFACES_PLUGIN_COMMON_H From 8b5ce01cf1deaf19ba3e6bf304bfbefb0d8955e5 Mon Sep 17 00:00:00 2001 From: agardijan Date: Thu, 15 Sep 2022 12:44:40 +0200 Subject: [PATCH 082/247] interfaces-plugin: add load interfaces data except ipv4/6, neighbors --- .../src/plugin/api/interfaces/load.c | 351 +++++++++++++++++- .../src/plugin/api/interfaces/load.h | 28 +- 2 files changed, 377 insertions(+), 2 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index cd646b03..7db35e39 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -1,8 +1,357 @@ #include "load.h" #include "utlist.h" +#include "plugin/common.h" +#include "plugin/data/interface.h" +#include "utils/memory.h" -int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interfaces_interface_element_t** interface) +#include + +#include + +#include +#include + +#include + +static char *interfaces_get_interface_name(struct rtnl_link *link) +{ + char *name = NULL; + + name = rtnl_link_get_name(link); + if (name == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_get_name error"); + } + + return name; +} + +static char *interfaces_get_interface_description(interfaces_ctx_t *ctx, char *name) +{ + int error = SR_ERR_OK; + char path_buffer[PATH_MAX] = {0}; + sr_val_t *val = {0}; + char *description = NULL; + + /* conjure description path for this interface: /ietf-interfaces:interfaces/interface[name='test_interface']/description */ + error = snprintf(path_buffer, sizeof(path_buffer) / sizeof(char), "%s[name=\"%s\"]/description", INTERFACES_INTERFACES_LIST_YANG_PATH, name); + if (error < 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf error"); + goto error_out; + } + + // get the interface description value + error = sr_get_item(ctx->startup_session, path_buffer, 0, &val); + if (error != SR_ERR_OK) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_get_item error (%d): %s", error, sr_strerror(error)); + goto error_out; + } + + if (strlen(val->data.string_val) > 0) { + description = val->data.string_val; + } + +error_out: + return description; +} + +static int read_from_sys_file(const char *dir_path, char *interface, int *val) +{ + int error = 0; + char tmp_buffer[PATH_MAX]; + FILE *fptr = NULL; + char tmp_val[4] = {0}; + + error = snprintf(tmp_buffer, sizeof(tmp_buffer), "%s/%s/type", dir_path, interface); + if (error < 0) { + // snprintf error + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: snprintf failed", __func__); + goto out; + } + + /* snprintf returns return the number of bytes that are written - reset error to 0 */ + error = 0; + + fptr = fopen((const char *) tmp_buffer, "r"); + + if (fptr != NULL) { + fgets(tmp_val, sizeof(tmp_val), fptr); + + *val = atoi(tmp_val); + + fclose(fptr); + } else { + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: failed to open %s: %s", __func__, tmp_buffer, strerror(errno)); + error = -1; + goto out; + } + +out: + return error; +} + +static char *interfaces_get_interface_type(struct rtnl_link *link, char *name) +{ + int error = 0; + char *type = NULL; + + type = rtnl_link_get_type(link); + if (type == NULL) { + /* rtnl_link_get_type() will return NULL for interfaces that were not + * set with rtnl_link_set_type() + * + * get the type from: /sys/class/net//type + */ + const char *path_to_sys = "/sys/class/net/"; + int type_id = 0; + + error = read_from_sys_file(path_to_sys, name, &type_id); + if (error != 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: read_from_sys_file error", __func__); + goto error_out; + } + + switch (type_id) { + case ARPHRD_ETHER: + type = "eth"; + break; + case ARPHRD_LOOPBACK: + type = "lo"; + break; + default: + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: unkown type_id: %d", __func__, type_id); + } + } + +error_out: + return type; +} + +static uint8_t interfaces_get_interface_enabled(struct rtnl_link *link) +{ + uint8_t enabled = rtnl_link_get_operstate(link); + + /* + * if the lo interface state is unknown, treat it as enabled + * otherwise it will be set to down, and dns resolution won't work + */ + if (IF_OPER_UP == enabled || IF_OPER_UNKNOWN == enabled) { + enabled = interfaces_interfaces_interface_enable_enabled; + } else if (IF_OPER_DOWN == enabled ) { + enabled = interfaces_interfaces_interface_enable_disabled; + } + + return enabled; +} + +static char *interfaces_get_interface_parent_interface(struct nl_cache *cache, struct rtnl_link *link) +{ + int parent_index = 0; + char parent_buffer[MAX_IF_NAME_LEN] = {0}; + char *parent_interface = NULL; + + if (rtnl_link_is_vlan(link)) { + parent_index = rtnl_link_get_link(link); + parent_interface = rtnl_link_i2name(cache, parent_index, parent_buffer, MAX_IF_NAME_LEN); + } + + return parent_interface; +} + +/* TODO: outer tag, second id, tag - maybe refactor all to pass by reference, return error */ +static int interfaces_get_interface_vlan_id(struct rtnl_link *link, interfaces_interfaces_interface_t *interface) +{ + uint16_t *outer_vlan_id = &interface->encapsulation.dot1q_vlan.outer_tag.vlan_id; + char *first = NULL; + char *second = NULL; + + if (rtnl_link_is_vlan(link)) { + *outer_vlan_id = (uint16_t) rtnl_link_vlan_get_id(link); + if (*outer_vlan_id <= 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: couldn't get vlan ID", __func__); + return interfaces_load_failure; + } + + /* check if vlan_id in name, if it is this is the QinQ interface, skip it */ + first = strchr(interface->name, '.'); + second = strchr(first+1, '.'); + + if (second != 0) { + return interfaces_load_continue; + } + } + + return interfaces_load_success; +} + +static int interfaces_parse_link(interfaces_ctx_t *ctx, struct nl_sock *socket, struct nl_cache *cache, struct rtnl_link *link, interfaces_interfaces_interface_t *interface) +{ + int error = interfaces_load_success; + *interface = (interfaces_interfaces_interface_t) {0}; + + interface->name = interfaces_get_interface_name(link); + if (interface->name == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: name error", __func__); + goto error_out; + } + + interface->description = interfaces_get_interface_description(ctx, interface->name); + if (interface->description == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: description error", __func__); + goto error_out; + } + + interface->type = interfaces_get_interface_type(link, interface->name); + if (interface->type == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: type error", __func__); + goto error_out; + } + + interface->parent_interface = interfaces_get_interface_parent_interface(cache, link); + if (interface->parent_interface == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: parent_interface error", __func__); + goto error_out; + } + + error = interfaces_get_interface_vlan_id(link, interface); + if (error != interfaces_load_success) { + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: vlan id error", __func__); + goto out; // error_out would possibly change the error + } + + interface->enabled = interfaces_get_interface_enabled(link); + + goto out; +error_out: + error = interfaces_load_failure; +out: + /* allocated in interfaces_get_interface_description */ + if (interface->description != NULL) { + FREE_SAFE(interface->description); + } + + return error; +} + +static int interfaces_add_link(interface_ht_element_t **if_root, interfaces_interfaces_interface_t *interface) { int error = 0; + + error = interfaces_data_ht_add(*if_root, interface->name); + if (error != 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: error adding link (%d)", __func__, error); + goto error_out; + } + + if (interface->description != NULL) { + error = interfaces_data_ht_set_description(*if_root, interface->name, interface->description); + if (error != 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: error setting description (%d)", __func__, error); + goto error_out; + } + } + + if (interface->type != NULL) { + error = interfaces_data_ht_set_type(*if_root, interface->name, interface->type); + if (error != 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: error setting type (%d)", __func__, error); + goto error_out; + } + } + + goto out; +error_out: +out: + return error; +} + +static struct rtnl_link *interfaces_get_next_link(struct rtnl_link *link) +{ + return (struct rtnl_link *) nl_cache_get_next((struct nl_object *) link); +} + +static int interfaces_interfaces_worker(interfaces_ctx_t *ctx, struct nl_sock *socket, struct nl_cache *cache, interface_ht_element_t **if_root) +{ + int error = 0; + struct rtnl_link *link = NULL; + interfaces_interfaces_interface_t interface = {0}; + + link = (struct rtnl_link *) nl_cache_get_first(cache); + + while (link != NULL) { + error = interfaces_parse_link(ctx, socket, cache, link, &interface); + switch (error) { + case interfaces_load_success: + error = interfaces_add_link(if_root, &interface); + if (error != 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: error adding link (%d)", __func__, error); + goto error_out; + } + break; + case interfaces_load_continue: + break; + default: + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: error parsing link (%d)", __func__, error); + goto error_out; + } + + link = interfaces_get_next_link(link); + } + + goto out; +error_out: + error = -1; +out: + if (link != NULL) { + rtnl_link_put(link); + } + return error; } + +int interfaces_load_interface(interfaces_ctx_t* ctx, interface_ht_element_t **if_root) +{ + int error = 0; + struct nl_sock *socket = NULL; + struct nl_cache *cache = NULL; + + interfaces_data_ht_root_init(if_root); + + socket = nl_socket_alloc(); + if (socket == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "nl_socket_alloc error: invalid socket"); + goto error_out; + } + + error = nl_connect(socket, NETLINK_ROUTE); + if (error != 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "nl_connect error (%d): %s", error, nl_geterror(error)); + goto error_out; + } + + error = rtnl_link_alloc_cache(socket, AF_UNSPEC, &cache); + if (error != 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_alloc_cache error (%d): %s", error, nl_geterror(error)); + goto error_out; + } + + error = interfaces_interfaces_worker(ctx, socket, cache, if_root); + if (error != 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "interfaces_parse_links: error parsing links (%d)", error); + goto error_out; + } + + goto out; +error_out: + error = -1; +out: + if (socket != NULL) { + nl_socket_free(socket); + } + + if (cache != NULL) { + nl_cache_free(cache); + } + + return error; +} + diff --git a/src/interfaces/src/plugin/api/interfaces/load.h b/src/interfaces/src/plugin/api/interfaces/load.h index e93df333..60a9235c 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.h +++ b/src/interfaces/src/plugin/api/interfaces/load.h @@ -4,6 +4,32 @@ #include "plugin/context.h" #include -int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interfaces_interface_element_t** interface); +enum interfaces_load_exit_status { + interfaces_load_failure = -1, + interfaces_load_success = 0, + interfaces_load_continue = 1, +}; + +static char *interfaces_get_interface_name(struct rtnl_link *link); + +static char *interfaces_get_interface_description(interfaces_ctx_t *ctx, char *name); + +static int read_from_sys_file(const char *dir_path, char *interface, int *val); + +static char *interfaces_get_interface_type(struct rtnl_link *link, char *name); + +static uint8_t interfaces_get_interface_enabled(struct rtnl_link *link); + +static int interfaces_parse_link(interfaces_ctx_t *ctx, struct nl_sock *socket, struct nl_cache *cache, struct rtnl_link *link, interfaces_interfaces_interface_t *interface); + +static char *interfaces_get_interface_parent_interface(struct nl_cache *cache, struct rtnl_link *link); + +static int interfaces_add_link(interface_ht_element_t **if_root, interfaces_interfaces_interface_t *interface); + +static struct rtnl_link *interfaces_get_next_link(struct rtnl_link *link); + +static int interfaces_interfaces_worker(interfaces_ctx_t *ctx, struct nl_sock *socket, struct nl_cache *cache, interface_ht_element_t **if_root); + +int interfaces_load_interface(interfaces_ctx_t* ctx, interface_ht_element_t** interface); #endif // INTERFACES_PLUGIN_API_INTERFACES_LOAD_H From 178532f09faf1619a8bd91b036b6f0472276c7e5 Mon Sep 17 00:00:00 2001 From: agardijan Date: Thu, 15 Sep 2022 15:57:46 +0200 Subject: [PATCH 083/247] interfaces-plugin: refactor interface load to new hash table api --- .../src/plugin/api/interfaces/load.c | 24 ++++++++++++++----- .../src/plugin/api/interfaces/load.h | 7 +++--- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index 36875ce6..87270a49 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -1,7 +1,6 @@ #include "load.h" #include "utlist.h" #include "plugin/common.h" -#include "plugin/data/interface.h" #include "utils/memory.h" #include @@ -232,18 +231,21 @@ static int interfaces_parse_link(interfaces_ctx_t *ctx, struct nl_sock *socket, return error; } -static int interfaces_add_link(interface_ht_element_t **if_root, interfaces_interfaces_interface_t *interface) +static int interfaces_add_link(interfaces_interface_hash_element_t **if_hash, interfaces_interfaces_interface_t *interface) { int error = 0; + + interfaces_interface_hash_element_t *new_if_hash_elem = interfaces_interface_hash_element_new(); + interfaces_interface_hash_element_set_name(&new_if_hash_elem, interface->name); - error = interfaces_data_ht_add(*if_root, interface->name); + error = interfaces_interface_hash_add_element(if_hash, new_if_hash_elem); if (error != 0) { SRPLG_LOG_ERR(PLUGIN_NAME, "%s: error adding link (%d)", __func__, error); goto error_out; } if (interface->description != NULL) { - error = interfaces_data_ht_set_description(*if_root, interface->name, interface->description); + error = interfaces_interface_hash_element_set_description(&new_if_hash_elem, interface->description); if (error != 0) { SRPLG_LOG_ERR(PLUGIN_NAME, "%s: error setting description (%d)", __func__, error); goto error_out; @@ -251,13 +253,23 @@ static int interfaces_add_link(interface_ht_element_t **if_root, interfaces_inte } if (interface->type != NULL) { - error = interfaces_data_ht_set_type(*if_root, interface->name, interface->type); + error = interfaces_interface_hash_element_set_type(&new_if_hash_elem, interface->type); + if (error != 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: error setting type (%d)", __func__, error); + goto error_out; + } + } + + if (interface->parent_interface != NULL) { + error = interfaces_interface_hash_element_set_parent_interface(&new_if_hash_elem, interface->parent_interface); if (error != 0) { SRPLG_LOG_ERR(PLUGIN_NAME, "%s: error setting type (%d)", __func__, error); goto error_out; } } + interfaces_interface_hash_element_set_enabled(&new_if_hash_elem, interface->enabled); + goto out; error_out: out: @@ -314,7 +326,7 @@ int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_e struct nl_sock *socket = NULL; struct nl_cache *cache = NULL; - interfaces_data_ht_root_init(if_hash); + *if_hash = interfaces_interface_hash_new(); socket = nl_socket_alloc(); if (socket == NULL) { diff --git a/src/interfaces/src/plugin/api/interfaces/load.h b/src/interfaces/src/plugin/api/interfaces/load.h index 23abefc0..e2b8186f 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.h +++ b/src/interfaces/src/plugin/api/interfaces/load.h @@ -1,6 +1,7 @@ #ifndef INTERFACES_PLUGIN_API_INTERFACES_LOAD_H #define INTERFACES_PLUGIN_API_INTERFACES_LOAD_H +#include "plugin/data/interfaces/interface/hash.h" #include "plugin/context.h" #include @@ -24,12 +25,12 @@ static int interfaces_parse_link(interfaces_ctx_t *ctx, struct nl_sock *socket, static char *interfaces_get_interface_parent_interface(struct nl_cache *cache, struct rtnl_link *link); -static int interfaces_add_link(interface_ht_element_t **if_root, interfaces_interfaces_interface_t *interface); +static int interfaces_add_link(interfaces_interface_hash_element_t **if_hash, interfaces_interfaces_interface_t *interface); static struct rtnl_link *interfaces_get_next_link(struct rtnl_link *link); -static int interfaces_interfaces_worker(interfaces_ctx_t *ctx, struct nl_sock *socket, struct nl_cache *cache, interface_ht_element_t **if_root); +static int interfaces_interfaces_worker(interfaces_ctx_t *ctx, struct nl_sock *socket, struct nl_cache *cache, interfaces_interface_hash_element_t **if_hash); -int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t **if_hash); +int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t **if_hash; #endif // INTERFACES_PLUGIN_API_INTERFACES_LOAD_H From e52af5a07ba1b1484783d39fe506317697ac8a05 Mon Sep 17 00:00:00 2001 From: agardijan Date: Thu, 15 Sep 2022 16:01:49 +0200 Subject: [PATCH 084/247] interfaces-plugin: remove old interface hash table sources --- src/interfaces/src/plugin/data/interface.c | 210 --------------------- src/interfaces/src/plugin/data/interface.h | 32 ---- 2 files changed, 242 deletions(-) delete mode 100644 src/interfaces/src/plugin/data/interface.c delete mode 100644 src/interfaces/src/plugin/data/interface.h diff --git a/src/interfaces/src/plugin/data/interface.c b/src/interfaces/src/plugin/data/interface.c deleted file mode 100644 index 18eb53f6..00000000 --- a/src/interfaces/src/plugin/data/interface.c +++ /dev/null @@ -1,210 +0,0 @@ -#include "interface.h" -#include "plugin/common.h" -#include "utils/memory.h" - -#include - -void -interfaces_data_ht_root_init(interface_ht_element_t **if_root) -{ - /* uthash root node has to be initialized to NULL */ - *if_root = NULL; -} - -static void -interfaces_data_init(interfaces_interfaces_interface_t* interface) -{ - /* TODO: init all struct members */ - interface->name = NULL; - interface->description = NULL; - interface->type = NULL; - interface->enabled = 0; - interface->loopback = NULL; - interface->parent_interface = NULL; -} - -interface_ht_element_t * -interfaces_data_ht_get_by_name(interface_ht_element_t *if_root, char *name) -{ - interface_ht_element_t *elem = NULL; - HASH_FIND_STR(if_root, name, elem); - return elem; -} - -void -interfaces_data_ht_set_name(interfaces_interfaces_interface_t *interface, char *name) -{ - interface->name = xstrdup(name); -} - -int -interfaces_data_ht_add(interface_ht_element_t *if_root, char *name) -{ - interface_ht_element_t *tmp = NULL, *elem = NULL; - int rc = 0; - - HASH_FIND_STR(if_root, name, tmp); - if (tmp != NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "interface with name key: %s already exists in hash table", name); - goto error_out; - } - - elem = (interface_ht_element_t *) xmalloc(sizeof elem); - interfaces_data_init(&elem->interface); - interfaces_data_ht_set_name(&elem->interface, name); - - /* since name is char *, *_KEYPTR has to be used instead of *_STR */ - HASH_ADD_KEYPTR(hh, if_root, elem->interface.name, sizeof(elem->interface.name), elem); - - goto out; -error_out: - rc = -1; -out: - return rc; -} - -int -interfaces_data_ht_set_description(interface_ht_element_t *if_root, char *name, char *description) -{ - interface_ht_element_t *elem = NULL; - int rc = 0; - - elem = interfaces_data_ht_get_by_name(if_root, name); - if (elem == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "interface with name key: %s non-existant in hash table", name); - goto error_out; - } - - if (elem->interface.description != NULL) { - FREE_SAFE(elem->interface.description); - } - elem->interface.description = xstrdup(description); - if (elem->interface.description == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "couldn't copy description: %s", description); - goto error_out; - } - - goto out; -error_out: - rc = -1; -out: - return rc; -} - -int -interfaces_data_ht_set_type(interface_ht_element_t *if_root, char *name, char *type) -{ - interface_ht_element_t *elem = NULL; - int rc = 0; - - elem = interfaces_data_ht_get_by_name(if_root, name); - if (elem == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "interface with name key: %s non-existant in hash table", name); - goto error_out; - } - - if (elem->interface.type != NULL) { - FREE_SAFE(elem->interface.type); - } - elem->interface.type = xstrdup(type); - if (elem->interface.type == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "couldn't copy type: %s", type); - goto error_out; - } - - goto out; -error_out: - rc = -1; -out: - return rc; -} - -int -interfaces_data_ht_set_loopback(interface_ht_element_t *if_root, char *name, char *loopback) -{ - interface_ht_element_t *elem = NULL; - int rc = 0; - - elem = interfaces_data_ht_get_by_name(if_root, name); - if (elem == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "interface with name key: %s non-existant in hash table", name); - goto error_out; - } - - if (elem->interface.loopback != NULL) { - FREE_SAFE(elem->interface.loopback); - } - elem->interface.loopback = xstrdup(loopback); - if (elem->interface.loopback == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "couldn't copy loopback: %s", loopback); - goto error_out; - } - - goto out; -error_out: - rc = -1; -out: - return rc; -} - -int -interfaces_data_ht_set_parent_interface(interface_ht_element_t *if_root, char *name, char *parent_interface) -{ - interface_ht_element_t *elem = NULL; - int rc = 0; - - elem = interfaces_data_ht_get_by_name(if_root, name); - if (elem == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "interface with name key: %s non-existant in hash table", name); - goto error_out; - } - - if (elem->interface.parent_interface != NULL) { - FREE_SAFE(elem->interface.parent_interface); - } - elem->interface.parent_interface = xstrdup(parent_interface); - if (elem->interface.parent_interface == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "couldn't copy parent interface: %s", parent_interface); - goto error_out; - } - - goto out; -error_out: - rc = -1; -out: - return rc; -} - -void -interfaces_data_ht_if_free(interfaces_interfaces_interface_t *interface) -{ - /* TODO: free other struct members as needed */ - if (interface->name) { - FREE_SAFE(interface->name); - } - if (interface->description) { - FREE_SAFE(interface->description); - } - if (interface->type) { - FREE_SAFE(interface->type); - } - if (interface->loopback) { - FREE_SAFE(interface->loopback); - } - if (interface->parent_interface) { - FREE_SAFE(interface->parent_interface); - } -} - -void -interfaces_data_ht_free(interface_ht_element_t *if_root) -{ - interface_ht_element_t *tmp = NULL, *elem = NULL; - - HASH_ITER(hh, if_root, elem, tmp) { - HASH_DEL(if_root, elem); - interfaces_data_ht_if_free(&elem->interface); - FREE_SAFE(elem); - } -} - diff --git a/src/interfaces/src/plugin/data/interface.h b/src/interfaces/src/plugin/data/interface.h deleted file mode 100644 index fb7d15c4..00000000 --- a/src/interfaces/src/plugin/data/interface.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef IF_DATA_H -#define IF_DATA_H - -#include - -#include "plugin/types.h" - -void interfaces_data_ht_root_init(interface_ht_element_t** if_root); - -static void -interfaces_data_init(interfaces_interfaces_interface_t* interface); - -interface_ht_element_t* -interfaces_data_ht_get_by_name(interface_ht_element_t* if_root, char* name); - -void interfaces_data_ht_set_name(interfaces_interfaces_interface_t* interface, char* name); - -int interfaces_data_ht_add(interface_ht_element_t* if_root, char* name); - -int interfaces_data_ht_set_description(interface_ht_element_t* if_root, char* name, char* description); - -int interfaces_data_ht_set_type(interface_ht_element_t* if_root, char* name, char* type); - -int interfaces_data_ht_set_loopback(interface_ht_element_t* if_root, char* name, char* loopback); - -int interfaces_data_ht_set_parent_interface(interface_ht_element_t* if_root, char* name, char* parent_interface); - -void interfaces_data_ht_if_free(interfaces_interfaces_interface_t* interface); - -void interfaces_data_ht_free(interface_ht_element_t* if_root); - -#endif /* IF_DATA_H */ From 64caf689e0964b8986f2f28e6f7698d0c78e7cfe Mon Sep 17 00:00:00 2001 From: agardijan Date: Thu, 15 Sep 2022 16:05:59 +0200 Subject: [PATCH 085/247] interfaces-plugin: use utils/memory funcs in hash table api --- .../plugin/data/interfaces/interface/hash.c | 38 +++++++++---------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/src/interfaces/src/plugin/data/interfaces/interface/hash.c b/src/interfaces/src/plugin/data/interfaces/interface/hash.c index 17f77de6..b62f3b0d 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/hash.c +++ b/src/interfaces/src/plugin/data/interfaces/interface/hash.c @@ -1,4 +1,5 @@ #include "hash.h" +#include "utils/memory.h" interfaces_interface_hash_element_t* interfaces_interface_hash_new(void) { @@ -46,7 +47,7 @@ interfaces_interface_hash_element_t* interfaces_interface_hash_element_new(void) { interfaces_interface_hash_element_t* new_element = NULL; - new_element = malloc(sizeof(interfaces_interface_hash_element_t)); + new_element = xmalloc(sizeof(interfaces_interface_hash_element_t)); if (!new_element) return NULL; @@ -59,12 +60,11 @@ interfaces_interface_hash_element_t* interfaces_interface_hash_element_new(void) int interfaces_interface_hash_element_set_name(interfaces_interface_hash_element_t** el, const char* name) { if ((*el)->interface.name) { - free((*el)->interface.name); - (*el)->interface.name = NULL; + FREE_SAFE((*el)->interface.name); } if (name) { - (*el)->interface.name = strdup(name); + (*el)->interface.name = xstrdup(name); return (*el)->interface.name == NULL; } @@ -74,12 +74,11 @@ int interfaces_interface_hash_element_set_name(interfaces_interface_hash_element int interfaces_interface_hash_element_set_description(interfaces_interface_hash_element_t** el, const char* description) { if ((*el)->interface.description) { - free((*el)->interface.description); - (*el)->interface.description = NULL; + FREE_SAFE((*el)->interface.description); } if (description) { - (*el)->interface.description = strdup(description); + (*el)->interface.description = xstrdup(description); return (*el)->interface.description == NULL; } @@ -89,12 +88,11 @@ int interfaces_interface_hash_element_set_description(interfaces_interface_hash_ int interfaces_interface_hash_element_set_type(interfaces_interface_hash_element_t** el, const char* type) { if ((*el)->interface.type) { - free((*el)->interface.type); - (*el)->interface.type = NULL; + FREE_SAFE((*el)->interface.type); } if (type) { - (*el)->interface.type = strdup(type); + (*el)->interface.type = xstrdup(type); return (*el)->interface.type == NULL; } @@ -135,12 +133,11 @@ int interfaces_interface_hash_element_set_encapsulation(interfaces_interface_has int interfaces_interface_hash_element_set_loopback(interfaces_interface_hash_element_t** el, const char* loopback) { if ((*el)->interface.loopback) { - free((*el)->interface.loopback); - (*el)->interface.loopback = NULL; + FREE_SAFE((*el)->interface.loopback); } if (loopback) { - (*el)->interface.loopback = strdup(loopback); + (*el)->interface.loopback = xstrdup(loopback); return (*el)->interface.loopback == NULL; } @@ -156,12 +153,11 @@ int interfaces_interface_hash_element_set_max_frame_size(interfaces_interface_ha int interfaces_interface_hash_element_set_parent_interface(interfaces_interface_hash_element_t** el, const char* parent_interface) { if ((*el)->interface.parent_interface) { - free((*el)->interface.parent_interface); - (*el)->interface.parent_interface = NULL; + FREE_SAFE((*el)->interface.parent_interface); } if (parent_interface) { - (*el)->interface.parent_interface = strdup(parent_interface); + (*el)->interface.parent_interface = xstrdup(parent_interface); return (*el)->interface.parent_interface == NULL; } @@ -173,27 +169,27 @@ void interfaces_interface_hash_element_free(interfaces_interface_hash_element_t* if (*el) { // name if ((*el)->interface.name) { - free((*el)->interface.name); + FREE_SAFE((*el)->interface.name); } // description if ((*el)->interface.description) { - free((*el)->interface.description); + FREE_SAFE((*el)->interface.description); } // type if ((*el)->interface.type) { - free((*el)->interface.type); + FREE_SAFE((*el)->interface.type); } // loopback if ((*el)->interface.loopback) { - free((*el)->interface.loopback); + FREE_SAFE((*el)->interface.loopback); } // parent-interface if ((*el)->interface.parent_interface) { - free((*el)->interface.parent_interface); + FREE_SAFE((*el)->interface.parent_interface); } // element data From 8338a7ec1e77c780edcd6efd26ce575a0623c3a8 Mon Sep 17 00:00:00 2001 From: agardijan Date: Thu, 15 Sep 2022 16:07:19 +0200 Subject: [PATCH 086/247] interfaces-plugin: add missing parentheses --- src/interfaces/src/plugin/api/interfaces/load.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/load.h b/src/interfaces/src/plugin/api/interfaces/load.h index e2b8186f..2cf1136f 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.h +++ b/src/interfaces/src/plugin/api/interfaces/load.h @@ -3,7 +3,6 @@ #include "plugin/data/interfaces/interface/hash.h" #include "plugin/context.h" -#include enum interfaces_load_exit_status { interfaces_load_failure = -1, @@ -31,6 +30,6 @@ static struct rtnl_link *interfaces_get_next_link(struct rtnl_link *link); static int interfaces_interfaces_worker(interfaces_ctx_t *ctx, struct nl_sock *socket, struct nl_cache *cache, interfaces_interface_hash_element_t **if_hash); -int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t **if_hash; +int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t **if_hash); #endif // INTERFACES_PLUGIN_API_INTERFACES_LOAD_H From 40160333d0c4b8232cd20f0c076b7b20d1cbe68e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Fri, 16 Sep 2022 12:52:12 +0200 Subject: [PATCH 087/247] interfaces-plugin: add operational ietf-ip callbacks --- src/interfaces/src/plugin.c | 44 ++++ src/interfaces/src/plugin/common.h | 60 +++++ .../src/plugin/subscription/operational.c | 242 ++++++++++++++++++ .../src/plugin/subscription/operational.h | 11 + 4 files changed, 357 insertions(+) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index 0bc4a527..ac667362 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -183,6 +183,50 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) INTERFACES_INTERFACES_INTERFACE_FORWARDING_MODE_YANG_PATH, interfaces_subscription_operational_interfaces_interface_forwarding_mode, }, + { + INTERFACES_INTERFACES_INTERFACE_IPV4_ADDRESS_ORIGIN_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_ipv4_address_origin, + }, + { + INTERFACES_INTERFACES_INTERFACE_IPV4_ADDRESS_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_ipv4_address, + }, + { + INTERFACES_INTERFACES_INTERFACE_IPV4_NEIGHBOR_ORIGIN_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_ipv4_neighbor_origin, + }, + { + INTERFACES_INTERFACES_INTERFACE_IPV4_NEIGHBOR_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_ipv4_neighbor, + }, + { + INTERFACES_INTERFACES_INTERFACE_IPV6_ADDRESS_ORIGIN_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_ipv6_address_origin, + }, + { + INTERFACES_INTERFACES_INTERFACE_IPV6_ADDRESS_STATUS_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_ipv6_address_status, + }, + { + INTERFACES_INTERFACES_INTERFACE_IPV6_ADDRESS_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_ipv6_address, + }, + { + INTERFACES_INTERFACES_INTERFACE_IPV6_NEIGHBOR_ORIGIN_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_ipv6_neighbor_origin, + }, + { + INTERFACES_INTERFACES_INTERFACE_IPV6_NEIGHBOR_IS_ROUTER_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_ipv6_neighbor_is_router, + }, + { + INTERFACES_INTERFACES_INTERFACE_IPV6_NEIGHBOR_STATE_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_ipv6_neighbor_state, + }, + { + INTERFACES_INTERFACES_INTERFACE_IPV6_NEIGHBOR_YANG_PATH, + interfaces_subscription_operational_interfaces_interface_ipv6_neighbor, + }, { INTERFACES_INTERFACES_INTERFACE_YANG_PATH, interfaces_subscription_operational_interfaces_interface, diff --git a/src/interfaces/src/plugin/common.h b/src/interfaces/src/plugin/common.h index 8fb3b73a..2d8c9b86 100644 --- a/src/interfaces/src/plugin/common.h +++ b/src/interfaces/src/plugin/common.h @@ -33,6 +33,32 @@ #define INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_OUT_DISCARDS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_YANG_PATH "/out-discards" #define INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_OUT_ERRORS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_YANG_PATH "/out-errors" #define INTERFACES_INTERFACES_STATE_INTERFACE_STATISTICS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_YANG_PATH "/statistics" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV4_FORWARDING_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_IPV4_YANG_PATH "/forwarding" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV4_MTU_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_IPV4_YANG_PATH "/mtu" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV4_ADDRESS_IP_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_IPV4_ADDRESS_YANG_PATH "/ip" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV4_ADDRESS_PREFIX_LENGTH_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_IPV4_ADDRESS_YANG_PATH "/prefix-length" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV4_ADDRESS_NETMASK_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_IPV4_ADDRESS_YANG_PATH "/netmask" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV4_ADDRESS_ORIGIN_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_IPV4_ADDRESS_YANG_PATH "/origin" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV4_ADDRESS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_IPV4_YANG_PATH "/address" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV4_NEIGHBOR_IP_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_IPV4_NEIGHBOR_YANG_PATH "/ip" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV4_NEIGHBOR_LINK_LAYER_ADDRESS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_IPV4_NEIGHBOR_YANG_PATH "/link-layer-address" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV4_NEIGHBOR_ORIGIN_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_IPV4_NEIGHBOR_YANG_PATH "/origin" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV4_NEIGHBOR_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_IPV4_YANG_PATH "/neighbor" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV4_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_YANG_PATH "/ipv4" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_FORWARDING_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_YANG_PATH "/forwarding" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_MTU_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_YANG_PATH "/mtu" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_ADDRESS_IP_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_ADDRESS_YANG_PATH "/ip" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_ADDRESS_PREFIX_LENGTH_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_ADDRESS_YANG_PATH "/prefix-length" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_ADDRESS_ORIGIN_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_ADDRESS_YANG_PATH "/origin" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_ADDRESS_STATUS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_ADDRESS_YANG_PATH "/status" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_ADDRESS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_YANG_PATH "/address" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_NEIGHBOR_IP_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_NEIGHBOR_YANG_PATH "/ip" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_NEIGHBOR_LINK_LAYER_ADDRESS_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_NEIGHBOR_YANG_PATH "/link-layer-address" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_NEIGHBOR_ORIGIN_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_NEIGHBOR_YANG_PATH "/origin" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_NEIGHBOR_IS_ROUTER_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_NEIGHBOR_YANG_PATH "/is-router" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_NEIGHBOR_STATE_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_NEIGHBOR_YANG_PATH "/state" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_NEIGHBOR_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_YANG_PATH "/neighbor" +#define INTERFACES_INTERFACES_STATE_INTERFACE_IPV6_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_YANG_PATH "/ipv6" #define INTERFACES_INTERFACES_STATE_INTERFACE_YANG_PATH INTERFACES_INTERFACES_STATE_YANG_PATH "/interface" #define INTERFACES_INTERFACES_STATE_YANG_PATH "/ietf-interfaces:interfaces-state" #define INTERFACES_INTERFACES_INTERFACE_NAME_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/name" @@ -89,6 +115,40 @@ #define INTERFACES_INTERFACES_INTERFACE_MAX_FRAME_SIZE_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/max-frame-size" #define INTERFACES_INTERFACES_INTERFACE_FORWARDING_MODE_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/forwarding-mode" #define INTERFACES_INTERFACES_INTERFACE_PARENT_INTERFACE_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/parent-interface" +#define INTERFACES_INTERFACES_INTERFACE_IPV4_ENABLED_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV4_YANG_PATH "/enabled" +#define INTERFACES_INTERFACES_INTERFACE_IPV4_FORWARDING_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV4_YANG_PATH "/forwarding" +#define INTERFACES_INTERFACES_INTERFACE_IPV4_MTU_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV4_YANG_PATH "/mtu" +#define INTERFACES_INTERFACES_INTERFACE_IPV4_ADDRESS_IP_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV4_ADDRESS_YANG_PATH "/ip" +#define INTERFACES_INTERFACES_INTERFACE_IPV4_ADDRESS_PREFIX_LENGTH_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV4_ADDRESS_YANG_PATH "/prefix-length" +#define INTERFACES_INTERFACES_INTERFACE_IPV4_ADDRESS_NETMASK_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV4_ADDRESS_YANG_PATH "/netmask" +#define INTERFACES_INTERFACES_INTERFACE_IPV4_ADDRESS_ORIGIN_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV4_ADDRESS_YANG_PATH "/origin" +#define INTERFACES_INTERFACES_INTERFACE_IPV4_ADDRESS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV4_YANG_PATH "/address" +#define INTERFACES_INTERFACES_INTERFACE_IPV4_NEIGHBOR_IP_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV4_NEIGHBOR_YANG_PATH "/ip" +#define INTERFACES_INTERFACES_INTERFACE_IPV4_NEIGHBOR_LINK_LAYER_ADDRESS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV4_NEIGHBOR_YANG_PATH "/link-layer-address" +#define INTERFACES_INTERFACES_INTERFACE_IPV4_NEIGHBOR_ORIGIN_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV4_NEIGHBOR_YANG_PATH "/origin" +#define INTERFACES_INTERFACES_INTERFACE_IPV4_NEIGHBOR_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV4_YANG_PATH "/neighbor" +#define INTERFACES_INTERFACES_INTERFACE_IPV4_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/ipv4" +#define INTERFACES_INTERFACES_INTERFACE_IPV6_ENABLED_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV6_YANG_PATH "/enabled" +#define INTERFACES_INTERFACES_INTERFACE_IPV6_FORWARDING_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV6_YANG_PATH "/forwarding" +#define INTERFACES_INTERFACES_INTERFACE_IPV6_MTU_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV6_YANG_PATH "/mtu" +#define INTERFACES_INTERFACES_INTERFACE_IPV6_ADDRESS_IP_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV6_ADDRESS_YANG_PATH "/ip" +#define INTERFACES_INTERFACES_INTERFACE_IPV6_ADDRESS_PREFIX_LENGTH_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV6_ADDRESS_YANG_PATH "/prefix-length" +#define INTERFACES_INTERFACES_INTERFACE_IPV6_ADDRESS_ORIGIN_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV6_ADDRESS_YANG_PATH "/origin" +#define INTERFACES_INTERFACES_INTERFACE_IPV6_ADDRESS_STATUS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV6_ADDRESS_YANG_PATH "/status" +#define INTERFACES_INTERFACES_INTERFACE_IPV6_ADDRESS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV6_YANG_PATH "/address" +#define INTERFACES_INTERFACES_INTERFACE_IPV6_NEIGHBOR_IP_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV6_NEIGHBOR_YANG_PATH "/ip" +#define INTERFACES_INTERFACES_INTERFACE_IPV6_NEIGHBOR_LINK_LAYER_ADDRESS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV6_NEIGHBOR_YANG_PATH "/link-layer-address" +#define INTERFACES_INTERFACES_INTERFACE_IPV6_NEIGHBOR_ORIGIN_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV6_NEIGHBOR_YANG_PATH "/origin" +#define INTERFACES_INTERFACES_INTERFACE_IPV6_NEIGHBOR_IS_ROUTER_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV6_NEIGHBOR_YANG_PATH "/is-router" +#define INTERFACES_INTERFACES_INTERFACE_IPV6_NEIGHBOR_STATE_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV6_NEIGHBOR_YANG_PATH "/state" +#define INTERFACES_INTERFACES_INTERFACE_IPV6_NEIGHBOR_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV6_YANG_PATH "/neighbor" +#define INTERFACES_INTERFACES_INTERFACE_IPV6_DUP_ADDR_DETECT_TRANSMITS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV6_YANG_PATH "/dup-addr-detect-transmits" +#define INTERFACES_INTERFACES_INTERFACE_IPV6_AUTOCONF_CREATE_GLOBAL_ADDRESSES_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV6_AUTOCONF_YANG_PATH "/create-global-addresses" +#define INTERFACES_INTERFACES_INTERFACE_IPV6_AUTOCONF_CREATE_TEMPORARY_ADDRESSES_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV6_AUTOCONF_YANG_PATH "/create-temporary-addresses" +#define INTERFACES_INTERFACES_INTERFACE_IPV6_AUTOCONF_TEMPORARY_VALID_LIFETIME_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV6_AUTOCONF_YANG_PATH "/temporary-valid-lifetime" +#define INTERFACES_INTERFACES_INTERFACE_IPV6_AUTOCONF_TEMPORARY_PREFERRED_LIFETIME_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV6_AUTOCONF_YANG_PATH "/temporary-preferred-lifetime" +#define INTERFACES_INTERFACES_INTERFACE_IPV6_AUTOCONF_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV6_YANG_PATH "/autoconf" +#define INTERFACES_INTERFACES_INTERFACE_IPV6_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/ipv6" #define INTERFACES_INTERFACES_INTERFACE_YANG_PATH INTERFACES_INTERFACES_YANG_PATH "/interface" #define INTERFACES_INTERFACES_YANG_PATH "/ietf-interfaces:interfaces" diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index c80a4008..e3c2777e 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -1264,6 +1264,248 @@ int interfaces_subscription_operational_interfaces_interface_forwarding_mode(sr_ return error; } +int interfaces_subscription_operational_interfaces_interface_ipv4_address_origin(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_ipv4_address(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_ipv4_neighbor_origin(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_ipv4_neighbor(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_ipv6_address_origin(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_ipv6_address_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_ipv6_address(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_ipv6_neighbor_origin(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_ipv6_neighbor_is_router(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_ipv6_neighbor_state(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + +int interfaces_subscription_operational_interfaces_interface_ipv6_neighbor(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) +{ + int error = SR_ERR_OK; + const struct ly_ctx* ly_ctx = NULL; + + if (*parent == NULL) { + ly_ctx = sr_acquire_context(sr_session_get_connection(session)); + if (ly_ctx == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); + goto error_out; + } + } + + goto out; + +error_out: + error = SR_ERR_CALLBACK_FAILED; + +out: + return error; +} + int interfaces_subscription_operational_interfaces_interface(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; diff --git a/src/interfaces/src/plugin/subscription/operational.h b/src/interfaces/src/plugin/subscription/operational.h index 8c8c4a29..6b395434 100644 --- a/src/interfaces/src/plugin/subscription/operational.h +++ b/src/interfaces/src/plugin/subscription/operational.h @@ -32,6 +32,17 @@ int interfaces_subscription_operational_interfaces_interface_dampening_penalty(s int interfaces_subscription_operational_interfaces_interface_dampening_suppressed(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); int interfaces_subscription_operational_interfaces_interface_dampening_time_remaining(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); int interfaces_subscription_operational_interfaces_interface_forwarding_mode(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_ipv4_address_origin(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_ipv4_address(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_ipv4_neighbor_origin(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_ipv4_neighbor(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_ipv6_address_origin(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_ipv6_address_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_ipv6_address(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_ipv6_neighbor_origin(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_ipv6_neighbor_is_router(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_ipv6_neighbor_state(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); +int interfaces_subscription_operational_interfaces_interface_ipv6_neighbor(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); int interfaces_subscription_operational_interfaces_interface(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data); #endif // INTERFACES_PLUGIN_SUBSCRIPTION_OPERATIONAL_H \ No newline at end of file From 8e873884eae0ccd584136765126a2229c6ee3c1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Fri, 16 Sep 2022 12:54:30 +0200 Subject: [PATCH 088/247] interfaces-plugin: add ietf-ip ipv4 and ipv6 API --- src/interfaces/CMakeLists.txt | 7 + .../interface/ipv4/address/change.c | 100 +++++++++ .../interface/ipv4/address/change.h | 17 ++ .../api/interfaces/interface/ipv4/change.c | 164 +++++++++++++++ .../api/interfaces/interface/ipv4/change.h | 23 ++ .../interface/ipv4/neighbor/change.c | 68 ++++++ .../interface/ipv4/neighbor/change.h | 14 ++ .../interface/ipv6/address/change.c | 68 ++++++ .../interface/ipv6/address/change.h | 14 ++ .../interface/ipv6/autoconf/change.c | 132 ++++++++++++ .../interface/ipv6/autoconf/change.h | 20 ++ .../api/interfaces/interface/ipv6/change.c | 196 ++++++++++++++++++ .../api/interfaces/interface/ipv6/change.h | 26 +++ .../interface/ipv6/neighbor/change.c | 68 ++++++ .../interface/ipv6/neighbor/change.h | 14 ++ 15 files changed, 931 insertions(+) create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.h create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.h create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.h create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.c create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.h create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv6/autoconf/change.c create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv6/autoconf/change.h create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv6/change.c create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv6/change.h create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/change.c create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/change.h diff --git a/src/interfaces/CMakeLists.txt b/src/interfaces/CMakeLists.txt index 40470f87..d59fa65b 100644 --- a/src/interfaces/CMakeLists.txt +++ b/src/interfaces/CMakeLists.txt @@ -32,6 +32,13 @@ set( src/plugin/api/interfaces/store.c src/plugin/api/interfaces/change.c src/plugin/api/interfaces/interface/change.c + src/plugin/api/interfaces/interface/ipv6/change.c + src/plugin/api/interfaces/interface/ipv6/autoconf/change.c + src/plugin/api/interfaces/interface/ipv6/neighbor/change.c + src/plugin/api/interfaces/interface/ipv6/address/change.c + src/plugin/api/interfaces/interface/ipv4/change.c + src/plugin/api/interfaces/interface/ipv4/neighbor/change.c + src/plugin/api/interfaces/interface/ipv4/address/change.c src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/second-tag/change.c src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/outer-tag/change.c src/plugin/api/interfaces/interface/dampening/change.c diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c new file mode 100644 index 00000000..a032b5ee --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c @@ -0,0 +1,100 @@ +#include "change.h" +#include "plugin/common.h" + +#include + +int interfaces_interface_ipv4_address_change_netmask_init(void* priv) +{ + int error = 0; + return error; +} + +int interfaces_interface_ipv4_address_change_netmask(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +void interfaces_interface_ipv4_address_change_netmask_free(void* priv) +{ +} + +int interfaces_interface_ipv4_address_change_prefix_length_init(void* priv) +{ + int error = 0; + return error; +} + +int interfaces_interface_ipv4_address_change_prefix_length(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +void interfaces_interface_ipv4_address_change_prefix_length_free(void* priv) +{ +} + +int interfaces_interface_ipv4_address_change_ip_init(void* priv) +{ + int error = 0; + return error; +} + +int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +void interfaces_interface_ipv4_address_change_ip_free(void* priv) +{ +} diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.h b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.h new file mode 100644 index 00000000..d40b23da --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.h @@ -0,0 +1,17 @@ +#ifndef INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV4_ADDRESS_CHANGE_H +#define INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV4_ADDRESS_CHANGE_H + +#include +#include + +int interfaces_interface_ipv4_address_change_netmask_init(void* priv); +int interfaces_interface_ipv4_address_change_netmask(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +void interfaces_interface_ipv4_address_change_netmask_free(void* priv); +int interfaces_interface_ipv4_address_change_prefix_length_init(void* priv); +int interfaces_interface_ipv4_address_change_prefix_length(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +void interfaces_interface_ipv4_address_change_prefix_length_free(void* priv); +int interfaces_interface_ipv4_address_change_ip_init(void* priv); +int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +void interfaces_interface_ipv4_address_change_ip_free(void* priv); + +#endif // INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV4_ADDRESS_CHANGE_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c new file mode 100644 index 00000000..3080e3d5 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c @@ -0,0 +1,164 @@ +#include "change.h" +#include "plugin/common.h" + +#include + +int interfaces_interface_ipv4_change_neighbor_init(void* priv) +{ + int error = 0; + return error; +} + +int interfaces_interface_ipv4_change_neighbor(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +void interfaces_interface_ipv4_change_neighbor_free(void* priv) +{ +} + +int interfaces_interface_ipv4_change_address_init(void* priv) +{ + int error = 0; + return error; +} + +int interfaces_interface_ipv4_change_address(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +void interfaces_interface_ipv4_change_address_free(void* priv) +{ +} + +int interfaces_interface_ipv4_change_mtu_init(void* priv) +{ + int error = 0; + return error; +} + +int interfaces_interface_ipv4_change_mtu(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +void interfaces_interface_ipv4_change_mtu_free(void* priv) +{ +} + +int interfaces_interface_ipv4_change_forwarding_init(void* priv) +{ + int error = 0; + return error; +} + +int interfaces_interface_ipv4_change_forwarding(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +void interfaces_interface_ipv4_change_forwarding_free(void* priv) +{ +} + +int interfaces_interface_ipv4_change_enabled_init(void* priv) +{ + int error = 0; + return error; +} + +int interfaces_interface_ipv4_change_enabled(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +void interfaces_interface_ipv4_change_enabled_free(void* priv) +{ +} diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.h b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.h new file mode 100644 index 00000000..16524db5 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.h @@ -0,0 +1,23 @@ +#ifndef INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV4_CHANGE_H +#define INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV4_CHANGE_H + +#include +#include + +int interfaces_interface_ipv4_change_neighbor_init(void* priv); +int interfaces_interface_ipv4_change_neighbor(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +void interfaces_interface_ipv4_change_neighbor_free(void* priv); +int interfaces_interface_ipv4_change_address_init(void* priv); +int interfaces_interface_ipv4_change_address(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +void interfaces_interface_ipv4_change_address_free(void* priv); +int interfaces_interface_ipv4_change_mtu_init(void* priv); +int interfaces_interface_ipv4_change_mtu(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +void interfaces_interface_ipv4_change_mtu_free(void* priv); +int interfaces_interface_ipv4_change_forwarding_init(void* priv); +int interfaces_interface_ipv4_change_forwarding(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +void interfaces_interface_ipv4_change_forwarding_free(void* priv); +int interfaces_interface_ipv4_change_enabled_init(void* priv); +int interfaces_interface_ipv4_change_enabled(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +void interfaces_interface_ipv4_change_enabled_free(void* priv); + +#endif // INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV4_CHANGE_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c new file mode 100644 index 00000000..8485bbdb --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c @@ -0,0 +1,68 @@ +#include "change.h" +#include "plugin/common.h" + +#include + +int interfaces_interface_ipv4_neighbor_change_link_layer_address_init(void* priv) +{ + int error = 0; + return error; +} + +int interfaces_interface_ipv4_neighbor_change_link_layer_address(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +void interfaces_interface_ipv4_neighbor_change_link_layer_address_free(void* priv) +{ +} + +int interfaces_interface_ipv4_neighbor_change_ip_init(void* priv) +{ + int error = 0; + return error; +} + +int interfaces_interface_ipv4_neighbor_change_ip(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +void interfaces_interface_ipv4_neighbor_change_ip_free(void* priv) +{ +} diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.h b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.h new file mode 100644 index 00000000..9169ddbc --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.h @@ -0,0 +1,14 @@ +#ifndef INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV4_NEIGHBOR_CHANGE_H +#define INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV4_NEIGHBOR_CHANGE_H + +#include +#include + +int interfaces_interface_ipv4_neighbor_change_link_layer_address_init(void* priv); +int interfaces_interface_ipv4_neighbor_change_link_layer_address(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +void interfaces_interface_ipv4_neighbor_change_link_layer_address_free(void* priv); +int interfaces_interface_ipv4_neighbor_change_ip_init(void* priv); +int interfaces_interface_ipv4_neighbor_change_ip(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +void interfaces_interface_ipv4_neighbor_change_ip_free(void* priv); + +#endif // INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV4_NEIGHBOR_CHANGE_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.c new file mode 100644 index 00000000..8e9b88fd --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.c @@ -0,0 +1,68 @@ +#include "change.h" +#include "plugin/common.h" + +#include + +int interfaces_interface_ipv6_address_change_prefix_length_init(void* priv) +{ + int error = 0; + return error; +} + +int interfaces_interface_ipv6_address_change_prefix_length(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +void interfaces_interface_ipv6_address_change_prefix_length_free(void* priv) +{ +} + +int interfaces_interface_ipv6_address_change_ip_init(void* priv) +{ + int error = 0; + return error; +} + +int interfaces_interface_ipv6_address_change_ip(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +void interfaces_interface_ipv6_address_change_ip_free(void* priv) +{ +} diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.h b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.h new file mode 100644 index 00000000..e90bac00 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.h @@ -0,0 +1,14 @@ +#ifndef INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV6_ADDRESS_CHANGE_H +#define INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV6_ADDRESS_CHANGE_H + +#include +#include + +int interfaces_interface_ipv6_address_change_prefix_length_init(void* priv); +int interfaces_interface_ipv6_address_change_prefix_length(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +void interfaces_interface_ipv6_address_change_prefix_length_free(void* priv); +int interfaces_interface_ipv6_address_change_ip_init(void* priv); +int interfaces_interface_ipv6_address_change_ip(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +void interfaces_interface_ipv6_address_change_ip_free(void* priv); + +#endif // INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV6_ADDRESS_CHANGE_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/autoconf/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/autoconf/change.c new file mode 100644 index 00000000..eac37112 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/autoconf/change.c @@ -0,0 +1,132 @@ +#include "change.h" +#include "plugin/common.h" + +#include + +int interfaces_interface_ipv6_autoconf_change_temporary_preferred_lifetime_init(void* priv) +{ + int error = 0; + return error; +} + +int interfaces_interface_ipv6_autoconf_change_temporary_preferred_lifetime(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +void interfaces_interface_ipv6_autoconf_change_temporary_preferred_lifetime_free(void* priv) +{ +} + +int interfaces_interface_ipv6_autoconf_change_temporary_valid_lifetime_init(void* priv) +{ + int error = 0; + return error; +} + +int interfaces_interface_ipv6_autoconf_change_temporary_valid_lifetime(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +void interfaces_interface_ipv6_autoconf_change_temporary_valid_lifetime_free(void* priv) +{ +} + +int interfaces_interface_ipv6_autoconf_change_create_temporary_addresses_init(void* priv) +{ + int error = 0; + return error; +} + +int interfaces_interface_ipv6_autoconf_change_create_temporary_addresses(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +void interfaces_interface_ipv6_autoconf_change_create_temporary_addresses_free(void* priv) +{ +} + +int interfaces_interface_ipv6_autoconf_change_create_global_addresses_init(void* priv) +{ + int error = 0; + return error; +} + +int interfaces_interface_ipv6_autoconf_change_create_global_addresses(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +void interfaces_interface_ipv6_autoconf_change_create_global_addresses_free(void* priv) +{ +} diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/autoconf/change.h b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/autoconf/change.h new file mode 100644 index 00000000..080ad2ba --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/autoconf/change.h @@ -0,0 +1,20 @@ +#ifndef INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV6_AUTOCONF_CHANGE_H +#define INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV6_AUTOCONF_CHANGE_H + +#include +#include + +int interfaces_interface_ipv6_autoconf_change_temporary_preferred_lifetime_init(void* priv); +int interfaces_interface_ipv6_autoconf_change_temporary_preferred_lifetime(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +void interfaces_interface_ipv6_autoconf_change_temporary_preferred_lifetime_free(void* priv); +int interfaces_interface_ipv6_autoconf_change_temporary_valid_lifetime_init(void* priv); +int interfaces_interface_ipv6_autoconf_change_temporary_valid_lifetime(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +void interfaces_interface_ipv6_autoconf_change_temporary_valid_lifetime_free(void* priv); +int interfaces_interface_ipv6_autoconf_change_create_temporary_addresses_init(void* priv); +int interfaces_interface_ipv6_autoconf_change_create_temporary_addresses(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +void interfaces_interface_ipv6_autoconf_change_create_temporary_addresses_free(void* priv); +int interfaces_interface_ipv6_autoconf_change_create_global_addresses_init(void* priv); +int interfaces_interface_ipv6_autoconf_change_create_global_addresses(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +void interfaces_interface_ipv6_autoconf_change_create_global_addresses_free(void* priv); + +#endif // INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV6_AUTOCONF_CHANGE_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/change.c new file mode 100644 index 00000000..eef313fe --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/change.c @@ -0,0 +1,196 @@ +#include "change.h" +#include "plugin/common.h" + +#include + +int interfaces_interface_ipv6_change_dup_addr_detect_transmits_init(void* priv) +{ + int error = 0; + return error; +} + +int interfaces_interface_ipv6_change_dup_addr_detect_transmits(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +void interfaces_interface_ipv6_change_dup_addr_detect_transmits_free(void* priv) +{ +} + +int interfaces_interface_ipv6_change_neighbor_init(void* priv) +{ + int error = 0; + return error; +} + +int interfaces_interface_ipv6_change_neighbor(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +void interfaces_interface_ipv6_change_neighbor_free(void* priv) +{ +} + +int interfaces_interface_ipv6_change_address_init(void* priv) +{ + int error = 0; + return error; +} + +int interfaces_interface_ipv6_change_address(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +void interfaces_interface_ipv6_change_address_free(void* priv) +{ +} + +int interfaces_interface_ipv6_change_mtu_init(void* priv) +{ + int error = 0; + return error; +} + +int interfaces_interface_ipv6_change_mtu(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +void interfaces_interface_ipv6_change_mtu_free(void* priv) +{ +} + +int interfaces_interface_ipv6_change_forwarding_init(void* priv) +{ + int error = 0; + return error; +} + +int interfaces_interface_ipv6_change_forwarding(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +void interfaces_interface_ipv6_change_forwarding_free(void* priv) +{ +} + +int interfaces_interface_ipv6_change_enabled_init(void* priv) +{ + int error = 0; + return error; +} + +int interfaces_interface_ipv6_change_enabled(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +void interfaces_interface_ipv6_change_enabled_free(void* priv) +{ +} diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/change.h b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/change.h new file mode 100644 index 00000000..dc9d2584 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/change.h @@ -0,0 +1,26 @@ +#ifndef INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV6_CHANGE_H +#define INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV6_CHANGE_H + +#include +#include + +int interfaces_interface_ipv6_change_dup_addr_detect_transmits_init(void* priv); +int interfaces_interface_ipv6_change_dup_addr_detect_transmits(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +void interfaces_interface_ipv6_change_dup_addr_detect_transmits_free(void* priv); +int interfaces_interface_ipv6_change_neighbor_init(void* priv); +int interfaces_interface_ipv6_change_neighbor(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +void interfaces_interface_ipv6_change_neighbor_free(void* priv); +int interfaces_interface_ipv6_change_address_init(void* priv); +int interfaces_interface_ipv6_change_address(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +void interfaces_interface_ipv6_change_address_free(void* priv); +int interfaces_interface_ipv6_change_mtu_init(void* priv); +int interfaces_interface_ipv6_change_mtu(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +void interfaces_interface_ipv6_change_mtu_free(void* priv); +int interfaces_interface_ipv6_change_forwarding_init(void* priv); +int interfaces_interface_ipv6_change_forwarding(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +void interfaces_interface_ipv6_change_forwarding_free(void* priv); +int interfaces_interface_ipv6_change_enabled_init(void* priv); +int interfaces_interface_ipv6_change_enabled(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +void interfaces_interface_ipv6_change_enabled_free(void* priv); + +#endif // INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV6_CHANGE_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/change.c new file mode 100644 index 00000000..8fa2ffe1 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/change.c @@ -0,0 +1,68 @@ +#include "change.h" +#include "plugin/common.h" + +#include + +int interfaces_interface_ipv6_neighbor_change_link_layer_address_init(void* priv) +{ + int error = 0; + return error; +} + +int interfaces_interface_ipv6_neighbor_change_link_layer_address(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +void interfaces_interface_ipv6_neighbor_change_link_layer_address_free(void* priv) +{ +} + +int interfaces_interface_ipv6_neighbor_change_ip_init(void* priv) +{ + int error = 0; + return error; +} + +int interfaces_interface_ipv6_neighbor_change_ip(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + switch (change_ctx->operation) { + case SR_OP_CREATED: + break; + case SR_OP_MODIFIED: + break; + case SR_OP_DELETED: + break; + case SR_OP_MOVED: + break; + } + + return error; +} + +void interfaces_interface_ipv6_neighbor_change_ip_free(void* priv) +{ +} diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/change.h b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/change.h new file mode 100644 index 00000000..b3c6b129 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/change.h @@ -0,0 +1,14 @@ +#ifndef INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV6_NEIGHBOR_CHANGE_H +#define INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV6_NEIGHBOR_CHANGE_H + +#include +#include + +int interfaces_interface_ipv6_neighbor_change_link_layer_address_init(void* priv); +int interfaces_interface_ipv6_neighbor_change_link_layer_address(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +void interfaces_interface_ipv6_neighbor_change_link_layer_address_free(void* priv); +int interfaces_interface_ipv6_neighbor_change_ip_init(void* priv); +int interfaces_interface_ipv6_neighbor_change_ip(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +void interfaces_interface_ipv6_neighbor_change_ip_free(void* priv); + +#endif // INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV6_NEIGHBOR_CHANGE_H \ No newline at end of file From 50249efc46bdb531225106e40236a06f236def2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Fri, 16 Sep 2022 13:02:11 +0200 Subject: [PATCH 089/247] interfaces-plugin: add ietf-ip ipv4 and ipv6 types --- src/interfaces/src/plugin/types.h | 81 +++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/src/interfaces/src/plugin/types.h b/src/interfaces/src/plugin/types.h index 02a3e9c8..41434a1e 100644 --- a/src/interfaces/src/plugin/types.h +++ b/src/interfaces/src/plugin/types.h @@ -15,6 +15,17 @@ typedef struct interfaces_interfaces_interface_encapsulation_dot1q_vlan_outer_ta typedef struct interfaces_interfaces_interface_encapsulation_dot1q_vlan_second_tag interfaces_interfaces_interface_encapsulation_dot1q_vlan_second_tag_t; typedef struct interfaces_interfaces_interface_encapsulation_dot1q_vlan interfaces_interfaces_interface_encapsulation_dot1q_vlan_t; typedef struct interfaces_interfaces_interface_encapsulation interfaces_interfaces_interface_encapsulation_t; +typedef struct interfaces_interfaces_interface_ipv4_address interfaces_interfaces_interface_ipv4_address_t; +typedef struct interfaces_interfaces_interface_ipv4_address_element interfaces_interfaces_interface_ipv4_address_element_t; +typedef struct interfaces_interfaces_interface_ipv4_neighbor interfaces_interfaces_interface_ipv4_neighbor_t; +typedef struct interfaces_interfaces_interface_ipv4_neighbor_element interfaces_interfaces_interface_ipv4_neighbor_element_t; +typedef struct interfaces_interfaces_interface_ipv4 interfaces_interfaces_interface_ipv4_t; +typedef struct interfaces_interfaces_interface_ipv6_address interfaces_interfaces_interface_ipv6_address_t; +typedef struct interfaces_interfaces_interface_ipv6_address_element interfaces_interfaces_interface_ipv6_address_element_t; +typedef struct interfaces_interfaces_interface_ipv6_neighbor interfaces_interfaces_interface_ipv6_neighbor_t; +typedef struct interfaces_interfaces_interface_ipv6_neighbor_element interfaces_interfaces_interface_ipv6_neighbor_element_t; +typedef struct interfaces_interfaces_interface_ipv6_autoconf interfaces_interfaces_interface_ipv6_autoconf_t; +typedef struct interfaces_interfaces_interface_ipv6 interfaces_interfaces_interface_ipv6_t; typedef struct interfaces_interfaces_interface interfaces_interfaces_interface_t; typedef struct interfaces_interfaces_interface_element interfaces_interfaces_interface_element_t; typedef struct interfaces_interfaces interfaces_interfaces_t; @@ -61,6 +72,74 @@ struct interfaces_interfaces_interface_encapsulation { interfaces_interfaces_interface_encapsulation_dot1q_vlan_t dot1q_vlan; }; +struct interfaces_interfaces_interface_ipv4_address { + char* ip; + union { + uint8_t prefix_length; + char* netmask; + } subnet; +}; + +struct interfaces_interfaces_interface_ipv4_address_element { + interfaces_interfaces_interface_ipv4_address_element_t* next; + interfaces_interfaces_interface_ipv4_address_t address; +}; + +struct interfaces_interfaces_interface_ipv4_neighbor { + char* ip; + char* link_layer_address; +}; + +struct interfaces_interfaces_interface_ipv4_neighbor_element { + interfaces_interfaces_interface_ipv4_neighbor_element_t* next; + interfaces_interfaces_interface_ipv4_neighbor_t neighbor; +}; + +struct interfaces_interfaces_interface_ipv4 { + uint8_t enabled; + uint8_t forwarding; + uint16_t mtu; + interfaces_interfaces_interface_ipv4_address_element_t* address; + interfaces_interfaces_interface_ipv4_neighbor_element_t* neighbor; +}; + +struct interfaces_interfaces_interface_ipv6_address { + char* ip; + uint8_t prefix_length; +}; + +struct interfaces_interfaces_interface_ipv6_address_element { + interfaces_interfaces_interface_ipv6_address_element_t* next; + interfaces_interfaces_interface_ipv6_address_t address; +}; + +struct interfaces_interfaces_interface_ipv6_neighbor { + char* ip; + char* link_layer_address; +}; + +struct interfaces_interfaces_interface_ipv6_neighbor_element { + interfaces_interfaces_interface_ipv6_neighbor_element_t* next; + interfaces_interfaces_interface_ipv6_neighbor_t neighbor; +}; + +struct interfaces_interfaces_interface_ipv6_autoconf { + uint8_t create_global_addresses; + uint8_t create_temporary_addresses; + uint32_t temporary_valid_lifetime; + uint32_t temporary_preferred_lifetime; +}; + +struct interfaces_interfaces_interface_ipv6 { + uint8_t enabled; + uint8_t forwarding; + uint32_t mtu; + interfaces_interfaces_interface_ipv6_address_element_t* address; + interfaces_interfaces_interface_ipv6_neighbor_element_t* neighbor; + uint32_t dup_addr_detect_transmits; + interfaces_interfaces_interface_ipv6_autoconf_t autoconf; +}; + struct interfaces_interfaces_interface { char* name; char* description; @@ -73,6 +152,8 @@ struct interfaces_interfaces_interface { char* loopback; uint32_t max_frame_size; char* parent_interface; + interfaces_interfaces_interface_ipv4_t ipv4; + interfaces_interfaces_interface_ipv6_t ipv6; }; struct interfaces_interfaces_interface_element { From 270ef8fcab6156401f3f90f981283fcbaaec0705 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Fri, 16 Sep 2022 18:30:24 +0200 Subject: [PATCH 090/247] interfaces-plugin: add ly_tree ietf-ip API --- src/interfaces/src/plugin/ly_tree.c | 179 +++++++++++++++++++++++++++- src/interfaces/src/plugin/ly_tree.h | 34 ++++++ 2 files changed, 208 insertions(+), 5 deletions(-) diff --git a/src/interfaces/src/plugin/ly_tree.c b/src/interfaces/src/plugin/ly_tree.c index 9afe3cc6..07c59b11 100644 --- a/src/interfaces/src/plugin/ly_tree.c +++ b/src/interfaces/src/plugin/ly_tree.c @@ -3,11 +3,6 @@ #include -int interfaces_ly_tree_create_interfaces_state_interface_name(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* name) -{ - return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "name", name); -} - int interfaces_ly_tree_create_interfaces(const struct ly_ctx* ly_ctx, struct lyd_node** interfaces_node) { return srpc_ly_tree_create_container(ly_ctx, NULL, interfaces_node, "interfaces"); @@ -19,6 +14,180 @@ int interfaces_ly_tree_create_interfaces_interface(const struct ly_ctx* ly_ctx, return srpc_ly_tree_create_list(ly_ctx, interfaces_node, interface_node, "interface", "name", name); } +int interfaces_ly_tree_create_interfaces_interface_ipv6(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, struct lyd_node** ipv6_node) +{ + return srpc_ly_tree_create_container(ly_ctx, interface_node, ipv6_node, "ipv6"); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv6_autoconf(const struct ly_ctx* ly_ctx, struct lyd_node* ipv6_node, struct lyd_node** autoconf_node) +{ + return srpc_ly_tree_create_container(ly_ctx, ipv6_node, autoconf_node, "autoconf"); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv6_autoconf_temporary_preferred_lifetime(const struct ly_ctx* ly_ctx, struct lyd_node* autoconf_node, const char* temporary_preferred_lifetime) +{ + return srpc_ly_tree_create_leaf(ly_ctx, autoconf_node, NULL, "temporary-preferred-lifetime", temporary_preferred_lifetime); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv6_autoconf_temporary_valid_lifetime(const struct ly_ctx* ly_ctx, struct lyd_node* autoconf_node, const char* temporary_valid_lifetime) +{ + return srpc_ly_tree_create_leaf(ly_ctx, autoconf_node, NULL, "temporary-valid-lifetime", temporary_valid_lifetime); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv6_autoconf_create_temporary_addresses(const struct ly_ctx* ly_ctx, struct lyd_node* autoconf_node, const char* create_temporary_addresses) +{ + return srpc_ly_tree_create_leaf(ly_ctx, autoconf_node, NULL, "create-temporary-addresses", create_temporary_addresses); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv6_autoconf_create_global_addresses(const struct ly_ctx* ly_ctx, struct lyd_node* autoconf_node, const char* create_global_addresses) +{ + return srpc_ly_tree_create_leaf(ly_ctx, autoconf_node, NULL, "create-global-addresses", create_global_addresses); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv6_dup_addr_detect_transmits(const struct ly_ctx* ly_ctx, struct lyd_node* ipv6_node, const char* dup_addr_detect_transmits) +{ + return srpc_ly_tree_create_leaf(ly_ctx, ipv6_node, NULL, "dup-addr-detect-transmits", dup_addr_detect_transmits); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv6_neighbor(const struct ly_ctx* ly_ctx, struct lyd_node* ipv6_node, struct lyd_node** neighbor_node, const char* ip) +{ + // TODO: fix this for multiple keys with SRPC library + return srpc_ly_tree_create_list(ly_ctx, ipv6_node, neighbor_node, "neighbor", "ip", ip); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv6_neighbor_state(const struct ly_ctx* ly_ctx, struct lyd_node* neighbor_node, const char* state) +{ + return srpc_ly_tree_create_leaf(ly_ctx, neighbor_node, NULL, "state", state); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv6_neighbor_is_router(const struct ly_ctx* ly_ctx, struct lyd_node* neighbor_node, const char* is_router) +{ + return srpc_ly_tree_create_leaf(ly_ctx, neighbor_node, NULL, "is-router", is_router); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv6_neighbor_origin(const struct ly_ctx* ly_ctx, struct lyd_node* neighbor_node, const char* origin) +{ + return srpc_ly_tree_create_leaf(ly_ctx, neighbor_node, NULL, "origin", origin); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv6_neighbor_link_layer_address(const struct ly_ctx* ly_ctx, struct lyd_node* neighbor_node, const char* link_layer_address) +{ + return srpc_ly_tree_create_leaf(ly_ctx, neighbor_node, NULL, "link-layer-address", link_layer_address); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv6_neighbor_ip(const struct ly_ctx* ly_ctx, struct lyd_node* neighbor_node, const char* ip) +{ + return srpc_ly_tree_create_leaf(ly_ctx, neighbor_node, NULL, "ip", ip); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv6_address(const struct ly_ctx* ly_ctx, struct lyd_node* ipv6_node, struct lyd_node** address_node, const char* ip) +{ + // TODO: fix this for multiple keys with SRPC library + return srpc_ly_tree_create_list(ly_ctx, ipv6_node, address_node, "address", "ip", ip); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv6_address_status(const struct ly_ctx* ly_ctx, struct lyd_node* address_node, const char* status) +{ + return srpc_ly_tree_create_leaf(ly_ctx, address_node, NULL, "status", status); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv6_address_origin(const struct ly_ctx* ly_ctx, struct lyd_node* address_node, const char* origin) +{ + return srpc_ly_tree_create_leaf(ly_ctx, address_node, NULL, "origin", origin); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv6_address_prefix_length(const struct ly_ctx* ly_ctx, struct lyd_node* address_node, const char* prefix_length) +{ + return srpc_ly_tree_create_leaf(ly_ctx, address_node, NULL, "prefix-length", prefix_length); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv6_address_ip(const struct ly_ctx* ly_ctx, struct lyd_node* address_node, const char* ip) +{ + return srpc_ly_tree_create_leaf(ly_ctx, address_node, NULL, "ip", ip); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv6_mtu(const struct ly_ctx* ly_ctx, struct lyd_node* ipv6_node, const char* mtu) +{ + return srpc_ly_tree_create_leaf(ly_ctx, ipv6_node, NULL, "mtu", mtu); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv6_forwarding(const struct ly_ctx* ly_ctx, struct lyd_node* ipv6_node, const char* forwarding) +{ + return srpc_ly_tree_create_leaf(ly_ctx, ipv6_node, NULL, "forwarding", forwarding); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv6_enabled(const struct ly_ctx* ly_ctx, struct lyd_node* ipv6_node, const char* enabled) +{ + return srpc_ly_tree_create_leaf(ly_ctx, ipv6_node, NULL, "enabled", enabled); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv4(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, struct lyd_node** ipv4_node) +{ + return srpc_ly_tree_create_container(ly_ctx, interface_node, ipv4_node, "ipv4"); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv4_neighbor(const struct ly_ctx* ly_ctx, struct lyd_node* ipv4_node, struct lyd_node** neighbor_node, const char* ip) +{ + // TODO: fix this for multiple keys with SRPC library + return srpc_ly_tree_create_list(ly_ctx, ipv4_node, neighbor_node, "neighbor", "ip", ip); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv4_neighbor_origin(const struct ly_ctx* ly_ctx, struct lyd_node* neighbor_node, const char* origin) +{ + return srpc_ly_tree_create_leaf(ly_ctx, neighbor_node, NULL, "origin", origin); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv4_neighbor_link_layer_address(const struct ly_ctx* ly_ctx, struct lyd_node* neighbor_node, const char* link_layer_address) +{ + return srpc_ly_tree_create_leaf(ly_ctx, neighbor_node, NULL, "link-layer-address", link_layer_address); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv4_neighbor_ip(const struct ly_ctx* ly_ctx, struct lyd_node* neighbor_node, const char* ip) +{ + return srpc_ly_tree_create_leaf(ly_ctx, neighbor_node, NULL, "ip", ip); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv4_address(const struct ly_ctx* ly_ctx, struct lyd_node* ipv4_node, struct lyd_node** address_node, const char* ip) +{ + // TODO: fix this for multiple keys with SRPC library + return srpc_ly_tree_create_list(ly_ctx, ipv4_node, address_node, "address", "ip", ip); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv4_address_origin(const struct ly_ctx* ly_ctx, struct lyd_node* address_node, const char* origin) +{ + return srpc_ly_tree_create_leaf(ly_ctx, address_node, NULL, "origin", origin); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv4_address_netmask(const struct ly_ctx* ly_ctx, struct lyd_node* address_node, const char* netmask) +{ + return srpc_ly_tree_create_leaf(ly_ctx, address_node, NULL, "netmask", netmask); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv4_address_prefix_length(const struct ly_ctx* ly_ctx, struct lyd_node* address_node, const char* prefix_length) +{ + return srpc_ly_tree_create_leaf(ly_ctx, address_node, NULL, "prefix-length", prefix_length); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv4_address_ip(const struct ly_ctx* ly_ctx, struct lyd_node* address_node, const char* ip) +{ + return srpc_ly_tree_create_leaf(ly_ctx, address_node, NULL, "ip", ip); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv4_mtu(const struct ly_ctx* ly_ctx, struct lyd_node* ipv4_node, const char* mtu) +{ + return srpc_ly_tree_create_leaf(ly_ctx, ipv4_node, NULL, "mtu", mtu); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv4_forwarding(const struct ly_ctx* ly_ctx, struct lyd_node* ipv4_node, const char* forwarding) +{ + return srpc_ly_tree_create_leaf(ly_ctx, ipv4_node, NULL, "forwarding", forwarding); +} + +int interfaces_ly_tree_create_interfaces_interface_ipv4_enabled(const struct ly_ctx* ly_ctx, struct lyd_node* ipv4_node, const char* enabled) +{ + return srpc_ly_tree_create_leaf(ly_ctx, ipv4_node, NULL, "enabled", enabled); +} + int interfaces_ly_tree_create_interfaces_interface_parent_interface(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* parent_interface) { return srpc_ly_tree_create_leaf(ly_ctx, interface_node, NULL, "parent-interface", parent_interface); diff --git a/src/interfaces/src/plugin/ly_tree.h b/src/interfaces/src/plugin/ly_tree.h index f14b0ffd..8e47b513 100644 --- a/src/interfaces/src/plugin/ly_tree.h +++ b/src/interfaces/src/plugin/ly_tree.h @@ -5,6 +5,40 @@ int interfaces_ly_tree_create_interfaces(const struct ly_ctx* ly_ctx, struct lyd_node** interfaces_node); int interfaces_ly_tree_create_interfaces_interface(const struct ly_ctx* ly_ctx, struct lyd_node* interfaces_node, struct lyd_node** interface_node, const char* name); +int interfaces_ly_tree_create_interfaces_interface_ipv6(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, struct lyd_node** ipv6_node); +int interfaces_ly_tree_create_interfaces_interface_ipv6_autoconf(const struct ly_ctx* ly_ctx, struct lyd_node* ipv6_node, struct lyd_node** autoconf_node); +int interfaces_ly_tree_create_interfaces_interface_ipv6_autoconf_temporary_preferred_lifetime(const struct ly_ctx* ly_ctx, struct lyd_node* autoconf_node, const char* temporary_preferred_lifetime); +int interfaces_ly_tree_create_interfaces_interface_ipv6_autoconf_temporary_valid_lifetime(const struct ly_ctx* ly_ctx, struct lyd_node* autoconf_node, const char* temporary_valid_lifetime); +int interfaces_ly_tree_create_interfaces_interface_ipv6_autoconf_create_temporary_addresses(const struct ly_ctx* ly_ctx, struct lyd_node* autoconf_node, const char* create_temporary_addresses); +int interfaces_ly_tree_create_interfaces_interface_ipv6_autoconf_create_global_addresses(const struct ly_ctx* ly_ctx, struct lyd_node* autoconf_node, const char* create_global_addresses); +int interfaces_ly_tree_create_interfaces_interface_ipv6_dup_addr_detect_transmits(const struct ly_ctx* ly_ctx, struct lyd_node* ipv6_node, const char* dup_addr_detect_transmits); +int interfaces_ly_tree_create_interfaces_interface_ipv6_neighbor(const struct ly_ctx* ly_ctx, struct lyd_node* ipv6_node, struct lyd_node** neighbor_node, const char* ip); +int interfaces_ly_tree_create_interfaces_interface_ipv6_neighbor_state(const struct ly_ctx* ly_ctx, struct lyd_node* neighbor_node, const char* state); +int interfaces_ly_tree_create_interfaces_interface_ipv6_neighbor_is_router(const struct ly_ctx* ly_ctx, struct lyd_node* neighbor_node, const char* is_router); +int interfaces_ly_tree_create_interfaces_interface_ipv6_neighbor_origin(const struct ly_ctx* ly_ctx, struct lyd_node* neighbor_node, const char* origin); +int interfaces_ly_tree_create_interfaces_interface_ipv6_neighbor_link_layer_address(const struct ly_ctx* ly_ctx, struct lyd_node* neighbor_node, const char* link_layer_address); +int interfaces_ly_tree_create_interfaces_interface_ipv6_neighbor_ip(const struct ly_ctx* ly_ctx, struct lyd_node* neighbor_node, const char* ip); +int interfaces_ly_tree_create_interfaces_interface_ipv6_address(const struct ly_ctx* ly_ctx, struct lyd_node* ipv6_node, struct lyd_node** address_node, const char* ip); +int interfaces_ly_tree_create_interfaces_interface_ipv6_address_status(const struct ly_ctx* ly_ctx, struct lyd_node* address_node, const char* status); +int interfaces_ly_tree_create_interfaces_interface_ipv6_address_origin(const struct ly_ctx* ly_ctx, struct lyd_node* address_node, const char* origin); +int interfaces_ly_tree_create_interfaces_interface_ipv6_address_prefix_length(const struct ly_ctx* ly_ctx, struct lyd_node* address_node, const char* prefix_length); +int interfaces_ly_tree_create_interfaces_interface_ipv6_address_ip(const struct ly_ctx* ly_ctx, struct lyd_node* address_node, const char* ip); +int interfaces_ly_tree_create_interfaces_interface_ipv6_mtu(const struct ly_ctx* ly_ctx, struct lyd_node* ipv6_node, const char* mtu); +int interfaces_ly_tree_create_interfaces_interface_ipv6_forwarding(const struct ly_ctx* ly_ctx, struct lyd_node* ipv6_node, const char* forwarding); +int interfaces_ly_tree_create_interfaces_interface_ipv6_enabled(const struct ly_ctx* ly_ctx, struct lyd_node* ipv6_node, const char* enabled); +int interfaces_ly_tree_create_interfaces_interface_ipv4(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, struct lyd_node** ipv4_node); +int interfaces_ly_tree_create_interfaces_interface_ipv4_neighbor(const struct ly_ctx* ly_ctx, struct lyd_node* ipv4_node, struct lyd_node** neighbor_node, const char* ip); +int interfaces_ly_tree_create_interfaces_interface_ipv4_neighbor_origin(const struct ly_ctx* ly_ctx, struct lyd_node* neighbor_node, const char* origin); +int interfaces_ly_tree_create_interfaces_interface_ipv4_neighbor_link_layer_address(const struct ly_ctx* ly_ctx, struct lyd_node* neighbor_node, const char* link_layer_address); +int interfaces_ly_tree_create_interfaces_interface_ipv4_neighbor_ip(const struct ly_ctx* ly_ctx, struct lyd_node* neighbor_node, const char* ip); +int interfaces_ly_tree_create_interfaces_interface_ipv4_address(const struct ly_ctx* ly_ctx, struct lyd_node* ipv4_node, struct lyd_node** address_node, const char* ip); +int interfaces_ly_tree_create_interfaces_interface_ipv4_address_origin(const struct ly_ctx* ly_ctx, struct lyd_node* address_node, const char* origin); +int interfaces_ly_tree_create_interfaces_interface_ipv4_address_netmask(const struct ly_ctx* ly_ctx, struct lyd_node* address_node, const char* netmask); +int interfaces_ly_tree_create_interfaces_interface_ipv4_address_prefix_length(const struct ly_ctx* ly_ctx, struct lyd_node* address_node, const char* prefix_length); +int interfaces_ly_tree_create_interfaces_interface_ipv4_address_ip(const struct ly_ctx* ly_ctx, struct lyd_node* address_node, const char* ip); +int interfaces_ly_tree_create_interfaces_interface_ipv4_mtu(const struct ly_ctx* ly_ctx, struct lyd_node* ipv4_node, const char* mtu); +int interfaces_ly_tree_create_interfaces_interface_ipv4_forwarding(const struct ly_ctx* ly_ctx, struct lyd_node* ipv4_node, const char* forwarding); +int interfaces_ly_tree_create_interfaces_interface_ipv4_enabled(const struct ly_ctx* ly_ctx, struct lyd_node* ipv4_node, const char* enabled); int interfaces_ly_tree_create_interfaces_interface_parent_interface(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* parent_interface); int interfaces_ly_tree_create_interfaces_interface_forwarding_mode(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* forwarding_mode); int interfaces_ly_tree_create_interfaces_interface_max_frame_size(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, const char* max_frame_size); From 76a6ba405cfdd77b642314dbb82981ee63cc809e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Fri, 16 Sep 2022 18:41:20 +0200 Subject: [PATCH 091/247] interfaces-plugin: fix ly_tree interfaces container creation --- src/interfaces/src/plugin/ly_tree.c | 2 +- src/interfaces/src/plugin/startup/load.c | 13 ++----------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/interfaces/src/plugin/ly_tree.c b/src/interfaces/src/plugin/ly_tree.c index 07c59b11..b15e32dd 100644 --- a/src/interfaces/src/plugin/ly_tree.c +++ b/src/interfaces/src/plugin/ly_tree.c @@ -5,7 +5,7 @@ int interfaces_ly_tree_create_interfaces(const struct ly_ctx* ly_ctx, struct lyd_node** interfaces_node) { - return srpc_ly_tree_create_container(ly_ctx, NULL, interfaces_node, "interfaces"); + return srpc_ly_tree_create_container(ly_ctx, NULL, interfaces_node, "/ietf-interfaces:interfaces"); } int interfaces_ly_tree_create_interfaces_interface(const struct ly_ctx* ly_ctx, struct lyd_node* interfaces_node, struct lyd_node** interface_node, const char* name) diff --git a/src/interfaces/src/plugin/startup/load.c b/src/interfaces/src/plugin/startup/load.c index 61b9cc1d..99b7db6d 100644 --- a/src/interfaces/src/plugin/startup/load.c +++ b/src/interfaces/src/plugin/startup/load.c @@ -3,6 +3,7 @@ #include "plugin/ly_tree.h" #include "plugin/api/interfaces/load.h" +#include "srpc/common.h" #include #include @@ -32,11 +33,7 @@ int interfaces_startup_load(interfaces_ctx_t* ctx, sr_session_ctx_t* session) goto error_out; } - error = interfaces_ly_tree_create_interfaces(ly_ctx, &root_node); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "Unable to create ly root tree container"); - goto error_out; - } + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces(ly_ctx, &root_node), error_out); for (size_t i = 0; i < ARRAY_SIZE(load_values); i++) { const srpc_startup_load_t* load = &load_values[i]; @@ -91,12 +88,6 @@ static int interfaces_startup_load_interface(void* priv, sr_session_ctx_t* sessi goto error_out; } - error = interfaces_ly_tree_create_interfaces(ly_ctx, &parent_node); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "interfaces_ly_tree_create_interfaces() error (%d)", error); - goto error_out; - } - goto out; error_out: From 749496b856a64bf2f12e032f39b55f94b60b6b8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Fri, 16 Sep 2022 19:04:57 +0200 Subject: [PATCH 092/247] interfaces-plugin: add ipv4 and ipv6 setters for interface hash element API --- .../src/plugin/data/interfaces/interface/hash.c | 14 ++++++++++++++ .../src/plugin/data/interfaces/interface/hash.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/src/interfaces/src/plugin/data/interfaces/interface/hash.c b/src/interfaces/src/plugin/data/interfaces/interface/hash.c index 17f77de6..0de43b3e 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/hash.c +++ b/src/interfaces/src/plugin/data/interfaces/interface/hash.c @@ -168,6 +168,20 @@ int interfaces_interface_hash_element_set_parent_interface(interfaces_interface_ return 0; } +int interfaces_interface_hash_element_set_ipv4(interfaces_interface_hash_element_t** el, interfaces_interfaces_interface_ipv4_t ipv4) +{ + (*el)->interface.ipv4 = ipv4; + + return 0; +} + +int interfaces_interface_hash_element_set_ipv6(interfaces_interface_hash_element_t** el, interfaces_interfaces_interface_ipv6_t ipv6) +{ + (*el)->interface.ipv6 = ipv6; + + return 0; +} + void interfaces_interface_hash_element_free(interfaces_interface_hash_element_t** el) { if (*el) { diff --git a/src/interfaces/src/plugin/data/interfaces/interface/hash.h b/src/interfaces/src/plugin/data/interfaces/interface/hash.h index ef2e0812..0d5b9057 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/hash.h +++ b/src/interfaces/src/plugin/data/interfaces/interface/hash.h @@ -28,6 +28,8 @@ int interfaces_interface_hash_element_set_encapsulation(interfaces_interface_has int interfaces_interface_hash_element_set_loopback(interfaces_interface_hash_element_t** el, const char* loopback); int interfaces_interface_hash_element_set_max_frame_size(interfaces_interface_hash_element_t** el, uint32_t max_frame_size); int interfaces_interface_hash_element_set_parent_interface(interfaces_interface_hash_element_t** el, const char* parent_interface); +int interfaces_interface_hash_element_set_ipv4(interfaces_interface_hash_element_t** el, interfaces_interfaces_interface_ipv4_t ipv4); +int interfaces_interface_hash_element_set_ipv6(interfaces_interface_hash_element_t** el, interfaces_interfaces_interface_ipv6_t ipv6); void interfaces_interface_hash_element_free(interfaces_interface_hash_element_t** el); #endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_HASH_H \ No newline at end of file From 0574f6bc08cbf2b1ed3becd17913923c80daa81b Mon Sep 17 00:00:00 2001 From: agardijan Date: Mon, 19 Sep 2022 13:17:05 +0200 Subject: [PATCH 093/247] interfaces-plugin: deep copy tag types in hash api --- src/interfaces/src/plugin/data/interfaces/interface/hash.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/interfaces/src/plugin/data/interfaces/interface/hash.c b/src/interfaces/src/plugin/data/interfaces/interface/hash.c index b62f3b0d..632dcf2c 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/hash.c +++ b/src/interfaces/src/plugin/data/interfaces/interface/hash.c @@ -127,6 +127,8 @@ int interfaces_interface_hash_element_set_dampening(interfaces_interface_hash_el int interfaces_interface_hash_element_set_encapsulation(interfaces_interface_hash_element_t** el, interfaces_interfaces_interface_encapsulation_t encapsulation) { (*el)->interface.encapsulation = encapsulation; + (*el)->interface.encapsulation.dot1q_vlan.outer_tag.tag_type = xstrdup(encapsulation.dot1q_vlan.outer_tag.tag_type); + (*el)->interface.encapsulation.dot1q_vlan.second_tag.tag_type = xstrdup(encapsulation.dot1q_vlan.second_tag.tag_type); return 0; } From 8556164b7bedc79079929eb436fb47728980a09b Mon Sep 17 00:00:00 2001 From: agardijan Date: Mon, 19 Sep 2022 13:31:19 +0200 Subject: [PATCH 094/247] interfaces-plugin: return dynamically allocated string copies --- .../src/plugin/api/interfaces/load.c | 18 +++++++++++++----- .../src/plugin/api/interfaces/load.h | 2 ++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index 87270a49..2e2df515 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -21,7 +21,7 @@ static char *interfaces_get_interface_name(struct rtnl_link *link) SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_get_name error"); } - return name; + return xstrdup(name); } static char *interfaces_get_interface_description(interfaces_ctx_t *ctx, char *name) @@ -46,7 +46,7 @@ static char *interfaces_get_interface_description(interfaces_ctx_t *ctx, char *n } if (strlen(val->data.string_val) > 0) { - description = val->data.string_val; + description = xstrdup(val->data.string_val); } error_out: @@ -122,7 +122,7 @@ static char *interfaces_get_interface_type(struct rtnl_link *link, char *name) } error_out: - return type; + return xstrdup(type); } static uint8_t interfaces_get_interface_enabled(struct rtnl_link *link) @@ -153,7 +153,7 @@ static char *interfaces_get_interface_parent_interface(struct nl_cache *cache, s parent_interface = rtnl_link_i2name(cache, parent_index, parent_buffer, MAX_IF_NAME_LEN); } - return parent_interface; + return xstrdup(parent_interface); } /* TODO: outer tag, second id, tag - maybe refactor all to pass by reference, return error */ @@ -223,10 +223,18 @@ static int interfaces_parse_link(interfaces_ctx_t *ctx, struct nl_sock *socket, error_out: error = interfaces_load_failure; out: - /* allocated in interfaces_get_interface_description */ + if (interface->name != NULL) { + FREE_SAFE(interface->name); + } if (interface->description != NULL) { FREE_SAFE(interface->description); } + if (interface->type != NULL) { + FREE_SAFE(interface->type); + } + if (interface->parent_interface != NULL) { + FREE_SAFE(interface->parent_interface); + } return error; } diff --git a/src/interfaces/src/plugin/api/interfaces/load.h b/src/interfaces/src/plugin/api/interfaces/load.h index 2cf1136f..3b338e1c 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.h +++ b/src/interfaces/src/plugin/api/interfaces/load.h @@ -24,6 +24,8 @@ static int interfaces_parse_link(interfaces_ctx_t *ctx, struct nl_sock *socket, static char *interfaces_get_interface_parent_interface(struct nl_cache *cache, struct rtnl_link *link); +static int interfaces_get_interface_vlan_id(struct rtnl_link *link, interfaces_interfaces_interface_t *interface); + static int interfaces_add_link(interfaces_interface_hash_element_t **if_hash, interfaces_interfaces_interface_t *interface); static struct rtnl_link *interfaces_get_next_link(struct rtnl_link *link); From 261c071a95043d1a1b46d52c834367ab6e0a44a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 19 Sep 2022 14:16:41 +0200 Subject: [PATCH 095/247] interfaces-plugin: use latest SRPC API --- src/interfaces/src/plugin.c | 32 ++++++++++++++--------------- src/interfaces/src/plugin/context.h | 10 +++++++++ 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index e47e74d6..c9dd5e54 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -37,8 +37,6 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) sr_session_ctx_t* startup_session = NULL; sr_conn_ctx_t* connection = NULL; sr_subscription_ctx_t* subscription = NULL; - srpc_feature_status_t* ietf_interfaces_features = NULL; - srpc_feature_status_t* ietf_if_extensions_features = NULL; // plugin interfaces_ctx_t* ctx = NULL; @@ -49,13 +47,10 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) *private_data = ctx; - // initialize feature status hashes - ietf_interfaces_features = srpc_feature_status_hash_new(); - ietf_if_extensions_features = srpc_feature_status_hash_new(); - // load enabled features from modules in sysrepo - SRPC_SAFE_CALL_ERR(error, srpc_feature_status_hash_load(&ietf_interfaces_features, running_session, "ietf-interfaces"), error_out); - SRPC_SAFE_CALL_ERR(error, srpc_feature_status_hash_load(&ietf_if_extensions_features, running_session, "ietf-if-extensions"), error_out); + SRPC_SAFE_CALL_ERR(error, srpc_feature_status_hash_load(&ctx->features.ietf_interfaces_features, running_session, "ietf-interfaces"), error_out); + SRPC_SAFE_CALL_ERR(error, srpc_feature_status_hash_load(&ctx->features.ietf_if_extensions_features, running_session, "ietf-if-extensions"), error_out); + SRPC_SAFE_CALL_ERR(error, srpc_feature_status_hash_load(&ctx->features.ietf_ip_features, running_session, "ietf-if-extensions"), error_out); // module changes srpc_module_change_t module_changes[] = { @@ -70,7 +65,7 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) { //depends on if-mib feature INTERFACES_INTERFACES_INTERFACE_ADMIN_STATUS_YANG_PATH, - srpc_feature_status_hash_check(ietf_interfaces_features, "if-mib")? interfaces_subscription_operational_interfaces_interface_admin_status: NULL, + srpc_feature_status_hash_check(ctx->features.ietf_interfaces_features, "if-mib") ? interfaces_subscription_operational_interfaces_interface_admin_status : NULL, }, { INTERFACES_INTERFACES_INTERFACE_OPER_STATUS_YANG_PATH, @@ -83,7 +78,7 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) { //depends on if-mib feature INTERFACES_INTERFACES_INTERFACE_IF_INDEX_YANG_PATH, - srpc_feature_status_hash_check(ietf_interfaces_features, "if-mib")? interfaces_subscription_operational_interfaces_interface_if_index: NULL, + srpc_feature_status_hash_check(ctx->features.ietf_interfaces_features, "if-mib") ? interfaces_subscription_operational_interfaces_interface_if_index : NULL, }, { INTERFACES_INTERFACES_INTERFACE_PHYS_ADDRESS_YANG_PATH, @@ -164,27 +159,27 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) { //depends on carrier-delay feature INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_CARRIER_TRANSITIONS_YANG_PATH, - srpc_feature_status_hash_check(ietf_if_extensions_features, "carrier-delay")? interfaces_subscription_operational_interfaces_interface_carrier_delay_carrier_transitions: NULL, + srpc_feature_status_hash_check(ctx->features.ietf_if_extensions_features, "carrier-delay") ? interfaces_subscription_operational_interfaces_interface_carrier_delay_carrier_transitions : NULL, }, { //depends on carrier-delay feature INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_TIMER_RUNNING_YANG_PATH, - srpc_feature_status_hash_check(ietf_if_extensions_features, "carrier-delay")? interfaces_subscription_operational_interfaces_interface_carrier_delay_timer_running: NULL, + srpc_feature_status_hash_check(ctx->features.ietf_if_extensions_features, "carrier-delay") ? interfaces_subscription_operational_interfaces_interface_carrier_delay_timer_running : NULL, }, { //depends on dampening feature INTERFACES_INTERFACES_INTERFACE_DAMPENING_PENALTY_YANG_PATH, - srpc_feature_status_hash_check(ietf_if_extensions_features, "dampening")? interfaces_subscription_operational_interfaces_interface_dampening_penalty: NULL, + srpc_feature_status_hash_check(ctx->features.ietf_if_extensions_features, "dampening") ? interfaces_subscription_operational_interfaces_interface_dampening_penalty : NULL, }, { //depends on dampening feature INTERFACES_INTERFACES_INTERFACE_DAMPENING_SUPPRESSED_YANG_PATH, - srpc_feature_status_hash_check(ietf_if_extensions_features, "dampening")? interfaces_subscription_operational_interfaces_interface_dampening_suppressed: NULL, + srpc_feature_status_hash_check(ctx->features.ietf_if_extensions_features, "dampening") ? interfaces_subscription_operational_interfaces_interface_dampening_suppressed : NULL, }, { //depends on dampening feature INTERFACES_INTERFACES_INTERFACE_DAMPENING_TIME_REMAINING_YANG_PATH, - srpc_feature_status_hash_check(ietf_if_extensions_features, "dampening")? interfaces_subscription_operational_interfaces_interface_dampening_time_remaining: NULL, + srpc_feature_status_hash_check(ctx->features.ietf_if_extensions_features, "dampening") ? interfaces_subscription_operational_interfaces_interface_dampening_time_remaining : NULL, }, { INTERFACES_INTERFACES_INTERFACE_FORWARDING_MODE_YANG_PATH, @@ -327,8 +322,6 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) SRPLG_LOG_ERR(PLUGIN_NAME, "Error occured while initializing the plugin (%d)", error); out: - srpc_feature_status_hash_free(&ietf_interfaces_features); - srpc_feature_status_hash_free(&ietf_if_extensions_features); return error ? SR_ERR_CALLBACK_FAILED : SR_ERR_OK; } @@ -369,6 +362,11 @@ void sr_plugin_cleanup_cb(sr_session_ctx_t* running_session, void* private_data) pthread_mutex_unlock(&ctx->state_ctx.state_hash_mutex); + // free feature status hashes + srpc_feature_status_hash_free(&ctx->features.ietf_interfaces_features); + srpc_feature_status_hash_free(&ctx->features.ietf_if_extensions_features); + srpc_feature_status_hash_free(&ctx->features.ietf_ip_features); + free(ctx); } diff --git a/src/interfaces/src/plugin/context.h b/src/interfaces/src/plugin/context.h index c66e45b9..ed790e0c 100644 --- a/src/interfaces/src/plugin/context.h +++ b/src/interfaces/src/plugin/context.h @@ -8,11 +8,14 @@ #include +#include + // typedefs typedef struct interfaces_nl_ctx_s interfaces_nl_ctx_t; typedef struct interfaces_ctx_s interfaces_ctx_t; typedef struct interfaces_state_changes_ctx_s interfaces_state_changes_ctx_t; typedef struct interfaces_mod_changes_ctx_s interfaces_mod_changes_ctx_t; +typedef struct interfaces_features_ctx_s interfaces_features_ctx_t; struct interfaces_state_changes_ctx_s { // libnl data @@ -33,6 +36,12 @@ struct interfaces_mod_changes_ctx_s { struct nl_cache* link_cache; }; +struct interfaces_features_ctx_s { + srpc_feature_status_hash_t* ietf_interfaces_features; + srpc_feature_status_hash_t* ietf_if_extensions_features; + srpc_feature_status_hash_t* ietf_ip_features; +}; + struct interfaces_nl_ctx_s { struct nl_sock* socket; struct nl_cache* link_cache; @@ -43,6 +52,7 @@ struct interfaces_ctx_s { interfaces_nl_ctx_t nl_ctx; interfaces_state_changes_ctx_t state_ctx; interfaces_mod_changes_ctx_t mod_ctx; + interfaces_features_ctx_t features; }; #endif // INTERFACES_PLUGIN_CONTEXT_H \ No newline at end of file From d0eabc446a38bdeaee8027da88a21532409ef240 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 19 Sep 2022 15:18:26 +0200 Subject: [PATCH 096/247] interfaces-plugin: improve context types organization --- src/interfaces/src/plugin.c | 40 +++++++-------- .../src/plugin/api/interfaces/change.c | 14 +++--- .../plugin/api/interfaces/interface/change.c | 20 ++++---- src/interfaces/src/plugin/context.h | 50 ++++++++++++------- .../src/plugin/subscription/operational.c | 10 ++-- 5 files changed, 75 insertions(+), 59 deletions(-) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index c9dd5e54..5cbb00d5 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -313,7 +313,7 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) } // tracking oper-status changes for interfaces - SRPC_SAFE_CALL_ERR(error, interfaces_init_state_changes_tracking(&ctx->state_ctx), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_init_state_changes_tracking(&ctx->oper_ctx.state_changes_ctx), error_out); goto out; @@ -338,29 +338,29 @@ void sr_plugin_cleanup_cb(sr_session_ctx_t* running_session, void* private_data) SRPLG_LOG_ERR(PLUGIN_NAME, "sr_copy_config() error (%d): %s", error, sr_strerror(error)); } - if (ctx->nl_ctx.link_cache) { - nl_cache_put(ctx->nl_ctx.link_cache); + if (ctx->oper_ctx.nl_ctx.link_cache) { + nl_cache_put(ctx->oper_ctx.nl_ctx.link_cache); } - if (ctx->nl_ctx.socket) { - nl_socket_free(ctx->nl_ctx.socket); + if (ctx->oper_ctx.nl_ctx.socket) { + nl_socket_free(ctx->oper_ctx.nl_ctx.socket); } - pthread_mutex_lock(&ctx->state_ctx.state_hash_mutex); + pthread_mutex_lock(&ctx->oper_ctx.state_changes_ctx.state_hash_mutex); - if (ctx->state_ctx.socket) { - nl_socket_free(ctx->state_ctx.socket); + if (ctx->oper_ctx.state_changes_ctx.nl_ctx.socket) { + nl_socket_free(ctx->oper_ctx.state_changes_ctx.nl_ctx.socket); } - if (ctx->state_ctx.link_cache_manager) { - nl_cache_mngr_free(ctx->state_ctx.link_cache_manager); + if (ctx->oper_ctx.state_changes_ctx.nl_ctx.link_cache_manager) { + nl_cache_mngr_free(ctx->oper_ctx.state_changes_ctx.nl_ctx.link_cache_manager); } - if (ctx->state_ctx.state_hash) { - interfaces_interface_state_hash_free(&ctx->state_ctx.state_hash); + if (ctx->oper_ctx.state_changes_ctx.state_hash) { + interfaces_interface_state_hash_free(&ctx->oper_ctx.state_changes_ctx.state_hash); } - pthread_mutex_unlock(&ctx->state_ctx.state_hash_mutex); + pthread_mutex_unlock(&ctx->oper_ctx.state_changes_ctx.state_hash_mutex); // free feature status hashes srpc_feature_status_hash_free(&ctx->features.ietf_interfaces_features); @@ -381,16 +381,16 @@ static int interfaces_init_state_changes_tracking(interfaces_state_changes_ctx_t ctx->state_hash = interfaces_interface_state_hash_new(); // init libnl data - SRPC_SAFE_CALL_PTR(ctx->socket, nl_socket_alloc(), error_out); + SRPC_SAFE_CALL_PTR(ctx->nl_ctx.socket, nl_socket_alloc(), error_out); // connect and get all links - SRPC_SAFE_CALL_ERR(error, nl_connect(ctx->socket, NETLINK_ROUTE), error_out); - SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(ctx->socket, AF_UNSPEC, &ctx->link_cache), error_out); + SRPC_SAFE_CALL_ERR(error, nl_connect(ctx->nl_ctx.socket, NETLINK_ROUTE), error_out); + SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(ctx->nl_ctx.socket, AF_UNSPEC, &ctx->nl_ctx.link_cache), error_out); // init hash mutex SRPC_SAFE_CALL_ERR(error, pthread_mutex_init(&ctx->state_hash_mutex, NULL), error_out); - link = (struct rtnl_link*)nl_cache_get_first(ctx->link_cache); + link = (struct rtnl_link*)nl_cache_get_first(ctx->nl_ctx.link_cache); while (link != NULL) { // create hash entries @@ -413,8 +413,8 @@ static int interfaces_init_state_changes_tracking(interfaces_state_changes_ctx_t } // setup cache manager - SRPC_SAFE_CALL_ERR(error, nl_cache_mngr_alloc(NULL, NETLINK_ROUTE, 0, &ctx->link_cache_manager), error_out); - SRPC_SAFE_CALL_ERR(error, nl_cache_mngr_add(ctx->link_cache_manager, "route/link", interfaces_link_cache_change_cb, ctx, &ctx->link_cache), error_out); + SRPC_SAFE_CALL_ERR(error, nl_cache_mngr_alloc(NULL, NETLINK_ROUTE, 0, &ctx->nl_ctx.link_cache_manager), error_out); + SRPC_SAFE_CALL_ERR(error, nl_cache_mngr_add(ctx->nl_ctx.link_cache_manager, "route/link", interfaces_link_cache_change_cb, ctx, &ctx->nl_ctx.link_cache), error_out); // setup detatched thread for sending change signals to the cache manager SRPC_SAFE_CALL_ERR(error, pthread_attr_init(&attr), error_out); @@ -508,7 +508,7 @@ static void* interfaces_link_manager_thread_cb(void* data) interfaces_state_changes_ctx_t* ctx = data; do { - nl_cache_mngr_data_ready(ctx->link_cache_manager); + nl_cache_mngr_data_ready(ctx->nl_ctx.link_cache_manager); sleep(1); } while (1); diff --git a/src/interfaces/src/plugin/api/interfaces/change.c b/src/interfaces/src/plugin/api/interfaces/change.c index 97901fd7..a159e7f8 100644 --- a/src/interfaces/src/plugin/api/interfaces/change.c +++ b/src/interfaces/src/plugin/api/interfaces/change.c @@ -16,13 +16,13 @@ int interfaces_change_interface_init(void* priv) SRPLG_LOG_INF(PLUGIN_NAME, "Initializing context data for interface changes"); // allocate socket - SRPC_SAFE_CALL_PTR(mod_ctx->socket, nl_socket_alloc(), error_out); + SRPC_SAFE_CALL_PTR(mod_ctx->nl_ctx.socket, nl_socket_alloc(), error_out); // connect - SRPC_SAFE_CALL_ERR(error, nl_connect(mod_ctx->socket, NETLINK_ROUTE), error_out); + SRPC_SAFE_CALL_ERR(error, nl_connect(mod_ctx->nl_ctx.socket, NETLINK_ROUTE), error_out); // allocate link cache - SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(mod_ctx->socket, AF_UNSPEC, &mod_ctx->link_cache), error_out); + SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(mod_ctx->nl_ctx.socket, AF_UNSPEC, &mod_ctx->nl_ctx.link_cache), error_out); goto out; @@ -87,11 +87,11 @@ void interfaces_change_interface_free(void* priv) SRPLG_LOG_INF(PLUGIN_NAME, "Freeing context data for interface changes"); - if (mod_ctx->link_cache) { - nl_cache_put(ctx->nl_ctx.link_cache); + if (mod_ctx->nl_ctx.link_cache) { + nl_cache_put(mod_ctx->nl_ctx.link_cache); } - if (mod_ctx->socket) { - nl_socket_free(ctx->nl_ctx.socket); + if (mod_ctx->nl_ctx.socket) { + nl_socket_free(mod_ctx->nl_ctx.socket); } // set to NULL diff --git a/src/interfaces/src/plugin/api/interfaces/interface/change.c b/src/interfaces/src/plugin/api/interfaces/interface/change.c index fb8eaff5..69541ff3 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/change.c @@ -125,7 +125,7 @@ int interfaces_interface_change_enabled(void* priv, sr_session_ctx_t* session, c case SR_OP_CREATED: case SR_OP_MODIFIED: // get link by name - SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->link_cache, interface_name_buffer), error_out); + SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->nl_ctx.link_cache, interface_name_buffer), error_out); // create request link SRPC_SAFE_CALL_PTR(request_link, rtnl_link_alloc(), error_out); @@ -142,12 +142,12 @@ int interfaces_interface_change_enabled(void* priv, sr_session_ctx_t* session, c SRPLG_LOG_INF(PLUGIN_NAME, "Changed link status: %d", rtnl_link_get_operstate(request_link)); // apply changes - SRPC_SAFE_CALL_ERR(error, rtnl_link_change(mod_ctx->socket, current_link, request_link, NLM_F_REPLACE), error_out); + SRPC_SAFE_CALL_ERR(error, rtnl_link_change(mod_ctx->nl_ctx.socket, current_link, request_link, NLM_F_REPLACE), error_out); break; case SR_OP_DELETED: // get link by name // goto out if this function fails - if the link has completely been deleted, no need to delete enabled leaf - SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->link_cache, interface_name_buffer), out); + SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->nl_ctx.link_cache, interface_name_buffer), out); // create request link SRPC_SAFE_CALL_PTR(request_link, rtnl_link_alloc(), error_out); @@ -164,7 +164,7 @@ int interfaces_interface_change_enabled(void* priv, sr_session_ctx_t* session, c SRPLG_LOG_INF(PLUGIN_NAME, "Changed link status: %d", rtnl_link_get_operstate(request_link)); // apply changes - SRPC_SAFE_CALL_ERR(error, rtnl_link_change(mod_ctx->socket, current_link, request_link, NLM_F_REPLACE), error_out); + SRPC_SAFE_CALL_ERR(error, rtnl_link_change(mod_ctx->nl_ctx.socket, current_link, request_link, NLM_F_REPLACE), error_out); break; case SR_OP_MOVED: break; @@ -232,7 +232,7 @@ int interfaces_interface_change_type(void* priv, sr_session_ctx_t* session, cons SRPC_SAFE_CALL_ERR(error, interfacecs_interface_extract_name(session, change_ctx->node, interface_name_buffer, sizeof(interface_name_buffer)), error_out); // get link by name - SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->link_cache, interface_name_buffer), error_out); + SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->nl_ctx.link_cache, interface_name_buffer), error_out); // create request link SRPC_SAFE_CALL_PTR(request_link, rtnl_link_alloc(), error_out); @@ -255,7 +255,7 @@ int interfaces_interface_change_type(void* priv, sr_session_ctx_t* session, cons } // apply changes - SRPC_SAFE_CALL_ERR(error, rtnl_link_change(mod_ctx->socket, current_link, request_link, 0), error_out); + SRPC_SAFE_CALL_ERR(error, rtnl_link_change(mod_ctx->nl_ctx.socket, current_link, request_link, 0), error_out); break; case SR_OP_DELETED: // unsupported - type is necessarry @@ -311,7 +311,7 @@ int interfaces_interface_change_name(void* priv, sr_session_ctx_t* session, cons switch (change_ctx->operation) { case SR_OP_CREATED: - old_link = rtnl_link_get_by_name(mod_ctx->link_cache, node_value); + old_link = rtnl_link_get_by_name(mod_ctx->nl_ctx.link_cache, node_value); // add a new link if such a link doesn't exist if (!old_link) { @@ -324,7 +324,7 @@ int interfaces_interface_change_name(void* priv, sr_session_ctx_t* session, cons // set temp as initial type SRPC_SAFE_CALL_ERR(error, rtnl_link_set_type(new_link, "dummy"), error_out); - SRPC_SAFE_CALL_ERR(error, rtnl_link_add(mod_ctx->socket, new_link, NLM_F_CREATE), error_out); + SRPC_SAFE_CALL_ERR(error, rtnl_link_add(mod_ctx->nl_ctx.socket, new_link, NLM_F_CREATE), error_out); } break; case SR_OP_MODIFIED: @@ -332,9 +332,9 @@ int interfaces_interface_change_name(void* priv, sr_session_ctx_t* session, cons goto error_out; case SR_OP_DELETED: // get link and delete it - SRPC_SAFE_CALL_PTR(old_link, rtnl_link_get_by_name(mod_ctx->link_cache, node_value), error_out); + SRPC_SAFE_CALL_PTR(old_link, rtnl_link_get_by_name(mod_ctx->nl_ctx.link_cache, node_value), error_out); - SRPC_SAFE_CALL_ERR(error, rtnl_link_delete(mod_ctx->socket, old_link), error_out); + SRPC_SAFE_CALL_ERR(error, rtnl_link_delete(mod_ctx->nl_ctx.socket, old_link), error_out); break; case SR_OP_MOVED: break; diff --git a/src/interfaces/src/plugin/context.h b/src/interfaces/src/plugin/context.h index ed790e0c..f3083776 100644 --- a/src/interfaces/src/plugin/context.h +++ b/src/interfaces/src/plugin/context.h @@ -15,13 +15,31 @@ typedef struct interfaces_nl_ctx_s interfaces_nl_ctx_t; typedef struct interfaces_ctx_s interfaces_ctx_t; typedef struct interfaces_state_changes_ctx_s interfaces_state_changes_ctx_t; typedef struct interfaces_mod_changes_ctx_s interfaces_mod_changes_ctx_t; +typedef struct interfaces_oper_ctx_s interfaces_oper_ctx_t; typedef struct interfaces_features_ctx_s interfaces_features_ctx_t; -struct interfaces_state_changes_ctx_s { - // libnl data +struct interfaces_features_ctx_s { + srpc_feature_status_hash_t* ietf_interfaces_features; + srpc_feature_status_hash_t* ietf_if_extensions_features; + srpc_feature_status_hash_t* ietf_ip_features; +}; + +struct interfaces_nl_ctx_s { struct nl_sock* socket; struct nl_cache* link_cache; struct nl_cache_mngr* link_cache_manager; +}; + +struct interfaces_mod_changes_ctx_s { + // libnl links data + interfaces_nl_ctx_t nl_ctx; +}; + +struct interfaces_state_changes_ctx_s { + // libnl data + interfaces_nl_ctx_t nl_ctx; + + // cache manager refresh thread pthread_t manager_thread; // main hash DS for storing state info @@ -31,27 +49,25 @@ struct interfaces_state_changes_ctx_s { pthread_mutex_t state_hash_mutex; }; -struct interfaces_mod_changes_ctx_s { - struct nl_sock* socket; - struct nl_cache* link_cache; -}; - -struct interfaces_features_ctx_s { - srpc_feature_status_hash_t* ietf_interfaces_features; - srpc_feature_status_hash_t* ietf_if_extensions_features; - srpc_feature_status_hash_t* ietf_ip_features; -}; +struct interfaces_oper_ctx_s { + // operational libnl context - refill cache of links + interfaces_nl_ctx_t nl_ctx; -struct interfaces_nl_ctx_s { - struct nl_sock* socket; - struct nl_cache* link_cache; + // state changes monitoring + interfaces_state_changes_ctx_t state_changes_ctx; }; struct interfaces_ctx_s { + // startup DS sr_session_ctx_t* startup_session; - interfaces_nl_ctx_t nl_ctx; - interfaces_state_changes_ctx_t state_ctx; + + // module changes data interfaces_mod_changes_ctx_t mod_ctx; + + // operational data + interfaces_oper_ctx_t oper_ctx; + + // features enabled on plugin load interfaces_features_ctx_t features; }; diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index e3c2777e..78933752 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -112,7 +112,7 @@ int interfaces_subscription_operational_interfaces_interface_last_change(sr_sess // context const struct ly_ctx* ly_ctx = NULL; interfaces_ctx_t* ctx = private_data; - interfaces_state_changes_ctx_t* state_ctx = &ctx->state_ctx; + interfaces_state_changes_ctx_t* state_ctx = &ctx->oper_ctx.state_changes_ctx; interfaces_interface_state_hash_element_t* state_element = NULL; // libnl @@ -267,7 +267,7 @@ int interfaces_subscription_operational_interfaces_interface_higher_layer_if(sr_ // context const struct ly_ctx* ly_ctx = NULL; interfaces_ctx_t* ctx = private_data; - interfaces_nl_ctx_t* nl_ctx = &ctx->nl_ctx; + interfaces_nl_ctx_t* nl_ctx = &ctx->oper_ctx.nl_ctx; char xpath_buffer[PATH_MAX] = { 0 }; @@ -316,7 +316,7 @@ int interfaces_subscription_operational_interfaces_interface_lower_layer_if(sr_s // context const struct ly_ctx* ly_ctx = NULL; interfaces_ctx_t* ctx = private_data; - interfaces_nl_ctx_t* nl_ctx = &ctx->nl_ctx; + interfaces_nl_ctx_t* nl_ctx = &ctx->oper_ctx.nl_ctx; char xpath_buffer[PATH_MAX] = { 0 }; @@ -1512,7 +1512,7 @@ int interfaces_subscription_operational_interfaces_interface(sr_session_ctx_t* s void* error_ptr = NULL; const struct ly_ctx* ly_ctx = NULL; interfaces_ctx_t* ctx = private_data; - interfaces_nl_ctx_t* nl_ctx = &ctx->nl_ctx; + interfaces_nl_ctx_t* nl_ctx = &ctx->oper_ctx.nl_ctx; struct rtnl_link* link_iter = NULL; // libyang @@ -1571,7 +1571,7 @@ static struct rtnl_link* interfaces_get_current_link(interfaces_ctx_t* ctx, sr_s { int error = 0; - const interfaces_nl_ctx_t* nl_ctx = &ctx->nl_ctx; + const interfaces_nl_ctx_t* nl_ctx = &ctx->oper_ctx.nl_ctx; // buffers char interface_name_buffer[100] = { 0 }; From 4007406585f18212579642d1dbf75d3057308754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 19 Sep 2022 16:08:35 +0200 Subject: [PATCH 097/247] interfaces-plugin: fix common #defines --- src/interfaces/src/plugin.c | 53 +++++++++++++++-- src/interfaces/src/plugin/common.h | 8 ++- src/interfaces/src/plugin/context.h | 1 + .../src/plugin/subscription/change.c | 2 +- .../src/plugin/subscription/operational.c | 59 +++++++++++++++++++ 5 files changed, 113 insertions(+), 10 deletions(-) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index 5cbb00d5..134e7def 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -63,173 +63,214 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) // operational getters srpc_operational_t oper[] = { { - //depends on if-mib feature + // depends on if-mib feature + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_ADMIN_STATUS_YANG_PATH, srpc_feature_status_hash_check(ctx->features.ietf_interfaces_features, "if-mib") ? interfaces_subscription_operational_interfaces_interface_admin_status : NULL, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_OPER_STATUS_YANG_PATH, interfaces_subscription_operational_interfaces_interface_oper_status, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_LAST_CHANGE_YANG_PATH, interfaces_subscription_operational_interfaces_interface_last_change, }, { + IETF_INTERFACES_YANG_MODULE, //depends on if-mib feature INTERFACES_INTERFACES_INTERFACE_IF_INDEX_YANG_PATH, srpc_feature_status_hash_check(ctx->features.ietf_interfaces_features, "if-mib") ? interfaces_subscription_operational_interfaces_interface_if_index : NULL, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_PHYS_ADDRESS_YANG_PATH, interfaces_subscription_operational_interfaces_interface_phys_address, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_HIGHER_LAYER_IF_YANG_PATH, interfaces_subscription_operational_interfaces_interface_higher_layer_if, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_LOWER_LAYER_IF_YANG_PATH, interfaces_subscription_operational_interfaces_interface_lower_layer_if, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_SPEED_YANG_PATH, interfaces_subscription_operational_interfaces_interface_speed, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_STATISTICS_DISCONTINUITY_TIME_YANG_PATH, interfaces_subscription_operational_interfaces_interface_statistics_discontinuity_time, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_OCTETS_YANG_PATH, interfaces_subscription_operational_interfaces_interface_statistics_in_octets, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_UNICAST_PKTS_YANG_PATH, interfaces_subscription_operational_interfaces_interface_statistics_in_unicast_pkts, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_BROADCAST_PKTS_YANG_PATH, interfaces_subscription_operational_interfaces_interface_statistics_in_broadcast_pkts, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_MULTICAST_PKTS_YANG_PATH, interfaces_subscription_operational_interfaces_interface_statistics_in_multicast_pkts, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_DISCARDS_YANG_PATH, interfaces_subscription_operational_interfaces_interface_statistics_in_discards, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_ERRORS_YANG_PATH, interfaces_subscription_operational_interfaces_interface_statistics_in_errors, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_UNKNOWN_PROTOS_YANG_PATH, interfaces_subscription_operational_interfaces_interface_statistics_in_unknown_protos, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_STATISTICS_OUT_OCTETS_YANG_PATH, interfaces_subscription_operational_interfaces_interface_statistics_out_octets, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_STATISTICS_OUT_UNICAST_PKTS_YANG_PATH, interfaces_subscription_operational_interfaces_interface_statistics_out_unicast_pkts, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_STATISTICS_OUT_BROADCAST_PKTS_YANG_PATH, interfaces_subscription_operational_interfaces_interface_statistics_out_broadcast_pkts, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_STATISTICS_OUT_MULTICAST_PKTS_YANG_PATH, interfaces_subscription_operational_interfaces_interface_statistics_out_multicast_pkts, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_STATISTICS_OUT_DISCARDS_YANG_PATH, interfaces_subscription_operational_interfaces_interface_statistics_out_discards, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_STATISTICS_OUT_ERRORS_YANG_PATH, interfaces_subscription_operational_interfaces_interface_statistics_out_errors, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_STATISTICS_IN_DISCARD_UNKNOWN_ENCAPS_YANG_PATH, interfaces_subscription_operational_interfaces_interface_statistics_in_discard_unknown_encaps, }, { + IETF_INTERFACES_YANG_MODULE, //depends on carrier-delay feature INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_CARRIER_TRANSITIONS_YANG_PATH, srpc_feature_status_hash_check(ctx->features.ietf_if_extensions_features, "carrier-delay") ? interfaces_subscription_operational_interfaces_interface_carrier_delay_carrier_transitions : NULL, }, { + IETF_INTERFACES_YANG_MODULE, //depends on carrier-delay feature INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_TIMER_RUNNING_YANG_PATH, srpc_feature_status_hash_check(ctx->features.ietf_if_extensions_features, "carrier-delay") ? interfaces_subscription_operational_interfaces_interface_carrier_delay_timer_running : NULL, }, { + IETF_INTERFACES_YANG_MODULE, //depends on dampening feature INTERFACES_INTERFACES_INTERFACE_DAMPENING_PENALTY_YANG_PATH, srpc_feature_status_hash_check(ctx->features.ietf_if_extensions_features, "dampening") ? interfaces_subscription_operational_interfaces_interface_dampening_penalty : NULL, }, { + IETF_INTERFACES_YANG_MODULE, //depends on dampening feature INTERFACES_INTERFACES_INTERFACE_DAMPENING_SUPPRESSED_YANG_PATH, srpc_feature_status_hash_check(ctx->features.ietf_if_extensions_features, "dampening") ? interfaces_subscription_operational_interfaces_interface_dampening_suppressed : NULL, }, { + IETF_INTERFACES_YANG_MODULE, //depends on dampening feature INTERFACES_INTERFACES_INTERFACE_DAMPENING_TIME_REMAINING_YANG_PATH, srpc_feature_status_hash_check(ctx->features.ietf_if_extensions_features, "dampening") ? interfaces_subscription_operational_interfaces_interface_dampening_time_remaining : NULL, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_FORWARDING_MODE_YANG_PATH, interfaces_subscription_operational_interfaces_interface_forwarding_mode, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_IPV4_ADDRESS_ORIGIN_YANG_PATH, interfaces_subscription_operational_interfaces_interface_ipv4_address_origin, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_IPV4_ADDRESS_YANG_PATH, interfaces_subscription_operational_interfaces_interface_ipv4_address, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_IPV4_NEIGHBOR_ORIGIN_YANG_PATH, interfaces_subscription_operational_interfaces_interface_ipv4_neighbor_origin, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_IPV4_NEIGHBOR_YANG_PATH, interfaces_subscription_operational_interfaces_interface_ipv4_neighbor, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_IPV6_ADDRESS_ORIGIN_YANG_PATH, interfaces_subscription_operational_interfaces_interface_ipv6_address_origin, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_IPV6_ADDRESS_STATUS_YANG_PATH, interfaces_subscription_operational_interfaces_interface_ipv6_address_status, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_IPV6_ADDRESS_YANG_PATH, interfaces_subscription_operational_interfaces_interface_ipv6_address, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_IPV6_NEIGHBOR_ORIGIN_YANG_PATH, interfaces_subscription_operational_interfaces_interface_ipv6_neighbor_origin, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_IPV6_NEIGHBOR_IS_ROUTER_YANG_PATH, interfaces_subscription_operational_interfaces_interface_ipv6_neighbor_is_router, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_IPV6_NEIGHBOR_STATE_YANG_PATH, interfaces_subscription_operational_interfaces_interface_ipv6_neighbor_state, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_IPV6_NEIGHBOR_YANG_PATH, interfaces_subscription_operational_interfaces_interface_ipv6_neighbor, }, { + IETF_INTERFACES_YANG_MODULE, INTERFACES_INTERFACES_INTERFACE_YANG_PATH, interfaces_subscription_operational_interfaces_interface, }, @@ -260,7 +301,7 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) } // copy contents of the startup session to the current running session - error = sr_copy_config(running_session, BASE_YANG_MODEL, SR_DS_STARTUP, 0); + error = sr_copy_config(running_session, IETF_INTERFACES_YANG_MODULE, SR_DS_STARTUP, 0); if (error) { SRPLG_LOG_ERR(PLUGIN_NAME, "sr_copy_config() error (%d): %s", error, sr_strerror(error)); goto error_out; @@ -277,7 +318,7 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) // } // copy contents of the startup session to the current running session - error = sr_copy_config(running_session, BASE_YANG_MODEL, SR_DS_STARTUP, 0); + error = sr_copy_config(running_session, IETF_INTERFACES_YANG_MODULE, SR_DS_STARTUP, 0); if (error) { SRPLG_LOG_ERR(PLUGIN_NAME, "sr_copy_config() error (%d): %s", error, sr_strerror(error)); goto error_out; @@ -290,7 +331,7 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) // in case of work on a specific callback set it to NULL if (change->cb) { - error = sr_module_change_subscribe(running_session, BASE_YANG_MODEL, change->path, change->cb, *private_data, 0, SR_SUBSCR_DEFAULT, &subscription); + error = sr_module_change_subscribe(running_session, IETF_INTERFACES_YANG_MODULE, change->path, change->cb, *private_data, 0, SR_SUBSCR_DEFAULT, &subscription); if (error) { SRPLG_LOG_ERR(PLUGIN_NAME, "sr_module_change_subscribe() error for \"%s\" (%d): %s", change->path, error, sr_strerror(error)); goto error_out; @@ -304,7 +345,7 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) // in case of work on a specific callback set it to NULL if (op->cb) { - error = sr_oper_get_subscribe(running_session, BASE_YANG_MODEL, op->path, op->cb, *private_data, SR_SUBSCR_DEFAULT, &subscription); + error = sr_oper_get_subscribe(running_session, IETF_INTERFACES_YANG_MODULE, op->path, op->cb, *private_data, SR_SUBSCR_DEFAULT, &subscription); if (error) { SRPLG_LOG_ERR(PLUGIN_NAME, "sr_oper_get_subscribe() error (%d): %s", error, sr_strerror(error)); goto error_out; @@ -333,7 +374,7 @@ void sr_plugin_cleanup_cb(sr_session_ctx_t* running_session, void* private_data) interfaces_ctx_t* ctx = (interfaces_ctx_t*)private_data; // save current running configuration into startup for next time when the plugin starts - error = sr_copy_config(ctx->startup_session, BASE_YANG_MODEL, SR_DS_RUNNING, 0); + error = sr_copy_config(ctx->startup_session, IETF_INTERFACES_YANG_MODULE, SR_DS_RUNNING, 0); if (error) { SRPLG_LOG_ERR(PLUGIN_NAME, "sr_copy_config() error (%d): %s", error, sr_strerror(error)); } diff --git a/src/interfaces/src/plugin/common.h b/src/interfaces/src/plugin/common.h index 2d8c9b86..92ca8670 100644 --- a/src/interfaces/src/plugin/common.h +++ b/src/interfaces/src/plugin/common.h @@ -1,11 +1,13 @@ #ifndef INTERFACES_PLUGIN_COMMON_H #define INTERFACES_PLUGIN_COMMON_H -#define PLUGIN_NAME "interfaces-plugin" +#define PLUGIN_NAME "ietf-interfaces-plugin" -#define BASE_YANG_MODEL "ietf-interfaces" +#define IETF_INTERFACES_YANG_MODULE "ietf-interfaces" +#define IETF_IP_YANG_MODULE "ietf-ip" +#define IETF_IF_EXTENSIONS_YANG_MODULE "ietf-if-extensions" -#define INTERFACES_INTERFACES_CONTAINER_YANG_PATH "/" BASE_YANG_MODEL ":interfaces" +#define INTERFACES_INTERFACES_CONTAINER_YANG_PATH "/" IETF_INTERFACES_YANG_MODULE ":interfaces" #define INTERFACES_INTERFACES_LIST_YANG_PATH INTERFACES_INTERFACES_CONTAINER_YANG_PATH "/interface" #define INTERFACES_INTERFACES_STATE_INTERFACE_NAME_YANG_PATH INTERFACES_INTERFACES_STATE_INTERFACE_YANG_PATH "/name" diff --git a/src/interfaces/src/plugin/context.h b/src/interfaces/src/plugin/context.h index f3083776..3aad79e9 100644 --- a/src/interfaces/src/plugin/context.h +++ b/src/interfaces/src/plugin/context.h @@ -27,6 +27,7 @@ struct interfaces_features_ctx_s { struct interfaces_nl_ctx_s { struct nl_sock* socket; struct nl_cache* link_cache; + struct nl_cache* addr_cache; struct nl_cache_mngr* link_cache_manager; }; diff --git a/src/interfaces/src/plugin/subscription/change.c b/src/interfaces/src/plugin/subscription/change.c index 616397e8..8f2150ea 100644 --- a/src/interfaces/src/plugin/subscription/change.c +++ b/src/interfaces/src/plugin/subscription/change.c @@ -21,7 +21,7 @@ int interfaces_subscription_change_interfaces_interface(sr_session_ctx_t* sessio SRPLG_LOG_ERR(PLUGIN_NAME, "Aborting changes for %s", xpath); goto error_out; } else if (event == SR_EV_DONE) { - error = sr_copy_config(ctx->startup_session, BASE_YANG_MODEL, SR_DS_RUNNING, 0); + error = sr_copy_config(ctx->startup_session, IETF_INTERFACES_YANG_MODULE, SR_DS_RUNNING, 0); if (error) { SRPLG_LOG_ERR(PLUGIN_NAME, "sr_copy_config() error (%d): %s", error, sr_strerror(error)); goto error_out; diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 78933752..71bb2ec1 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -1,4 +1,5 @@ #include "operational.h" +#include "libyang/context.h" #include "libyang/tree_data.h" #include "netlink/addr.h" #include "netlink/cache.h" @@ -21,6 +22,7 @@ #include #include +#include #include #include #include @@ -1289,7 +1291,23 @@ int interfaces_subscription_operational_interfaces_interface_ipv4_address_origin int interfaces_subscription_operational_interfaces_interface_ipv4_address(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + int rc = 0; + void* error_ptr = NULL; + + interfaces_ctx_t* ctx = private_data; + interfaces_oper_ctx_t* oper_ctx = &ctx->oper_ctx; + + char xpath_buffer[PATH_MAX] = { 0 }; + char ip_buffer[20] = { 0 }; + char prefix_buffer[20] = { 0 }; + + SRPLG_LOG_INF(PLUGIN_NAME, "ADDRESS CALLBACK"); + const struct ly_ctx* ly_ctx = NULL; + struct lys_module* ietf_ip_module = NULL; + + struct rtnl_link* link = NULL; + struct rtnl_addr* addr_iter = NULL; if (*parent == NULL) { ly_ctx = sr_acquire_context(sr_session_get_connection(session)); @@ -1297,6 +1315,43 @@ int interfaces_subscription_operational_interfaces_interface_ipv4_address(sr_ses SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); goto error_out; } + + // load ietf-ip module + SRPC_SAFE_CALL_PTR(ietf_ip_module, ly_ctx_get_module(ly_ctx, "ietf-ip", "2018-02-22"), error_out); + } + + // there needs to be an allocated link cache in memory + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "ipv4") == 0); + + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); + + addr_iter = (struct rtnl_addr*)nl_cache_get_first(oper_ctx->nl_ctx.addr_cache); + + while (addr_iter) { + if (rtnl_addr_get_ifindex(addr_iter) == rtnl_link_get_ifindex(link)) { + const struct nl_addr* local = rtnl_addr_get_local(addr_iter); + + // IP + SRPC_SAFE_CALL_PTR(error_ptr, nl_addr2str(local, ip_buffer, sizeof(ip_buffer)), error_out); + + // prefix + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(prefix_buffer, sizeof(prefix_buffer), "%d", rtnl_addr_get_prefixlen(addr_iter)), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "ipv4:address(%s) = %s", rtnl_link_get_name(link), ip_buffer); + + // // address from the current link - add to the list + // SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_address(ly_ctx, *parent, NULL, ip_buffer), error_out); + + // // prefix + // SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_address_prefix_length(ly_ctx, *parent, prefix_buffer), error_out); + } + + addr_iter = (struct rtnl_addr*)nl_cache_get_next((struct nl_object*)addr_iter); } goto out; @@ -1530,9 +1585,13 @@ int interfaces_subscription_operational_interfaces_interface(sr_session_ctx_t* s // cache was already allocated - free existing cache if (nl_ctx->link_cache) { nl_cache_refill(nl_ctx->socket, nl_ctx->link_cache); + nl_cache_refill(nl_ctx->socket, nl_ctx->addr_cache); } else { // allocate new link cache SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(nl_ctx->socket, AF_UNSPEC, &nl_ctx->link_cache), error_out); + + // allocate new address cache + SRPC_SAFE_CALL_ERR(error, rtnl_addr_alloc_cache(nl_ctx->socket, &nl_ctx->addr_cache), error_out); } if (*parent == NULL) { From 5a523d4438bcbce91d85eef6396073fd9b15d683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 19 Sep 2022 16:09:11 +0200 Subject: [PATCH 098/247] interfaces-plugin: fix ietf-ip feature status hash load error --- src/interfaces/src/plugin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index 134e7def..3a0ddd52 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -50,7 +50,7 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) // load enabled features from modules in sysrepo SRPC_SAFE_CALL_ERR(error, srpc_feature_status_hash_load(&ctx->features.ietf_interfaces_features, running_session, "ietf-interfaces"), error_out); SRPC_SAFE_CALL_ERR(error, srpc_feature_status_hash_load(&ctx->features.ietf_if_extensions_features, running_session, "ietf-if-extensions"), error_out); - SRPC_SAFE_CALL_ERR(error, srpc_feature_status_hash_load(&ctx->features.ietf_ip_features, running_session, "ietf-if-extensions"), error_out); + SRPC_SAFE_CALL_ERR(error, srpc_feature_status_hash_load(&ctx->features.ietf_ip_features, running_session, "ietf-ip"), error_out); // module changes srpc_module_change_t module_changes[] = { From d528b4e702eb26e021b683a62cb3967e3ccb19ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 19 Sep 2022 16:55:21 +0200 Subject: [PATCH 099/247] interfaces-plugin: implement ipv4 address list operational callback --- src/interfaces/src/plugin.c | 6 ++++- src/interfaces/src/plugin/common.h | 2 +- src/interfaces/src/plugin/ly_tree.c | 4 +-- .../src/plugin/subscription/operational.c | 26 +++++++++++++------ 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index 3a0ddd52..a50ba8d7 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -329,6 +329,8 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) for (size_t i = 0; i < ARRAY_SIZE(module_changes); i++) { const srpc_module_change_t* change = &module_changes[i]; + SRPLG_LOG_INF(PLUGIN_NAME, "Subscribing module change callback %s", change->path); + // in case of work on a specific callback set it to NULL if (change->cb) { error = sr_module_change_subscribe(running_session, IETF_INTERFACES_YANG_MODULE, change->path, change->cb, *private_data, 0, SR_SUBSCR_DEFAULT, &subscription); @@ -343,9 +345,11 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) for (size_t i = 0; i < ARRAY_SIZE(oper); i++) { const srpc_operational_t* op = &oper[i]; + SRPLG_LOG_INF(PLUGIN_NAME, "Subscribing operational callback %s:%s", op->module, op->path); + // in case of work on a specific callback set it to NULL if (op->cb) { - error = sr_oper_get_subscribe(running_session, IETF_INTERFACES_YANG_MODULE, op->path, op->cb, *private_data, SR_SUBSCR_DEFAULT, &subscription); + error = sr_oper_get_subscribe(running_session, op->module, op->path, op->cb, *private_data, SR_SUBSCR_DEFAULT, &subscription); if (error) { SRPLG_LOG_ERR(PLUGIN_NAME, "sr_oper_get_subscribe() error (%d): %s", error, sr_strerror(error)); goto error_out; diff --git a/src/interfaces/src/plugin/common.h b/src/interfaces/src/plugin/common.h index 92ca8670..e80ca480 100644 --- a/src/interfaces/src/plugin/common.h +++ b/src/interfaces/src/plugin/common.h @@ -129,7 +129,7 @@ #define INTERFACES_INTERFACES_INTERFACE_IPV4_NEIGHBOR_LINK_LAYER_ADDRESS_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV4_NEIGHBOR_YANG_PATH "/link-layer-address" #define INTERFACES_INTERFACES_INTERFACE_IPV4_NEIGHBOR_ORIGIN_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV4_NEIGHBOR_YANG_PATH "/origin" #define INTERFACES_INTERFACES_INTERFACE_IPV4_NEIGHBOR_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV4_YANG_PATH "/neighbor" -#define INTERFACES_INTERFACES_INTERFACE_IPV4_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/ipv4" +#define INTERFACES_INTERFACES_INTERFACE_IPV4_YANG_PATH INTERFACES_INTERFACES_INTERFACE_YANG_PATH "/ietf-ip:ipv4" #define INTERFACES_INTERFACES_INTERFACE_IPV6_ENABLED_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV6_YANG_PATH "/enabled" #define INTERFACES_INTERFACES_INTERFACE_IPV6_FORWARDING_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV6_YANG_PATH "/forwarding" #define INTERFACES_INTERFACES_INTERFACE_IPV6_MTU_YANG_PATH INTERFACES_INTERFACES_INTERFACE_IPV6_YANG_PATH "/mtu" diff --git a/src/interfaces/src/plugin/ly_tree.c b/src/interfaces/src/plugin/ly_tree.c index b15e32dd..dd02ec48 100644 --- a/src/interfaces/src/plugin/ly_tree.c +++ b/src/interfaces/src/plugin/ly_tree.c @@ -16,7 +16,7 @@ int interfaces_ly_tree_create_interfaces_interface(const struct ly_ctx* ly_ctx, int interfaces_ly_tree_create_interfaces_interface_ipv6(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, struct lyd_node** ipv6_node) { - return srpc_ly_tree_create_container(ly_ctx, interface_node, ipv6_node, "ipv6"); + return srpc_ly_tree_create_container(ly_ctx, interface_node, ipv6_node, "ietf-ip:ipv6"); } int interfaces_ly_tree_create_interfaces_interface_ipv6_autoconf(const struct ly_ctx* ly_ctx, struct lyd_node* ipv6_node, struct lyd_node** autoconf_node) @@ -123,7 +123,7 @@ int interfaces_ly_tree_create_interfaces_interface_ipv6_enabled(const struct ly_ int interfaces_ly_tree_create_interfaces_interface_ipv4(const struct ly_ctx* ly_ctx, struct lyd_node* interface_node, struct lyd_node** ipv4_node) { - return srpc_ly_tree_create_container(ly_ctx, interface_node, ipv4_node, "ipv4"); + return srpc_ly_tree_create_container(ly_ctx, interface_node, ipv4_node, "ietf-ip:ipv4"); } int interfaces_ly_tree_create_interfaces_interface_ipv4_neighbor(const struct ly_ctx* ly_ctx, struct lyd_node* ipv4_node, struct lyd_node** neighbor_node, const char* ip) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 71bb2ec1..59c2fba4 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -1301,9 +1302,8 @@ int interfaces_subscription_operational_interfaces_interface_ipv4_address(sr_ses char ip_buffer[20] = { 0 }; char prefix_buffer[20] = { 0 }; - SRPLG_LOG_INF(PLUGIN_NAME, "ADDRESS CALLBACK"); - const struct ly_ctx* ly_ctx = NULL; + struct lyd_node* address_node = NULL; struct lys_module* ietf_ip_module = NULL; struct rtnl_link* link = NULL; @@ -1333,22 +1333,29 @@ int interfaces_subscription_operational_interfaces_interface_ipv4_address(sr_ses addr_iter = (struct rtnl_addr*)nl_cache_get_first(oper_ctx->nl_ctx.addr_cache); while (addr_iter) { - if (rtnl_addr_get_ifindex(addr_iter) == rtnl_link_get_ifindex(link)) { + if (rtnl_addr_get_ifindex(addr_iter) == rtnl_link_get_ifindex(link) && rtnl_addr_get_family(addr_iter) == AF_INET) { + SRPLG_LOG_INF(PLUGIN_NAME, "Found address for %s", rtnl_link_get_name(link)); + const struct nl_addr* local = rtnl_addr_get_local(addr_iter); // IP SRPC_SAFE_CALL_PTR(error_ptr, nl_addr2str(local, ip_buffer, sizeof(ip_buffer)), error_out); + // remove prefix from IP + char* prefix = strchr(ip_buffer, '/'); + *prefix = 0; + ++prefix; + // prefix SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(prefix_buffer, sizeof(prefix_buffer), "%d", rtnl_addr_get_prefixlen(addr_iter)), error_out); - SRPLG_LOG_INF(PLUGIN_NAME, "ipv4:address(%s) = %s", rtnl_link_get_name(link), ip_buffer); + SRPLG_LOG_INF(PLUGIN_NAME, "ipv4:address(%s) = %s/%s", rtnl_link_get_name(link), ip_buffer, prefix); - // // address from the current link - add to the list - // SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_address(ly_ctx, *parent, NULL, ip_buffer), error_out); + // address from the current link - add to the list + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_address(ly_ctx, *parent, &address_node, ip_buffer), error_out); - // // prefix - // SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_address_prefix_length(ly_ctx, *parent, prefix_buffer), error_out); + // prefix + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_address_prefix_length(ly_ctx, address_node, prefix_buffer), error_out); } addr_iter = (struct rtnl_addr*)nl_cache_get_next((struct nl_object*)addr_iter); @@ -1613,6 +1620,9 @@ int interfaces_subscription_operational_interfaces_interface(sr_session_ctx_t* s // add interface SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface(ly_ctx, *parent, &interface_list_node, rtnl_link_get_name(link_iter)), error_out); + // create needed containers for the interface + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4(ly_ctx, interface_list_node, NULL), error_out); + link_iter = (struct rtnl_link*)nl_cache_get_next((struct nl_object*)link_iter); } From c72c949c65ead832eb329fd5c769804926c0c236 Mon Sep 17 00:00:00 2001 From: agardijan Date: Tue, 20 Sep 2022 12:29:36 +0200 Subject: [PATCH 100/247] interfaces-plugin: use SRPC_SAFE_CALL_PTR --- .../src/plugin/api/interfaces/load.c | 24 ++++--------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index 2e2df515..6775a26d 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -187,29 +187,13 @@ static int interfaces_parse_link(interfaces_ctx_t *ctx, struct nl_sock *socket, int error = interfaces_load_success; *interface = (interfaces_interfaces_interface_t) {0}; - interface->name = interfaces_get_interface_name(link); - if (interface->name == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "%s: name error", __func__); - goto error_out; - } + SRPC_SAFE_CALL_PTR(interface->name, interfaces_get_interface_name(link), error_out); - interface->description = interfaces_get_interface_description(ctx, interface->name); - if (interface->description == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "%s: description error", __func__); - goto error_out; - } + SRPC_SAFE_CALL_PTR(interface->description, interfaces_get_interface_description(ctx, interface->name), error_out); - interface->type = interfaces_get_interface_type(link, interface->name); - if (interface->type == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "%s: type error", __func__); - goto error_out; - } + SRPC_SAFE_CALL_PTR(interface->type, interfaces_get_interface_type(link, interface->name), error_out); - interface->parent_interface = interfaces_get_interface_parent_interface(cache, link); - if (interface->parent_interface == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "%s: parent_interface error", __func__); - goto error_out; - } + SRPC_SAFE_CALL_PTR(interface->parent_interface, interfaces_get_interface_parent_interface(cache, link), error_out); error = interfaces_get_interface_vlan_id(link, interface); if (error != interfaces_load_success) { From dd29fac05c767132dfb418a93c4405fc71eaaa0b Mon Sep 17 00:00:00 2001 From: agardijan Date: Tue, 20 Sep 2022 12:42:35 +0200 Subject: [PATCH 101/247] interfaces-plugin: use SRPC_SAFE_CALL --- .../src/plugin/api/interfaces/load.c | 30 ++++--------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index 6775a26d..e71f262f 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -103,11 +103,7 @@ static char *interfaces_get_interface_type(struct rtnl_link *link, char *name) const char *path_to_sys = "/sys/class/net/"; int type_id = 0; - error = read_from_sys_file(path_to_sys, name, &type_id); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "%s: read_from_sys_file error", __func__); - goto error_out; - } + SRPC_SAFE_CALL(read_from_sys_file(path_to_sys, name, &type_id), error_out); switch (type_id) { case ARPHRD_ETHER: @@ -237,27 +233,15 @@ static int interfaces_add_link(interfaces_interface_hash_element_t **if_hash, in } if (interface->description != NULL) { - error = interfaces_interface_hash_element_set_description(&new_if_hash_elem, interface->description); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "%s: error setting description (%d)", __func__, error); - goto error_out; - } + SRPC_SAFE_CALL(interfaces_interface_hash_element_set_description(&new_if_hash_elem, interface->description), error_out); } if (interface->type != NULL) { - error = interfaces_interface_hash_element_set_type(&new_if_hash_elem, interface->type); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "%s: error setting type (%d)", __func__, error); - goto error_out; - } + SRPC_SAFE_CALL(interfaces_interface_hash_element_set_type(&new_if_hash_elem, interface->type), error_out); } if (interface->parent_interface != NULL) { - error = interfaces_interface_hash_element_set_parent_interface(&new_if_hash_elem, interface->parent_interface); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "%s: error setting type (%d)", __func__, error); - goto error_out; - } + SRPC_SAFE_CALL(interfaces_interface_hash_element_set_parent_interface(&new_if_hash_elem, interface->parent_interface), error_out); } interfaces_interface_hash_element_set_enabled(&new_if_hash_elem, interface->enabled); @@ -285,11 +269,7 @@ static int interfaces_interfaces_worker(interfaces_ctx_t *ctx, struct nl_sock *s error = interfaces_parse_link(ctx, socket, cache, link, &interface); switch (error) { case interfaces_load_success: - error = interfaces_add_link(if_hash, &interface); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "%s: error adding link (%d)", __func__, error); - goto error_out; - } + SRPC_SAFE_CALL(interfaces_add_link(if_hash, &interface), error_out); break; case interfaces_load_continue: break; From 5fdce52325bb884ebae3693219f70daf392b81d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 20 Sep 2022 13:17:52 +0200 Subject: [PATCH 102/247] interfaces-plugin: implement ipv6 address list operational callback --- .../src/plugin/subscription/operational.c | 74 +++++++++++++++++-- 1 file changed, 68 insertions(+), 6 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 59c2fba4..1939eaa6 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -1308,6 +1308,7 @@ int interfaces_subscription_operational_interfaces_interface_ipv4_address(sr_ses struct rtnl_link* link = NULL; struct rtnl_addr* addr_iter = NULL; + struct nl_addr* local = NULL; if (*parent == NULL) { ly_ctx = sr_acquire_context(sr_session_get_connection(session)); @@ -1334,22 +1335,22 @@ int interfaces_subscription_operational_interfaces_interface_ipv4_address(sr_ses while (addr_iter) { if (rtnl_addr_get_ifindex(addr_iter) == rtnl_link_get_ifindex(link) && rtnl_addr_get_family(addr_iter) == AF_INET) { - SRPLG_LOG_INF(PLUGIN_NAME, "Found address for %s", rtnl_link_get_name(link)); - - const struct nl_addr* local = rtnl_addr_get_local(addr_iter); + SRPLG_LOG_INF(PLUGIN_NAME, "Found IPv4 address for %s", rtnl_link_get_name(link)); // IP + SRPC_SAFE_CALL_PTR(local, rtnl_addr_get_local(addr_iter), error_out); SRPC_SAFE_CALL_PTR(error_ptr, nl_addr2str(local, ip_buffer, sizeof(ip_buffer)), error_out); // remove prefix from IP char* prefix = strchr(ip_buffer, '/'); - *prefix = 0; - ++prefix; + if (prefix) { + *prefix = 0; + } // prefix SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(prefix_buffer, sizeof(prefix_buffer), "%d", rtnl_addr_get_prefixlen(addr_iter)), error_out); - SRPLG_LOG_INF(PLUGIN_NAME, "ipv4:address(%s) = %s/%s", rtnl_link_get_name(link), ip_buffer, prefix); + SRPLG_LOG_INF(PLUGIN_NAME, "ipv4:address(%s) = %s/%s", rtnl_link_get_name(link), ip_buffer, prefix_buffer); // address from the current link - add to the list SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_address(ly_ctx, *parent, &address_node, ip_buffer), error_out); @@ -1461,7 +1462,23 @@ int interfaces_subscription_operational_interfaces_interface_ipv6_address_status int interfaces_subscription_operational_interfaces_interface_ipv6_address(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + int rc = 0; + void* error_ptr = NULL; + + interfaces_ctx_t* ctx = private_data; + interfaces_oper_ctx_t* oper_ctx = &ctx->oper_ctx; + + char xpath_buffer[PATH_MAX] = { 0 }; + char ip_buffer[100] = { 0 }; + char prefix_buffer[20] = { 0 }; + const struct ly_ctx* ly_ctx = NULL; + struct lyd_node* address_node = NULL; + struct lys_module* ietf_ip_module = NULL; + + struct rtnl_link* link = NULL; + struct rtnl_addr* addr_iter = NULL; + struct nl_addr* local = NULL; if (*parent == NULL) { ly_ctx = sr_acquire_context(sr_session_get_connection(session)); @@ -1469,6 +1486,49 @@ int interfaces_subscription_operational_interfaces_interface_ipv6_address(sr_ses SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); goto error_out; } + + // load ietf-ip module + SRPC_SAFE_CALL_PTR(ietf_ip_module, ly_ctx_get_module(ly_ctx, "ietf-ip", "2018-02-22"), error_out); + } + + // there needs to be an allocated link cache in memory + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "ipv6") == 0); + + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); + + addr_iter = (struct rtnl_addr*)nl_cache_get_first(oper_ctx->nl_ctx.addr_cache); + + while (addr_iter) { + if (rtnl_addr_get_ifindex(addr_iter) == rtnl_link_get_ifindex(link) && rtnl_addr_get_family(addr_iter) == AF_INET6) { + SRPLG_LOG_INF(PLUGIN_NAME, "Found IPv6 address for %s", rtnl_link_get_name(link)); + + SRPC_SAFE_CALL_PTR(local, rtnl_addr_get_local(addr_iter), error_out); + SRPC_SAFE_CALL_PTR(error_ptr, nl_addr2str(local, ip_buffer, sizeof(ip_buffer)), error_out); + + // remove prefix from IP + char* prefix = strchr(ip_buffer, '/'); + if (prefix) { + *prefix = 0; + } + + // prefix + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(prefix_buffer, sizeof(prefix_buffer), "%d", rtnl_addr_get_prefixlen(addr_iter)), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "ipv6:address(%s) = %s/%s", rtnl_link_get_name(link), ip_buffer, prefix_buffer); + + // address from the current link - add to the list + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv6_address(ly_ctx, *parent, &address_node, ip_buffer), error_out); + + // prefix + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv6_address_prefix_length(ly_ctx, address_node, prefix_buffer), error_out); + } + + addr_iter = (struct rtnl_addr*)nl_cache_get_next((struct nl_object*)addr_iter); } goto out; @@ -1621,7 +1681,9 @@ int interfaces_subscription_operational_interfaces_interface(sr_session_ctx_t* s SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface(ly_ctx, *parent, &interface_list_node, rtnl_link_get_name(link_iter)), error_out); // create needed containers for the interface + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_statistics(ly_ctx, interface_list_node, NULL), error_out); SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4(ly_ctx, interface_list_node, NULL), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv6(ly_ctx, interface_list_node, NULL), error_out); link_iter = (struct rtnl_link*)nl_cache_get_next((struct nl_object*)link_iter); } From f2abbea22e5a88717e4756e090ced7e5fe643a83 Mon Sep 17 00:00:00 2001 From: agardijan Date: Tue, 20 Sep 2022 13:58:47 +0200 Subject: [PATCH 103/247] interfaces-plugin: add missing srpcs safe calls --- .../src/plugin/api/interfaces/load.c | 24 ++++--------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index e71f262f..8cd400c5 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -226,11 +226,7 @@ static int interfaces_add_link(interfaces_interface_hash_element_t **if_hash, in interfaces_interface_hash_element_t *new_if_hash_elem = interfaces_interface_hash_element_new(); interfaces_interface_hash_element_set_name(&new_if_hash_elem, interface->name); - error = interfaces_interface_hash_add_element(if_hash, new_if_hash_elem); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "%s: error adding link (%d)", __func__, error); - goto error_out; - } + SRPC_SAFE_CALL(interfaces_interface_hash_add_element(if_hash, new_if_hash_elem), error_out); if (interface->description != NULL) { SRPC_SAFE_CALL(interfaces_interface_hash_element_set_description(&new_if_hash_elem, interface->description), error_out); @@ -306,23 +302,11 @@ int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_e goto error_out; } - error = nl_connect(socket, NETLINK_ROUTE); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_connect error (%d): %s", error, nl_geterror(error)); - goto error_out; - } + SRPC_SAFE_CALL(nl_connect(socket, NETLINK_ROUTE), error_out); - error = rtnl_link_alloc_cache(socket, AF_UNSPEC, &cache); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_alloc_cache error (%d): %s", error, nl_geterror(error)); - goto error_out; - } + SRPC_SAFE_CALL(rtnl_link_alloc_cache(socket, AF_UNSPEC, &cache), error_out); - error = interfaces_interfaces_worker(ctx, socket, cache, if_hash); - if (error != 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "interfaces_parse_links: error parsing links (%d)", error); - goto error_out; - } + SRPC_SAFE_CALL(interfaces_interfaces_worker(ctx, socket, cache, if_hash), error_out); goto out; error_out: From aa69113608d83f9065ac0f08752891032477bbfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jurica=20Kule=C5=A1?= Date: Tue, 20 Sep 2022 16:18:34 +0200 Subject: [PATCH 104/247] sysrepo-plugin-interfaces: implement interface store API --- .../src/plugin/api/interfaces/store.c | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/interfaces/src/plugin/api/interfaces/store.c b/src/interfaces/src/plugin/api/interfaces/store.c index a665ce5e..f27652de 100644 --- a/src/interfaces/src/plugin/api/interfaces/store.c +++ b/src/interfaces/src/plugin/api/interfaces/store.c @@ -1,8 +1,46 @@ #include "store.h" #include "utlist.h" +#include "uthash.h" +#include "types.h" +#include +#include "sysrepo/xpath.h" +#include "plugin/common.h" +#include "plugin/context.h" +#include +#include "netlink/errno.h" +#include "netlink/route/link.h" int interfaces_store_interface(interfaces_ctx_t* ctx, const interfaces_interface_hash_element_t* if_hash) { int error = 0; + interfaces_interface_hash_element_t *i = NULL, *tmp = NULL; + struct nl_sock *sk = NULL; + struct rtnl_link* new_link = NULL; + + // setup nl socket + + SRPC_SAFE_CALL_PTR(sk, nl_socket_alloc(), error_out); + + // connect + SRPC_SAFE_CALL_ERR(error, nl_connect(sk, NETLINK_ROUTE), error_out); + + HASH_ITER (hh, if_hash, i, tmp) { + // create a new link + SRPC_SAFE_CALL_PTR(new_link, rtnl_link_alloc(), error_out); + + // setup link and add it to the system + rtnl_link_set_name(new_link, i->interface.name); + SRPC_SAFE_CALL_ERR(error, rtnl_link_set_type(new_link, i->interface.type), error_out); + SRPC_SAFE_CALL_ERR(error, rtnl_link_add(sk, new_link, NLM_F_CREATE), error_out); + + } + +error_out: + if (error < 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "nl_geterror(): %d = %s", error, nl_geterror(error)); + } + error = -1; + +error: return error; } From 507630e1677d69ab441b1f4bca8cefd1dff54361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 20 Sep 2022 16:54:37 +0200 Subject: [PATCH 105/247] interfaces-plugin: implement ipv4 address origin operational callback --- .../src/plugin/subscription/operational.c | 117 ++++++++++++++++-- 1 file changed, 108 insertions(+), 9 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 1939eaa6..67094ac5 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -30,6 +31,7 @@ static struct rtnl_link* interfaces_get_current_link(interfaces_ctx_t* ctx, sr_session_ctx_t* session, const char* xpath); static int interfaces_extract_interface_name(sr_session_ctx_t* session, const char* xpath, char* buffer, size_t buffer_size); +static int interfaces_extract_interface_address_ip(sr_session_ctx_t* session, const char* xpath, char* buffer, size_t buffer_size); static int interfaces_get_system_boot_time(char* buffer, size_t buffer_size); int interfaces_subscription_operational_interfaces_interface_admin_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) @@ -1270,8 +1272,30 @@ int interfaces_subscription_operational_interfaces_interface_forwarding_mode(sr_ int interfaces_subscription_operational_interfaces_interface_ipv4_address_origin(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + int rc = 0; + void* error_ptr = NULL; + + sr_session_ctx_t* running_session = NULL; + sr_conn_ctx_t* connection = NULL; + + sr_val_t* prefix_length_val = NULL; + + interfaces_ctx_t* ctx = private_data; + interfaces_oper_ctx_t* oper_ctx = &ctx->oper_ctx; + + char xpath_buffer[PATH_MAX] = { 0 }; + char ip_buffer[20] = { 0 }; + char prefix_buffer[20] = { 0 }; + char address_buffer[100] = { 0 }; + + char prefix_path_buffer[PATH_MAX] = { 0 }; + const struct ly_ctx* ly_ctx = NULL; + struct rtnl_link* link = NULL; + struct nl_addr* local = NULL; + struct rtnl_addr* addr = NULL; + if (*parent == NULL) { ly_ctx = sr_acquire_context(sr_session_get_connection(session)); if (ly_ctx == NULL) { @@ -1280,12 +1304,54 @@ int interfaces_subscription_operational_interfaces_interface_ipv4_address_origin } } + // connect to the operational DS + SRPC_SAFE_CALL_PTR(connection, sr_session_get_connection(session), error_out); + SRPC_SAFE_CALL_ERR(error, sr_session_start(connection, SR_DS_RUNNING, &running_session), error_out); + + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "address") == 0); + + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); + + // get IP + SRPC_SAFE_CALL_ERR(error, interfaces_extract_interface_address_ip(session, xpath_buffer, ip_buffer, sizeof(ip_buffer)), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "origin(interface[%s]:address[%s]) = %s", rtnl_link_get_name(link), ip_buffer, ip_buffer); + + // get prefix length from the operational DS + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(prefix_path_buffer, sizeof(prefix_path_buffer), "/ietf-interfaces:interfaces/interface[name=\"%s\"]/ietf-ip:ipv4/address[ip=\"%s\"]/prefix-length", rtnl_link_get_name(link), ip_buffer), error_out); + SRPC_SAFE_CALL_ERR(error, sr_get_item(running_session, prefix_path_buffer, 0, &prefix_length_val), error_out); + + // create an address + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(address_buffer, sizeof(address_buffer), "%s/%d", ip_buffer, prefix_length_val->data.uint8_val), error_out); + + // parse address + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(address_buffer, AF_INET, &local), error_out); + + // get rtnl address + SRPC_SAFE_CALL_PTR(addr, rtnl_addr_get(oper_ctx->nl_ctx.addr_cache, rtnl_link_get_ifindex(link), local), error_out); + + // get address origin - static or dynamic + const char* origin = (rtnl_addr_get_flags(addr) & IFA_F_PERMANENT) > 0 ? "static" : "dhcp"; + + // add origin + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_address_origin(ly_ctx, *parent, origin), error_out); + + error = 0; goto out; error_out: error = SR_ERR_CALLBACK_FAILED; out: + if (running_session) { + sr_session_stop(running_session); + } + return error; } @@ -1304,7 +1370,6 @@ int interfaces_subscription_operational_interfaces_interface_ipv4_address(sr_ses const struct ly_ctx* ly_ctx = NULL; struct lyd_node* address_node = NULL; - struct lys_module* ietf_ip_module = NULL; struct rtnl_link* link = NULL; struct rtnl_addr* addr_iter = NULL; @@ -1316,9 +1381,6 @@ int interfaces_subscription_operational_interfaces_interface_ipv4_address(sr_ses SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); goto error_out; } - - // load ietf-ip module - SRPC_SAFE_CALL_PTR(ietf_ip_module, ly_ctx_get_module(ly_ctx, "ietf-ip", "2018-02-22"), error_out); } // there needs to be an allocated link cache in memory @@ -1474,7 +1536,6 @@ int interfaces_subscription_operational_interfaces_interface_ipv6_address(sr_ses const struct ly_ctx* ly_ctx = NULL; struct lyd_node* address_node = NULL; - struct lys_module* ietf_ip_module = NULL; struct rtnl_link* link = NULL; struct rtnl_addr* addr_iter = NULL; @@ -1486,9 +1547,6 @@ int interfaces_subscription_operational_interfaces_interface_ipv6_address(sr_ses SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); goto error_out; } - - // load ietf-ip module - SRPC_SAFE_CALL_PTR(ietf_ip_module, ly_ctx_get_module(ly_ctx, "ietf-ip", "2018-02-22"), error_out); } // there needs to be an allocated link cache in memory @@ -1730,11 +1788,15 @@ static int interfaces_extract_interface_name(sr_session_ctx_t* session, const ch int error = 0; const char* name = NULL; + char* xpath_copy = NULL; sr_xpath_ctx_t xpath_ctx = { 0 }; + // copy xpath due to changing it when using xpath_ctx from sysrepo + SRPC_SAFE_CALL_PTR(xpath_copy, strdup(xpath), error_out); + // extract key - SRPC_SAFE_CALL_PTR(name, sr_xpath_key_value((char*)xpath, "interface", "name", &xpath_ctx), error_out); + SRPC_SAFE_CALL_PTR(name, sr_xpath_key_value(xpath_copy, "interface", "name", &xpath_ctx), error_out); // store to buffer error = snprintf(buffer, buffer_size, "%s", name); @@ -1750,6 +1812,43 @@ static int interfaces_extract_interface_name(sr_session_ctx_t* session, const ch error = -1; out: + if (xpath_copy) { + free(xpath_copy); + } + + return error; +} + +static int interfaces_extract_interface_address_ip(sr_session_ctx_t* session, const char* xpath, char* buffer, size_t buffer_size) +{ + int error = 0; + + const char* ip = NULL; + char* xpath_copy = NULL; + + sr_xpath_ctx_t xpath_ctx = { 0 }; + + // copy xpath due to changing it when using xpath_ctx from sysrepo + SRPC_SAFE_CALL_PTR(xpath_copy, strdup(xpath), error_out); + + // extract key + SRPC_SAFE_CALL_PTR(ip, sr_xpath_key_value(xpath_copy, "address", "ip", &xpath_ctx), error_out); + + // store to buffer + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(buffer, buffer_size, "%s", ip), error_out); + + error = 0; + + goto out; + +error_out: + error = -1; + +out: + if (xpath_copy) { + free(xpath_copy); + } + return error; } From ea00e5a652ec72320ee28717dc8b042f11219b89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 20 Sep 2022 17:24:54 +0200 Subject: [PATCH 106/247] interfaces-plugin: remove unused buffer --- src/interfaces/src/plugin/subscription/operational.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 67094ac5..157ae320 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -1285,7 +1285,6 @@ int interfaces_subscription_operational_interfaces_interface_ipv4_address_origin char xpath_buffer[PATH_MAX] = { 0 }; char ip_buffer[20] = { 0 }; - char prefix_buffer[20] = { 0 }; char address_buffer[100] = { 0 }; char prefix_path_buffer[PATH_MAX] = { 0 }; @@ -1323,11 +1322,11 @@ int interfaces_subscription_operational_interfaces_interface_ipv4_address_origin SRPLG_LOG_INF(PLUGIN_NAME, "origin(interface[%s]:address[%s]) = %s", rtnl_link_get_name(link), ip_buffer, ip_buffer); // get prefix length from the operational DS - SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(prefix_path_buffer, sizeof(prefix_path_buffer), "/ietf-interfaces:interfaces/interface[name=\"%s\"]/ietf-ip:ipv4/address[ip=\"%s\"]/prefix-length", rtnl_link_get_name(link), ip_buffer), error_out); + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(prefix_path_buffer, sizeof(prefix_path_buffer), "/ietf-interfaces:interfaces/interface[name=\"%s\"]/ietf-ip:ipv4/address[ip=\"%s\"]/prefix-length", rtnl_link_get_name(link), ip_buffer), error_out); SRPC_SAFE_CALL_ERR(error, sr_get_item(running_session, prefix_path_buffer, 0, &prefix_length_val), error_out); // create an address - SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(address_buffer, sizeof(address_buffer), "%s/%d", ip_buffer, prefix_length_val->data.uint8_val), error_out); + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(address_buffer, sizeof(address_buffer), "%s/%d", ip_buffer, prefix_length_val->data.uint8_val), error_out); // parse address SRPC_SAFE_CALL_ERR(error, nl_addr_parse(address_buffer, AF_INET, &local), error_out); @@ -1341,7 +1340,6 @@ int interfaces_subscription_operational_interfaces_interface_ipv4_address_origin // add origin SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_address_origin(ly_ctx, *parent, origin), error_out); - error = 0; goto out; error_out: From c2fa08e0a520953128a161c8d41f248abf8ce5fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 20 Sep 2022 17:27:12 +0200 Subject: [PATCH 107/247] interfaces-plugin: implement ipv6 address origin operational callback --- .../src/plugin/subscription/operational.c | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 157ae320..844a932d 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -1478,8 +1478,29 @@ int interfaces_subscription_operational_interfaces_interface_ipv4_neighbor(sr_se int interfaces_subscription_operational_interfaces_interface_ipv6_address_origin(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + int rc = 0; + void* error_ptr = NULL; + + sr_session_ctx_t* running_session = NULL; + sr_conn_ctx_t* connection = NULL; + + sr_val_t* prefix_length_val = NULL; + + interfaces_ctx_t* ctx = private_data; + interfaces_oper_ctx_t* oper_ctx = &ctx->oper_ctx; + + char xpath_buffer[PATH_MAX] = { 0 }; + char ip_buffer[100] = { 0 }; + char address_buffer[100] = { 0 }; + + char prefix_path_buffer[PATH_MAX] = { 0 }; + const struct ly_ctx* ly_ctx = NULL; + struct rtnl_link* link = NULL; + struct nl_addr* local = NULL; + struct rtnl_addr* addr = NULL; + if (*parent == NULL) { ly_ctx = sr_acquire_context(sr_session_get_connection(session)); if (ly_ctx == NULL) { @@ -1488,12 +1509,53 @@ int interfaces_subscription_operational_interfaces_interface_ipv6_address_origin } } + // connect to the operational DS + SRPC_SAFE_CALL_PTR(connection, sr_session_get_connection(session), error_out); + SRPC_SAFE_CALL_ERR(error, sr_session_start(connection, SR_DS_RUNNING, &running_session), error_out); + + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "address") == 0); + + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); + + // get IP + SRPC_SAFE_CALL_ERR(error, interfaces_extract_interface_address_ip(session, xpath_buffer, ip_buffer, sizeof(ip_buffer)), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "origin(interface[%s]:address[%s]) = %s", rtnl_link_get_name(link), ip_buffer, ip_buffer); + + // get prefix length from the operational DS + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(prefix_path_buffer, sizeof(prefix_path_buffer), "/ietf-interfaces:interfaces/interface[name=\"%s\"]/ietf-ip:ipv6/address[ip=\"%s\"]/prefix-length", rtnl_link_get_name(link), ip_buffer), error_out); + SRPC_SAFE_CALL_ERR(error, sr_get_item(running_session, prefix_path_buffer, 0, &prefix_length_val), error_out); + + // create an address + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(address_buffer, sizeof(address_buffer), "%s/%d", ip_buffer, prefix_length_val->data.uint8_val), error_out); + + // parse address + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(address_buffer, AF_INET6, &local), error_out); + + // get rtnl address + SRPC_SAFE_CALL_PTR(addr, rtnl_addr_get(oper_ctx->nl_ctx.addr_cache, rtnl_link_get_ifindex(link), local), error_out); + + // get address origin - static or dynamic + const char* origin = (rtnl_addr_get_flags(addr) & IFA_F_PERMANENT) > 0 ? "static" : "dhcp"; + + // add origin + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_address_origin(ly_ctx, *parent, origin), error_out); + goto out; error_out: error = SR_ERR_CALLBACK_FAILED; out: + if (running_session) { + sr_session_stop(running_session); + } + return error; } From 473b324b77494a1a9b9184bbe7b6b87ea63f169a Mon Sep 17 00:00:00 2001 From: agardijan Date: Thu, 22 Sep 2022 12:18:25 +0200 Subject: [PATCH 108/247] interfaces-plugin: add linked list ipv4/6, neighbor API --- .../data/interfaces/interface/linked_list.c | 174 ++++++++++++++++++ .../data/interfaces/interface/linked_list.h | 122 ++++++++++++ 2 files changed, 296 insertions(+) create mode 100644 src/interfaces/src/plugin/data/interfaces/interface/linked_list.c create mode 100644 src/interfaces/src/plugin/data/interfaces/interface/linked_list.h diff --git a/src/interfaces/src/plugin/data/interfaces/interface/linked_list.c b/src/interfaces/src/plugin/data/interfaces/interface/linked_list.c new file mode 100644 index 00000000..7b6468de --- /dev/null +++ b/src/interfaces/src/plugin/data/interfaces/interface/linked_list.c @@ -0,0 +1,174 @@ +#include "linked_list.h" +#include "utils/memory.h" + +void *interfaces_interface_linked_list_ipv4_address_element_new(void) +{ + interfaces_interfaces_interface_ipv4_address_element_t *new_element = NULL; + + new_element = xmalloc(sizeof(interfaces_interfaces_interface_ipv4_address_element_t)); + + /* NULL all address fields */ + new_element->address = (interfaces_interfaces_interface_ipv4_address_t) {0}; + + return new_element; +} + +void *interfaces_interface_linked_list_ipv4_neighbor_element_new(void) +{ + interfaces_interfaces_interface_ipv4_neighbor_element_t *new_element = NULL; + + new_element = xmalloc(sizeof(interfaces_interfaces_interface_ipv4_neighbor_element_t)); + + /* NULL all address fields */ + new_element->neighbor = (interfaces_interfaces_interface_ipv4_neighbor_t) {0}; + + return new_element; +} + +void *interfaces_interface_linked_list_ipv6_address_element_new(void) +{ + interfaces_interfaces_interface_ipv6_address_element_t *new_element = NULL; + + new_element = xmalloc(sizeof(interfaces_interfaces_interface_ipv6_address_element_t)); + + /* NULL all address fields */ + new_element->address = (interfaces_interfaces_interface_ipv6_address_t) {0}; + + return new_element; +} + +void *interfaces_interface_linked_list_ipv6_neighbor_element_new(void) +{ + interfaces_interfaces_interface_ipv6_neighbor_element_t *new_element = NULL; + + new_element = xmalloc(sizeof(interfaces_interfaces_interface_ipv6_neighbor_element_t)); + + /* NULL all address fields */ + new_element->neighbor = (interfaces_interfaces_interface_ipv6_neighbor_t) {0}; + + return new_element; +} + +void interfaces_interface_linked_list_ipv4_address_free(interfaces_interfaces_interface_ipv4_address_element_t **ll) +{ + interfaces_interfaces_interface_ipv4_address_element_t *elem, *tmp; + + INTERFACES_INTERFACE_LINKED_LIST_IPV4_FREE_ADDRESS(ll, elem, tmp); +} + +void interfaces_interface_linked_list_ipv4_neighbor_free(interfaces_interfaces_interface_ipv4_neighbor_element_t **ll) +{ + interfaces_interfaces_interface_ipv4_neighbor_element_t *elem, *tmp; + + INTERFACES_INTERFACE_LINKED_LIST_FREE_NEIGHBOR(ll, elem, tmp); +} + +void interfaces_interface_linked_list_ipv6_address_free(interfaces_interfaces_interface_ipv6_address_element_t **ll) +{ + interfaces_interfaces_interface_ipv6_address_element_t *elem, *tmp; + + INTERFACES_INTERFACE_LINKED_LIST_IPV6_FREE_ADDRESS(ll, elem, tmp); +} + +void interfaces_interface_linked_list_ipv6_neighbor_free(interfaces_interfaces_interface_ipv6_neighbor_element_t **ll) +{ + interfaces_interfaces_interface_ipv6_neighbor_element_t *elem, *tmp; + INTERFACES_INTERFACE_LINKED_LIST_FREE_NEIGHBOR(ll, elem, tmp); +} + +int interfaces_interface_linked_list_ipv4_address_element_set_address(interfaces_interfaces_interface_ipv4_address_element_t **ll, interfaces_interfaces_interface_ipv4_address_t *address) +{ + + if ((*ll)->address.ip != NULL) { + FREE_SAFE((*ll)->address.ip); + } + if ((*ll)->address.subnet.prefix_length != NULL) { + FREE_SAFE((*ll)->address.subnet.prefix_length); + } + + if (address != NULL) { + (*ll)->address.subnet.prefix_length = address->subnet.prefix_length; + /* deepcopy char * */ + if (address->ip != NULL) { + (*ll)->address.ip = xstrdup(address->ip); + } + /* netmask is part of a union with prefix_length, doesn't have to be set */ + if (address->subnet.netmask != NULL) { + (*ll)->address.subnet.netmask = xstrdup(address->subnet.netmask); + return (*ll)->address.ip == NULL || (*ll)->address.subnet.netmask == NULL; + } + return (*ll)->address.ip == NULL; + } + + return 0; +} + +int interfaces_interface_linked_list_ipv4_address_element_set_neighbor(interfaces_interfaces_interface_ipv4_neighbor_element_t **ll, interfaces_interfaces_interface_ipv4_neighbor_t *neighbor) +{ + + if ((*ll)->neighbor.ip != NULL) { + FREE_SAFE((*ll)->neighbor.ip); + } + if ((*ll)->neighbor.link_layer_address != NULL) { + FREE_SAFE((*ll)->neighbor.link_layer_address); + } + + if (neighbor != NULL) { + if (neighbor->ip != NULL) { + (*ll)->neighbor.ip = xstrdup(neighbor->ip); + } + if (neighbor->link_layer_address != NULL) { + (*ll)->neighbor.link_layer_address = xstrdup(neighbor->link_layer_address); + } + + return (*ll)->neighbor.ip == NULL || (*ll)->neighbor.link_layer_address == NULL; + } + + return 0; +} + +int interfaces_interface_linked_list_ipv6_address_element_set_address(interfaces_interfaces_interface_ipv6_address_element_t **ll, interfaces_interfaces_interface_ipv6_address_t *address) +{ + + if ((*ll)->address.ip != NULL) { + FREE_SAFE((*ll)->address.ip); + } + if ((*ll)->address.prefix_length != NULL) { + FREE_SAFE((*ll)->address.prefix_length); + } + + if (address != NULL) { + (*ll)->address.prefix_length = address->prefix_length; + /* deepcopy char * */ + if (address->ip != NULL) { + (*ll)->address.ip = xstrdup(address->ip); + } + return (*ll)->address.ip == NULL; + } + + return 0; +} + +int interfaces_interface_linked_list_ipv6_address_element_set_neighbor(interfaces_interfaces_interface_ipv6_neighbor_element_t **ll, interfaces_interfaces_interface_ipv6_neighbor_t *neighbor) +{ + + if ((*ll)->neighbor.ip != NULL) { + FREE_SAFE((*ll)->neighbor.ip); + } + if ((*ll)->neighbor.link_layer_address != NULL) { + FREE_SAFE((*ll)->neighbor.link_layer_address); + } + + if (neighbor != NULL) { + if (neighbor->ip != NULL) { + (*ll)->neighbor.ip = xstrdup(neighbor->ip); + } + if (neighbor->link_layer_address != NULL) { + (*ll)->neighbor.link_layer_address = xstrdup(neighbor->link_layer_address); + } + + return (*ll)->neighbor.ip == NULL || (*ll)->neighbor.link_layer_address == NULL; + } + + return 0; +} diff --git a/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h b/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h new file mode 100644 index 00000000..d93c2309 --- /dev/null +++ b/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h @@ -0,0 +1,122 @@ +#ifndef INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_LIST_H +#define INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_LIST_H + +#include "plugin/types.h" + +#include +#include + +/* + Linked list operations +*/ + +#define INTERFACES_INTERFACE_LINKED_LIST_NEW(ll_ptr) \ + do \ + { \ + (ll_ptr) = NULL; \ + } while(0) + +#define INTERFACES_INTERFACE_LINKED_LIST_IPV4_FREE_ADDRESS(ll_ptr, elem_ptr, tmp_ptr) \ + do \ + { \ + LL_FOREACH_SAFE(*ll_ptr, elem_ptr, tmp_ptr) { \ + LL_DELETE(*ll_ptr, elem_ptr); \ + if (elem_ptr) { \ + if (elem_ptr->address.ip != NULL) { \ + FREE_SAFE(elem_ptr->address.ip); \ + } \ + if (elem_ptr->address.subnet.netmask != NULL) { \ + FREE_SAFE(elem_ptr->address.subnet.netmask); \ + } \ + FREE_SAFE(elem_ptr); \ + } \ + } \ + } \ + while (0) + +#define INTERFACES_INTERFACE_LINKED_LIST_IPV6_FREE_ADDRESS(ll_ptr, elem_ptr, tmp_ptr) \ + do \ + { \ + LL_FOREACH_SAFE(*ll_ptr, elem_ptr, tmp_ptr) { \ + LL_DELETE(*ll_ptr, elem_ptr); \ + if (elem_ptr) { \ + if (elem_ptr->address.ip != NULL) { \ + FREE_SAFE(elem_ptr->address.ip); \ + } \ + FREE_SAFE(elem_ptr); \ + } \ + } \ + } \ + while (0) + +#define INTERFACES_INTERFACE_LINKED_LIST_FREE_NEIGHBOR(ll_ptr, elem_ptr, tmp_ptr) \ + do \ + { \ + LL_FOREACH_SAFE(*ll_ptr, elem_ptr, tmp_ptr) { \ + LL_DELETE(*ll_ptr, elem_ptr); \ + if (elem_ptr) { \ + if (elem_ptr->neighbor.ip != NULL) { \ + FREE_SAFE(elem_ptr->neighbor.ip); \ + } \ + if (elem_ptr->neighbor.link_layer_address != NULL) { \ + FREE_SAFE(elem_ptr->neighbor.link_layer_address); \ + } \ + FREE_SAFE(elem_ptr); \ + } \ + } \ + } \ + while (0) + +#define INTERFACES_INTERFACE_LINKED_LIST_FREE(ll_ptr) \ + _Generic((ll_ptr), \ + interfaces_interfaces_interface_ipv4_address_element_t** : interfaces_interface_linked_list_ipv4_address_free \ + interfaces_interfaces_interface_ipv4_neighbor_element_t** : interfaces_interface_linked_list_ipv4_neighbor_free \ + interfaces_interfaces_interface_ipv6_address_element_t** : interfaces_interface_linked_list_ipv6_address_free \ + interfaces_interfaces_interface_ipv6_neighbor_element_t** : interfaces_interface_linked_list_ipv6_neighbor_free \ + )(ll_ptr) + +/* prepend since ordering doesn't matter - O(1) */ +#define INTERFACES_INTERFACE_LINKED_LIST_ADD_ELEMENT(ll_ptr, new_element_ptr) \ + do \ + { \ + LL_PREPEND(ll_ptr, new_element_ptr); \ + } while(0) \ + +#define INTERFACES_INTERFACE_LINKED_LIST_GET_ELEMENT_STRING(ll_ptr, element_ptr, member, value) \ + do \ + { \ + LL_FOREACH(ll_ptr, element_ptr) { \ + if (strcmp(element_ptr->member, value) == 0) { \ + break; \ + } \ + } \ + } while(0) + +#define INTERFACES_INTERFACE_LINKED_LIST_GET_ELEMENT_SCALAR(ll_ptr, element_ptr, member, value) \ + do \ + { \ + LL_SEARCH_SCALAR(ll_ptr, element_ptr, member, value); \ + } while(0) + +void interfaces_interface_linked_list_ipv4_address_free(interfaces_interfaces_interface_ipv4_address_element_t **ll); + +void interfaces_interface_linked_list_ipv4_neighbor_free(interfaces_interfaces_interface_ipv4_neighbor_element_t **ll); + +void interfaces_interface_linked_list_ipv6_address_free(interfaces_interfaces_interface_ipv6_address_element_t **ll); + +void interfaces_interface_linked_list_ipv6_neighbor_free(interfaces_interfaces_interface_ipv6_neighbor_element_t **ll); + +/* + Element operations +*/ + +void *interfaces_interface_linked_list_ipv4_address_element_new(void); +void *interfaces_interface_linked_list_ipv4_neighbor_element_new(void); +void *interfaces_interface_linked_list_ipv6_address_element_new(void); +void *interfaces_interface_linked_list_ipv6_neighbor_element_new(void); + +int interfaces_interface_linked_list_ipv4_address_element_set_address(interfaces_interfaces_interface_ipv4_address_element_t **ll, interfaces_interfaces_interface_ipv4_address_t *address); +int interfaces_interface_linked_list_ipv4_address_element_set_neighbor(interfaces_interfaces_interface_ipv4_neighbor_element_t **ll, interfaces_interfaces_interface_ipv4_neighbor_t *neighbor); + +#endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_LIST_H + From 157e3f6d3a0a205d116a01afe3d33b3fed99acd8 Mon Sep 17 00:00:00 2001 From: agardijan Date: Thu, 22 Sep 2022 12:19:45 +0200 Subject: [PATCH 109/247] interfaces-plugin: add linked list API to cmake sources --- src/interfaces/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/interfaces/CMakeLists.txt b/src/interfaces/CMakeLists.txt index d59fa65b..d45c5646 100644 --- a/src/interfaces/CMakeLists.txt +++ b/src/interfaces/CMakeLists.txt @@ -47,6 +47,7 @@ set( # data src/plugin/data/interfaces/interface/state_hash.c src/plugin/data/interfaces/interface/hash.c + src/plugin/data/interfaces/interface/linked_list.c # main files src/plugin.c From 0c2d471dae519c912ef5d7ac76c9954ef14c9d6a Mon Sep 17 00:00:00 2001 From: agardijan Date: Thu, 22 Sep 2022 12:20:24 +0200 Subject: [PATCH 110/247] interfaces-plugin: include linked list API --- src/interfaces/src/plugin/api/interfaces/load.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/interfaces/src/plugin/api/interfaces/load.h b/src/interfaces/src/plugin/api/interfaces/load.h index 3b338e1c..cd59b8a1 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.h +++ b/src/interfaces/src/plugin/api/interfaces/load.h @@ -2,6 +2,7 @@ #define INTERFACES_PLUGIN_API_INTERFACES_LOAD_H #include "plugin/data/interfaces/interface/hash.h" +#include "plugin/data/interfaces/interface/linked_list.h" #include "plugin/context.h" enum interfaces_load_exit_status { From 60eb402ddd7cc980288acc6a85a976874ec5a1d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Thu, 22 Sep 2022 17:30:15 +0200 Subject: [PATCH 111/247] interfaces-plugin: enable startup store functionality --- src/interfaces/src/plugin.c | 27 +++++-------------- .../src/plugin/api/interfaces/check.c | 3 ++- .../plugin/data/interfaces/interface/hash.c | 6 +++++ .../plugin/data/interfaces/interface/hash.h | 3 +++ src/interfaces/src/plugin/startup/store.c | 15 +++++++++-- 5 files changed, 31 insertions(+), 23 deletions(-) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index a50ba8d7..5431eee0 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -294,35 +294,22 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) if (empty_startup) { SRPLG_LOG_INF(PLUGIN_NAME, "Startup datastore is empty"); SRPLG_LOG_INF(PLUGIN_NAME, "Loading initial system data"); - error = interfaces_startup_load(ctx, startup_session); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "Error loading initial data into the startup datastore... exiting"); - goto error_out; - } + + // load startup data on the system + SRPC_SAFE_CALL_ERR(error, interfaces_startup_load(ctx, startup_session), error_out); // copy contents of the startup session to the current running session - error = sr_copy_config(running_session, IETF_INTERFACES_YANG_MODULE, SR_DS_STARTUP, 0); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_copy_config() error (%d): %s", error, sr_strerror(error)); - goto error_out; - } + SRPC_SAFE_CALL_ERR(error, sr_copy_config(running_session, IETF_INTERFACES_YANG_MODULE, SR_DS_STARTUP, 0), error_out); } else { // make sure the data from startup DS is stored in the interfaces SRPLG_LOG_INF(PLUGIN_NAME, "Startup datastore contains data"); SRPLG_LOG_INF(PLUGIN_NAME, "Storing startup datastore data in the system"); - // error = interfaces_startup_store(ctx, startup_session); - // if (error) { - // SRPLG_LOG_ERR(PLUGIN_NAME, "Error applying initial data from startup datastore to the system... exiting"); - // goto error_out; - // } + // check and store startup data on the system + SRPC_SAFE_CALL_ERR(error, interfaces_startup_store(ctx, startup_session), error_out); // copy contents of the startup session to the current running session - error = sr_copy_config(running_session, IETF_INTERFACES_YANG_MODULE, SR_DS_STARTUP, 0); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_copy_config() error (%d): %s", error, sr_strerror(error)); - goto error_out; - } + SRPC_SAFE_CALL_ERR(error, sr_copy_config(running_session, IETF_INTERFACES_YANG_MODULE, SR_DS_STARTUP, 0), error_out); } // subscribe every module change diff --git a/src/interfaces/src/plugin/api/interfaces/check.c b/src/interfaces/src/plugin/api/interfaces/check.c index 460ed924..f5ed0178 100644 --- a/src/interfaces/src/plugin/api/interfaces/check.c +++ b/src/interfaces/src/plugin/api/interfaces/check.c @@ -1,7 +1,8 @@ #include "check.h" +#include "srpc/types.h" srpc_check_status_t interfaces_check_interface(interfaces_ctx_t* ctx, const interfaces_interface_hash_element_t* if_hash) { - srpc_check_status_t status = srpc_check_status_none; + srpc_check_status_t status = srpc_check_status_non_existant; return status; } diff --git a/src/interfaces/src/plugin/data/interfaces/interface/hash.c b/src/interfaces/src/plugin/data/interfaces/interface/hash.c index 0de43b3e..a801423b 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/hash.c +++ b/src/interfaces/src/plugin/data/interfaces/interface/hash.c @@ -5,6 +5,12 @@ interfaces_interface_hash_element_t* interfaces_interface_hash_new(void) return NULL; } +interfaces_interface_hash_element_t* interfaces_interface_hash_from_ly(const struct lyd_node* interface_list_node) +{ + interfaces_interface_hash_element_t* if_hash = interfaces_interface_hash_new(); + return if_hash; +} + int interfaces_interface_hash_add_element(interfaces_interface_hash_element_t** hash, interfaces_interface_hash_element_t* new_element) { interfaces_interface_hash_element_t* found_element = NULL; diff --git a/src/interfaces/src/plugin/data/interfaces/interface/hash.h b/src/interfaces/src/plugin/data/interfaces/interface/hash.h index 0d5b9057..e6b42da0 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/hash.h +++ b/src/interfaces/src/plugin/data/interfaces/interface/hash.h @@ -3,11 +3,14 @@ #include "plugin/types.h" +#include + /* Hash table operations */ interfaces_interface_hash_element_t* interfaces_interface_hash_new(void); +interfaces_interface_hash_element_t* interfaces_interface_hash_from_ly(const struct lyd_node* interface_list_node); int interfaces_interface_hash_add_element(interfaces_interface_hash_element_t** hash, interfaces_interface_hash_element_t* new_element); interfaces_interface_hash_element_t* interfaces_interface_hash_get_element(interfaces_interface_hash_element_t** hash, const char* name); void interfaces_interface_hash_free(interfaces_interface_hash_element_t** hash); diff --git a/src/interfaces/src/plugin/startup/store.c b/src/interfaces/src/plugin/startup/store.c index a0c18247..9c00361b 100644 --- a/src/interfaces/src/plugin/startup/store.c +++ b/src/interfaces/src/plugin/startup/store.c @@ -3,6 +3,7 @@ #include "plugin/api/interfaces/check.h" #include "plugin/api/interfaces/store.h" +#include "srpc/ly_tree.h" #include #include @@ -57,13 +58,23 @@ static int interfaces_startup_store_interface(void* priv, const struct lyd_node* interfaces_ctx_t* ctx = (interfaces_ctx_t*)priv; srpc_check_status_t check_status = srpc_check_status_none; interfaces_interface_hash_element_t* interface_head = NULL; + struct lyd_node* interface_node = NULL; + struct lyd_node *interface_name_node = NULL, *interface_type_name = NULL, *intereface_enabled_node = NULL; - struct lyd_node* interfaces_node = srpc_ly_tree_get_child_leaf(parent_container, "interfaces"); - if (interfaces_node == NULL) { + interface_node + = srpc_ly_tree_get_child_list(parent_container, "interface"); + if (interface_node == NULL) { SRPLG_LOG_ERR(PLUGIN_NAME, "srpc_ly_tree_get_child_leaf returned NULL for 'interfaces'"); goto error_out; } + // map libyang data to the interface hash + while (interface_node) { + + SRPLG_LOG_INF(PLUGIN_NAME, "Node name: %s", lyd_get_value(interface_node)); + interface_node = srpc_ly_tree_get_list_next(interface_node); + } + SRPLG_LOG_INF(PLUGIN_NAME, "Checking interface list"); check_status = interfaces_check_interface(ctx, interface_head); From 1b895f27996f6a6f0b8df4d8bc9bf24688a1a326 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Thu, 22 Sep 2022 17:51:40 +0200 Subject: [PATCH 112/247] interfaces-plugin: convert libyang interface list to internal data structure --- .../plugin/data/interfaces/interface/hash.c | 88 ++++++++++++++++++- .../plugin/data/interfaces/interface/hash.h | 3 +- src/interfaces/src/plugin/startup/store.c | 22 +++-- 3 files changed, 100 insertions(+), 13 deletions(-) diff --git a/src/interfaces/src/plugin/data/interfaces/interface/hash.c b/src/interfaces/src/plugin/data/interfaces/interface/hash.c index a801423b..a44ae111 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/hash.c +++ b/src/interfaces/src/plugin/data/interfaces/interface/hash.c @@ -1,14 +1,94 @@ #include "hash.h" +#include "libyang/tree_data.h" +#include "plugin/common.h" +#include "src/uthash.h" +#include "srpc/ly_tree.h" +#include "sysrepo.h" + +#include +#include interfaces_interface_hash_element_t* interfaces_interface_hash_new(void) { return NULL; } -interfaces_interface_hash_element_t* interfaces_interface_hash_from_ly(const struct lyd_node* interface_list_node) +void interfaces_interface_hash_print_debug(const interfaces_interface_hash_element_t* if_hash) +{ + const interfaces_interface_hash_element_t *iter = NULL, *tmp = NULL; + + HASH_ITER(hh, if_hash, iter, tmp) + { + SRPLG_LOG_INF(PLUGIN_NAME, "Interface %s:", iter->interface.name); + SRPLG_LOG_INF(PLUGIN_NAME, "\t Name: %s", iter->interface.name); + SRPLG_LOG_INF(PLUGIN_NAME, "\t Type: %s", iter->interface.type); + SRPLG_LOG_INF(PLUGIN_NAME, "\t Enabled: %d", iter->interface.enabled); + } +} + +int interfaces_interface_hash_from_ly(const struct lyd_node* interface_list_node, interfaces_interface_hash_element_t** if_hash) { - interfaces_interface_hash_element_t* if_hash = interfaces_interface_hash_new(); - return if_hash; + int error = 0; + + // make sure the hash is empty at the start + assert(*if_hash == NULL); + + // libyang + struct lyd_node* if_iter = (struct lyd_node*)interface_list_node; + struct lyd_node *if_name_node = NULL, *if_type_node = NULL, *if_enabled_node = NULL; + + // extracted data + const char *if_name = NULL, *if_type = NULL, *if_enabled = NULL; + + // internal DS + interfaces_interface_hash_element_t* new_element = NULL; + // interfaces_interfaces_interface_ipv4_t v4_config = { 0 }; + // interfaces_interfaces_interface_ipv4_t v6_config = { 0 }; + + while (if_iter) { + if_name_node = srpc_ly_tree_get_child_leaf(if_iter, "name"); + if_type_node = srpc_ly_tree_get_child_leaf(if_iter, "type"); + if_enabled_node = srpc_ly_tree_get_child_leaf(if_iter, "enabled"); + + // extract data + if (if_name_node) { + if_name = lyd_get_value(if_name_node); + } + if (if_type_node) { + if_type = lyd_get_value(if_type_node); + } + if (if_enabled_node) { + if_enabled = lyd_get_value(if_enabled_node); + } + + // create new element + new_element = interfaces_interface_hash_element_new(); + + // set data + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_name(&new_element, if_name), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_type(&new_element, if_type), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_enabled(&new_element, strcmp(if_enabled, "true") ? 1 : 0), error_out); + + // add element to the hash + interfaces_interface_hash_add_element(if_hash, new_element); + + // set to NULL - free() + new_element = NULL; + + // iterate next + if_iter = srpc_ly_tree_get_list_next(if_iter); + } + + goto out; +error_out: + error = -1; + +out: + if (new_element) { + interfaces_interface_hash_element_free(&new_element); + } + + return error; } int interfaces_interface_hash_add_element(interfaces_interface_hash_element_t** hash, interfaces_interface_hash_element_t* new_element) @@ -46,6 +126,8 @@ void interfaces_interface_hash_free(interfaces_interface_hash_element_t** hash) HASH_DEL(*hash, element); interfaces_interface_hash_element_free(&element); } + + *hash = NULL; } interfaces_interface_hash_element_t* interfaces_interface_hash_element_new(void) diff --git a/src/interfaces/src/plugin/data/interfaces/interface/hash.h b/src/interfaces/src/plugin/data/interfaces/interface/hash.h index e6b42da0..0d6f3c5b 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/hash.h +++ b/src/interfaces/src/plugin/data/interfaces/interface/hash.h @@ -10,7 +10,8 @@ */ interfaces_interface_hash_element_t* interfaces_interface_hash_new(void); -interfaces_interface_hash_element_t* interfaces_interface_hash_from_ly(const struct lyd_node* interface_list_node); +void interfaces_interface_hash_print_debug(const interfaces_interface_hash_element_t* if_hash); +int interfaces_interface_hash_from_ly(const struct lyd_node* interface_list_node, interfaces_interface_hash_element_t** if_hash); int interfaces_interface_hash_add_element(interfaces_interface_hash_element_t** hash, interfaces_interface_hash_element_t* new_element); interfaces_interface_hash_element_t* interfaces_interface_hash_get_element(interfaces_interface_hash_element_t** hash, const char* name); void interfaces_interface_hash_free(interfaces_interface_hash_element_t** hash); diff --git a/src/interfaces/src/plugin/startup/store.c b/src/interfaces/src/plugin/startup/store.c index 9c00361b..c47185b8 100644 --- a/src/interfaces/src/plugin/startup/store.c +++ b/src/interfaces/src/plugin/startup/store.c @@ -3,6 +3,7 @@ #include "plugin/api/interfaces/check.h" #include "plugin/api/interfaces/store.h" +#include "plugin/data/interfaces/interface/hash.h" #include "srpc/ly_tree.h" #include @@ -57,9 +58,8 @@ static int interfaces_startup_store_interface(void* priv, const struct lyd_node* int error = 0; interfaces_ctx_t* ctx = (interfaces_ctx_t*)priv; srpc_check_status_t check_status = srpc_check_status_none; - interfaces_interface_hash_element_t* interface_head = NULL; + interfaces_interface_hash_element_t* if_hash = NULL; struct lyd_node* interface_node = NULL; - struct lyd_node *interface_name_node = NULL, *interface_type_name = NULL, *intereface_enabled_node = NULL; interface_node = srpc_ly_tree_get_child_list(parent_container, "interface"); @@ -69,14 +69,13 @@ static int interfaces_startup_store_interface(void* priv, const struct lyd_node* } // map libyang data to the interface hash - while (interface_node) { + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_from_ly(interface_node, &if_hash), error_out); - SRPLG_LOG_INF(PLUGIN_NAME, "Node name: %s", lyd_get_value(interface_node)); - interface_node = srpc_ly_tree_get_list_next(interface_node); - } + interfaces_interface_hash_print_debug(if_hash); - SRPLG_LOG_INF(PLUGIN_NAME, "Checking interface list"); - check_status = interfaces_check_interface(ctx, interface_head); + // check startup data + SRPLG_LOG_INF(PLUGIN_NAME, "Checking interface list data"); + check_status = interfaces_check_interface(ctx, if_hash); switch (check_status) { case srpc_check_status_none: @@ -88,7 +87,7 @@ static int interfaces_startup_store_interface(void* priv, const struct lyd_node* case srpc_check_status_non_existant: SRPLG_LOG_INF(PLUGIN_NAME, "Storing interface array"); - error = interfaces_store_interface(ctx, interface_head); + error = interfaces_store_interface(ctx, if_hash); if (error) { SRPLG_LOG_ERR(PLUGIN_NAME, "interfaces_store_interface() failed (%d)", error); goto error_out; @@ -107,6 +106,11 @@ static int interfaces_startup_store_interface(void* priv, const struct lyd_node* error_out: error = -1; + out: + if (if_hash) { + interfaces_interface_hash_free(&if_hash); + } + return error; } From ed8804f19200a3dbb1f3c19664b65c302c5bd27c Mon Sep 17 00:00:00 2001 From: agardijan Date: Fri, 23 Sep 2022 11:30:55 +0200 Subject: [PATCH 113/247] interfaces-plugin: move static functions, enum out of the header --- .../src/plugin/api/interfaces/load.c | 6 ++++ .../src/plugin/api/interfaces/load.h | 28 ------------------- 2 files changed, 6 insertions(+), 28 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index 8cd400c5..f96e707b 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -12,6 +12,12 @@ #include +enum interfaces_load_exit_status { + interfaces_load_failure = -1, + interfaces_load_success = 0, + interfaces_load_continue = 1, +}; + static char *interfaces_get_interface_name(struct rtnl_link *link) { char *name = NULL; diff --git a/src/interfaces/src/plugin/api/interfaces/load.h b/src/interfaces/src/plugin/api/interfaces/load.h index cd59b8a1..8eef49c8 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.h +++ b/src/interfaces/src/plugin/api/interfaces/load.h @@ -5,34 +5,6 @@ #include "plugin/data/interfaces/interface/linked_list.h" #include "plugin/context.h" -enum interfaces_load_exit_status { - interfaces_load_failure = -1, - interfaces_load_success = 0, - interfaces_load_continue = 1, -}; - -static char *interfaces_get_interface_name(struct rtnl_link *link); - -static char *interfaces_get_interface_description(interfaces_ctx_t *ctx, char *name); - -static int read_from_sys_file(const char *dir_path, char *interface, int *val); - -static char *interfaces_get_interface_type(struct rtnl_link *link, char *name); - -static uint8_t interfaces_get_interface_enabled(struct rtnl_link *link); - -static int interfaces_parse_link(interfaces_ctx_t *ctx, struct nl_sock *socket, struct nl_cache *cache, struct rtnl_link *link, interfaces_interfaces_interface_t *interface); - -static char *interfaces_get_interface_parent_interface(struct nl_cache *cache, struct rtnl_link *link); - -static int interfaces_get_interface_vlan_id(struct rtnl_link *link, interfaces_interfaces_interface_t *interface); - -static int interfaces_add_link(interfaces_interface_hash_element_t **if_hash, interfaces_interfaces_interface_t *interface); - -static struct rtnl_link *interfaces_get_next_link(struct rtnl_link *link); - -static int interfaces_interfaces_worker(interfaces_ctx_t *ctx, struct nl_sock *socket, struct nl_cache *cache, interfaces_interface_hash_element_t **if_hash); - int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t **if_hash); #endif // INTERFACES_PLUGIN_API_INTERFACES_LOAD_H From bb26a9f292819e22ca111d6a6937648e66826c9a Mon Sep 17 00:00:00 2001 From: agardijan Date: Fri, 23 Sep 2022 11:32:37 +0200 Subject: [PATCH 114/247] interfaces-plugin: don't redefine IFNAMSIZ --- src/interfaces/src/plugin/api/interfaces/load.c | 4 ++-- src/interfaces/src/plugin/common.h | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index f96e707b..434bb652 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -147,12 +147,12 @@ static uint8_t interfaces_get_interface_enabled(struct rtnl_link *link) static char *interfaces_get_interface_parent_interface(struct nl_cache *cache, struct rtnl_link *link) { int parent_index = 0; - char parent_buffer[MAX_IF_NAME_LEN] = {0}; + char parent_buffer[IFNAMSIZ] = {0}; char *parent_interface = NULL; if (rtnl_link_is_vlan(link)) { parent_index = rtnl_link_get_link(link); - parent_interface = rtnl_link_i2name(cache, parent_index, parent_buffer, MAX_IF_NAME_LEN); + parent_interface = rtnl_link_i2name(cache, parent_index, parent_buffer, IFNAMSIZ); } return xstrdup(parent_interface); diff --git a/src/interfaces/src/plugin/common.h b/src/interfaces/src/plugin/common.h index 2d0fa182..e80ca480 100644 --- a/src/interfaces/src/plugin/common.h +++ b/src/interfaces/src/plugin/common.h @@ -156,6 +156,4 @@ #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) -#define MAX_IF_NAME_LEN IFNAMSIZ // 16 bytes - #endif // INTERFACES_PLUGIN_COMMON_H From ec6fd07a271816f5c7dbf16e653060d26cd0073f Mon Sep 17 00:00:00 2001 From: agardijan Date: Fri, 23 Sep 2022 11:34:11 +0200 Subject: [PATCH 115/247] interfaces-plugin: match if enabled with bool YANG data format --- src/interfaces/src/plugin/types.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/interfaces/src/plugin/types.h b/src/interfaces/src/plugin/types.h index b2c1897c..e625dd2d 100644 --- a/src/interfaces/src/plugin/types.h +++ b/src/interfaces/src/plugin/types.h @@ -35,8 +35,8 @@ typedef struct interfaces_interface_state_hash_element interfaces_interface_stat typedef struct interfaces_interface_hash_element interfaces_interface_hash_element_t; enum interfaces_interfaces_interface_enable { - interfaces_interfaces_interface_enable_disabled, - interfaces_interfaces_interface_enable_enabled, + interfaces_interfaces_interface_enable_disabled = 0, + interfaces_interfaces_interface_enable_enabled = 1, }; enum interfaces_interfaces_interface_link_up_down_trap_enable { From 2748b2d8164fac5d70d36f64d9c66c8dd619127c Mon Sep 17 00:00:00 2001 From: agardijan Date: Fri, 23 Sep 2022 11:38:39 +0200 Subject: [PATCH 116/247] interfaces-plugin: change naming convention for consistency with the hash API --- .../data/interfaces/interface/linked_list.c | 24 +++++++------- .../data/interfaces/interface/linked_list.h | 32 +++++++++---------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/interfaces/src/plugin/data/interfaces/interface/linked_list.c b/src/interfaces/src/plugin/data/interfaces/interface/linked_list.c index 7b6468de..6160daeb 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/linked_list.c +++ b/src/interfaces/src/plugin/data/interfaces/interface/linked_list.c @@ -1,7 +1,7 @@ #include "linked_list.h" #include "utils/memory.h" -void *interfaces_interface_linked_list_ipv4_address_element_new(void) +void *interfaces_interface_ipv4_address_list_element_new(void) { interfaces_interfaces_interface_ipv4_address_element_t *new_element = NULL; @@ -13,7 +13,7 @@ void *interfaces_interface_linked_list_ipv4_address_element_new(void) return new_element; } -void *interfaces_interface_linked_list_ipv4_neighbor_element_new(void) +void *interfaces_interface_ipv4_neighbor_list_element_new(void) { interfaces_interfaces_interface_ipv4_neighbor_element_t *new_element = NULL; @@ -25,7 +25,7 @@ void *interfaces_interface_linked_list_ipv4_neighbor_element_new(void) return new_element; } -void *interfaces_interface_linked_list_ipv6_address_element_new(void) +void *interfaces_interface_ipv6_address_list_element_new(void) { interfaces_interfaces_interface_ipv6_address_element_t *new_element = NULL; @@ -37,7 +37,7 @@ void *interfaces_interface_linked_list_ipv6_address_element_new(void) return new_element; } -void *interfaces_interface_linked_list_ipv6_neighbor_element_new(void) +void *interfaces_interface_ipv6_neighbor_list_element_new(void) { interfaces_interfaces_interface_ipv6_neighbor_element_t *new_element = NULL; @@ -49,34 +49,34 @@ void *interfaces_interface_linked_list_ipv6_neighbor_element_new(void) return new_element; } -void interfaces_interface_linked_list_ipv4_address_free(interfaces_interfaces_interface_ipv4_address_element_t **ll) +void interfaces_interface_ipv4_address_list_free(interfaces_interfaces_interface_ipv4_address_element_t **ll) { interfaces_interfaces_interface_ipv4_address_element_t *elem, *tmp; INTERFACES_INTERFACE_LINKED_LIST_IPV4_FREE_ADDRESS(ll, elem, tmp); } -void interfaces_interface_linked_list_ipv4_neighbor_free(interfaces_interfaces_interface_ipv4_neighbor_element_t **ll) +void interfaces_interface_ipv4_neighbor_list_free(interfaces_interfaces_interface_ipv4_neighbor_element_t **ll) { interfaces_interfaces_interface_ipv4_neighbor_element_t *elem, *tmp; INTERFACES_INTERFACE_LINKED_LIST_FREE_NEIGHBOR(ll, elem, tmp); } -void interfaces_interface_linked_list_ipv6_address_free(interfaces_interfaces_interface_ipv6_address_element_t **ll) +void interfaces_interface_ipv6_address_list_free(interfaces_interfaces_interface_ipv6_address_element_t **ll) { interfaces_interfaces_interface_ipv6_address_element_t *elem, *tmp; INTERFACES_INTERFACE_LINKED_LIST_IPV6_FREE_ADDRESS(ll, elem, tmp); } -void interfaces_interface_linked_list_ipv6_neighbor_free(interfaces_interfaces_interface_ipv6_neighbor_element_t **ll) +void interfaces_interface_ipv6_neighbor_list_free(interfaces_interfaces_interface_ipv6_neighbor_element_t **ll) { interfaces_interfaces_interface_ipv6_neighbor_element_t *elem, *tmp; INTERFACES_INTERFACE_LINKED_LIST_FREE_NEIGHBOR(ll, elem, tmp); } -int interfaces_interface_linked_list_ipv4_address_element_set_address(interfaces_interfaces_interface_ipv4_address_element_t **ll, interfaces_interfaces_interface_ipv4_address_t *address) +int interfaces_interface_ipv4_address_list_element_set_address(interfaces_interfaces_interface_ipv4_address_element_t **ll, interfaces_interfaces_interface_ipv4_address_t *address) { if ((*ll)->address.ip != NULL) { @@ -103,7 +103,7 @@ int interfaces_interface_linked_list_ipv4_address_element_set_address(interfaces return 0; } -int interfaces_interface_linked_list_ipv4_address_element_set_neighbor(interfaces_interfaces_interface_ipv4_neighbor_element_t **ll, interfaces_interfaces_interface_ipv4_neighbor_t *neighbor) +int interfaces_interface_ipv4_address_list_element_set_neighbor(interfaces_interfaces_interface_ipv4_neighbor_element_t **ll, interfaces_interfaces_interface_ipv4_neighbor_t *neighbor) { if ((*ll)->neighbor.ip != NULL) { @@ -127,7 +127,7 @@ int interfaces_interface_linked_list_ipv4_address_element_set_neighbor(interface return 0; } -int interfaces_interface_linked_list_ipv6_address_element_set_address(interfaces_interfaces_interface_ipv6_address_element_t **ll, interfaces_interfaces_interface_ipv6_address_t *address) +int interfaces_interface_ipv6_address_list_element_set_address(interfaces_interfaces_interface_ipv6_address_element_t **ll, interfaces_interfaces_interface_ipv6_address_t *address) { if ((*ll)->address.ip != NULL) { @@ -149,7 +149,7 @@ int interfaces_interface_linked_list_ipv6_address_element_set_address(interfaces return 0; } -int interfaces_interface_linked_list_ipv6_address_element_set_neighbor(interfaces_interfaces_interface_ipv6_neighbor_element_t **ll, interfaces_interfaces_interface_ipv6_neighbor_t *neighbor) +int interfaces_interface_ipv6_address_list_element_set_neighbor(interfaces_interfaces_interface_ipv6_neighbor_element_t **ll, interfaces_interfaces_interface_ipv6_neighbor_t *neighbor) { if ((*ll)->neighbor.ip != NULL) { diff --git a/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h b/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h index d93c2309..5110835a 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h +++ b/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h @@ -67,12 +67,12 @@ } \ while (0) -#define INTERFACES_INTERFACE_LINKED_LIST_FREE(ll_ptr) \ - _Generic((ll_ptr), \ - interfaces_interfaces_interface_ipv4_address_element_t** : interfaces_interface_linked_list_ipv4_address_free \ - interfaces_interfaces_interface_ipv4_neighbor_element_t** : interfaces_interface_linked_list_ipv4_neighbor_free \ - interfaces_interfaces_interface_ipv6_address_element_t** : interfaces_interface_linked_list_ipv6_address_free \ - interfaces_interfaces_interface_ipv6_neighbor_element_t** : interfaces_interface_linked_list_ipv6_neighbor_free \ +#define INTERFACES_INTERFACE_LINKED_LIST_FREE(ll_ptr) \ + _Generic((ll_ptr), \ + interfaces_interfaces_interface_ipv4_address_element_t** : interfaces_interface_ipv4_address_list_free \ + interfaces_interfaces_interface_ipv4_neighbor_element_t** : interfaces_interface_ipv4_neighbor_list_free \ + interfaces_interfaces_interface_ipv6_address_element_t** : interfaces_interface_ipv6_address_list_free \ + interfaces_interfaces_interface_ipv6_neighbor_element_t** : interfaces_interface_ipv6_neighbor_list_free \ )(ll_ptr) /* prepend since ordering doesn't matter - O(1) */ @@ -98,25 +98,25 @@ LL_SEARCH_SCALAR(ll_ptr, element_ptr, member, value); \ } while(0) -void interfaces_interface_linked_list_ipv4_address_free(interfaces_interfaces_interface_ipv4_address_element_t **ll); +void interfaces_interface_ipv4_address_list_free(interfaces_interfaces_interface_ipv4_address_element_t **ll); -void interfaces_interface_linked_list_ipv4_neighbor_free(interfaces_interfaces_interface_ipv4_neighbor_element_t **ll); +void interfaces_interface_ipv4_neighbor_list_free(interfaces_interfaces_interface_ipv4_neighbor_element_t **ll); -void interfaces_interface_linked_list_ipv6_address_free(interfaces_interfaces_interface_ipv6_address_element_t **ll); +void interfaces_interface_ipv6_address_list_free(interfaces_interfaces_interface_ipv6_address_element_t **ll); -void interfaces_interface_linked_list_ipv6_neighbor_free(interfaces_interfaces_interface_ipv6_neighbor_element_t **ll); +void interfaces_interface_ipv6_neighbor_list_free(interfaces_interfaces_interface_ipv6_neighbor_element_t **ll); /* Element operations */ -void *interfaces_interface_linked_list_ipv4_address_element_new(void); -void *interfaces_interface_linked_list_ipv4_neighbor_element_new(void); -void *interfaces_interface_linked_list_ipv6_address_element_new(void); -void *interfaces_interface_linked_list_ipv6_neighbor_element_new(void); +void *interfaces_interface_ipv4_address_list_element_new(void); +void *interfaces_interface_ipv4_neighbor_list_element_new(void); +void *interfaces_interface_ipv6_address_list_element_new(void); +void *interfaces_interface_ipv6_neighbor_list_element_new(void); -int interfaces_interface_linked_list_ipv4_address_element_set_address(interfaces_interfaces_interface_ipv4_address_element_t **ll, interfaces_interfaces_interface_ipv4_address_t *address); -int interfaces_interface_linked_list_ipv4_address_element_set_neighbor(interfaces_interfaces_interface_ipv4_neighbor_element_t **ll, interfaces_interfaces_interface_ipv4_neighbor_t *neighbor); +int interfaces_interface_ipv4_address_list_element_set_address(interfaces_interfaces_interface_ipv4_address_element_t **ll, interfaces_interfaces_interface_ipv4_address_t *address); +int interfaces_interface_ipv4_address_list_element_set_neighbor(interfaces_interfaces_interface_ipv4_neighbor_element_t **ll, interfaces_interfaces_interface_ipv4_neighbor_t *neighbor); #endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_LIST_H From e0783b957c345d15d081df066843c2000b634b25 Mon Sep 17 00:00:00 2001 From: agardijan Date: Fri, 23 Sep 2022 11:51:02 +0200 Subject: [PATCH 117/247] interfaces-plugin: change macro function naming convention for consistency with the hash API --- .../data/interfaces/interface/linked_list.c | 8 ++++---- .../data/interfaces/interface/linked_list.h | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/interfaces/src/plugin/data/interfaces/interface/linked_list.c b/src/interfaces/src/plugin/data/interfaces/interface/linked_list.c index 6160daeb..27f855f1 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/linked_list.c +++ b/src/interfaces/src/plugin/data/interfaces/interface/linked_list.c @@ -53,27 +53,27 @@ void interfaces_interface_ipv4_address_list_free(interfaces_interfaces_interface { interfaces_interfaces_interface_ipv4_address_element_t *elem, *tmp; - INTERFACES_INTERFACE_LINKED_LIST_IPV4_FREE_ADDRESS(ll, elem, tmp); + INTERFACES_INTERFACE_IPV4_ADDRESS_LIST_FREE(ll, elem, tmp); } void interfaces_interface_ipv4_neighbor_list_free(interfaces_interfaces_interface_ipv4_neighbor_element_t **ll) { interfaces_interfaces_interface_ipv4_neighbor_element_t *elem, *tmp; - INTERFACES_INTERFACE_LINKED_LIST_FREE_NEIGHBOR(ll, elem, tmp); + INTERFACES_INTERFACE_NEIGHBOR_LIST_FREE(ll, elem, tmp); } void interfaces_interface_ipv6_address_list_free(interfaces_interfaces_interface_ipv6_address_element_t **ll) { interfaces_interfaces_interface_ipv6_address_element_t *elem, *tmp; - INTERFACES_INTERFACE_LINKED_LIST_IPV6_FREE_ADDRESS(ll, elem, tmp); + INTERFACES_INTERFACE_IPV6_ADDRESS_LIST_FREE(ll, elem, tmp); } void interfaces_interface_ipv6_neighbor_list_free(interfaces_interfaces_interface_ipv6_neighbor_element_t **ll) { interfaces_interfaces_interface_ipv6_neighbor_element_t *elem, *tmp; - INTERFACES_INTERFACE_LINKED_LIST_FREE_NEIGHBOR(ll, elem, tmp); + INTERFACES_INTERFACE_NEIGHBOR_LIST_FREE(ll, elem, tmp); } int interfaces_interface_ipv4_address_list_element_set_address(interfaces_interfaces_interface_ipv4_address_element_t **ll, interfaces_interfaces_interface_ipv4_address_t *address) diff --git a/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h b/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h index 5110835a..083565ee 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h +++ b/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h @@ -10,13 +10,13 @@ Linked list operations */ -#define INTERFACES_INTERFACE_LINKED_LIST_NEW(ll_ptr) \ +#define INTERFACES_INTERFACE_LIST_NEW(ll_ptr) \ do \ { \ (ll_ptr) = NULL; \ } while(0) -#define INTERFACES_INTERFACE_LINKED_LIST_IPV4_FREE_ADDRESS(ll_ptr, elem_ptr, tmp_ptr) \ +#define INTERFACES_INTERFACE_IPV4_ADDRESS_LIST_FREE(ll_ptr, elem_ptr, tmp_ptr) \ do \ { \ LL_FOREACH_SAFE(*ll_ptr, elem_ptr, tmp_ptr) { \ @@ -34,7 +34,7 @@ } \ while (0) -#define INTERFACES_INTERFACE_LINKED_LIST_IPV6_FREE_ADDRESS(ll_ptr, elem_ptr, tmp_ptr) \ +#define INTERFACES_INTERFACE_IPV6_ADDRESS_LIST_FREE(ll_ptr, elem_ptr, tmp_ptr) \ do \ { \ LL_FOREACH_SAFE(*ll_ptr, elem_ptr, tmp_ptr) { \ @@ -49,7 +49,7 @@ } \ while (0) -#define INTERFACES_INTERFACE_LINKED_LIST_FREE_NEIGHBOR(ll_ptr, elem_ptr, tmp_ptr) \ +#define INTERFACES_INTERFACE_NEIGHBOR_LIST_FREE(ll_ptr, elem_ptr, tmp_ptr) \ do \ { \ LL_FOREACH_SAFE(*ll_ptr, elem_ptr, tmp_ptr) { \ @@ -67,7 +67,7 @@ } \ while (0) -#define INTERFACES_INTERFACE_LINKED_LIST_FREE(ll_ptr) \ +#define INTERFACES_INTERFACE_LIST_FREE(ll_ptr) \ _Generic((ll_ptr), \ interfaces_interfaces_interface_ipv4_address_element_t** : interfaces_interface_ipv4_address_list_free \ interfaces_interfaces_interface_ipv4_neighbor_element_t** : interfaces_interface_ipv4_neighbor_list_free \ @@ -76,13 +76,13 @@ )(ll_ptr) /* prepend since ordering doesn't matter - O(1) */ -#define INTERFACES_INTERFACE_LINKED_LIST_ADD_ELEMENT(ll_ptr, new_element_ptr) \ +#define INTERFACES_INTERFACE_LIST_ADD_ELEMENT(ll_ptr, new_element_ptr) \ do \ { \ LL_PREPEND(ll_ptr, new_element_ptr); \ } while(0) \ -#define INTERFACES_INTERFACE_LINKED_LIST_GET_ELEMENT_STRING(ll_ptr, element_ptr, member, value) \ +#define INTERFACES_INTERFACE_LIST_GET_ELEMENT_STRING(ll_ptr, element_ptr, member, value) \ do \ { \ LL_FOREACH(ll_ptr, element_ptr) { \ @@ -92,7 +92,7 @@ } \ } while(0) -#define INTERFACES_INTERFACE_LINKED_LIST_GET_ELEMENT_SCALAR(ll_ptr, element_ptr, member, value) \ +#define INTERFACES_INTERFACE_LIST_GET_ELEMENT_SCALAR(ll_ptr, element_ptr, member, value) \ do \ { \ LL_SEARCH_SCALAR(ll_ptr, element_ptr, member, value); \ From 7c9bbbdaa234175918b5a374f9c949458a0e2d71 Mon Sep 17 00:00:00 2001 From: agardijan Date: Fri, 23 Sep 2022 16:08:14 +0200 Subject: [PATCH 118/247] interfaces-plugin: split ipv4/6 code into multiples files based on plugin/api --- .../interfaces/interface/ipv4/linked_list.c | 91 +++++++++++++++++++ .../interfaces/interface/ipv4/linked_list.h | 64 +++++++++++++ .../interfaces/interface/ipv6/linked_list.c | 85 +++++++++++++++++ .../interfaces/interface/ipv6/linked_list.h | 61 +++++++++++++ .../data/interfaces/interface/linked_list.h | 73 +-------------- 5 files changed, 303 insertions(+), 71 deletions(-) create mode 100644 src/interfaces/src/plugin/data/interfaces/interface/ipv4/linked_list.c create mode 100644 src/interfaces/src/plugin/data/interfaces/interface/ipv4/linked_list.h create mode 100644 src/interfaces/src/plugin/data/interfaces/interface/ipv6/linked_list.c create mode 100644 src/interfaces/src/plugin/data/interfaces/interface/ipv6/linked_list.h diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/linked_list.c b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/linked_list.c new file mode 100644 index 00000000..cf76173d --- /dev/null +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/linked_list.c @@ -0,0 +1,91 @@ +#include "linked_list.h" +#include "utils/memory.h" + +void *interfaces_interface_ipv4_address_list_element_new(void) +{ + interfaces_interfaces_interface_ipv4_address_element_t *new_element = NULL; + + new_element = xmalloc(sizeof(interfaces_interfaces_interface_ipv4_address_element_t)); + + /* NULL all address fields */ + new_element->address = (interfaces_interfaces_interface_ipv4_address_t) {0}; + + return new_element; +} + +void *interfaces_interface_ipv4_neighbor_list_element_new(void) +{ + interfaces_interfaces_interface_ipv4_neighbor_element_t *new_element = NULL; + + new_element = xmalloc(sizeof(interfaces_interfaces_interface_ipv4_neighbor_element_t)); + + /* NULL all address fields */ + new_element->neighbor = (interfaces_interfaces_interface_ipv4_neighbor_t) {0}; + + return new_element; +} + +void interfaces_interface_ipv4_address_list_free(interfaces_interfaces_interface_ipv4_address_element_t **ll) +{ + interfaces_interfaces_interface_ipv4_address_element_t *elem, *tmp; + + INTERFACES_INTERFACE_IPV4_ADDRESS_LIST_FREE(ll, elem, tmp); +} + +void interfaces_interface_ipv4_neighbor_list_free(interfaces_interfaces_interface_ipv4_neighbor_element_t **ll) +{ + interfaces_interfaces_interface_ipv4_neighbor_element_t *elem, *tmp; + + INTERFACES_INTERFACE_IPV4_NEIGHBOR_LIST_FREE(ll, elem, tmp); +} + +int interfaces_interface_ipv4_address_list_element_set_address(interfaces_interfaces_interface_ipv4_address_element_t **ll, interfaces_interfaces_interface_ipv4_address_t *address) +{ + + if ((*ll)->address.ip != NULL) { + FREE_SAFE((*ll)->address.ip); + } + if ((*ll)->address.subnet.prefix_length != NULL) { + FREE_SAFE((*ll)->address.subnet.prefix_length); + } + + if (address != NULL) { + (*ll)->address.subnet.prefix_length = address->subnet.prefix_length; + /* deepcopy char * */ + if (address->ip != NULL) { + (*ll)->address.ip = xstrdup(address->ip); + } + /* netmask is part of a union with prefix_length, doesn't have to be set */ + if (address->subnet.netmask != NULL) { + (*ll)->address.subnet.netmask = xstrdup(address->subnet.netmask); + return (*ll)->address.ip == NULL || (*ll)->address.subnet.netmask == NULL; + } + return (*ll)->address.ip == NULL; + } + + return 0; +} + +int interfaces_interface_ipv4_address_list_element_set_neighbor(interfaces_interfaces_interface_ipv4_neighbor_element_t **ll, interfaces_interfaces_interface_ipv4_neighbor_t *neighbor) +{ + + if ((*ll)->neighbor.ip != NULL) { + FREE_SAFE((*ll)->neighbor.ip); + } + if ((*ll)->neighbor.link_layer_address != NULL) { + FREE_SAFE((*ll)->neighbor.link_layer_address); + } + + if (neighbor != NULL) { + if (neighbor->ip != NULL) { + (*ll)->neighbor.ip = xstrdup(neighbor->ip); + } + if (neighbor->link_layer_address != NULL) { + (*ll)->neighbor.link_layer_address = xstrdup(neighbor->link_layer_address); + } + + return (*ll)->neighbor.ip == NULL || (*ll)->neighbor.link_layer_address == NULL; + } + + return 0; +} diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/linked_list.h b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/linked_list.h new file mode 100644 index 00000000..2b10dda9 --- /dev/null +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/linked_list.h @@ -0,0 +1,64 @@ +#ifndef INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV4_LIST_H +#define INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV4_LIST_H + +#include "plugin/types.h" + +#include +#include + +/* + Linked list operations +*/ + +#define INTERFACES_INTERFACE_IPV4_ADDRESS_LIST_FREE(ll_ptr, elem_ptr, tmp_ptr) \ + do \ + { \ + LL_FOREACH_SAFE(*ll_ptr, elem_ptr, tmp_ptr) { \ + LL_DELETE(*ll_ptr, elem_ptr); \ + if (elem_ptr) { \ + if (elem_ptr->address.ip != NULL) { \ + FREE_SAFE(elem_ptr->address.ip); \ + } \ + if (elem_ptr->address.subnet.netmask != NULL) { \ + FREE_SAFE(elem_ptr->address.subnet.netmask); \ + } \ + FREE_SAFE(elem_ptr); \ + } \ + } \ + } \ + while (0) + +#define INTERFACES_INTERFACE_IPV4_NEIGHBOR_LIST_FREE(ll_ptr, elem_ptr, tmp_ptr) \ + do \ + { \ + LL_FOREACH_SAFE(*ll_ptr, elem_ptr, tmp_ptr) { \ + LL_DELETE(*ll_ptr, elem_ptr); \ + if (elem_ptr) { \ + if (elem_ptr->neighbor.ip != NULL) { \ + FREE_SAFE(elem_ptr->neighbor.ip); \ + } \ + if (elem_ptr->neighbor.link_layer_address != NULL) { \ + FREE_SAFE(elem_ptr->neighbor.link_layer_address); \ + } \ + FREE_SAFE(elem_ptr); \ + } \ + } \ + } \ + while (0) + +void interfaces_interface_ipv4_address_list_free(interfaces_interfaces_interface_ipv4_address_element_t **ll); + +void interfaces_interface_ipv4_neighbor_list_free(interfaces_interfaces_interface_ipv4_neighbor_element_t **ll); + +/* + Element operations +*/ + +void *interfaces_interface_ipv4_address_list_element_new(void); +void *interfaces_interface_ipv4_neighbor_list_element_new(void); + +int interfaces_interface_ipv4_address_list_element_set_address(interfaces_interfaces_interface_ipv4_address_element_t **ll, interfaces_interfaces_interface_ipv4_address_t *address); +int interfaces_interface_ipv4_address_list_element_set_neighbor(interfaces_interfaces_interface_ipv4_neighbor_element_t **ll, interfaces_interfaces_interface_ipv4_neighbor_t *neighbor); + +#endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV4_LIST_H + diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv6/linked_list.c b/src/interfaces/src/plugin/data/interfaces/interface/ipv6/linked_list.c new file mode 100644 index 00000000..8f4bf255 --- /dev/null +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv6/linked_list.c @@ -0,0 +1,85 @@ +#include "linked_list.h" +#include "utils/memory.h" + +void *interfaces_interface_ipv6_address_list_element_new(void) +{ + interfaces_interfaces_interface_ipv6_address_element_t *new_element = NULL; + + new_element = xmalloc(sizeof(interfaces_interfaces_interface_ipv6_address_element_t)); + + /* NULL all address fields */ + new_element->address = (interfaces_interfaces_interface_ipv6_address_t) {0}; + + return new_element; +} + +void *interfaces_interface_ipv6_neighbor_list_element_new(void) +{ + interfaces_interfaces_interface_ipv6_neighbor_element_t *new_element = NULL; + + new_element = xmalloc(sizeof(interfaces_interfaces_interface_ipv6_neighbor_element_t)); + + /* NULL all address fields */ + new_element->neighbor = (interfaces_interfaces_interface_ipv6_neighbor_t) {0}; + + return new_element; +} + +void interfaces_interface_ipv6_address_list_free(interfaces_interfaces_interface_ipv6_address_element_t **ll) +{ + interfaces_interfaces_interface_ipv6_address_element_t *elem, *tmp; + + INTERFACES_INTERFACE_IPV6_ADDRESS_LIST_FREE(ll, elem, tmp); +} + +void interfaces_interface_ipv6_neighbor_list_free(interfaces_interfaces_interface_ipv6_neighbor_element_t **ll) +{ + interfaces_interfaces_interface_ipv6_neighbor_element_t *elem, *tmp; + INTERFACES_INTERFACE_IPV6_NEIGHBOR_LIST_FREE(ll, elem, tmp); +} + +int interfaces_interface_ipv6_address_list_element_set_address(interfaces_interfaces_interface_ipv6_address_element_t **ll, interfaces_interfaces_interface_ipv6_address_t *address) +{ + + if ((*ll)->address.ip != NULL) { + FREE_SAFE((*ll)->address.ip); + } + if ((*ll)->address.prefix_length != NULL) { + FREE_SAFE((*ll)->address.prefix_length); + } + + if (address != NULL) { + (*ll)->address.prefix_length = address->prefix_length; + /* deepcopy char * */ + if (address->ip != NULL) { + (*ll)->address.ip = xstrdup(address->ip); + } + return (*ll)->address.ip == NULL; + } + + return 0; +} + +int interfaces_interface_ipv6_address_list_element_set_neighbor(interfaces_interfaces_interface_ipv6_neighbor_element_t **ll, interfaces_interfaces_interface_ipv6_neighbor_t *neighbor) +{ + + if ((*ll)->neighbor.ip != NULL) { + FREE_SAFE((*ll)->neighbor.ip); + } + if ((*ll)->neighbor.link_layer_address != NULL) { + FREE_SAFE((*ll)->neighbor.link_layer_address); + } + + if (neighbor != NULL) { + if (neighbor->ip != NULL) { + (*ll)->neighbor.ip = xstrdup(neighbor->ip); + } + if (neighbor->link_layer_address != NULL) { + (*ll)->neighbor.link_layer_address = xstrdup(neighbor->link_layer_address); + } + + return (*ll)->neighbor.ip == NULL || (*ll)->neighbor.link_layer_address == NULL; + } + + return 0; +} diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv6/linked_list.h b/src/interfaces/src/plugin/data/interfaces/interface/ipv6/linked_list.h new file mode 100644 index 00000000..0583bd89 --- /dev/null +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv6/linked_list.h @@ -0,0 +1,61 @@ +#ifndef INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV6_LIST_H +#define INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV6_LIST_H + +#include "plugin/types.h" + +#include +#include + +/* + Linked list operations +*/ + +#define INTERFACES_INTERFACE_IPV6_ADDRESS_LIST_FREE(ll_ptr, elem_ptr, tmp_ptr) \ + do \ + { \ + LL_FOREACH_SAFE(*ll_ptr, elem_ptr, tmp_ptr) { \ + LL_DELETE(*ll_ptr, elem_ptr); \ + if (elem_ptr) { \ + if (elem_ptr->address.ip != NULL) { \ + FREE_SAFE(elem_ptr->address.ip); \ + } \ + FREE_SAFE(elem_ptr); \ + } \ + } \ + } \ + while (0) + +#define INTERFACES_INTERFACE_IPV6_NEIGHBOR_LIST_FREE(ll_ptr, elem_ptr, tmp_ptr) \ + do \ + { \ + LL_FOREACH_SAFE(*ll_ptr, elem_ptr, tmp_ptr) { \ + LL_DELETE(*ll_ptr, elem_ptr); \ + if (elem_ptr) { \ + if (elem_ptr->neighbor.ip != NULL) { \ + FREE_SAFE(elem_ptr->neighbor.ip); \ + } \ + if (elem_ptr->neighbor.link_layer_address != NULL) { \ + FREE_SAFE(elem_ptr->neighbor.link_layer_address); \ + } \ + FREE_SAFE(elem_ptr); \ + } \ + } \ + } \ + while (0) + +void interfaces_interface_ipv6_address_list_free(interfaces_interfaces_interface_ipv6_address_element_t **ll); + +void interfaces_interface_ipv6_neighbor_list_free(interfaces_interfaces_interface_ipv6_neighbor_element_t **ll); + +/* + Element operations +*/ + +void *interfaces_interface_ipv6_address_list_element_new(void); +void *interfaces_interface_ipv6_neighbor_list_element_new(void); + +int interfaces_interface_ipv6_address_list_element_set_address(interfaces_interfaces_interface_ipv6_address_element_t **ll, interfaces_interfaces_interface_ipv6_address_t *address); +int interfaces_interface_ipv6_address_list_element_set_neighbor(interfaces_interfaces_interface_ipv6_neighbor_element_t **ll, interfaces_interfaces_interface_ipv6_neighbor_t *neighbor); + +#endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV6_LIST_H + diff --git a/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h b/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h index 083565ee..9c1f1373 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h +++ b/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h @@ -1,6 +1,8 @@ #ifndef INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_LIST_H #define INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_LIST_H +#include "ipv4/linked_list.h" +#include "ipv6/linked_list.h" #include "plugin/types.h" #include @@ -16,57 +18,6 @@ (ll_ptr) = NULL; \ } while(0) -#define INTERFACES_INTERFACE_IPV4_ADDRESS_LIST_FREE(ll_ptr, elem_ptr, tmp_ptr) \ - do \ - { \ - LL_FOREACH_SAFE(*ll_ptr, elem_ptr, tmp_ptr) { \ - LL_DELETE(*ll_ptr, elem_ptr); \ - if (elem_ptr) { \ - if (elem_ptr->address.ip != NULL) { \ - FREE_SAFE(elem_ptr->address.ip); \ - } \ - if (elem_ptr->address.subnet.netmask != NULL) { \ - FREE_SAFE(elem_ptr->address.subnet.netmask); \ - } \ - FREE_SAFE(elem_ptr); \ - } \ - } \ - } \ - while (0) - -#define INTERFACES_INTERFACE_IPV6_ADDRESS_LIST_FREE(ll_ptr, elem_ptr, tmp_ptr) \ - do \ - { \ - LL_FOREACH_SAFE(*ll_ptr, elem_ptr, tmp_ptr) { \ - LL_DELETE(*ll_ptr, elem_ptr); \ - if (elem_ptr) { \ - if (elem_ptr->address.ip != NULL) { \ - FREE_SAFE(elem_ptr->address.ip); \ - } \ - FREE_SAFE(elem_ptr); \ - } \ - } \ - } \ - while (0) - -#define INTERFACES_INTERFACE_NEIGHBOR_LIST_FREE(ll_ptr, elem_ptr, tmp_ptr) \ - do \ - { \ - LL_FOREACH_SAFE(*ll_ptr, elem_ptr, tmp_ptr) { \ - LL_DELETE(*ll_ptr, elem_ptr); \ - if (elem_ptr) { \ - if (elem_ptr->neighbor.ip != NULL) { \ - FREE_SAFE(elem_ptr->neighbor.ip); \ - } \ - if (elem_ptr->neighbor.link_layer_address != NULL) { \ - FREE_SAFE(elem_ptr->neighbor.link_layer_address); \ - } \ - FREE_SAFE(elem_ptr); \ - } \ - } \ - } \ - while (0) - #define INTERFACES_INTERFACE_LIST_FREE(ll_ptr) \ _Generic((ll_ptr), \ interfaces_interfaces_interface_ipv4_address_element_t** : interfaces_interface_ipv4_address_list_free \ @@ -98,25 +49,5 @@ LL_SEARCH_SCALAR(ll_ptr, element_ptr, member, value); \ } while(0) -void interfaces_interface_ipv4_address_list_free(interfaces_interfaces_interface_ipv4_address_element_t **ll); - -void interfaces_interface_ipv4_neighbor_list_free(interfaces_interfaces_interface_ipv4_neighbor_element_t **ll); - -void interfaces_interface_ipv6_address_list_free(interfaces_interfaces_interface_ipv6_address_element_t **ll); - -void interfaces_interface_ipv6_neighbor_list_free(interfaces_interfaces_interface_ipv6_neighbor_element_t **ll); - -/* - Element operations -*/ - -void *interfaces_interface_ipv4_address_list_element_new(void); -void *interfaces_interface_ipv4_neighbor_list_element_new(void); -void *interfaces_interface_ipv6_address_list_element_new(void); -void *interfaces_interface_ipv6_neighbor_list_element_new(void); - -int interfaces_interface_ipv4_address_list_element_set_address(interfaces_interfaces_interface_ipv4_address_element_t **ll, interfaces_interfaces_interface_ipv4_address_t *address); -int interfaces_interface_ipv4_address_list_element_set_neighbor(interfaces_interfaces_interface_ipv4_neighbor_element_t **ll, interfaces_interfaces_interface_ipv4_neighbor_t *neighbor); - #endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_LIST_H From e6cfc29589dcca7060a7f8b60b5efed6019d6f18 Mon Sep 17 00:00:00 2001 From: agardijan Date: Fri, 23 Sep 2022 16:09:54 +0200 Subject: [PATCH 119/247] interfaces-plugin: add split ipv4/6 cmake sources --- src/interfaces/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/interfaces/CMakeLists.txt b/src/interfaces/CMakeLists.txt index d45c5646..89b45a76 100644 --- a/src/interfaces/CMakeLists.txt +++ b/src/interfaces/CMakeLists.txt @@ -47,7 +47,8 @@ set( # data src/plugin/data/interfaces/interface/state_hash.c src/plugin/data/interfaces/interface/hash.c - src/plugin/data/interfaces/interface/linked_list.c + src/plugin/data/interfaces/interface/ipv4/linked_list.c + src/plugin/data/interfaces/interface/ipv6/linked_list.c # main files src/plugin.c From b78f3a875ae5dfc7d806901193752837b1f270d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Fri, 23 Sep 2022 16:55:22 +0200 Subject: [PATCH 120/247] interfaces-plugin: update interface hash element API --- src/interfaces/src/plugin/data/interface.c | 77 +++---- src/interfaces/src/plugin/data/interface.h | 6 +- .../plugin/data/interfaces/interface/hash.c | 195 +++++++++++++----- .../plugin/data/interfaces/interface/hash.h | 30 ++- src/interfaces/src/plugin/types.h | 142 ++++++------- 5 files changed, 273 insertions(+), 177 deletions(-) diff --git a/src/interfaces/src/plugin/data/interface.c b/src/interfaces/src/plugin/data/interface.c index 18eb53f6..b3c86b36 100644 --- a/src/interfaces/src/plugin/data/interface.c +++ b/src/interfaces/src/plugin/data/interface.c @@ -4,41 +4,38 @@ #include -void -interfaces_data_ht_root_init(interface_ht_element_t **if_root) +void interfaces_data_ht_root_init(interface_ht_element_t** if_root) { /* uthash root node has to be initialized to NULL */ *if_root = NULL; } -static void -interfaces_data_init(interfaces_interfaces_interface_t* interface) +static void +interfaces_data_init(interfaces_interface_t* interface) { /* TODO: init all struct members */ - interface->name = NULL; - interface->description = NULL; - interface->type = NULL; - interface->enabled = 0; - interface->loopback = NULL; - interface->parent_interface = NULL; + interface->name = NULL; + interface->description = NULL; + interface->type = NULL; + interface->enabled = 0; + interface->loopback = NULL; + interface->parent_interface = NULL; } -interface_ht_element_t * -interfaces_data_ht_get_by_name(interface_ht_element_t *if_root, char *name) +interface_ht_element_t* +interfaces_data_ht_get_by_name(interface_ht_element_t* if_root, char* name) { - interface_ht_element_t *elem = NULL; + interface_ht_element_t* elem = NULL; HASH_FIND_STR(if_root, name, elem); return elem; } -void -interfaces_data_ht_set_name(interfaces_interfaces_interface_t *interface, char *name) +void interfaces_data_ht_set_name(interfaces_interface_t* interface, char* name) { - interface->name = xstrdup(name); + interface->name = xstrdup(name); } -int -interfaces_data_ht_add(interface_ht_element_t *if_root, char *name) +int interfaces_data_ht_add(interface_ht_element_t* if_root, char* name) { interface_ht_element_t *tmp = NULL, *elem = NULL; int rc = 0; @@ -49,13 +46,13 @@ interfaces_data_ht_add(interface_ht_element_t *if_root, char *name) goto error_out; } - elem = (interface_ht_element_t *) xmalloc(sizeof elem); + elem = (interface_ht_element_t*)xmalloc(sizeof elem); interfaces_data_init(&elem->interface); interfaces_data_ht_set_name(&elem->interface, name); /* since name is char *, *_KEYPTR has to be used instead of *_STR */ HASH_ADD_KEYPTR(hh, if_root, elem->interface.name, sizeof(elem->interface.name), elem); - + goto out; error_out: rc = -1; @@ -63,10 +60,9 @@ interfaces_data_ht_add(interface_ht_element_t *if_root, char *name) return rc; } -int -interfaces_data_ht_set_description(interface_ht_element_t *if_root, char *name, char *description) +int interfaces_data_ht_set_description(interface_ht_element_t* if_root, char* name, char* description) { - interface_ht_element_t *elem = NULL; + interface_ht_element_t* elem = NULL; int rc = 0; elem = interfaces_data_ht_get_by_name(if_root, name); @@ -74,7 +70,7 @@ interfaces_data_ht_set_description(interface_ht_element_t *if_root, char *name, SRPLG_LOG_ERR(PLUGIN_NAME, "interface with name key: %s non-existant in hash table", name); goto error_out; } - + if (elem->interface.description != NULL) { FREE_SAFE(elem->interface.description); } @@ -91,10 +87,9 @@ interfaces_data_ht_set_description(interface_ht_element_t *if_root, char *name, return rc; } -int -interfaces_data_ht_set_type(interface_ht_element_t *if_root, char *name, char *type) +int interfaces_data_ht_set_type(interface_ht_element_t* if_root, char* name, char* type) { - interface_ht_element_t *elem = NULL; + interface_ht_element_t* elem = NULL; int rc = 0; elem = interfaces_data_ht_get_by_name(if_root, name); @@ -102,7 +97,7 @@ interfaces_data_ht_set_type(interface_ht_element_t *if_root, char *name, char *t SRPLG_LOG_ERR(PLUGIN_NAME, "interface with name key: %s non-existant in hash table", name); goto error_out; } - + if (elem->interface.type != NULL) { FREE_SAFE(elem->interface.type); } @@ -119,10 +114,9 @@ interfaces_data_ht_set_type(interface_ht_element_t *if_root, char *name, char *t return rc; } -int -interfaces_data_ht_set_loopback(interface_ht_element_t *if_root, char *name, char *loopback) +int interfaces_data_ht_set_loopback(interface_ht_element_t* if_root, char* name, char* loopback) { - interface_ht_element_t *elem = NULL; + interface_ht_element_t* elem = NULL; int rc = 0; elem = interfaces_data_ht_get_by_name(if_root, name); @@ -130,7 +124,7 @@ interfaces_data_ht_set_loopback(interface_ht_element_t *if_root, char *name, cha SRPLG_LOG_ERR(PLUGIN_NAME, "interface with name key: %s non-existant in hash table", name); goto error_out; } - + if (elem->interface.loopback != NULL) { FREE_SAFE(elem->interface.loopback); } @@ -147,10 +141,9 @@ interfaces_data_ht_set_loopback(interface_ht_element_t *if_root, char *name, cha return rc; } -int -interfaces_data_ht_set_parent_interface(interface_ht_element_t *if_root, char *name, char *parent_interface) +int interfaces_data_ht_set_parent_interface(interface_ht_element_t* if_root, char* name, char* parent_interface) { - interface_ht_element_t *elem = NULL; + interface_ht_element_t* elem = NULL; int rc = 0; elem = interfaces_data_ht_get_by_name(if_root, name); @@ -158,7 +151,7 @@ interfaces_data_ht_set_parent_interface(interface_ht_element_t *if_root, char *n SRPLG_LOG_ERR(PLUGIN_NAME, "interface with name key: %s non-existant in hash table", name); goto error_out; } - + if (elem->interface.parent_interface != NULL) { FREE_SAFE(elem->interface.parent_interface); } @@ -175,8 +168,7 @@ interfaces_data_ht_set_parent_interface(interface_ht_element_t *if_root, char *n return rc; } -void -interfaces_data_ht_if_free(interfaces_interfaces_interface_t *interface) +void interfaces_data_ht_if_free(interfaces_interface_t* interface) { /* TODO: free other struct members as needed */ if (interface->name) { @@ -196,15 +188,14 @@ interfaces_data_ht_if_free(interfaces_interfaces_interface_t *interface) } } -void -interfaces_data_ht_free(interface_ht_element_t *if_root) +void interfaces_data_ht_free(interface_ht_element_t* if_root) { interface_ht_element_t *tmp = NULL, *elem = NULL; - - HASH_ITER(hh, if_root, elem, tmp) { + + HASH_ITER(hh, if_root, elem, tmp) + { HASH_DEL(if_root, elem); interfaces_data_ht_if_free(&elem->interface); FREE_SAFE(elem); } } - diff --git a/src/interfaces/src/plugin/data/interface.h b/src/interfaces/src/plugin/data/interface.h index fb7d15c4..03d9f753 100644 --- a/src/interfaces/src/plugin/data/interface.h +++ b/src/interfaces/src/plugin/data/interface.h @@ -8,12 +8,12 @@ void interfaces_data_ht_root_init(interface_ht_element_t** if_root); static void -interfaces_data_init(interfaces_interfaces_interface_t* interface); +interfaces_data_init(interfaces_interface_t* interface); interface_ht_element_t* interfaces_data_ht_get_by_name(interface_ht_element_t* if_root, char* name); -void interfaces_data_ht_set_name(interfaces_interfaces_interface_t* interface, char* name); +void interfaces_data_ht_set_name(interfaces_interface_t* interface, char* name); int interfaces_data_ht_add(interface_ht_element_t* if_root, char* name); @@ -25,7 +25,7 @@ int interfaces_data_ht_set_loopback(interface_ht_element_t* if_root, char* name, int interfaces_data_ht_set_parent_interface(interface_ht_element_t* if_root, char* name, char* parent_interface); -void interfaces_data_ht_if_free(interfaces_interfaces_interface_t* interface); +void interfaces_data_ht_if_free(interfaces_interface_t* interface); void interfaces_data_ht_free(interface_ht_element_t* if_root); diff --git a/src/interfaces/src/plugin/data/interfaces/interface/hash.c b/src/interfaces/src/plugin/data/interfaces/interface/hash.c index a44ae111..f018057f 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/hash.c +++ b/src/interfaces/src/plugin/data/interfaces/interface/hash.c @@ -1,28 +1,78 @@ #include "hash.h" #include "libyang/tree_data.h" #include "plugin/common.h" -#include "src/uthash.h" #include "srpc/ly_tree.h" #include "sysrepo.h" +#include "uthash.h" +#include "utlist.h" #include #include +#include +#include interfaces_interface_hash_element_t* interfaces_interface_hash_new(void) { return NULL; } +void interfaces_interface_hash_element_free(interfaces_interface_hash_element_t** el) +{ + if (*el) { + // name + if ((*el)->interface.name) { + free((*el)->interface.name); + } + + // description + if ((*el)->interface.description) { + free((*el)->interface.description); + } + + // type + if ((*el)->interface.type) { + free((*el)->interface.type); + } + + // loopback + if ((*el)->interface.loopback) { + free((*el)->interface.loopback); + } + + // parent-interface + if ((*el)->interface.parent_interface) { + free((*el)->interface.parent_interface); + } + + // element data + free(*el); + *el = NULL; + } +} + void interfaces_interface_hash_print_debug(const interfaces_interface_hash_element_t* if_hash) { const interfaces_interface_hash_element_t *iter = NULL, *tmp = NULL; + interfaces_interface_ipv4_address_element_t* v4addr_iter = NULL; HASH_ITER(hh, if_hash, iter, tmp) { SRPLG_LOG_INF(PLUGIN_NAME, "Interface %s:", iter->interface.name); - SRPLG_LOG_INF(PLUGIN_NAME, "\t Name: %s", iter->interface.name); - SRPLG_LOG_INF(PLUGIN_NAME, "\t Type: %s", iter->interface.type); - SRPLG_LOG_INF(PLUGIN_NAME, "\t Enabled: %d", iter->interface.enabled); + SRPLG_LOG_INF(PLUGIN_NAME, "\t Name = %s", iter->interface.name); + SRPLG_LOG_INF(PLUGIN_NAME, "\t Type = %s", iter->interface.type); + SRPLG_LOG_INF(PLUGIN_NAME, "\t Enabled = %d", iter->interface.enabled); + SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv4:"); + SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv4:Enabled = %d", iter->interface.ipv4.enabled); + SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv4:Forwarding = %d", iter->interface.ipv4.forwarding); + SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv4:MTU = %hu", iter->interface.ipv4.mtu); + SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv4:Address List:"); + + LL_FOREACH(iter->interface.ipv4.address, v4addr_iter) + { + SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv4:Address %s:", v4addr_iter->address.ip); + SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv4:Address IP = %s", v4addr_iter->address.ip); + SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv4:Address Prefix Length = %d", v4addr_iter->address.subnet.prefix_length); + } } } @@ -36,38 +86,69 @@ int interfaces_interface_hash_from_ly(const struct lyd_node* interface_list_node // libyang struct lyd_node* if_iter = (struct lyd_node*)interface_list_node; struct lyd_node *if_name_node = NULL, *if_type_node = NULL, *if_enabled_node = NULL; - - // extracted data - const char *if_name = NULL, *if_type = NULL, *if_enabled = NULL; + struct lyd_node *ipv4_container_node = NULL, *ipv6_container_node = NULL; + struct lyd_node *ipv4_enabled_node = NULL, *ipv4_forwarding_node = NULL, *ipv4_mtu_node = NULL, *ipv4_address_node = NULL; + struct lyd_node *ipv6_enabled_node = NULL, *ipv6_forwarding_node = NULL, *ipv6_mtu_node = NULL, *ipv6_address_node = NULL; // internal DS interfaces_interface_hash_element_t* new_element = NULL; - // interfaces_interfaces_interface_ipv4_t v4_config = { 0 }; - // interfaces_interfaces_interface_ipv4_t v6_config = { 0 }; + interfaces_interface_ipv4_address_element_t* new_v4_element = NULL; + interfaces_interface_ipv6_address_element_t* new_v6_element = NULL; while (if_iter) { + // create new element + new_element = interfaces_interface_hash_element_new(); + + // get existing nodes if_name_node = srpc_ly_tree_get_child_leaf(if_iter, "name"); if_type_node = srpc_ly_tree_get_child_leaf(if_iter, "type"); if_enabled_node = srpc_ly_tree_get_child_leaf(if_iter, "enabled"); + ipv4_container_node = srpc_ly_tree_get_child_container(if_iter, "ipv4"); + ipv6_container_node = srpc_ly_tree_get_child_container(if_iter, "ipv6"); + + // ipv4 + if (ipv4_container_node) { + ipv4_enabled_node = srpc_ly_tree_get_child_leaf(ipv4_container_node, "enabled"); + ipv4_forwarding_node = srpc_ly_tree_get_child_leaf(ipv4_container_node, "forwarding"); + ipv4_mtu_node = srpc_ly_tree_get_child_leaf(ipv4_container_node, "mtu"); + ipv4_address_node = srpc_ly_tree_get_child_list(ipv4_container_node, "address"); + } - // extract data + // ipv6 + if (ipv6_container_node) { + ipv6_enabled_node = srpc_ly_tree_get_child_leaf(ipv6_container_node, "enabled"); + ipv6_forwarding_node = srpc_ly_tree_get_child_leaf(ipv6_container_node, "forwarding"); + ipv6_mtu_node = srpc_ly_tree_get_child_leaf(ipv6_container_node, "mtu"); + ipv6_address_node = srpc_ly_tree_get_child_list(ipv6_container_node, "address"); + } + + // extract and set data if (if_name_node) { - if_name = lyd_get_value(if_name_node); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_name(&new_element, lyd_get_value(if_name_node)), error_out); } if (if_type_node) { - if_type = lyd_get_value(if_type_node); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_type(&new_element, lyd_get_value(if_type_node)), error_out); } if (if_enabled_node) { - if_enabled = lyd_get_value(if_enabled_node); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_enabled(&new_element, strcmp(lyd_get_value(if_enabled_node), "true") ? 1 : 0), error_out); + } + if (ipv4_enabled_node) { + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_ipv4_enabled(&new_element, strcmp(lyd_get_value(ipv4_enabled_node), "true") ? 1 : 0), error_out); } + if (ipv4_forwarding_node) { + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_ipv4_forwarding(&new_element, strcmp(lyd_get_value(ipv4_forwarding_node), "true") ? 1 : 0), error_out); + } + if (ipv4_mtu_node) { + const char* mtu_str = lyd_get_value(ipv4_mtu_node); + uint16_t mtu = (uint16_t)atoi(mtu_str); - // create new element - new_element = interfaces_interface_hash_element_new(); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_ipv4_mtu(&new_element, mtu), error_out); + } - // set data - SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_name(&new_element, if_name), error_out); - SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_type(&new_element, if_type), error_out); - SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_enabled(&new_element, strcmp(if_enabled, "true") ? 1 : 0), error_out); + // IPv4 address list + while (ipv4_address_node) { + ipv4_address_node = srpc_ly_tree_get_list_next(ipv4_address_node); + } // add element to the hash interfaces_interface_hash_add_element(if_hash, new_element); @@ -139,7 +220,7 @@ interfaces_interface_hash_element_t* interfaces_interface_hash_element_new(void) return NULL; // NULL all fields - new_element->interface = (interfaces_interfaces_interface_t) { 0 }; + new_element->interface = (interfaces_interface_t) { 0 }; return new_element; } @@ -196,25 +277,25 @@ int interfaces_interface_hash_element_set_enabled(interfaces_interface_hash_elem return 0; } -int interfaces_interface_hash_element_set_link_up_down_trap_enable(interfaces_interface_hash_element_t** el, interfaces_interfaces_interface_link_up_down_trap_enable_t link_up_down_trap_enable) +int interfaces_interface_hash_element_set_link_up_down_trap_enable(interfaces_interface_hash_element_t** el, interfaces_interface_link_up_down_trap_enable_t link_up_down_trap_enable) { (*el)->interface.link_up_down_trap_enable = link_up_down_trap_enable; return 0; } -int interfaces_interface_hash_element_set_carrier_delay(interfaces_interface_hash_element_t** el, interfaces_interfaces_interface_carrier_delay_t carrier_delay) +int interfaces_interface_hash_element_set_carrier_delay(interfaces_interface_hash_element_t** el, interfaces_interface_carrier_delay_t carrier_delay) { (*el)->interface.carrier_delay = carrier_delay; return 0; } -int interfaces_interface_hash_element_set_dampening(interfaces_interface_hash_element_t** el, interfaces_interfaces_interface_dampening_t dampening) +int interfaces_interface_hash_element_set_dampening(interfaces_interface_hash_element_t** el, interfaces_interface_dampening_t dampening) { (*el)->interface.dampening = dampening; return 0; } -int interfaces_interface_hash_element_set_encapsulation(interfaces_interface_hash_element_t** el, interfaces_interfaces_interface_encapsulation_t encapsulation) +int interfaces_interface_hash_element_set_encapsulation(interfaces_interface_hash_element_t** el, interfaces_interface_encapsulation_t encapsulation) { (*el)->interface.encapsulation = encapsulation; return 0; @@ -256,50 +337,58 @@ int interfaces_interface_hash_element_set_parent_interface(interfaces_interface_ return 0; } -int interfaces_interface_hash_element_set_ipv4(interfaces_interface_hash_element_t** el, interfaces_interfaces_interface_ipv4_t ipv4) +int interfaces_interface_hash_element_set_ipv4(interfaces_interface_hash_element_t** el, interfaces_interface_ipv4_t ipv4) { (*el)->interface.ipv4 = ipv4; return 0; } -int interfaces_interface_hash_element_set_ipv6(interfaces_interface_hash_element_t** el, interfaces_interfaces_interface_ipv6_t ipv6) +int interfaces_interface_hash_element_set_ipv4_enabled(interfaces_interface_hash_element_t** el, uint8_t enabled) { - (*el)->interface.ipv6 = ipv6; + (*el)->interface.ipv4.enabled = enabled; return 0; } -void interfaces_interface_hash_element_free(interfaces_interface_hash_element_t** el) +int interfaces_interface_hash_element_set_ipv4_forwarding(interfaces_interface_hash_element_t** el, uint8_t forwarding) { - if (*el) { - // name - if ((*el)->interface.name) { - free((*el)->interface.name); - } + (*el)->interface.ipv4.forwarding = forwarding; - // description - if ((*el)->interface.description) { - free((*el)->interface.description); - } + return 0; +} - // type - if ((*el)->interface.type) { - free((*el)->interface.type); - } +int interfaces_interface_hash_element_set_ipv4_mtu(interfaces_interface_hash_element_t** el, uint16_t mtu) +{ + (*el)->interface.ipv4.mtu = mtu; - // loopback - if ((*el)->interface.loopback) { - free((*el)->interface.loopback); - } + return 0; +} - // parent-interface - if ((*el)->interface.parent_interface) { - free((*el)->interface.parent_interface); - } +int interfaces_interface_hash_element_set_ipv6(interfaces_interface_hash_element_t** el, interfaces_interface_ipv6_t ipv6) +{ + (*el)->interface.ipv6 = ipv6; - // element data - free(*el); - *el = NULL; - } + return 0; +} + +int interfaces_interface_hash_element_set_ipv6_enabled(interfaces_interface_hash_element_t** el, uint8_t enabled) +{ + (*el)->interface.ipv6.enabled = enabled; + + return 0; +} + +int interfaces_interface_hash_element_set_ipv6_forwarding(interfaces_interface_hash_element_t** el, uint8_t forwarding) +{ + (*el)->interface.ipv6.forwarding = forwarding; + + return 0; } + +int interfaces_interface_hash_element_set_ipv6_mtu(interfaces_interface_hash_element_t** el, uint16_t mtu) +{ + (*el)->interface.ipv6.mtu = mtu; + + return 0; +} \ No newline at end of file diff --git a/src/interfaces/src/plugin/data/interfaces/interface/hash.h b/src/interfaces/src/plugin/data/interfaces/interface/hash.h index 0d6f3c5b..db0c86d7 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/hash.h +++ b/src/interfaces/src/plugin/data/interfaces/interface/hash.h @@ -21,19 +21,35 @@ void interfaces_interface_hash_free(interfaces_interface_hash_element_t** hash); */ interfaces_interface_hash_element_t* interfaces_interface_hash_element_new(void); +void interfaces_interface_hash_element_free(interfaces_interface_hash_element_t** el); int interfaces_interface_hash_element_set_name(interfaces_interface_hash_element_t** el, const char* name); int interfaces_interface_hash_element_set_description(interfaces_interface_hash_element_t** el, const char* description); int interfaces_interface_hash_element_set_type(interfaces_interface_hash_element_t** el, const char* type); int interfaces_interface_hash_element_set_enabled(interfaces_interface_hash_element_t** el, uint8_t enabled); -int interfaces_interface_hash_element_set_link_up_down_trap_enable(interfaces_interface_hash_element_t** el, interfaces_interfaces_interface_link_up_down_trap_enable_t link_up_down_trap_enable); -int interfaces_interface_hash_element_set_carrier_delay(interfaces_interface_hash_element_t** el, interfaces_interfaces_interface_carrier_delay_t carrier_delay); -int interfaces_interface_hash_element_set_dampening(interfaces_interface_hash_element_t** el, interfaces_interfaces_interface_dampening_t dampening); -int interfaces_interface_hash_element_set_encapsulation(interfaces_interface_hash_element_t** el, interfaces_interfaces_interface_encapsulation_t encapsulation); +int interfaces_interface_hash_element_set_link_up_down_trap_enable(interfaces_interface_hash_element_t** el, interfaces_interface_link_up_down_trap_enable_t link_up_down_trap_enable); +int interfaces_interface_hash_element_set_carrier_delay(interfaces_interface_hash_element_t** el, interfaces_interface_carrier_delay_t carrier_delay); +int interfaces_interface_hash_element_set_dampening(interfaces_interface_hash_element_t** el, interfaces_interface_dampening_t dampening); +int interfaces_interface_hash_element_set_encapsulation(interfaces_interface_hash_element_t** el, interfaces_interface_encapsulation_t encapsulation); int interfaces_interface_hash_element_set_loopback(interfaces_interface_hash_element_t** el, const char* loopback); int interfaces_interface_hash_element_set_max_frame_size(interfaces_interface_hash_element_t** el, uint32_t max_frame_size); int interfaces_interface_hash_element_set_parent_interface(interfaces_interface_hash_element_t** el, const char* parent_interface); -int interfaces_interface_hash_element_set_ipv4(interfaces_interface_hash_element_t** el, interfaces_interfaces_interface_ipv4_t ipv4); -int interfaces_interface_hash_element_set_ipv6(interfaces_interface_hash_element_t** el, interfaces_interfaces_interface_ipv6_t ipv6); -void interfaces_interface_hash_element_free(interfaces_interface_hash_element_t** el); + +/* + IPv4 +*/ + +int interfaces_interface_hash_element_set_ipv4(interfaces_interface_hash_element_t** el, interfaces_interface_ipv4_t ipv4); +int interfaces_interface_hash_element_set_ipv4_enabled(interfaces_interface_hash_element_t** el, uint8_t enabled); +int interfaces_interface_hash_element_set_ipv4_forwarding(interfaces_interface_hash_element_t** el, uint8_t forwarding); +int interfaces_interface_hash_element_set_ipv4_mtu(interfaces_interface_hash_element_t** el, uint16_t mtu); + +/* + IPv6 +*/ + +int interfaces_interface_hash_element_set_ipv6(interfaces_interface_hash_element_t** el, interfaces_interface_ipv6_t ipv6); +int interfaces_interface_hash_element_set_ipv6_enabled(interfaces_interface_hash_element_t** el, uint8_t enabled); +int interfaces_interface_hash_element_set_ipv6_forwarding(interfaces_interface_hash_element_t** el, uint8_t forwarding); +int interfaces_interface_hash_element_set_ipv6_mtu(interfaces_interface_hash_element_t** el, uint16_t mtu); #endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_HASH_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/types.h b/src/interfaces/src/plugin/types.h index 41434a1e..878fbabe 100644 --- a/src/interfaces/src/plugin/types.h +++ b/src/interfaces/src/plugin/types.h @@ -9,70 +9,70 @@ #include // typedefs -typedef struct interfaces_interfaces_interface_carrier_delay interfaces_interfaces_interface_carrier_delay_t; -typedef struct interfaces_interfaces_interface_dampening interfaces_interfaces_interface_dampening_t; -typedef struct interfaces_interfaces_interface_encapsulation_dot1q_vlan_outer_tag interfaces_interfaces_interface_encapsulation_dot1q_vlan_outer_tag_t; -typedef struct interfaces_interfaces_interface_encapsulation_dot1q_vlan_second_tag interfaces_interfaces_interface_encapsulation_dot1q_vlan_second_tag_t; -typedef struct interfaces_interfaces_interface_encapsulation_dot1q_vlan interfaces_interfaces_interface_encapsulation_dot1q_vlan_t; -typedef struct interfaces_interfaces_interface_encapsulation interfaces_interfaces_interface_encapsulation_t; -typedef struct interfaces_interfaces_interface_ipv4_address interfaces_interfaces_interface_ipv4_address_t; -typedef struct interfaces_interfaces_interface_ipv4_address_element interfaces_interfaces_interface_ipv4_address_element_t; -typedef struct interfaces_interfaces_interface_ipv4_neighbor interfaces_interfaces_interface_ipv4_neighbor_t; -typedef struct interfaces_interfaces_interface_ipv4_neighbor_element interfaces_interfaces_interface_ipv4_neighbor_element_t; -typedef struct interfaces_interfaces_interface_ipv4 interfaces_interfaces_interface_ipv4_t; -typedef struct interfaces_interfaces_interface_ipv6_address interfaces_interfaces_interface_ipv6_address_t; -typedef struct interfaces_interfaces_interface_ipv6_address_element interfaces_interfaces_interface_ipv6_address_element_t; -typedef struct interfaces_interfaces_interface_ipv6_neighbor interfaces_interfaces_interface_ipv6_neighbor_t; -typedef struct interfaces_interfaces_interface_ipv6_neighbor_element interfaces_interfaces_interface_ipv6_neighbor_element_t; -typedef struct interfaces_interfaces_interface_ipv6_autoconf interfaces_interfaces_interface_ipv6_autoconf_t; -typedef struct interfaces_interfaces_interface_ipv6 interfaces_interfaces_interface_ipv6_t; -typedef struct interfaces_interfaces_interface interfaces_interfaces_interface_t; -typedef struct interfaces_interfaces_interface_element interfaces_interfaces_interface_element_t; -typedef struct interfaces_interfaces interfaces_interfaces_t; +typedef struct interfaces_interface_carrier_delay interfaces_interface_carrier_delay_t; +typedef struct interfaces_interface_dampening interfaces_interface_dampening_t; +typedef struct interfaces_interface_encapsulation_dot1q_vlan_outer_tag interfaces_interface_encapsulation_dot1q_vlan_outer_tag_t; +typedef struct interfaces_interface_encapsulation_dot1q_vlan_second_tag interfaces_interface_encapsulation_dot1q_vlan_second_tag_t; +typedef struct interfaces_interface_encapsulation_dot1q_vlan interfaces_interface_encapsulation_dot1q_vlan_t; +typedef struct interfaces_interface_encapsulation interfaces_interface_encapsulation_t; +typedef struct interfaces_interface_ipv4_address interfaces_interface_ipv4_address_t; +typedef struct interfaces_interface_ipv4_address_element interfaces_interface_ipv4_address_element_t; +typedef struct interfaces_interface_ipv4_neighbor interfaces_interface_ipv4_neighbor_t; +typedef struct interfaces_interface_ipv4_neighbor_element interfaces_interface_ipv4_neighbor_element_t; +typedef struct interfaces_interface_ipv4 interfaces_interface_ipv4_t; +typedef struct interfaces_interface_ipv6_address interfaces_interface_ipv6_address_t; +typedef struct interfaces_interface_ipv6_address_element interfaces_interface_ipv6_address_element_t; +typedef struct interfaces_interface_ipv6_neighbor interfaces_interface_ipv6_neighbor_t; +typedef struct interfaces_interface_ipv6_neighbor_element interfaces_interface_ipv6_neighbor_element_t; +typedef struct interfaces_interface_ipv6_autoconf interfaces_interface_ipv6_autoconf_t; +typedef struct interfaces_interface_ipv6 interfaces_interface_ipv6_t; +typedef struct interfaces_interface interfaces_interface_t; +typedef struct interfaces_interface_element interfaces_interface_element_t; +typedef struct interfaces interfaces_t; typedef struct interface_ht_element interface_ht_element_t; typedef struct interfaces_interface_state interfaces_interface_state_t; typedef struct interfaces_interface_state_hash_element interfaces_interface_state_hash_element_t; typedef struct interfaces_interface_hash_element interfaces_interface_hash_element_t; -enum interfaces_interfaces_interface_link_up_down_trap_enable { - interfaces_interfaces_interface_link_up_down_trap_enable_disabled, - interfaces_interfaces_interface_link_up_down_trap_enable_enabled, +enum interfaces_interface_link_up_down_trap_enable { + interfaces_interface_link_up_down_trap_enable_disabled, + interfaces_interface_link_up_down_trap_enable_enabled, }; -typedef enum interfaces_interfaces_interface_link_up_down_trap_enable interfaces_interfaces_interface_link_up_down_trap_enable_t; +typedef enum interfaces_interface_link_up_down_trap_enable interfaces_interface_link_up_down_trap_enable_t; -struct interfaces_interfaces_interface_carrier_delay { +struct interfaces_interface_carrier_delay { uint32_t down; uint32_t up; }; -struct interfaces_interfaces_interface_dampening { +struct interfaces_interface_dampening { uint32_t half_life; uint32_t reuse; uint32_t suppress; uint32_t max_suppress_time; }; -struct interfaces_interfaces_interface_encapsulation_dot1q_vlan_outer_tag { +struct interfaces_interface_encapsulation_dot1q_vlan_outer_tag { char* tag_type; uint16_t vlan_id; }; -struct interfaces_interfaces_interface_encapsulation_dot1q_vlan_second_tag { +struct interfaces_interface_encapsulation_dot1q_vlan_second_tag { char* tag_type; uint16_t vlan_id; }; -struct interfaces_interfaces_interface_encapsulation_dot1q_vlan { - interfaces_interfaces_interface_encapsulation_dot1q_vlan_outer_tag_t outer_tag; - interfaces_interfaces_interface_encapsulation_dot1q_vlan_second_tag_t second_tag; +struct interfaces_interface_encapsulation_dot1q_vlan { + interfaces_interface_encapsulation_dot1q_vlan_outer_tag_t outer_tag; + interfaces_interface_encapsulation_dot1q_vlan_second_tag_t second_tag; }; -struct interfaces_interfaces_interface_encapsulation { - interfaces_interfaces_interface_encapsulation_dot1q_vlan_t dot1q_vlan; +struct interfaces_interface_encapsulation { + interfaces_interface_encapsulation_dot1q_vlan_t dot1q_vlan; }; -struct interfaces_interfaces_interface_ipv4_address { +struct interfaces_interface_ipv4_address { char* ip; union { uint8_t prefix_length; @@ -80,85 +80,85 @@ struct interfaces_interfaces_interface_ipv4_address { } subnet; }; -struct interfaces_interfaces_interface_ipv4_address_element { - interfaces_interfaces_interface_ipv4_address_element_t* next; - interfaces_interfaces_interface_ipv4_address_t address; +struct interfaces_interface_ipv4_address_element { + interfaces_interface_ipv4_address_element_t* next; + interfaces_interface_ipv4_address_t address; }; -struct interfaces_interfaces_interface_ipv4_neighbor { +struct interfaces_interface_ipv4_neighbor { char* ip; char* link_layer_address; }; -struct interfaces_interfaces_interface_ipv4_neighbor_element { - interfaces_interfaces_interface_ipv4_neighbor_element_t* next; - interfaces_interfaces_interface_ipv4_neighbor_t neighbor; +struct interfaces_interface_ipv4_neighbor_element { + interfaces_interface_ipv4_neighbor_element_t* next; + interfaces_interface_ipv4_neighbor_t neighbor; }; -struct interfaces_interfaces_interface_ipv4 { +struct interfaces_interface_ipv4 { uint8_t enabled; uint8_t forwarding; uint16_t mtu; - interfaces_interfaces_interface_ipv4_address_element_t* address; - interfaces_interfaces_interface_ipv4_neighbor_element_t* neighbor; + interfaces_interface_ipv4_address_element_t* address; + interfaces_interface_ipv4_neighbor_element_t* neighbor; }; -struct interfaces_interfaces_interface_ipv6_address { +struct interfaces_interface_ipv6_address { char* ip; uint8_t prefix_length; }; -struct interfaces_interfaces_interface_ipv6_address_element { - interfaces_interfaces_interface_ipv6_address_element_t* next; - interfaces_interfaces_interface_ipv6_address_t address; +struct interfaces_interface_ipv6_address_element { + interfaces_interface_ipv6_address_element_t* next; + interfaces_interface_ipv6_address_t address; }; -struct interfaces_interfaces_interface_ipv6_neighbor { +struct interfaces_interface_ipv6_neighbor { char* ip; char* link_layer_address; }; -struct interfaces_interfaces_interface_ipv6_neighbor_element { - interfaces_interfaces_interface_ipv6_neighbor_element_t* next; - interfaces_interfaces_interface_ipv6_neighbor_t neighbor; +struct interfaces_interface_ipv6_neighbor_element { + interfaces_interface_ipv6_neighbor_element_t* next; + interfaces_interface_ipv6_neighbor_t neighbor; }; -struct interfaces_interfaces_interface_ipv6_autoconf { +struct interfaces_interface_ipv6_autoconf { uint8_t create_global_addresses; uint8_t create_temporary_addresses; uint32_t temporary_valid_lifetime; uint32_t temporary_preferred_lifetime; }; -struct interfaces_interfaces_interface_ipv6 { +struct interfaces_interface_ipv6 { uint8_t enabled; uint8_t forwarding; uint32_t mtu; - interfaces_interfaces_interface_ipv6_address_element_t* address; - interfaces_interfaces_interface_ipv6_neighbor_element_t* neighbor; + interfaces_interface_ipv6_address_element_t* address; + interfaces_interface_ipv6_neighbor_element_t* neighbor; uint32_t dup_addr_detect_transmits; - interfaces_interfaces_interface_ipv6_autoconf_t autoconf; + interfaces_interface_ipv6_autoconf_t autoconf; }; -struct interfaces_interfaces_interface { +struct interfaces_interface { char* name; char* description; char* type; uint8_t enabled; - interfaces_interfaces_interface_link_up_down_trap_enable_t link_up_down_trap_enable; - interfaces_interfaces_interface_carrier_delay_t carrier_delay; - interfaces_interfaces_interface_dampening_t dampening; - interfaces_interfaces_interface_encapsulation_t encapsulation; + interfaces_interface_link_up_down_trap_enable_t link_up_down_trap_enable; + interfaces_interface_carrier_delay_t carrier_delay; + interfaces_interface_dampening_t dampening; + interfaces_interface_encapsulation_t encapsulation; char* loopback; uint32_t max_frame_size; char* parent_interface; - interfaces_interfaces_interface_ipv4_t ipv4; - interfaces_interfaces_interface_ipv6_t ipv6; + interfaces_interface_ipv4_t ipv4; + interfaces_interface_ipv6_t ipv6; }; -struct interfaces_interfaces_interface_element { - interfaces_interfaces_interface_element_t* next; - interfaces_interfaces_interface_t interface; +struct interfaces_interface_element { + interfaces_interface_element_t* next; + interfaces_interface_t interface; }; /* @@ -166,13 +166,13 @@ struct interfaces_interfaces_interface_element { * - used due to interface name indexing */ struct interface_ht_element { - interfaces_interfaces_interface_t interface; + interfaces_interface_t interface; /* makes the structure hashable */ UT_hash_handle hh; }; -struct interfaces_interfaces { - interfaces_interfaces_interface_element_t* interface; +struct interfaces { + interfaces_interface_element_t* interface; }; struct interfaces_interface_state { @@ -187,7 +187,7 @@ struct interfaces_interface_state_hash_element { }; struct interfaces_interface_hash_element { - interfaces_interfaces_interface_t interface; + interfaces_interface_t interface; UT_hash_handle hh; }; From aea52d40c7b814dd93c6536fbb3f87376794c47d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 26 Sep 2022 12:33:08 +0200 Subject: [PATCH 121/247] interfaces-plugin: add subnet type enum --- src/interfaces/src/plugin/types.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/interfaces/src/plugin/types.h b/src/interfaces/src/plugin/types.h index 878fbabe..5b7492b5 100644 --- a/src/interfaces/src/plugin/types.h +++ b/src/interfaces/src/plugin/types.h @@ -72,12 +72,21 @@ struct interfaces_interface_encapsulation { interfaces_interface_encapsulation_dot1q_vlan_t dot1q_vlan; }; +enum interfaces_interface_ipv4_address_subnet { + interfaces_interface_ipv4_address_subnet_none = 0, + interfaces_interface_ipv4_address_subnet_prefix_length, + interfaces_interface_ipv4_address_subnet_netmask, +}; + +typedef enum interfaces_interface_ipv4_address_subnet interfaces_interface_ipv4_address_subnet_t; + struct interfaces_interface_ipv4_address { char* ip; union { uint8_t prefix_length; char* netmask; } subnet; + interfaces_interface_ipv4_address_subnet_t subnet_type; }; struct interfaces_interface_ipv4_address_element { From 7833697163fb529053b08d6f547f9684c47c2409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 26 Sep 2022 15:12:10 +0200 Subject: [PATCH 122/247] interfaces-plugin: reorganize interfaces module and state hash API implementations --- src/interfaces/CMakeLists.txt | 4 +- src/interfaces/src/plugin.c | 2 +- .../src/plugin/api/interfaces/load.h | 6 +- src/interfaces/src/plugin/data/interface.c | 201 ------------------ src/interfaces/src/plugin/data/interface.h | 32 --- .../{interface/hash.c => interface.c} | 4 +- .../{interface/hash.h => interface.h} | 7 +- .../state_hash.c => interface_state.c} | 2 +- .../state_hash.h => interface_state.h} | 0 src/interfaces/src/plugin/startup/store.c | 2 +- .../src/plugin/subscription/operational.c | 2 +- 11 files changed, 14 insertions(+), 248 deletions(-) delete mode 100644 src/interfaces/src/plugin/data/interface.c delete mode 100644 src/interfaces/src/plugin/data/interface.h rename src/interfaces/src/plugin/data/interfaces/{interface/hash.c => interface.c} (99%) rename src/interfaces/src/plugin/data/interfaces/{interface/hash.h => interface.h} (94%) rename src/interfaces/src/plugin/data/interfaces/{interface/state_hash.c => interface_state.c} (98%) rename src/interfaces/src/plugin/data/interfaces/{interface/state_hash.h => interface_state.h} (100%) diff --git a/src/interfaces/CMakeLists.txt b/src/interfaces/CMakeLists.txt index 89b45a76..1db53f1c 100644 --- a/src/interfaces/CMakeLists.txt +++ b/src/interfaces/CMakeLists.txt @@ -45,8 +45,8 @@ set( src/plugin/api/interfaces/interface/carrier-delay/change.c # data - src/plugin/data/interfaces/interface/state_hash.c - src/plugin/data/interfaces/interface/hash.c + src/plugin/data/interfaces/interface.c + src/plugin/data/interfaces/interface_state.c src/plugin/data/interfaces/interface/ipv4/linked_list.c src/plugin/data/interfaces/interface/ipv6/linked_list.c diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index 5431eee0..b62da816 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -6,7 +6,7 @@ #include "plugin/context.h" // startup -#include "plugin/data/interfaces/interface/state_hash.h" +#include "plugin/data/interfaces/interface_state.h" #include "plugin/startup/load.h" #include "plugin/startup/store.h" diff --git a/src/interfaces/src/plugin/api/interfaces/load.h b/src/interfaces/src/plugin/api/interfaces/load.h index 8eef49c8..158f3874 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.h +++ b/src/interfaces/src/plugin/api/interfaces/load.h @@ -1,10 +1,10 @@ #ifndef INTERFACES_PLUGIN_API_INTERFACES_LOAD_H #define INTERFACES_PLUGIN_API_INTERFACES_LOAD_H -#include "plugin/data/interfaces/interface/hash.h" -#include "plugin/data/interfaces/interface/linked_list.h" #include "plugin/context.h" +#include "plugin/data/interfaces/interface.h" +#include "plugin/data/interfaces/interface/linked_list.h" -int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t **if_hash); +int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** if_hash); #endif // INTERFACES_PLUGIN_API_INTERFACES_LOAD_H diff --git a/src/interfaces/src/plugin/data/interface.c b/src/interfaces/src/plugin/data/interface.c deleted file mode 100644 index b3c86b36..00000000 --- a/src/interfaces/src/plugin/data/interface.c +++ /dev/null @@ -1,201 +0,0 @@ -#include "interface.h" -#include "plugin/common.h" -#include "utils/memory.h" - -#include - -void interfaces_data_ht_root_init(interface_ht_element_t** if_root) -{ - /* uthash root node has to be initialized to NULL */ - *if_root = NULL; -} - -static void -interfaces_data_init(interfaces_interface_t* interface) -{ - /* TODO: init all struct members */ - interface->name = NULL; - interface->description = NULL; - interface->type = NULL; - interface->enabled = 0; - interface->loopback = NULL; - interface->parent_interface = NULL; -} - -interface_ht_element_t* -interfaces_data_ht_get_by_name(interface_ht_element_t* if_root, char* name) -{ - interface_ht_element_t* elem = NULL; - HASH_FIND_STR(if_root, name, elem); - return elem; -} - -void interfaces_data_ht_set_name(interfaces_interface_t* interface, char* name) -{ - interface->name = xstrdup(name); -} - -int interfaces_data_ht_add(interface_ht_element_t* if_root, char* name) -{ - interface_ht_element_t *tmp = NULL, *elem = NULL; - int rc = 0; - - HASH_FIND_STR(if_root, name, tmp); - if (tmp != NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "interface with name key: %s already exists in hash table", name); - goto error_out; - } - - elem = (interface_ht_element_t*)xmalloc(sizeof elem); - interfaces_data_init(&elem->interface); - interfaces_data_ht_set_name(&elem->interface, name); - - /* since name is char *, *_KEYPTR has to be used instead of *_STR */ - HASH_ADD_KEYPTR(hh, if_root, elem->interface.name, sizeof(elem->interface.name), elem); - - goto out; -error_out: - rc = -1; -out: - return rc; -} - -int interfaces_data_ht_set_description(interface_ht_element_t* if_root, char* name, char* description) -{ - interface_ht_element_t* elem = NULL; - int rc = 0; - - elem = interfaces_data_ht_get_by_name(if_root, name); - if (elem == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "interface with name key: %s non-existant in hash table", name); - goto error_out; - } - - if (elem->interface.description != NULL) { - FREE_SAFE(elem->interface.description); - } - elem->interface.description = xstrdup(description); - if (elem->interface.description == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "couldn't copy description: %s", description); - goto error_out; - } - - goto out; -error_out: - rc = -1; -out: - return rc; -} - -int interfaces_data_ht_set_type(interface_ht_element_t* if_root, char* name, char* type) -{ - interface_ht_element_t* elem = NULL; - int rc = 0; - - elem = interfaces_data_ht_get_by_name(if_root, name); - if (elem == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "interface with name key: %s non-existant in hash table", name); - goto error_out; - } - - if (elem->interface.type != NULL) { - FREE_SAFE(elem->interface.type); - } - elem->interface.type = xstrdup(type); - if (elem->interface.type == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "couldn't copy type: %s", type); - goto error_out; - } - - goto out; -error_out: - rc = -1; -out: - return rc; -} - -int interfaces_data_ht_set_loopback(interface_ht_element_t* if_root, char* name, char* loopback) -{ - interface_ht_element_t* elem = NULL; - int rc = 0; - - elem = interfaces_data_ht_get_by_name(if_root, name); - if (elem == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "interface with name key: %s non-existant in hash table", name); - goto error_out; - } - - if (elem->interface.loopback != NULL) { - FREE_SAFE(elem->interface.loopback); - } - elem->interface.loopback = xstrdup(loopback); - if (elem->interface.loopback == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "couldn't copy loopback: %s", loopback); - goto error_out; - } - - goto out; -error_out: - rc = -1; -out: - return rc; -} - -int interfaces_data_ht_set_parent_interface(interface_ht_element_t* if_root, char* name, char* parent_interface) -{ - interface_ht_element_t* elem = NULL; - int rc = 0; - - elem = interfaces_data_ht_get_by_name(if_root, name); - if (elem == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "interface with name key: %s non-existant in hash table", name); - goto error_out; - } - - if (elem->interface.parent_interface != NULL) { - FREE_SAFE(elem->interface.parent_interface); - } - elem->interface.parent_interface = xstrdup(parent_interface); - if (elem->interface.parent_interface == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "couldn't copy parent interface: %s", parent_interface); - goto error_out; - } - - goto out; -error_out: - rc = -1; -out: - return rc; -} - -void interfaces_data_ht_if_free(interfaces_interface_t* interface) -{ - /* TODO: free other struct members as needed */ - if (interface->name) { - FREE_SAFE(interface->name); - } - if (interface->description) { - FREE_SAFE(interface->description); - } - if (interface->type) { - FREE_SAFE(interface->type); - } - if (interface->loopback) { - FREE_SAFE(interface->loopback); - } - if (interface->parent_interface) { - FREE_SAFE(interface->parent_interface); - } -} - -void interfaces_data_ht_free(interface_ht_element_t* if_root) -{ - interface_ht_element_t *tmp = NULL, *elem = NULL; - - HASH_ITER(hh, if_root, elem, tmp) - { - HASH_DEL(if_root, elem); - interfaces_data_ht_if_free(&elem->interface); - FREE_SAFE(elem); - } -} diff --git a/src/interfaces/src/plugin/data/interface.h b/src/interfaces/src/plugin/data/interface.h deleted file mode 100644 index 03d9f753..00000000 --- a/src/interfaces/src/plugin/data/interface.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef IF_DATA_H -#define IF_DATA_H - -#include - -#include "plugin/types.h" - -void interfaces_data_ht_root_init(interface_ht_element_t** if_root); - -static void -interfaces_data_init(interfaces_interface_t* interface); - -interface_ht_element_t* -interfaces_data_ht_get_by_name(interface_ht_element_t* if_root, char* name); - -void interfaces_data_ht_set_name(interfaces_interface_t* interface, char* name); - -int interfaces_data_ht_add(interface_ht_element_t* if_root, char* name); - -int interfaces_data_ht_set_description(interface_ht_element_t* if_root, char* name, char* description); - -int interfaces_data_ht_set_type(interface_ht_element_t* if_root, char* name, char* type); - -int interfaces_data_ht_set_loopback(interface_ht_element_t* if_root, char* name, char* loopback); - -int interfaces_data_ht_set_parent_interface(interface_ht_element_t* if_root, char* name, char* parent_interface); - -void interfaces_data_ht_if_free(interfaces_interface_t* interface); - -void interfaces_data_ht_free(interface_ht_element_t* if_root); - -#endif /* IF_DATA_H */ diff --git a/src/interfaces/src/plugin/data/interfaces/interface/hash.c b/src/interfaces/src/plugin/data/interfaces/interface.c similarity index 99% rename from src/interfaces/src/plugin/data/interfaces/interface/hash.c rename to src/interfaces/src/plugin/data/interfaces/interface.c index fabf6a99..0f61f87a 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/hash.c +++ b/src/interfaces/src/plugin/data/interfaces/interface.c @@ -1,10 +1,10 @@ -#include "hash.h" -#include "utils/memory.h" +#include "interface.h" #include "libyang/tree_data.h" #include "plugin/common.h" #include "srpc/ly_tree.h" #include "sysrepo.h" #include "uthash.h" +#include "utils/memory.h" #include "utlist.h" #include diff --git a/src/interfaces/src/plugin/data/interfaces/interface/hash.h b/src/interfaces/src/plugin/data/interfaces/interface.h similarity index 94% rename from src/interfaces/src/plugin/data/interfaces/interface/hash.h rename to src/interfaces/src/plugin/data/interfaces/interface.h index db0c86d7..4b0147be 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/hash.h +++ b/src/interfaces/src/plugin/data/interfaces/interface.h @@ -1,8 +1,7 @@ -#ifndef INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_HASH_H -#define INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_HASH_H +#ifndef INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_H +#define INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_H #include "plugin/types.h" - #include /* @@ -52,4 +51,4 @@ int interfaces_interface_hash_element_set_ipv6_enabled(interfaces_interface_hash int interfaces_interface_hash_element_set_ipv6_forwarding(interfaces_interface_hash_element_t** el, uint8_t forwarding); int interfaces_interface_hash_element_set_ipv6_mtu(interfaces_interface_hash_element_t** el, uint16_t mtu); -#endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_HASH_H \ No newline at end of file +#endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_H diff --git a/src/interfaces/src/plugin/data/interfaces/interface/state_hash.c b/src/interfaces/src/plugin/data/interfaces/interface_state.c similarity index 98% rename from src/interfaces/src/plugin/data/interfaces/interface/state_hash.c rename to src/interfaces/src/plugin/data/interfaces/interface_state.c index e70b5d19..cfacc597 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/state_hash.c +++ b/src/interfaces/src/plugin/data/interfaces/interface_state.c @@ -1,4 +1,4 @@ -#include "state_hash.h" +#include "interface_state.h" #include "src/uthash.h" interfaces_interface_state_hash_element_t* interfaces_interface_state_hash_new(void) diff --git a/src/interfaces/src/plugin/data/interfaces/interface/state_hash.h b/src/interfaces/src/plugin/data/interfaces/interface_state.h similarity index 100% rename from src/interfaces/src/plugin/data/interfaces/interface/state_hash.h rename to src/interfaces/src/plugin/data/interfaces/interface_state.h diff --git a/src/interfaces/src/plugin/startup/store.c b/src/interfaces/src/plugin/startup/store.c index c47185b8..b774ad1b 100644 --- a/src/interfaces/src/plugin/startup/store.c +++ b/src/interfaces/src/plugin/startup/store.c @@ -3,7 +3,7 @@ #include "plugin/api/interfaces/check.h" #include "plugin/api/interfaces/store.h" -#include "plugin/data/interfaces/interface/hash.h" +#include "plugin/data/interfaces/interface.h" #include "srpc/ly_tree.h" #include diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 844a932d..9b76027e 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -8,7 +8,7 @@ #include "netlink/socket.h" #include "plugin/common.h" #include "plugin/context.h" -#include "plugin/data/interfaces/interface/state_hash.h" +#include "plugin/data/interfaces/interface_state.h" #include "plugin/ly_tree.h" #include "plugin/types.h" #include "srpc/common.h" From 4cdbfcb4dcb626677a947add95d5252bc5266f06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 26 Sep 2022 15:58:12 +0200 Subject: [PATCH 123/247] interfaces-plugin: split IPv4 linked list implementations to address and neighbor files --- src/interfaces/CMakeLists.txt | 3 +- .../data/interfaces/interface/ipv4/address.c | 105 ++++++++++++++++++ .../data/interfaces/interface/ipv4/address.h | 27 +++++ .../data/interfaces/interface/ipv4/neighbor.c | 82 ++++++++++++++ .../data/interfaces/interface/ipv4/neighbor.h | 26 +++++ 5 files changed, 242 insertions(+), 1 deletion(-) create mode 100644 src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c create mode 100644 src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.h create mode 100644 src/interfaces/src/plugin/data/interfaces/interface/ipv4/neighbor.c create mode 100644 src/interfaces/src/plugin/data/interfaces/interface/ipv4/neighbor.h diff --git a/src/interfaces/CMakeLists.txt b/src/interfaces/CMakeLists.txt index 1db53f1c..79309416 100644 --- a/src/interfaces/CMakeLists.txt +++ b/src/interfaces/CMakeLists.txt @@ -47,7 +47,8 @@ set( # data src/plugin/data/interfaces/interface.c src/plugin/data/interfaces/interface_state.c - src/plugin/data/interfaces/interface/ipv4/linked_list.c + src/plugin/data/interfaces/interface/ipv4/address.c + src/plugin/data/interfaces/interface/ipv4/neighbor.c src/plugin/data/interfaces/interface/ipv6/linked_list.c # main files diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c new file mode 100644 index 00000000..82a1b0f7 --- /dev/null +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c @@ -0,0 +1,105 @@ +#include "address.h" +#include "plugin/types.h" +#include "src/utlist.h" +#include + +interfaces_interface_ipv4_address_element_t* interfaces_interface_ipv4_address_new(void) +{ + return NULL; +} + +int interfaces_interface_ipv4_address_add_element(interfaces_interface_ipv4_address_element_t** address, interfaces_interface_ipv4_address_element_t* new_element) +{ + LL_PREPEND(*address, new_element); + return 0; +} + +void interfaces_interface_ipv4_address_free(interfaces_interface_ipv4_address_element_t** address) +{ + interfaces_interface_ipv4_address_element_t *iter = NULL, *tmp = NULL; + + LL_FOREACH_SAFE(*address, iter, tmp) + { + // remove from list + LL_DELETE(*address, iter); + + // free element data + interfaces_interface_ipv4_address_element_free(&iter); + } +} + +interfaces_interface_ipv4_address_element_t* interfaces_interface_ipv4_address_element_new(void) +{ + interfaces_interface_ipv4_address_element_t* new_element = NULL; + + new_element = malloc(sizeof(interfaces_interface_ipv4_address_element_t)); + new_element->address = (interfaces_interface_ipv4_address_t) { 0 }; + + return new_element; +} + +void interfaces_interface_ipv4_address_element_free(interfaces_interface_ipv4_address_element_t** el) +{ + if (*el) { + // IP + if ((*el)->address.ip) { + free((*el)->address.ip); + } + + // netmask if one exists + if ((*el)->address.subnet_type != interfaces_interface_ipv4_address_subnet_none) { + if ((*el)->address.subnet_type == interfaces_interface_ipv4_address_subnet_netmask && (*el)->address.subnet.netmask != NULL) { + free((*el)->address.subnet.netmask); + } + } + + // address data + free(*el); + *el = NULL; + } +} + +int interfaces_interface_ipv4_address_element_set_ip(interfaces_interface_ipv4_address_element_t** el, const char* ip) +{ + if ((*el)->address.ip) { + free((*el)->address.ip); + } + + if (ip) { + (*el)->address.ip = strdup(ip); + return (*el)->address.ip == NULL; + } + + return 0; +} + +int interfaces_interface_ipv4_address_element_set_prefix_length(interfaces_interface_ipv4_address_element_t** el, uint8_t prefix_length) +{ + (*el)->address.subnet.prefix_length = prefix_length; + (*el)->address.subnet_type = interfaces_interface_ipv4_address_subnet_prefix_length; + + return 0; +} + +int interfaces_interface_ipv4_address_element_set_netmask(interfaces_interface_ipv4_address_element_t** el, const char* netmask) +{ + if ((*el)->address.subnet.netmask) { + free((*el)->address.subnet.netmask); + (*el)->address.subnet_type = interfaces_interface_ipv4_address_subnet_none; + } + + if (netmask) { + (*el)->address.subnet.netmask = strdup(netmask); + + // check for correctly set netmask + if ((*el)->address.subnet.netmask != NULL) { + (*el)->address.subnet_type = interfaces_interface_ipv4_address_subnet_netmask; + return 0; + } else { + (*el)->address.subnet_type = interfaces_interface_ipv4_address_subnet_none; + return 1; + } + } + + return 0; +} diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.h b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.h new file mode 100644 index 00000000..820c1fc4 --- /dev/null +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.h @@ -0,0 +1,27 @@ +#ifndef INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV4_ADDRESS_H +#define INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV4_ADDRESS_H + +#include "plugin/types.h" + +#include +#include + +/* + Linked list operations. +*/ + +interfaces_interface_ipv4_address_element_t* interfaces_interface_ipv4_address_new(void); +int interfaces_interface_ipv4_address_add_element(interfaces_interface_ipv4_address_element_t** address, interfaces_interface_ipv4_address_element_t* new_element); +void interfaces_interface_ipv4_address_free(interfaces_interface_ipv4_address_element_t** address); + +/* + Element operations. +*/ + +interfaces_interface_ipv4_address_element_t* interfaces_interface_ipv4_address_element_new(void); +void interfaces_interface_ipv4_address_element_free(interfaces_interface_ipv4_address_element_t** el); +int interfaces_interface_ipv4_address_element_set_ip(interfaces_interface_ipv4_address_element_t** el, const char* ip); +int interfaces_interface_ipv4_address_element_set_prefix_length(interfaces_interface_ipv4_address_element_t** el, uint8_t prefix_length); +int interfaces_interface_ipv4_address_element_set_netmask(interfaces_interface_ipv4_address_element_t** el, const char* netmask); + +#endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV4_ADDRESS_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/neighbor.c b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/neighbor.c new file mode 100644 index 00000000..3522207e --- /dev/null +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/neighbor.c @@ -0,0 +1,82 @@ +#include "neighbor.h" +#include "src/utlist.h" + +interfaces_interface_ipv4_neighbor_element_t* interfaces_interface_ipv4_neighbor_new(void) +{ + return NULL; +} + +int interfaces_interface_ipv4_neighbor_add_element(interfaces_interface_ipv4_neighbor_element_t** address, interfaces_interface_ipv4_neighbor_element_t* new_element) +{ + LL_PREPEND(*address, new_element); + return 0; +} + +void interfaces_interface_ipv4_neighbor_free(interfaces_interface_ipv4_neighbor_element_t** address) +{ + interfaces_interface_ipv4_neighbor_element_t *iter = NULL, *tmp = NULL; + + LL_FOREACH_SAFE(*address, iter, tmp) + { + // remove from list + LL_DELETE(*address, iter); + + // free element data + interfaces_interface_ipv4_neighbor_element_free(&iter); + } +} + +interfaces_interface_ipv4_neighbor_element_t* interfaces_interface_ipv4_neighbor_element_new(void) +{ + interfaces_interface_ipv4_neighbor_element_t* new_element = NULL; + + new_element = malloc(sizeof(interfaces_interface_ipv4_neighbor_element_t)); + new_element->neighbor = (interfaces_interface_ipv4_neighbor_t) { 0 }; + + return new_element; +} + +void interfaces_interface_ipv4_neighbor_element_free(interfaces_interface_ipv4_neighbor_element_t** el) +{ + if (*el) { + if ((*el)->neighbor.ip) { + free((*el)->neighbor.ip); + } + + if ((*el)->neighbor.link_layer_address) { + free((*el)->neighbor.link_layer_address); + } + + // address data + free(*el); + *el = NULL; + } +} + +int interfaces_interface_ipv4_neighbor_element_set_ip(interfaces_interface_ipv4_neighbor_element_t** el, const char* ip) +{ + if ((*el)->neighbor.ip) { + free((*el)->neighbor.ip); + } + + if (ip) { + (*el)->neighbor.ip = strdup(ip); + return (*el)->neighbor.ip == NULL; + } + + return 0; +} + +int interfaces_interface_ipv4_neighbor_element_set_link_layer_address(interfaces_interface_ipv4_neighbor_element_t** el, const char* link_layer_address) +{ + if ((*el)->neighbor.link_layer_address) { + free((*el)->neighbor.link_layer_address); + } + + if (link_layer_address) { + (*el)->neighbor.link_layer_address = strdup(link_layer_address); + return (*el)->neighbor.link_layer_address == NULL; + } + + return 0; +} diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/neighbor.h b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/neighbor.h new file mode 100644 index 00000000..17c5045e --- /dev/null +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/neighbor.h @@ -0,0 +1,26 @@ +#ifndef INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV4_NEIGHBOR_H +#define INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV4_NEIGHBOR_H + +#include "plugin/types.h" + +#include +#include + +/* + Linked list operations. +*/ + +interfaces_interface_ipv4_neighbor_element_t* interfaces_interface_ipv4_neighbor_new(void); +int interfaces_interface_ipv4_neighbor_add_element(interfaces_interface_ipv4_neighbor_element_t** address, interfaces_interface_ipv4_neighbor_element_t* new_element); +void interfaces_interface_ipv4_neighbor_free(interfaces_interface_ipv4_neighbor_element_t** address); + +/* + Element operations. +*/ + +interfaces_interface_ipv4_neighbor_element_t* interfaces_interface_ipv4_neighbor_element_new(void); +void interfaces_interface_ipv4_neighbor_element_free(interfaces_interface_ipv4_neighbor_element_t** el); +int interfaces_interface_ipv4_neighbor_element_set_ip(interfaces_interface_ipv4_neighbor_element_t** el, const char* ip); +int interfaces_interface_ipv4_neighbor_element_set_link_layer_address(interfaces_interface_ipv4_neighbor_element_t** el, const char* link_layer_address); + +#endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV4_NEIGHBOR_H \ No newline at end of file From c6daff42c41bf31a436d79e18cd23cc1884669a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 26 Sep 2022 16:02:30 +0200 Subject: [PATCH 124/247] interfaces-plugin: split IPv6 linked list implementations to address and neighbor files --- src/interfaces/CMakeLists.txt | 3 +- .../data/interfaces/interface/ipv6/address.c | 74 +++++++++++++++++ .../data/interfaces/interface/ipv6/address.h | 26 ++++++ .../data/interfaces/interface/ipv6/neighbor.c | 82 +++++++++++++++++++ .../data/interfaces/interface/ipv6/neighbor.h | 26 ++++++ 5 files changed, 210 insertions(+), 1 deletion(-) create mode 100644 src/interfaces/src/plugin/data/interfaces/interface/ipv6/address.c create mode 100644 src/interfaces/src/plugin/data/interfaces/interface/ipv6/address.h create mode 100644 src/interfaces/src/plugin/data/interfaces/interface/ipv6/neighbor.c create mode 100644 src/interfaces/src/plugin/data/interfaces/interface/ipv6/neighbor.h diff --git a/src/interfaces/CMakeLists.txt b/src/interfaces/CMakeLists.txt index 79309416..a63db8c7 100644 --- a/src/interfaces/CMakeLists.txt +++ b/src/interfaces/CMakeLists.txt @@ -49,7 +49,8 @@ set( src/plugin/data/interfaces/interface_state.c src/plugin/data/interfaces/interface/ipv4/address.c src/plugin/data/interfaces/interface/ipv4/neighbor.c - src/plugin/data/interfaces/interface/ipv6/linked_list.c + src/plugin/data/interfaces/interface/ipv6/address.c + src/plugin/data/interfaces/interface/ipv6/neighbor.c # main files src/plugin.c diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv6/address.c b/src/interfaces/src/plugin/data/interfaces/interface/ipv6/address.c new file mode 100644 index 00000000..956d586e --- /dev/null +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv6/address.c @@ -0,0 +1,74 @@ +#include "address.h" +#include "plugin/types.h" +#include "src/utlist.h" +#include + +interfaces_interface_ipv6_address_element_t* interfaces_interface_ipv6_address_new(void) +{ + return NULL; +} + +int interfaces_interface_ipv6_address_add_element(interfaces_interface_ipv6_address_element_t** address, interfaces_interface_ipv6_address_element_t* new_element) +{ + LL_PREPEND(*address, new_element); + return 0; +} + +void interfaces_interface_ipv6_address_free(interfaces_interface_ipv6_address_element_t** address) +{ + interfaces_interface_ipv6_address_element_t *iter = NULL, *tmp = NULL; + + LL_FOREACH_SAFE(*address, iter, tmp) + { + // remove from list + LL_DELETE(*address, iter); + + // free element data + interfaces_interface_ipv6_address_element_free(&iter); + } +} + +interfaces_interface_ipv6_address_element_t* interfaces_interface_ipv6_address_element_new(void) +{ + interfaces_interface_ipv6_address_element_t* new_element = NULL; + + new_element = malloc(sizeof(interfaces_interface_ipv6_address_element_t)); + new_element->address = (interfaces_interface_ipv6_address_t) { 0 }; + + return new_element; +} + +void interfaces_interface_ipv6_address_element_free(interfaces_interface_ipv6_address_element_t** el) +{ + if (*el) { + // IP + if ((*el)->address.ip) { + free((*el)->address.ip); + } + + // address data + free(*el); + *el = NULL; + } +} + +int interfaces_interface_ipv6_address_element_set_ip(interfaces_interface_ipv6_address_element_t** el, const char* ip) +{ + if ((*el)->address.ip) { + free((*el)->address.ip); + } + + if (ip) { + (*el)->address.ip = strdup(ip); + return (*el)->address.ip == NULL; + } + + return 0; +} + +int interfaces_interface_ipv6_address_element_set_prefix_length(interfaces_interface_ipv6_address_element_t** el, uint8_t prefix_length) +{ + (*el)->address.prefix_length = prefix_length; + + return 0; +} diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv6/address.h b/src/interfaces/src/plugin/data/interfaces/interface/ipv6/address.h new file mode 100644 index 00000000..7e38aa08 --- /dev/null +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv6/address.h @@ -0,0 +1,26 @@ +#ifndef INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV6_ADDRESS_H +#define INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV6_ADDRESS_H + +#include "plugin/types.h" + +#include +#include + +/* + Linked list operations. +*/ + +interfaces_interface_ipv6_address_element_t* interfaces_interface_ipv6_address_new(void); +int interfaces_interface_ipv6_address_add_element(interfaces_interface_ipv6_address_element_t** address, interfaces_interface_ipv6_address_element_t* new_element); +void interfaces_interface_ipv6_address_free(interfaces_interface_ipv6_address_element_t** address); + +/* + Element operations. +*/ + +interfaces_interface_ipv6_address_element_t* interfaces_interface_ipv6_address_element_new(void); +void interfaces_interface_ipv6_address_element_free(interfaces_interface_ipv6_address_element_t** el); +int interfaces_interface_ipv6_address_element_set_ip(interfaces_interface_ipv6_address_element_t** el, const char* ip); +int interfaces_interface_ipv6_address_element_set_prefix_length(interfaces_interface_ipv6_address_element_t** el, uint8_t prefix_length); + +#endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV6_ADDRESS_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv6/neighbor.c b/src/interfaces/src/plugin/data/interfaces/interface/ipv6/neighbor.c new file mode 100644 index 00000000..0b672390 --- /dev/null +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv6/neighbor.c @@ -0,0 +1,82 @@ +#include "neighbor.h" +#include "src/utlist.h" + +interfaces_interface_ipv6_neighbor_element_t* interfaces_interface_ipv6_neighbor_new(void) +{ + return NULL; +} + +int interfaces_interface_ipv6_neighbor_add_element(interfaces_interface_ipv6_neighbor_element_t** address, interfaces_interface_ipv6_neighbor_element_t* new_element) +{ + LL_PREPEND(*address, new_element); + return 0; +} + +void interfaces_interface_ipv6_neighbor_free(interfaces_interface_ipv6_neighbor_element_t** address) +{ + interfaces_interface_ipv6_neighbor_element_t *iter = NULL, *tmp = NULL; + + LL_FOREACH_SAFE(*address, iter, tmp) + { + // remove from list + LL_DELETE(*address, iter); + + // free element data + interfaces_interface_ipv6_neighbor_element_free(&iter); + } +} + +interfaces_interface_ipv6_neighbor_element_t* interfaces_interface_ipv6_neighbor_element_new(void) +{ + interfaces_interface_ipv6_neighbor_element_t* new_element = NULL; + + new_element = malloc(sizeof(interfaces_interface_ipv6_neighbor_element_t)); + new_element->neighbor = (interfaces_interface_ipv6_neighbor_t) { 0 }; + + return new_element; +} + +void interfaces_interface_ipv6_neighbor_element_free(interfaces_interface_ipv6_neighbor_element_t** el) +{ + if (*el) { + if ((*el)->neighbor.ip) { + free((*el)->neighbor.ip); + } + + if ((*el)->neighbor.link_layer_address) { + free((*el)->neighbor.link_layer_address); + } + + // address data + free(*el); + *el = NULL; + } +} + +int interfaces_interface_ipv6_neighbor_element_set_ip(interfaces_interface_ipv6_neighbor_element_t** el, const char* ip) +{ + if ((*el)->neighbor.ip) { + free((*el)->neighbor.ip); + } + + if (ip) { + (*el)->neighbor.ip = strdup(ip); + return (*el)->neighbor.ip == NULL; + } + + return 0; +} + +int interfaces_interface_ipv6_neighbor_element_set_link_layer_address(interfaces_interface_ipv6_neighbor_element_t** el, const char* link_layer_address) +{ + if ((*el)->neighbor.link_layer_address) { + free((*el)->neighbor.link_layer_address); + } + + if (link_layer_address) { + (*el)->neighbor.link_layer_address = strdup(link_layer_address); + return (*el)->neighbor.link_layer_address == NULL; + } + + return 0; +} diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv6/neighbor.h b/src/interfaces/src/plugin/data/interfaces/interface/ipv6/neighbor.h new file mode 100644 index 00000000..012aba1b --- /dev/null +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv6/neighbor.h @@ -0,0 +1,26 @@ +#ifndef INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV6_NEIGHBOR_H +#define INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV6_NEIGHBOR_H + +#include "plugin/types.h" + +#include +#include + +/* + Linked list operations. +*/ + +interfaces_interface_ipv6_neighbor_element_t* interfaces_interface_ipv6_neighbor_new(void); +int interfaces_interface_ipv6_neighbor_add_element(interfaces_interface_ipv6_neighbor_element_t** address, interfaces_interface_ipv6_neighbor_element_t* new_element); +void interfaces_interface_ipv6_neighbor_free(interfaces_interface_ipv6_neighbor_element_t** address); + +/* + Element operations. +*/ + +interfaces_interface_ipv6_neighbor_element_t* interfaces_interface_ipv6_neighbor_element_new(void); +void interfaces_interface_ipv6_neighbor_element_free(interfaces_interface_ipv6_neighbor_element_t** el); +int interfaces_interface_ipv6_neighbor_element_set_ip(interfaces_interface_ipv6_neighbor_element_t** el, const char* ip); +int interfaces_interface_ipv6_neighbor_element_set_link_layer_address(interfaces_interface_ipv6_neighbor_element_t** el, const char* link_layer_address); + +#endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV6_NEIGHBOR_H \ No newline at end of file From c17c0e7e20b80ffbafd67154fca440ecc44b9d4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 26 Sep 2022 16:15:22 +0200 Subject: [PATCH 125/247] interfaces-plugin: fix generic list free macro --- .../interfaces/interface/ipv4/linked_list.c | 91 ------------------- .../interfaces/interface/ipv4/linked_list.h | 64 ------------- .../interfaces/interface/ipv6/linked_list.c | 85 ----------------- .../interfaces/interface/ipv6/linked_list.h | 61 ------------- .../data/interfaces/interface/linked_list.h | 80 ++++++++-------- 5 files changed, 42 insertions(+), 339 deletions(-) delete mode 100644 src/interfaces/src/plugin/data/interfaces/interface/ipv4/linked_list.c delete mode 100644 src/interfaces/src/plugin/data/interfaces/interface/ipv4/linked_list.h delete mode 100644 src/interfaces/src/plugin/data/interfaces/interface/ipv6/linked_list.c delete mode 100644 src/interfaces/src/plugin/data/interfaces/interface/ipv6/linked_list.h diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/linked_list.c b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/linked_list.c deleted file mode 100644 index e7dde339..00000000 --- a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/linked_list.c +++ /dev/null @@ -1,91 +0,0 @@ -#include "linked_list.h" -#include "utils/memory.h" - -void *interfaces_interface_ipv4_address_list_element_new(void) -{ - interfaces_interface_ipv4_address_element_t *new_element = NULL; - - new_element = xmalloc(sizeof(interfaces_interface_ipv4_address_element_t)); - - /* NULL all address fields */ - new_element->address = (interfaces_interface_ipv4_address_t) {0}; - - return new_element; -} - -void *interfaces_interface_ipv4_neighbor_list_element_new(void) -{ - interfaces_interface_ipv4_neighbor_element_t *new_element = NULL; - - new_element = xmalloc(sizeof(interfaces_interface_ipv4_neighbor_element_t)); - - /* NULL all address fields */ - new_element->neighbor = (interfaces_interface_ipv4_neighbor_t) {0}; - - return new_element; -} - -void interfaces_interface_ipv4_address_list_free(interfaces_interface_ipv4_address_element_t **ll) -{ - interfaces_interface_ipv4_address_element_t *elem, *tmp; - - INTERFACES_INTERFACE_IPV4_ADDRESS_LIST_FREE(ll, elem, tmp); -} - -void interfaces_interface_ipv4_neighbor_list_free(interfaces_interface_ipv4_neighbor_element_t **ll) -{ - interfaces_interface_ipv4_neighbor_element_t *elem, *tmp; - - INTERFACES_INTERFACE_IPV4_NEIGHBOR_LIST_FREE(ll, elem, tmp); -} - -int interfaces_interface_ipv4_address_list_element_set_address(interfaces_interface_ipv4_address_element_t **ll, interfaces_interface_ipv4_address_t *address) -{ - - if ((*ll)->address.ip != NULL) { - FREE_SAFE((*ll)->address.ip); - } - if ((*ll)->address.subnet.prefix_length != NULL) { - FREE_SAFE((*ll)->address.subnet.prefix_length); - } - - if (address != NULL) { - (*ll)->address.subnet.prefix_length = address->subnet.prefix_length; - /* deepcopy char * */ - if (address->ip != NULL) { - (*ll)->address.ip = xstrdup(address->ip); - } - /* netmask is part of a union with prefix_length, doesn't have to be set */ - if (address->subnet.netmask != NULL) { - (*ll)->address.subnet.netmask = xstrdup(address->subnet.netmask); - return (*ll)->address.ip == NULL || (*ll)->address.subnet.netmask == NULL; - } - return (*ll)->address.ip == NULL; - } - - return 0; -} - -int interfaces_interface_ipv4_address_list_element_set_neighbor(interfaces_interface_ipv4_neighbor_element_t **ll, interfaces_interface_ipv4_neighbor_t *neighbor) -{ - - if ((*ll)->neighbor.ip != NULL) { - FREE_SAFE((*ll)->neighbor.ip); - } - if ((*ll)->neighbor.link_layer_address != NULL) { - FREE_SAFE((*ll)->neighbor.link_layer_address); - } - - if (neighbor != NULL) { - if (neighbor->ip != NULL) { - (*ll)->neighbor.ip = xstrdup(neighbor->ip); - } - if (neighbor->link_layer_address != NULL) { - (*ll)->neighbor.link_layer_address = xstrdup(neighbor->link_layer_address); - } - - return (*ll)->neighbor.ip == NULL || (*ll)->neighbor.link_layer_address == NULL; - } - - return 0; -} diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/linked_list.h b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/linked_list.h deleted file mode 100644 index c4bc9068..00000000 --- a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/linked_list.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV4_LIST_H -#define INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV4_LIST_H - -#include "plugin/types.h" - -#include -#include - -/* - Linked list operations -*/ - -#define INTERFACES_INTERFACE_IPV4_ADDRESS_LIST_FREE(ll_ptr, elem_ptr, tmp_ptr) \ - do \ - { \ - LL_FOREACH_SAFE(*ll_ptr, elem_ptr, tmp_ptr) { \ - LL_DELETE(*ll_ptr, elem_ptr); \ - if (elem_ptr) { \ - if (elem_ptr->address.ip != NULL) { \ - FREE_SAFE(elem_ptr->address.ip); \ - } \ - if (elem_ptr->address.subnet.netmask != NULL) { \ - FREE_SAFE(elem_ptr->address.subnet.netmask); \ - } \ - FREE_SAFE(elem_ptr); \ - } \ - } \ - } \ - while (0) - -#define INTERFACES_INTERFACE_IPV4_NEIGHBOR_LIST_FREE(ll_ptr, elem_ptr, tmp_ptr) \ - do \ - { \ - LL_FOREACH_SAFE(*ll_ptr, elem_ptr, tmp_ptr) { \ - LL_DELETE(*ll_ptr, elem_ptr); \ - if (elem_ptr) { \ - if (elem_ptr->neighbor.ip != NULL) { \ - FREE_SAFE(elem_ptr->neighbor.ip); \ - } \ - if (elem_ptr->neighbor.link_layer_address != NULL) { \ - FREE_SAFE(elem_ptr->neighbor.link_layer_address); \ - } \ - FREE_SAFE(elem_ptr); \ - } \ - } \ - } \ - while (0) - -void interfaces_interface_ipv4_address_list_free(interfaces_interface_ipv4_address_element_t **ll); - -void interfaces_interface_ipv4_neighbor_list_free(interfaces_interface_ipv4_neighbor_element_t **ll); - -/* - Element operations -*/ - -void *interfaces_interface_ipv4_address_list_element_new(void); -void *interfaces_interface_ipv4_neighbor_list_element_new(void); - -int interfaces_interface_ipv4_address_list_element_set_address(interfaces_interface_ipv4_address_element_t **ll, interfaces_interface_ipv4_address_t *address); -int interfaces_interface_ipv4_address_list_element_set_neighbor(interfaces_interface_ipv4_neighbor_element_t **ll, interfaces_interface_ipv4_neighbor_t *neighbor); - -#endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV4_LIST_H - diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv6/linked_list.c b/src/interfaces/src/plugin/data/interfaces/interface/ipv6/linked_list.c deleted file mode 100644 index 11b9a201..00000000 --- a/src/interfaces/src/plugin/data/interfaces/interface/ipv6/linked_list.c +++ /dev/null @@ -1,85 +0,0 @@ -#include "linked_list.h" -#include "utils/memory.h" - -void *interfaces_interface_ipv6_address_list_element_new(void) -{ - interfaces_interface_ipv6_address_element_t *new_element = NULL; - - new_element = xmalloc(sizeof(interfaces_interface_ipv6_address_element_t)); - - /* NULL all address fields */ - new_element->address = (interfaces_interface_ipv6_address_t) {0}; - - return new_element; -} - -void *interfaces_interface_ipv6_neighbor_list_element_new(void) -{ - interfaces_interface_ipv6_neighbor_element_t *new_element = NULL; - - new_element = xmalloc(sizeof(interfaces_interface_ipv6_neighbor_element_t)); - - /* NULL all address fields */ - new_element->neighbor = (interfaces_interface_ipv6_neighbor_t) {0}; - - return new_element; -} - -void interfaces_interface_ipv6_address_list_free(interfaces_interface_ipv6_address_element_t **ll) -{ - interfaces_interface_ipv6_address_element_t *elem, *tmp; - - INTERFACES_INTERFACE_IPV6_ADDRESS_LIST_FREE(ll, elem, tmp); -} - -void interfaces_interface_ipv6_neighbor_list_free(interfaces_interface_ipv6_neighbor_element_t **ll) -{ - interfaces_interface_ipv6_neighbor_element_t *elem, *tmp; - INTERFACES_INTERFACE_IPV6_NEIGHBOR_LIST_FREE(ll, elem, tmp); -} - -int interfaces_interface_ipv6_address_list_element_set_address(interfaces_interface_ipv6_address_element_t **ll, interfaces_interface_ipv6_address_t *address) -{ - - if ((*ll)->address.ip != NULL) { - FREE_SAFE((*ll)->address.ip); - } - if ((*ll)->address.prefix_length != NULL) { - FREE_SAFE((*ll)->address.prefix_length); - } - - if (address != NULL) { - (*ll)->address.prefix_length = address->prefix_length; - /* deepcopy char * */ - if (address->ip != NULL) { - (*ll)->address.ip = xstrdup(address->ip); - } - return (*ll)->address.ip == NULL; - } - - return 0; -} - -int interfaces_interface_ipv6_address_list_element_set_neighbor(interfaces_interface_ipv6_neighbor_element_t **ll, interfaces_interface_ipv6_neighbor_t *neighbor) -{ - - if ((*ll)->neighbor.ip != NULL) { - FREE_SAFE((*ll)->neighbor.ip); - } - if ((*ll)->neighbor.link_layer_address != NULL) { - FREE_SAFE((*ll)->neighbor.link_layer_address); - } - - if (neighbor != NULL) { - if (neighbor->ip != NULL) { - (*ll)->neighbor.ip = xstrdup(neighbor->ip); - } - if (neighbor->link_layer_address != NULL) { - (*ll)->neighbor.link_layer_address = xstrdup(neighbor->link_layer_address); - } - - return (*ll)->neighbor.ip == NULL || (*ll)->neighbor.link_layer_address == NULL; - } - - return 0; -} diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv6/linked_list.h b/src/interfaces/src/plugin/data/interfaces/interface/ipv6/linked_list.h deleted file mode 100644 index 226840e1..00000000 --- a/src/interfaces/src/plugin/data/interfaces/interface/ipv6/linked_list.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV6_LIST_H -#define INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV6_LIST_H - -#include "plugin/types.h" - -#include -#include - -/* - Linked list operations -*/ - -#define INTERFACES_INTERFACE_IPV6_ADDRESS_LIST_FREE(ll_ptr, elem_ptr, tmp_ptr) \ - do \ - { \ - LL_FOREACH_SAFE(*ll_ptr, elem_ptr, tmp_ptr) { \ - LL_DELETE(*ll_ptr, elem_ptr); \ - if (elem_ptr) { \ - if (elem_ptr->address.ip != NULL) { \ - FREE_SAFE(elem_ptr->address.ip); \ - } \ - FREE_SAFE(elem_ptr); \ - } \ - } \ - } \ - while (0) - -#define INTERFACES_INTERFACE_IPV6_NEIGHBOR_LIST_FREE(ll_ptr, elem_ptr, tmp_ptr) \ - do \ - { \ - LL_FOREACH_SAFE(*ll_ptr, elem_ptr, tmp_ptr) { \ - LL_DELETE(*ll_ptr, elem_ptr); \ - if (elem_ptr) { \ - if (elem_ptr->neighbor.ip != NULL) { \ - FREE_SAFE(elem_ptr->neighbor.ip); \ - } \ - if (elem_ptr->neighbor.link_layer_address != NULL) { \ - FREE_SAFE(elem_ptr->neighbor.link_layer_address); \ - } \ - FREE_SAFE(elem_ptr); \ - } \ - } \ - } \ - while (0) - -void interfaces_interface_ipv6_address_list_free(interfaces_interface_ipv6_address_element_t **ll); - -void interfaces_interface_ipv6_neighbor_list_free(interfaces_interface_ipv6_neighbor_element_t **ll); - -/* - Element operations -*/ - -void *interfaces_interface_ipv6_address_list_element_new(void); -void *interfaces_interface_ipv6_neighbor_list_element_new(void); - -int interfaces_interface_ipv6_address_list_element_set_address(interfaces_interface_ipv6_address_element_t **ll, interfaces_interface_ipv6_address_t *address); -int interfaces_interface_ipv6_address_list_element_set_neighbor(interfaces_interface_ipv6_neighbor_element_t **ll, interfaces_interface_ipv6_neighbor_t *neighbor); - -#endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV6_LIST_H - diff --git a/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h b/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h index 9c1f1373..6c597605 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h +++ b/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h @@ -1,53 +1,57 @@ #ifndef INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_LIST_H #define INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_LIST_H -#include "ipv4/linked_list.h" -#include "ipv6/linked_list.h" +#include "ipv4/address.h" +#include "ipv4/neighbor.h" +#include "ipv6/address.h" +#include "ipv6/neighbor.h" #include "plugin/types.h" -#include #include +#include /* Linked list operations */ -#define INTERFACES_INTERFACE_LIST_NEW(ll_ptr) \ - do \ - { \ - (ll_ptr) = NULL; \ - } while(0) - -#define INTERFACES_INTERFACE_LIST_FREE(ll_ptr) \ - _Generic((ll_ptr), \ - interfaces_interfaces_interface_ipv4_address_element_t** : interfaces_interface_ipv4_address_list_free \ - interfaces_interfaces_interface_ipv4_neighbor_element_t** : interfaces_interface_ipv4_neighbor_list_free \ - interfaces_interfaces_interface_ipv6_address_element_t** : interfaces_interface_ipv6_address_list_free \ - interfaces_interfaces_interface_ipv6_neighbor_element_t** : interfaces_interface_ipv6_neighbor_list_free \ - )(ll_ptr) +#define INTERFACES_INTERFACE_LIST_NEW(ll_ptr) \ + do { \ + (ll_ptr) = NULL; \ + } while (0) + +#define INTERFACES_INTERFACE_LIST_FREE(ll_ptr) \ + _Generic((ll_ptr), \ + interfaces_interfaces_interface_ipv4_address_element_t * \ + : interfaces_interface_ipv4_address_free \ + interfaces_interfaces_interface_ipv4_neighbor_element_t \ + * \ + : interfaces_interface_ipv4_neighbor_free \ + interfaces_interfaces_interface_ipv6_address_element_t \ + * \ + : interfaces_interface_ipv6_address_free \ + interfaces_interfaces_interface_ipv6_neighbor_element_t \ + * \ + : interfaces_interface_ipv6_neighbor_free)(ll_ptr) /* prepend since ordering doesn't matter - O(1) */ -#define INTERFACES_INTERFACE_LIST_ADD_ELEMENT(ll_ptr, new_element_ptr) \ - do \ - { \ - LL_PREPEND(ll_ptr, new_element_ptr); \ - } while(0) \ - -#define INTERFACES_INTERFACE_LIST_GET_ELEMENT_STRING(ll_ptr, element_ptr, member, value) \ - do \ - { \ - LL_FOREACH(ll_ptr, element_ptr) { \ - if (strcmp(element_ptr->member, value) == 0) { \ - break; \ - } \ - } \ - } while(0) - -#define INTERFACES_INTERFACE_LIST_GET_ELEMENT_SCALAR(ll_ptr, element_ptr, member, value) \ - do \ - { \ - LL_SEARCH_SCALAR(ll_ptr, element_ptr, member, value); \ - } while(0) +#define INTERFACES_INTERFACE_LIST_ADD_ELEMENT(ll_ptr, new_element_ptr) \ + do { \ + LL_PREPEND(ll_ptr, new_element_ptr); \ + } while (0) + +#define INTERFACES_INTERFACE_LIST_GET_ELEMENT_STRING(ll_ptr, element_ptr, member, value) \ + do { \ + LL_FOREACH(ll_ptr, element_ptr) \ + { \ + if (strcmp(element_ptr->member, value) == 0) { \ + break; \ + } \ + } \ + } while (0) + +#define INTERFACES_INTERFACE_LIST_GET_ELEMENT_SCALAR(ll_ptr, element_ptr, member, value) \ + do { \ + LL_SEARCH_SCALAR(ll_ptr, element_ptr, member, value); \ + } while (0) #endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_LIST_H - From 5f9c3a7142f65a586e33191d6510271197f7752d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 26 Sep 2022 17:04:10 +0200 Subject: [PATCH 126/247] interfaces-plugin: convert libyang IPv4 and IPv6 address lists to internal data structures --- .../src/plugin/data/interfaces/interface.c | 126 +++++++++++++++++- .../src/plugin/data/interfaces/interface.h | 3 +- src/interfaces/src/plugin/startup/store.c | 2 +- 3 files changed, 124 insertions(+), 7 deletions(-) diff --git a/src/interfaces/src/plugin/data/interfaces/interface.c b/src/interfaces/src/plugin/data/interfaces/interface.c index 0f61f87a..1491d701 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface.c +++ b/src/interfaces/src/plugin/data/interfaces/interface.c @@ -7,11 +7,22 @@ #include "utils/memory.h" #include "utlist.h" +// other data API +#include "interface/ipv4/address.h" +#include "interface/ipv4/neighbor.h" +#include "interface/ipv6/address.h" +#include "interface/ipv6/neighbor.h" +#include "interface/linked_list.h" + #include #include #include #include +/* + Libyang conversion functions. +*/ + interfaces_interface_hash_element_t* interfaces_interface_hash_new(void) { return NULL; @@ -55,6 +66,7 @@ void interfaces_interface_hash_print_debug(const interfaces_interface_hash_eleme { const interfaces_interface_hash_element_t *iter = NULL, *tmp = NULL; interfaces_interface_ipv4_address_element_t* v4addr_iter = NULL; + interfaces_interface_ipv6_address_element_t* v6addr_iter = NULL; HASH_ITER(hh, if_hash, iter, tmp) { @@ -74,10 +86,17 @@ void interfaces_interface_hash_print_debug(const interfaces_interface_hash_eleme SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv4:Address IP = %s", v4addr_iter->address.ip); SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv4:Address Prefix Length = %d", v4addr_iter->address.subnet.prefix_length); } + + LL_FOREACH(iter->interface.ipv6.address, v6addr_iter) + { + SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv6:Address %s:", v6addr_iter->address.ip); + SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv6:Address IP = %s", v6addr_iter->address.ip); + SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv6:Address Prefix Length = %d", v6addr_iter->address.prefix_length); + } } } -int interfaces_interface_hash_from_ly(const struct lyd_node* interface_list_node, interfaces_interface_hash_element_t** if_hash) +int interfaces_interface_hash_from_ly(interfaces_interface_hash_element_t** if_hash, const struct lyd_node* interface_list_node) { int error = 0; @@ -90,6 +109,8 @@ int interfaces_interface_hash_from_ly(const struct lyd_node* interface_list_node struct lyd_node *ipv4_container_node = NULL, *ipv6_container_node = NULL; struct lyd_node *ipv4_enabled_node = NULL, *ipv4_forwarding_node = NULL, *ipv4_mtu_node = NULL, *ipv4_address_node = NULL; struct lyd_node *ipv6_enabled_node = NULL, *ipv6_forwarding_node = NULL, *ipv6_mtu_node = NULL, *ipv6_address_node = NULL; + struct lyd_node *ipv4_ip_node = NULL, *ipv4_prefix_node = NULL, *ipv4_netmask_node = NULL; + struct lyd_node *ipv6_ip_node = NULL, *ipv6_prefix_node = NULL; // internal DS interfaces_interface_hash_element_t* new_element = NULL; @@ -101,8 +122,8 @@ int interfaces_interface_hash_from_ly(const struct lyd_node* interface_list_node new_element = interfaces_interface_hash_element_new(); // get existing nodes - if_name_node = srpc_ly_tree_get_child_leaf(if_iter, "name"); - if_type_node = srpc_ly_tree_get_child_leaf(if_iter, "type"); + SRPC_SAFE_CALL_PTR(if_name_node, srpc_ly_tree_get_child_leaf(if_iter, "name"), error_out); + SRPC_SAFE_CALL_PTR(if_type_node, srpc_ly_tree_get_child_leaf(if_iter, "type"), error_out); if_enabled_node = srpc_ly_tree_get_child_leaf(if_iter, "enabled"); ipv4_container_node = srpc_ly_tree_get_child_container(if_iter, "ipv4"); ipv6_container_node = srpc_ly_tree_get_child_container(if_iter, "ipv6"); @@ -127,18 +148,23 @@ int interfaces_interface_hash_from_ly(const struct lyd_node* interface_list_node if (if_name_node) { SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_name(&new_element, lyd_get_value(if_name_node)), error_out); } + if (if_type_node) { SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_type(&new_element, lyd_get_value(if_type_node)), error_out); } + if (if_enabled_node) { SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_enabled(&new_element, strcmp(lyd_get_value(if_enabled_node), "true") ? 1 : 0), error_out); } + if (ipv4_enabled_node) { - SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_ipv4_enabled(&new_element, strcmp(lyd_get_value(ipv4_enabled_node), "true") ? 1 : 0), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_ipv4_enabled(&new_element, strcmp(lyd_get_value(ipv4_enabled_node), "true") == 0 ? 1 : 0), error_out); } + if (ipv4_forwarding_node) { - SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_ipv4_forwarding(&new_element, strcmp(lyd_get_value(ipv4_forwarding_node), "true") ? 1 : 0), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_ipv4_forwarding(&new_element, strcmp(lyd_get_value(ipv4_forwarding_node), "true") == 0 ? 1 : 0), error_out); } + if (ipv4_mtu_node) { const char* mtu_str = lyd_get_value(ipv4_mtu_node); uint16_t mtu = (uint16_t)atoi(mtu_str); @@ -146,11 +172,93 @@ int interfaces_interface_hash_from_ly(const struct lyd_node* interface_list_node SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_ipv4_mtu(&new_element, mtu), error_out); } + // init every list + + // ipv4 + INTERFACES_INTERFACE_LIST_NEW(new_element->interface.ipv4.address); + INTERFACES_INTERFACE_LIST_NEW(new_element->interface.ipv4.neighbor); + + // ipv6 + INTERFACES_INTERFACE_LIST_NEW(new_element->interface.ipv6.address); + INTERFACES_INTERFACE_LIST_NEW(new_element->interface.ipv6.neighbor); + // IPv4 address list while (ipv4_address_node) { + // add new ipv4 address element + new_v4_element = interfaces_interface_ipv4_address_element_new(); + + // fetch address info nodes + SRPC_SAFE_CALL_PTR(ipv4_ip_node, srpc_ly_tree_get_child_leaf(ipv4_address_node, "ip"), error_out); + ipv4_prefix_node = srpc_ly_tree_get_child_leaf(ipv4_address_node, "prefix-length"); + ipv4_netmask_node = srpc_ly_tree_get_child_leaf(ipv4_address_node, "netmask"); + + // set IP + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_address_element_set_ip(&new_v4_element, lyd_get_value(ipv4_ip_node)), error_out); + + // set subnet data + if (ipv4_prefix_node) { + const char* prefix_length_str = NULL; + + SRPC_SAFE_CALL_PTR(prefix_length_str, lyd_get_value(ipv4_prefix_node), error_out); + const uint8_t prefix_length = (uint8_t)atoi(prefix_length_str); + + // set prefix length + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_address_element_set_prefix_length(&new_v4_element, prefix_length), error_out); + } else if (ipv4_netmask_node) { + const char* netmask_str = NULL; + + SRPC_SAFE_CALL_PTR(netmask_str, lyd_get_value(ipv4_netmask_node), error_out); + + // set netmask + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_address_element_set_netmask(&new_v4_element, netmask_str), error_out); + } else { + // should be impossible due to libyang's mandatory statement... but throw error + SRPLG_LOG_ERR(PLUGIN_NAME, "Unable to determine subnet of the following address: %s", lyd_get_value(ipv4_ip_node)); + goto error_out; + } + + // data set correctly - add address to the list + INTERFACES_INTERFACE_LIST_ADD_ELEMENT(new_element->interface.ipv4.address, new_v4_element); + + // null new element - free() + new_v4_element = NULL; + + // iterate ipv4_address_node = srpc_ly_tree_get_list_next(ipv4_address_node); } + // IPv6 address list + while (ipv6_address_node) { + // add new ipv4 address element + new_v6_element = interfaces_interface_ipv6_address_element_new(); + + // fetch address info nodes + SRPC_SAFE_CALL_PTR(ipv6_ip_node, srpc_ly_tree_get_child_leaf(ipv6_address_node, "ip"), error_out); + SRPC_SAFE_CALL_PTR(ipv6_prefix_node, srpc_ly_tree_get_child_leaf(ipv6_address_node, "prefix-length"), error_out); + + // set IP + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv6_address_element_set_ip(&new_v6_element, lyd_get_value(ipv6_ip_node)), error_out); + + // set prefix-length + const char* prefix_length_str = NULL; + + SRPC_SAFE_CALL_PTR(prefix_length_str, lyd_get_value(ipv6_prefix_node), error_out); + + const uint8_t prefix_length = (uint8_t)atoi(prefix_length_str); + + // set prefix length + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv6_address_element_set_prefix_length(&new_v6_element, prefix_length), error_out); + + // data set correctly - add address to the list + INTERFACES_INTERFACE_LIST_ADD_ELEMENT(new_element->interface.ipv6.address, new_v6_element); + + // null new element - free() + new_v6_element = NULL; + + // iterate + ipv6_address_node = srpc_ly_tree_get_list_next(ipv6_address_node); + } + // add element to the hash interfaces_interface_hash_add_element(if_hash, new_element); @@ -170,6 +278,14 @@ int interfaces_interface_hash_from_ly(const struct lyd_node* interface_list_node interfaces_interface_hash_element_free(&new_element); } + if (new_v4_element) { + interfaces_interface_ipv4_address_element_free(&new_v4_element); + } + + if (new_v6_element) { + interfaces_interface_ipv6_address_element_free(&new_v6_element); + } + return error; } diff --git a/src/interfaces/src/plugin/data/interfaces/interface.h b/src/interfaces/src/plugin/data/interfaces/interface.h index 4b0147be..dacdec58 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface.h +++ b/src/interfaces/src/plugin/data/interfaces/interface.h @@ -10,7 +10,7 @@ interfaces_interface_hash_element_t* interfaces_interface_hash_new(void); void interfaces_interface_hash_print_debug(const interfaces_interface_hash_element_t* if_hash); -int interfaces_interface_hash_from_ly(const struct lyd_node* interface_list_node, interfaces_interface_hash_element_t** if_hash); +int interfaces_interface_hash_from_ly(interfaces_interface_hash_element_t** if_hash, const struct lyd_node* interface_list_node); int interfaces_interface_hash_add_element(interfaces_interface_hash_element_t** hash, interfaces_interface_hash_element_t* new_element); interfaces_interface_hash_element_t* interfaces_interface_hash_get_element(interfaces_interface_hash_element_t** hash, const char* name); void interfaces_interface_hash_free(interfaces_interface_hash_element_t** hash); @@ -41,6 +41,7 @@ int interfaces_interface_hash_element_set_ipv4(interfaces_interface_hash_element int interfaces_interface_hash_element_set_ipv4_enabled(interfaces_interface_hash_element_t** el, uint8_t enabled); int interfaces_interface_hash_element_set_ipv4_forwarding(interfaces_interface_hash_element_t** el, uint8_t forwarding); int interfaces_interface_hash_element_set_ipv4_mtu(interfaces_interface_hash_element_t** el, uint16_t mtu); +int interfaces_interface_hash_element_set_ipv4_address(interfaces_interface_hash_element_t** el, interfaces_interface_ipv4_address_element_t* head); /* IPv6 diff --git a/src/interfaces/src/plugin/startup/store.c b/src/interfaces/src/plugin/startup/store.c index b774ad1b..550633f1 100644 --- a/src/interfaces/src/plugin/startup/store.c +++ b/src/interfaces/src/plugin/startup/store.c @@ -69,7 +69,7 @@ static int interfaces_startup_store_interface(void* priv, const struct lyd_node* } // map libyang data to the interface hash - SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_from_ly(interface_node, &if_hash), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_from_ly(&if_hash, interface_node), error_out); interfaces_interface_hash_print_debug(if_hash); From 191160f3dc85448f09e93d10fe5dae6db832a7bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 26 Sep 2022 17:10:44 +0200 Subject: [PATCH 127/247] interfaces-plugin: fix interfaces list free macro --- .../src/plugin/data/interfaces/interface/linked_list.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h b/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h index 6c597605..28f1c92a 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h +++ b/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h @@ -31,7 +31,7 @@ : interfaces_interface_ipv6_address_free \ interfaces_interfaces_interface_ipv6_neighbor_element_t \ * \ - : interfaces_interface_ipv6_neighbor_free)(ll_ptr) + : interfaces_interface_ipv6_neighbor_free)(&(ll_ptr)) /* prepend since ordering doesn't matter - O(1) */ #define INTERFACES_INTERFACE_LIST_ADD_ELEMENT(ll_ptr, new_element_ptr) \ From f6ef7ddacbf12672c6230b19257f848c02d2c40e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 26 Sep 2022 17:35:15 +0200 Subject: [PATCH 128/247] interfaces-plugin: switch to C11 instead of C99 --- CompileOptions.cmake | 36 +-- .../src/plugin/api/interfaces/change.c | 1 + .../plugin/api/interfaces/interface/change.c | 1 + .../src/plugin/api/interfaces/load.c | 258 +++++++++--------- .../src/plugin/data/interfaces/interface.c | 4 + .../data/interfaces/interface/ipv4/address.c | 2 + .../data/interfaces/interface/linked_list.h | 26 +- .../plugin/data/interfaces/interface_state.c | 1 + .../src/plugin/subscription/change.c | 1 + .../src/plugin/subscription/operational.c | 2 + 10 files changed, 174 insertions(+), 158 deletions(-) diff --git a/CompileOptions.cmake b/CompileOptions.cmake index 00bf1a93..fbe23896 100644 --- a/CompileOptions.cmake +++ b/CompileOptions.cmake @@ -1,20 +1,24 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99") -set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic") -set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") -set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wextra") -set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion") -set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wcast-align") -set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wstrict-prototypes") -set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wuninitialized") -set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow") -set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat=2") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wextra") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wcast-align") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wstrict-prototypes") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wuninitialized") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat=2") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_GNU_SOURCE") + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5) - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=incompatible-pointer-types") -endif () -set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-parameter") -if (CMAKE_C_COMPILER_ID MATCHES "Clang") - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-newline-eof") - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-gnu-zero-variadic-macro-arguments") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=incompatible-pointer-types") +endif() + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-parameter") + +if(CMAKE_C_COMPILER_ID MATCHES "Clang") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-newline-eof") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-gnu-zero-variadic-macro-arguments") endif() diff --git a/src/interfaces/src/plugin/api/interfaces/change.c b/src/interfaces/src/plugin/api/interfaces/change.c index a159e7f8..896699bd 100644 --- a/src/interfaces/src/plugin/api/interfaces/change.c +++ b/src/interfaces/src/plugin/api/interfaces/change.c @@ -4,6 +4,7 @@ #include "interface/change.h" +#include #include #include diff --git a/src/interfaces/src/plugin/api/interfaces/interface/change.c b/src/interfaces/src/plugin/api/interfaces/interface/change.c index 69541ff3..6cbd5c04 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/change.c @@ -6,6 +6,7 @@ #include "sysrepo/xpath.h" #include +#include #include #include #include diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index 464e8ac6..0c874fb6 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -1,9 +1,10 @@ #include "load.h" -#include "utlist.h" #include "plugin/common.h" #include "utils/memory.h" +#include "utlist.h" #include +#include #include @@ -14,90 +15,90 @@ enum interfaces_load_exit_status { interfaces_load_failure = -1, - interfaces_load_success = 0, + interfaces_load_success = 0, interfaces_load_continue = 1, }; -static char *interfaces_get_interface_name(struct rtnl_link *link) +static char* interfaces_get_interface_name(struct rtnl_link* link) { - char *name = NULL; + char* name = NULL; - name = rtnl_link_get_name(link); - if (name == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_get_name error"); - } + name = rtnl_link_get_name(link); + if (name == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_get_name error"); + } - return xstrdup(name); + return xstrdup(name); } -static char *interfaces_get_interface_description(interfaces_ctx_t *ctx, char *name) +static char* interfaces_get_interface_description(interfaces_ctx_t* ctx, char* name) { - int error = SR_ERR_OK; - char path_buffer[PATH_MAX] = {0}; - sr_val_t *val = {0}; - char *description = NULL; - - /* conjure description path for this interface: /ietf-interfaces:interfaces/interface[name='test_interface']/description */ - error = snprintf(path_buffer, sizeof(path_buffer) / sizeof(char), "%s[name=\"%s\"]/description", INTERFACES_INTERFACES_LIST_YANG_PATH, name); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf error"); - goto error_out; - } - - // get the interface description value - error = sr_get_item(ctx->startup_session, path_buffer, 0, &val); - if (error != SR_ERR_OK) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_get_item error (%d): %s", error, sr_strerror(error)); - goto error_out; - } - - if (strlen(val->data.string_val) > 0) { - description = xstrdup(val->data.string_val); - } - + int error = SR_ERR_OK; + char path_buffer[PATH_MAX] = { 0 }; + sr_val_t* val = { 0 }; + char* description = NULL; + + /* conjure description path for this interface: /ietf-interfaces:interfaces/interface[name='test_interface']/description */ + error = snprintf(path_buffer, sizeof(path_buffer) / sizeof(char), "%s[name=\"%s\"]/description", INTERFACES_INTERFACES_LIST_YANG_PATH, name); + if (error < 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf error"); + goto error_out; + } + + // get the interface description value + error = sr_get_item(ctx->startup_session, path_buffer, 0, &val); + if (error != SR_ERR_OK) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_get_item error (%d): %s", error, sr_strerror(error)); + goto error_out; + } + + if (strlen(val->data.string_val) > 0) { + description = xstrdup(val->data.string_val); + } + error_out: - return description; + return description; } -static int read_from_sys_file(const char *dir_path, char *interface, int *val) +static int read_from_sys_file(const char* dir_path, char* interface, int* val) { - int error = 0; - char tmp_buffer[PATH_MAX]; - FILE *fptr = NULL; - char tmp_val[4] = {0}; - - error = snprintf(tmp_buffer, sizeof(tmp_buffer), "%s/%s/type", dir_path, interface); - if (error < 0) { - // snprintf error - SRPLG_LOG_ERR(PLUGIN_NAME, "%s: snprintf failed", __func__); - goto out; - } + int error = 0; + char tmp_buffer[PATH_MAX]; + FILE* fptr = NULL; + char tmp_val[4] = { 0 }; + + error = snprintf(tmp_buffer, sizeof(tmp_buffer), "%s/%s/type", dir_path, interface); + if (error < 0) { + // snprintf error + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: snprintf failed", __func__); + goto out; + } - /* snprintf returns return the number of bytes that are written - reset error to 0 */ - error = 0; + /* snprintf returns return the number of bytes that are written - reset error to 0 */ + error = 0; - fptr = fopen((const char *) tmp_buffer, "r"); + fptr = fopen((const char*)tmp_buffer, "r"); - if (fptr != NULL) { - fgets(tmp_val, sizeof(tmp_val), fptr); + if (fptr != NULL) { + fgets(tmp_val, sizeof(tmp_val), fptr); - *val = atoi(tmp_val); + *val = atoi(tmp_val); - fclose(fptr); - } else { - SRPLG_LOG_ERR(PLUGIN_NAME, "%s: failed to open %s: %s", __func__, tmp_buffer, strerror(errno)); - error = -1; - goto out; - } + fclose(fptr); + } else { + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: failed to open %s: %s", __func__, tmp_buffer, strerror(errno)); + error = -1; + goto out; + } out: - return error; + return error; } -static char *interfaces_get_interface_type(struct rtnl_link *link, char *name) +static char* interfaces_get_interface_type(struct rtnl_link* link, char* name) { int error = 0; - char *type = NULL; + char* type = NULL; type = rtnl_link_get_type(link); if (type == NULL) { @@ -106,28 +107,28 @@ static char *interfaces_get_interface_type(struct rtnl_link *link, char *name) * * get the type from: /sys/class/net//type */ - const char *path_to_sys = "/sys/class/net/"; + const char* path_to_sys = "/sys/class/net/"; int type_id = 0; SRPC_SAFE_CALL(read_from_sys_file(path_to_sys, name, &type_id), error_out); switch (type_id) { - case ARPHRD_ETHER: - type = "eth"; - break; - case ARPHRD_LOOPBACK: - type = "lo"; - break; - default: - SRPLG_LOG_ERR(PLUGIN_NAME, "%s: unkown type_id: %d", __func__, type_id); + case ARPHRD_ETHER: + type = "eth"; + break; + case ARPHRD_LOOPBACK: + type = "lo"; + break; + default: + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: unkown type_id: %d", __func__, type_id); } } - + error_out: - return xstrdup(type); + return xstrdup(type); } -static uint8_t interfaces_get_interface_enabled(struct rtnl_link *link) +static uint8_t interfaces_get_interface_enabled(struct rtnl_link* link) { uint8_t enabled = rtnl_link_get_operstate(link); @@ -137,18 +138,18 @@ static uint8_t interfaces_get_interface_enabled(struct rtnl_link *link) */ if (IF_OPER_UP == enabled || IF_OPER_UNKNOWN == enabled) { enabled = interfaces_interface_enable_enabled; - } else if (IF_OPER_DOWN == enabled ) { + } else if (IF_OPER_DOWN == enabled) { enabled = interfaces_interface_enable_disabled; } - return enabled; + return enabled; } -static char *interfaces_get_interface_parent_interface(struct nl_cache *cache, struct rtnl_link *link) +static char* interfaces_get_interface_parent_interface(struct nl_cache* cache, struct rtnl_link* link) { int parent_index = 0; - char parent_buffer[IFNAMSIZ] = {0}; - char *parent_interface = NULL; + char parent_buffer[IFNAMSIZ] = { 0 }; + char* parent_interface = NULL; if (rtnl_link_is_vlan(link)) { parent_index = rtnl_link_get_link(link); @@ -159,14 +160,14 @@ static char *interfaces_get_interface_parent_interface(struct nl_cache *cache, s } /* TODO: outer tag, second id, tag - maybe refactor all to pass by reference, return error */ -static int interfaces_get_interface_vlan_id(struct rtnl_link *link, interfaces_interface_t *interface) +static int interfaces_get_interface_vlan_id(struct rtnl_link* link, interfaces_interface_t* interface) { - uint16_t *outer_vlan_id = &interface->encapsulation.dot1q_vlan.outer_tag.vlan_id; - char *first = NULL; - char *second = NULL; - + uint16_t* outer_vlan_id = &interface->encapsulation.dot1q_vlan.outer_tag.vlan_id; + char* first = NULL; + char* second = NULL; + if (rtnl_link_is_vlan(link)) { - *outer_vlan_id = (uint16_t) rtnl_link_vlan_get_id(link); + *outer_vlan_id = (uint16_t)rtnl_link_vlan_get_id(link); if (*outer_vlan_id <= 0) { SRPLG_LOG_ERR(PLUGIN_NAME, "%s: couldn't get vlan ID", __func__); return interfaces_load_failure; @@ -174,7 +175,7 @@ static int interfaces_get_interface_vlan_id(struct rtnl_link *link, interfaces_i /* check if vlan_id in name, if it is this is the QinQ interface, skip it */ first = strchr(interface->name, '.'); - second = strchr(first+1, '.'); + second = strchr(first + 1, '.'); if (second != 0) { return interfaces_load_continue; @@ -184,22 +185,22 @@ static int interfaces_get_interface_vlan_id(struct rtnl_link *link, interfaces_i return interfaces_load_success; } -static int interfaces_parse_link(interfaces_ctx_t *ctx, struct nl_sock *socket, struct nl_cache *cache, struct rtnl_link *link, interfaces_interface_t *interface) +static int interfaces_parse_link(interfaces_ctx_t* ctx, struct nl_sock* socket, struct nl_cache* cache, struct rtnl_link* link, interfaces_interface_t* interface) { int error = interfaces_load_success; - *interface = (interfaces_interface_t) {0}; + *interface = (interfaces_interface_t) { 0 }; SRPC_SAFE_CALL_PTR(interface->name, interfaces_get_interface_name(link), error_out); - + SRPC_SAFE_CALL_PTR(interface->description, interfaces_get_interface_description(ctx, interface->name), error_out); - + SRPC_SAFE_CALL_PTR(interface->type, interfaces_get_interface_type(link, interface->name), error_out); SRPC_SAFE_CALL_PTR(interface->parent_interface, interfaces_get_interface_parent_interface(cache, link), error_out); error = interfaces_get_interface_vlan_id(link, interface); if (error != interfaces_load_success) { - SRPLG_LOG_ERR(PLUGIN_NAME, "%s: vlan id error", __func__); + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: vlan id error", __func__); goto out; // error_out would possibly change the error } @@ -225,11 +226,11 @@ static int interfaces_parse_link(interfaces_ctx_t *ctx, struct nl_sock *socket, return error; } -static int interfaces_add_link(interfaces_interface_hash_element_t **if_hash, interfaces_interface_t *interface) +static int interfaces_add_link(interfaces_interface_hash_element_t** if_hash, interfaces_interface_t* interface) { int error = 0; - - interfaces_interface_hash_element_t *new_if_hash_elem = interfaces_interface_hash_element_new(); + + interfaces_interface_hash_element_t* new_if_hash_elem = interfaces_interface_hash_element_new(); interfaces_interface_hash_element_set_name(&new_if_hash_elem, interface->name); SRPC_SAFE_CALL(interfaces_interface_hash_add_element(if_hash, new_if_hash_elem), error_out); @@ -251,81 +252,80 @@ static int interfaces_add_link(interfaces_interface_hash_element_t **if_hash, in goto out; error_out: out: - return error; + return error; } -static struct rtnl_link *interfaces_get_next_link(struct rtnl_link *link) +static struct rtnl_link* interfaces_get_next_link(struct rtnl_link* link) { - return (struct rtnl_link *) nl_cache_get_next((struct nl_object *) link); + return (struct rtnl_link*)nl_cache_get_next((struct nl_object*)link); } -static int interfaces_interfaces_worker(interfaces_ctx_t *ctx, struct nl_sock *socket, struct nl_cache *cache, interfaces_interface_hash_element_t **if_hash) +static int interfaces_interfaces_worker(interfaces_ctx_t* ctx, struct nl_sock* socket, struct nl_cache* cache, interfaces_interface_hash_element_t** if_hash) { int error = 0; - struct rtnl_link *link = NULL; - interfaces_interface_t interface = {0}; + struct rtnl_link* link = NULL; + interfaces_interface_t interface = { 0 }; - link = (struct rtnl_link *) nl_cache_get_first(cache); + link = (struct rtnl_link*)nl_cache_get_first(cache); while (link != NULL) { error = interfaces_parse_link(ctx, socket, cache, link, &interface); switch (error) { - case interfaces_load_success: - SRPC_SAFE_CALL(interfaces_add_link(if_hash, &interface), error_out); - break; - case interfaces_load_continue: - break; - default: - SRPLG_LOG_ERR(PLUGIN_NAME, "%s: error parsing link (%d)", __func__, error); - goto error_out; + case interfaces_load_success: + SRPC_SAFE_CALL(interfaces_add_link(if_hash, &interface), error_out); + break; + case interfaces_load_continue: + break; + default: + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: error parsing link (%d)", __func__, error); + goto error_out; } - link = interfaces_get_next_link(link); - } + link = interfaces_get_next_link(link); + } goto out; error_out: error = -1; out: if (link != NULL) { - rtnl_link_put(link); - } + rtnl_link_put(link); + } return error; } -int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t **if_hash) +int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** if_hash) { int error = 0; - struct nl_sock *socket = NULL; - struct nl_cache *cache = NULL; + struct nl_sock* socket = NULL; + struct nl_cache* cache = NULL; *if_hash = interfaces_interface_hash_new(); - socket = nl_socket_alloc(); - if (socket == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_socket_alloc error: invalid socket"); - goto error_out; - } - + socket = nl_socket_alloc(); + if (socket == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "nl_socket_alloc error: invalid socket"); + goto error_out; + } + SRPC_SAFE_CALL(nl_connect(socket, NETLINK_ROUTE), error_out); SRPC_SAFE_CALL(rtnl_link_alloc_cache(socket, AF_UNSPEC, &cache), error_out); SRPC_SAFE_CALL(interfaces_interfaces_worker(ctx, socket, cache, if_hash), error_out); - - goto out; + + goto out; error_out: - error = -1; + error = -1; out: - if (socket != NULL) { - nl_socket_free(socket); - } + if (socket != NULL) { + nl_socket_free(socket); + } if (cache != NULL) { - nl_cache_free(cache); + nl_cache_free(cache); } return error; } - diff --git a/src/interfaces/src/plugin/data/interfaces/interface.c b/src/interfaces/src/plugin/data/interfaces/interface.c index 1491d701..e4425349 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface.c +++ b/src/interfaces/src/plugin/data/interfaces/interface.c @@ -56,6 +56,10 @@ void interfaces_interface_hash_element_free(interfaces_interface_hash_element_t* free((*el)->interface.parent_interface); } + if ((*el)->interface.ipv4.address) { + INTERFACES_INTERFACE_LIST_FREE((*el)->interface.ipv4.address); + } + // element data free(*el); *el = NULL; diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c index 82a1b0f7..210dd74b 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c @@ -1,7 +1,9 @@ #include "address.h" #include "plugin/types.h" #include "src/utlist.h" +#include #include +#include interfaces_interface_ipv4_address_element_t* interfaces_interface_ipv4_address_new(void) { diff --git a/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h b/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h index 28f1c92a..853345f0 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h +++ b/src/interfaces/src/plugin/data/interfaces/interface/linked_list.h @@ -19,19 +19,19 @@ (ll_ptr) = NULL; \ } while (0) -#define INTERFACES_INTERFACE_LIST_FREE(ll_ptr) \ - _Generic((ll_ptr), \ - interfaces_interfaces_interface_ipv4_address_element_t * \ - : interfaces_interface_ipv4_address_free \ - interfaces_interfaces_interface_ipv4_neighbor_element_t \ - * \ - : interfaces_interface_ipv4_neighbor_free \ - interfaces_interfaces_interface_ipv6_address_element_t \ - * \ - : interfaces_interface_ipv6_address_free \ - interfaces_interfaces_interface_ipv6_neighbor_element_t \ - * \ - : interfaces_interface_ipv6_neighbor_free)(&(ll_ptr)) +#define INTERFACES_INTERFACE_LIST_FREE(ll_ptr) \ + _Generic((ll_ptr), \ + interfaces_interface_ipv4_address_element_t * \ + : interfaces_interface_ipv4_address_free, \ + interfaces_interface_ipv4_neighbor_element_t \ + * \ + : interfaces_interface_ipv4_neighbor_free, \ + interfaces_interface_ipv6_address_element_t \ + * \ + : interfaces_interface_ipv6_address_free, \ + interfaces_interface_ipv6_neighbor_element_t \ + * \ + : interfaces_interface_ipv6_neighbor_free)(&ll_ptr) /* prepend since ordering doesn't matter - O(1) */ #define INTERFACES_INTERFACE_LIST_ADD_ELEMENT(ll_ptr, new_element_ptr) \ diff --git a/src/interfaces/src/plugin/data/interfaces/interface_state.c b/src/interfaces/src/plugin/data/interfaces/interface_state.c index cfacc597..426dff94 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface_state.c +++ b/src/interfaces/src/plugin/data/interfaces/interface_state.c @@ -1,5 +1,6 @@ #include "interface_state.h" #include "src/uthash.h" +#include interfaces_interface_state_hash_element_t* interfaces_interface_state_hash_new(void) { diff --git a/src/interfaces/src/plugin/subscription/change.c b/src/interfaces/src/plugin/subscription/change.c index 8f2150ea..9872cf7d 100644 --- a/src/interfaces/src/plugin/subscription/change.c +++ b/src/interfaces/src/plugin/subscription/change.c @@ -3,6 +3,7 @@ #include "plugin/context.h" #include +#include #include #include diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 9b76027e..9001b349 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -29,6 +29,8 @@ #include #include +#include + static struct rtnl_link* interfaces_get_current_link(interfaces_ctx_t* ctx, sr_session_ctx_t* session, const char* xpath); static int interfaces_extract_interface_name(sr_session_ctx_t* session, const char* xpath, char* buffer, size_t buffer_size); static int interfaces_extract_interface_address_ip(sr_session_ctx_t* session, const char* xpath, char* buffer, size_t buffer_size); From 1db65fb671d4a3eb68790ba76919e132a122a870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 00:35:27 +0200 Subject: [PATCH 129/247] interfaces-plugin: free all created lists from the hash element --- .../src/plugin/data/interfaces/interface.c | 14 ++++++++++++++ src/interfaces/src/plugin/startup/store.c | 3 +-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/interfaces/src/plugin/data/interfaces/interface.c b/src/interfaces/src/plugin/data/interfaces/interface.c index e4425349..92cbf54d 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface.c +++ b/src/interfaces/src/plugin/data/interfaces/interface.c @@ -56,10 +56,24 @@ void interfaces_interface_hash_element_free(interfaces_interface_hash_element_t* free((*el)->interface.parent_interface); } + // lists + if ((*el)->interface.ipv4.address) { INTERFACES_INTERFACE_LIST_FREE((*el)->interface.ipv4.address); } + if ((*el)->interface.ipv6.address) { + INTERFACES_INTERFACE_LIST_FREE((*el)->interface.ipv6.address); + } + + if ((*el)->interface.ipv4.address) { + INTERFACES_INTERFACE_LIST_FREE((*el)->interface.ipv4.neighbor); + } + + if ((*el)->interface.ipv6.address) { + INTERFACES_INTERFACE_LIST_FREE((*el)->interface.ipv6.neighbor); + } + // element data free(*el); *el = NULL; diff --git a/src/interfaces/src/plugin/startup/store.c b/src/interfaces/src/plugin/startup/store.c index 550633f1..133be4fd 100644 --- a/src/interfaces/src/plugin/startup/store.c +++ b/src/interfaces/src/plugin/startup/store.c @@ -61,8 +61,7 @@ static int interfaces_startup_store_interface(void* priv, const struct lyd_node* interfaces_interface_hash_element_t* if_hash = NULL; struct lyd_node* interface_node = NULL; - interface_node - = srpc_ly_tree_get_child_list(parent_container, "interface"); + interface_node = srpc_ly_tree_get_child_list(parent_container, "interface"); if (interface_node == NULL) { SRPLG_LOG_ERR(PLUGIN_NAME, "srpc_ly_tree_get_child_leaf returned NULL for 'interfaces'"); goto error_out; From 39aeeb5e6499ee68d1ce822888050948567c7a89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 00:36:54 +0200 Subject: [PATCH 130/247] interfaces-plugin: remove unused function --- src/interfaces/src/plugin/data/interfaces/interface.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/interfaces/src/plugin/data/interfaces/interface.h b/src/interfaces/src/plugin/data/interfaces/interface.h index dacdec58..80e450c1 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface.h +++ b/src/interfaces/src/plugin/data/interfaces/interface.h @@ -41,7 +41,6 @@ int interfaces_interface_hash_element_set_ipv4(interfaces_interface_hash_element int interfaces_interface_hash_element_set_ipv4_enabled(interfaces_interface_hash_element_t** el, uint8_t enabled); int interfaces_interface_hash_element_set_ipv4_forwarding(interfaces_interface_hash_element_t** el, uint8_t forwarding); int interfaces_interface_hash_element_set_ipv4_mtu(interfaces_interface_hash_element_t** el, uint16_t mtu); -int interfaces_interface_hash_element_set_ipv4_address(interfaces_interface_hash_element_t** el, interfaces_interface_ipv4_address_element_t* head); /* IPv6 From 70ebacc5d122646c9635b3447f68c7d5e9e2052f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 00:49:03 +0200 Subject: [PATCH 131/247] interfaces-plugin: add initial interface hash check API functionality --- .../src/plugin/api/interfaces/check.c | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin/api/interfaces/check.c b/src/interfaces/src/plugin/api/interfaces/check.c index f5ed0178..2f9c62c6 100644 --- a/src/interfaces/src/plugin/api/interfaces/check.c +++ b/src/interfaces/src/plugin/api/interfaces/check.c @@ -1,8 +1,38 @@ #include "check.h" +#include "plugin/api/interfaces/load.h" +#include "plugin/common.h" +#include "src/uthash.h" #include "srpc/types.h" +#include "sysrepo.h" + +#include srpc_check_status_t interfaces_check_interface(interfaces_ctx_t* ctx, const interfaces_interface_hash_element_t* if_hash) { - srpc_check_status_t status = srpc_check_status_non_existant; + srpc_check_status_t status = srpc_check_status_none; + int error = 0; + + // system data + interfaces_interface_hash_element_t* system_if_hash = NULL; + const interfaces_interface_hash_element_t *if_iter = NULL, *if_tmp = NULL; + + // load system interfaces + // SRPC_SAFE_CALL_ERR(error, interfaces_load_interface(ctx, &system_if_hash), error_out); + + HASH_ITER(hh, if_hash, if_iter, if_tmp) + { + } + + status = srpc_check_status_non_existant; + + goto out; + +error_out: + status = srpc_check_status_error; + +out: + // free system interface data + interfaces_interface_hash_free(&system_if_hash); + return status; } From 4181107b83098c99b407bc73db6906ff2cdf3012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 12:35:51 +0200 Subject: [PATCH 132/247] interfaces-plugin: remove unused variables --- .../src/plugin/subscription/operational.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 9001b349..2a402a00 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -39,7 +39,7 @@ static int interfaces_get_system_boot_time(char* buffer, size_t buffer_size); int interfaces_subscription_operational_interfaces_interface_admin_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; - void* error_ptr = NULL; + // void* error_ptr = NULL; const struct ly_ctx* ly_ctx = NULL; if (*parent == NULL) { @@ -1113,7 +1113,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_erro int interfaces_subscription_operational_interfaces_interface_statistics_in_discard_unknown_encaps(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; - void* error_ptr = NULL; + // void* error_ptr = NULL; const struct ly_ctx* ly_ctx = NULL; if (*parent == NULL) { @@ -1136,7 +1136,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_disca int interfaces_subscription_operational_interfaces_interface_carrier_delay_carrier_transitions(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; - void* error_ptr = NULL; + // void* error_ptr = NULL; const struct ly_ctx* ly_ctx = NULL; if (*parent == NULL) { @@ -1159,7 +1159,7 @@ int interfaces_subscription_operational_interfaces_interface_carrier_delay_carri int interfaces_subscription_operational_interfaces_interface_carrier_delay_timer_running(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; - void* error_ptr = NULL; + // void* error_ptr = NULL; const struct ly_ctx* ly_ctx = NULL; if (*parent == NULL) { @@ -1182,7 +1182,7 @@ int interfaces_subscription_operational_interfaces_interface_carrier_delay_timer int interfaces_subscription_operational_interfaces_interface_dampening_penalty(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; - void* error_ptr = NULL; + // void* error_ptr = NULL; const struct ly_ctx* ly_ctx = NULL; if (*parent == NULL) { @@ -1205,7 +1205,7 @@ int interfaces_subscription_operational_interfaces_interface_dampening_penalty(s int interfaces_subscription_operational_interfaces_interface_dampening_suppressed(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; - void* error_ptr = NULL; + // void* error_ptr = NULL; const struct ly_ctx* ly_ctx = NULL; if (*parent == NULL) { @@ -1228,7 +1228,7 @@ int interfaces_subscription_operational_interfaces_interface_dampening_suppresse int interfaces_subscription_operational_interfaces_interface_dampening_time_remaining(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; - void* error_ptr = NULL; + // void* error_ptr = NULL; const struct ly_ctx* ly_ctx = NULL; if (*parent == NULL) { @@ -1251,7 +1251,7 @@ int interfaces_subscription_operational_interfaces_interface_dampening_time_rema int interfaces_subscription_operational_interfaces_interface_forwarding_mode(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; - void* error_ptr = NULL; + // void* error_ptr = NULL; const struct ly_ctx* ly_ctx = NULL; if (*parent == NULL) { @@ -1751,7 +1751,7 @@ int interfaces_subscription_operational_interfaces_interface_ipv6_neighbor(sr_se int interfaces_subscription_operational_interfaces_interface(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; - void* error_ptr = NULL; + // void* error_ptr = NULL; const struct ly_ctx* ly_ctx = NULL; interfaces_ctx_t* ctx = private_data; interfaces_nl_ctx_t* nl_ctx = &ctx->oper_ctx.nl_ctx; From 2f41b767b4b695cd4595a03dcef10921fe2eeeae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 12:57:17 +0200 Subject: [PATCH 133/247] interfaces-plugin: implement admin-status operational leaf --- .../src/plugin/subscription/operational.c | 59 ++++++++++++++++--- 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 2a402a00..71757705 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -39,15 +40,59 @@ static int interfaces_get_system_boot_time(char* buffer, size_t buffer_size); int interfaces_subscription_operational_interfaces_interface_admin_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; - // void* error_ptr = NULL; + void* error_ptr = NULL; + + // context const struct ly_ctx* ly_ctx = NULL; + interfaces_ctx_t* ctx = private_data; - if (*parent == NULL) { - ly_ctx = sr_acquire_context(sr_session_get_connection(session)); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_acquire_context() failed"); - goto error_out; - } + enum { + admin_status_none = 0, + admin_status_up, + admin_status_down, + admin_status_testing, + } admin_status + = admin_status_none; + + const char* adminstate_map[] = { + [admin_status_none] = "none", + [admin_status_up] = "up", + [admin_status_down] = "down", + [admin_status_testing] = "testing", + }; + + // libnl + struct rtnl_link* link = NULL; + + char xpath_buffer[PATH_MAX] = { 0 }; + + // there needs to be an allocated link cache in memory + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "interface") == 0); + + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); + + // get admin status + const unsigned int flags = rtnl_link_get_flags(link); + + if ((flags & IFF_UP) || (flags & IFF_RUNNING)) { + admin_status = admin_status_up; + } else { + admin_status = admin_status_down; + } + + if (admin_status != admin_status_none) { + const char* admin_status_str = adminstate_map[admin_status]; + SRPLG_LOG_INF(PLUGIN_NAME, "oper-status(%s) = %s", rtnl_link_get_name(link), admin_status_str); + + // add admin-status node + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_admin_status(ly_ctx, *parent, admin_status_str), error_out); + } else { + SRPLG_LOG_INF(PLUGIN_NAME, "Unable to determine admin-status for link %s", rtnl_link_get_name(link)); } goto out; From 6e9383a83870e5c71f533b74f4ff8de6b217e420 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 13:44:31 +0200 Subject: [PATCH 134/247] interfaces-plugin: remove interface log --- src/interfaces/src/plugin/subscription/operational.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 71757705..de77ce01 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -1840,8 +1840,6 @@ int interfaces_subscription_operational_interfaces_interface(sr_session_ctx_t* s // iterate links and add them to the operational DS link_iter = (struct rtnl_link*)nl_cache_get_first(nl_ctx->link_cache); while (link_iter) { - SRPLG_LOG_INF(PLUGIN_NAME, "Interface %s", rtnl_link_get_name(link_iter)); - // add interface SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface(ly_ctx, *parent, &interface_list_node, rtnl_link_get_name(link_iter)), error_out); From d58f0ceb44e5c43a7a1cf8c5ecc70acdc9911cb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 13:48:58 +0200 Subject: [PATCH 135/247] interfaces-plugin: use SRPC safe call API for snprintf() usage for in-unicast-pkts --- src/interfaces/src/plugin/subscription/operational.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index de77ce01..4dbc9545 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -604,11 +604,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_unica const uint64_t in_multicast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_INMCASTPKTS); const uint64_t in_unicast_pkts = in_pkts - in_broadcast_pkts - in_multicast_pkts; - error = snprintf(in_unicast_pkts_buffer, sizeof(in_unicast_pkts_buffer), "%lu", in_unicast_pkts); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); - goto error_out; - } + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(in_unicast_pkts_buffer, sizeof(in_unicast_pkts_buffer), "%lu", in_unicast_pkts), error_out); SRPLG_LOG_INF(PLUGIN_NAME, "in-unicast-pkts(%s) = %s", rtnl_link_get_name(link), in_unicast_pkts_buffer); From 78f84fc4d518d26cf8035e05affa35dc005830f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 13:50:23 +0200 Subject: [PATCH 136/247] interfaces-plugin: use SRPC safe call API for snprintf() usage for if-index --- src/interfaces/src/plugin/subscription/operational.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 4dbc9545..7d61c780 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -244,11 +244,7 @@ int interfaces_subscription_operational_interfaces_interface_if_index(sr_session // get if-index const int ifindex = rtnl_link_get_ifindex(link); - error = snprintf(ifindex_buffer, sizeof(ifindex_buffer), "%d", ifindex); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); - goto error_out; - } + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(ifindex_buffer, sizeof(ifindex_buffer), "%d", ifindex), error_out); SRPLG_LOG_INF(PLUGIN_NAME, "if-index(%s) = %s", rtnl_link_get_name(link), ifindex_buffer); From b17a010bc2690091a0b62573fd4f924473488e41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 13:51:47 +0200 Subject: [PATCH 137/247] interfaces-plugin: use SRPC safe call API around snprintf() for speed operational leaf --- src/interfaces/src/plugin/subscription/operational.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 7d61c780..c345d542 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -455,11 +455,8 @@ int interfaces_subscription_operational_interfaces_interface_speed(sr_session_ct // get speed const uint64_t speed = rtnl_tc_get_stat(tc, RTNL_TC_RATE_BPS); - error = snprintf(speed_buffer, sizeof(speed_buffer), "%lu", speed); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); - goto error_out; - } + + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(speed_buffer, sizeof(speed_buffer), "%lu", speed), error_out); SRPLG_LOG_INF(PLUGIN_NAME, "speed(%s) = %s", rtnl_link_get_name(link), speed_buffer); From 4982b446dc56c7bfe0662be752185258d2148660 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 13:52:31 +0200 Subject: [PATCH 138/247] interfaces-plugin: use SRPC safe call API around snprintf() for in-octets operational leaf --- src/interfaces/src/plugin/subscription/operational.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index c345d542..ba394698 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -546,11 +546,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_octet const uint64_t in_octets = rtnl_link_get_stat(link, RTNL_LINK_RX_BYTES); - error = snprintf(in_octets_buffer, sizeof(in_octets_buffer), "%lu", in_octets); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); - goto error_out; - } + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(in_octets_buffer, sizeof(in_octets_buffer), "%lu", in_octets), error_out); SRPLG_LOG_INF(PLUGIN_NAME, "in-octets(%s) = %s", rtnl_link_get_name(link), in_octets_buffer); From 076e1fd2a53dde5368442b8eb8e0b3986f6ac014 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 13:53:15 +0200 Subject: [PATCH 139/247] interfaces-plugin: use SRPC safe call API around snprintf() for in-broadcast-pkts operational leaf --- src/interfaces/src/plugin/subscription/operational.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index ba394698..52b1fbc3 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -637,11 +637,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_broad const uint64_t in_broadcast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_INBCASTPKTS); - error = snprintf(in_broadcast_pkts_buffer, sizeof(in_broadcast_pkts_buffer), "%lu", in_broadcast_pkts); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); - goto error_out; - } + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(in_broadcast_pkts_buffer, sizeof(in_broadcast_pkts_buffer), "%lu", in_broadcast_pkts), error_out); SRPLG_LOG_INF(PLUGIN_NAME, "in-broadcast-pkts(%s) = %s", rtnl_link_get_name(link), in_broadcast_pkts_buffer); From 753674577508874e19102473fc2509fe0d1c0ffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 13:54:05 +0200 Subject: [PATCH 140/247] interfaces-plugin: use SRPC safe call API around snprintf() for in-multicast-pkts operational leaf --- src/interfaces/src/plugin/subscription/operational.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 52b1fbc3..472dc499 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -681,11 +681,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_multi const uint64_t in_multicast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_INMCASTPKTS); - error = snprintf(in_multicast_pkts_buffer, sizeof(in_multicast_pkts_buffer), "%lu", in_multicast_pkts); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); - goto error_out; - } + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(in_multicast_pkts_buffer, sizeof(in_multicast_pkts_buffer), "%lu", in_multicast_pkts), error_out); SRPLG_LOG_INF(PLUGIN_NAME, "in-multicast-pkts(%s) = %s", rtnl_link_get_name(link), in_multicast_pkts_buffer); From f07984292375342dba44e6f167cf96454ac6e64e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 13:57:41 +0200 Subject: [PATCH 141/247] interfaces-plugin: use SRPC safe call API around snprintf() --- .../src/plugin/subscription/operational.c | 60 ++++--------------- 1 file changed, 10 insertions(+), 50 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 472dc499..d3b414d7 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -725,11 +725,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_disca const uint32_t in_discards = (uint32_t)rtnl_link_get_stat(link, RTNL_LINK_RX_DROPPED); - error = snprintf(in_discards_buffer, sizeof(in_discards_buffer), "%u", in_discards); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); - goto error_out; - } + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(in_discards_buffer, sizeof(in_discards_buffer), "%u", in_discards), error_out); SRPLG_LOG_INF(PLUGIN_NAME, "in-discards(%s) = %s", rtnl_link_get_name(link), in_discards_buffer); @@ -773,11 +769,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_error const uint32_t in_errors = (uint32_t)rtnl_link_get_stat(link, RTNL_LINK_RX_ERRORS); - error = snprintf(in_errors_buffer, sizeof(in_errors_buffer), "%u", in_errors); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); - goto error_out; - } + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(in_errors_buffer, sizeof(in_errors_buffer), "%u", in_errors), error_out); SRPLG_LOG_INF(PLUGIN_NAME, "in-errors(%s) = %s", rtnl_link_get_name(link), in_errors_buffer); @@ -821,11 +813,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_in_unkno const uint32_t in_unknown_protos = (uint32_t)rtnl_link_get_stat(link, RTNL_LINK_IP6_INUNKNOWNPROTOS); - error = snprintf(in_unknown_protos_buffer, sizeof(in_unknown_protos_buffer), "%u", in_unknown_protos); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); - goto error_out; - } + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(in_unknown_protos_buffer, sizeof(in_unknown_protos_buffer), "%u", in_unknown_protos), error_out); SRPLG_LOG_INF(PLUGIN_NAME, "in-unknown-protos(%s) = %s", rtnl_link_get_name(link), in_unknown_protos_buffer); @@ -869,11 +857,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_octe const uint64_t out_octets = rtnl_link_get_stat(link, RTNL_LINK_TX_BYTES); - error = snprintf(out_octets_buffer, sizeof(out_octets_buffer), "%lu", out_octets); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); - goto error_out; - } + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(out_octets_buffer, sizeof(out_octets_buffer), "%lu", out_octets), error_out); SRPLG_LOG_INF(PLUGIN_NAME, "out-octets(%s) = %s", rtnl_link_get_name(link), out_octets_buffer); @@ -920,11 +904,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_unic const uint64_t out_multicast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_OUTMCASTPKTS); const uint64_t out_unicast_pkts = out_pkts - out_broadcast_pkts - out_multicast_pkts; - error = snprintf(out_unicast_pkts_buffer, sizeof(out_unicast_pkts_buffer), "%lu", out_unicast_pkts); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); - goto error_out; - } + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(out_unicast_pkts_buffer, sizeof(out_unicast_pkts_buffer), "%lu", out_unicast_pkts), error_out); SRPLG_LOG_INF(PLUGIN_NAME, "out-unicast-pkts(%s) = %s", rtnl_link_get_name(link), out_unicast_pkts_buffer); @@ -968,11 +948,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_broa const uint64_t out_broadcast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_OUTBCASTPKTS); - error = snprintf(out_broadcast_pkts_buffer, sizeof(out_broadcast_pkts_buffer), "%lu", out_broadcast_pkts); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); - goto error_out; - } + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(out_broadcast_pkts_buffer, sizeof(out_broadcast_pkts_buffer), "%lu", out_broadcast_pkts), error_out); SRPLG_LOG_INF(PLUGIN_NAME, "out-broadcast-pkts(%s) = %s", rtnl_link_get_name(link), out_broadcast_pkts_buffer); @@ -1016,11 +992,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_mult const uint64_t out_multicast_pkts = rtnl_link_get_stat(link, RTNL_LINK_IP6_OUTMCASTPKTS); - error = snprintf(out_multicast_pkts_buffer, sizeof(out_multicast_pkts_buffer), "%lu", out_multicast_pkts); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); - goto error_out; - } + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(out_multicast_pkts_buffer, sizeof(out_multicast_pkts_buffer), "%lu", out_multicast_pkts), error_out); SRPLG_LOG_INF(PLUGIN_NAME, "out-multicast-pkts(%s) = %s", rtnl_link_get_name(link), out_multicast_pkts_buffer); @@ -1064,11 +1036,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_disc const uint64_t out_discards = rtnl_link_get_stat(link, RTNL_LINK_TX_DROPPED); - error = snprintf(out_discards_buffer, sizeof(out_discards_buffer), "%lu", out_discards); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); - goto error_out; - } + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(out_discards_buffer, sizeof(out_discards_buffer), "%lu", out_discards), error_out); SRPLG_LOG_INF(PLUGIN_NAME, "out-discards(%s) = %s", rtnl_link_get_name(link), out_discards_buffer); @@ -1112,11 +1080,7 @@ int interfaces_subscription_operational_interfaces_interface_statistics_out_erro const uint64_t out_errors = rtnl_link_get_stat(link, RTNL_LINK_TX_DROPPED); - error = snprintf(out_errors_buffer, sizeof(out_errors_buffer), "%lu", out_errors); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed (%d)", error); - goto error_out; - } + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(out_errors_buffer, sizeof(out_errors_buffer), "%lu", out_errors), error_out); SRPLG_LOG_INF(PLUGIN_NAME, "out-errors(%s) = %s", rtnl_link_get_name(link), out_errors_buffer); @@ -1881,11 +1845,7 @@ static int interfaces_extract_interface_name(sr_session_ctx_t* session, const ch SRPC_SAFE_CALL_PTR(name, sr_xpath_key_value(xpath_copy, "interface", "name", &xpath_ctx), error_out); // store to buffer - error = snprintf(buffer, buffer_size, "%s", name); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf() failed"); - goto error_out; - } + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(buffer, buffer_size, "%s", name), error_out); error = 0; goto out; From 89fdb1e7b183667eaa7020723952307333ef52b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 14:32:03 +0200 Subject: [PATCH 142/247] interfaces-plugin: implement operational IPv4 neighbor list --- src/interfaces/src/plugin/context.h | 1 + .../src/plugin/subscription/operational.c | 63 +++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/src/interfaces/src/plugin/context.h b/src/interfaces/src/plugin/context.h index 3aad79e9..918e8ead 100644 --- a/src/interfaces/src/plugin/context.h +++ b/src/interfaces/src/plugin/context.h @@ -28,6 +28,7 @@ struct interfaces_nl_ctx_s { struct nl_sock* socket; struct nl_cache* link_cache; struct nl_cache* addr_cache; + struct nl_cache* neigh_cache; struct nl_cache_mngr* link_cache_manager; }; diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index d3b414d7..c9f77733 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -4,6 +4,7 @@ #include "netlink/addr.h" #include "netlink/cache.h" #include "netlink/object.h" +#include "netlink/route/neighbour.h" #include "netlink/route/tc.h" #include "netlink/socket.h" #include "plugin/common.h" @@ -1444,7 +1445,22 @@ int interfaces_subscription_operational_interfaces_interface_ipv4_neighbor_origi int interfaces_subscription_operational_interfaces_interface_ipv4_neighbor(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + int rc = 0; + void* error_ptr = NULL; + + interfaces_ctx_t* ctx = private_data; + interfaces_oper_ctx_t* oper_ctx = &ctx->oper_ctx; + + char xpath_buffer[PATH_MAX] = { 0 }; + char dst_buffer[20] = { 0 }; + char ll_buffer[100] = { 0 }; + const struct ly_ctx* ly_ctx = NULL; + struct lyd_node* address_node = NULL; + + struct rtnl_link* link = NULL; + struct rtnl_neigh* neigh_iter = NULL; + struct nl_addr *dst_addr = NULL, *ll_addr = NULL; if (*parent == NULL) { ly_ctx = sr_acquire_context(sr_session_get_connection(session)); @@ -1454,6 +1470,49 @@ int interfaces_subscription_operational_interfaces_interface_ipv4_neighbor(sr_se } } + // there needs to be an allocated link cache in memory + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "ipv4") == 0); + + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); + + neigh_iter = (struct rtnl_neigh*)nl_cache_get_first(oper_ctx->nl_ctx.neigh_cache); + + while (neigh_iter) { + // check for interface IPv4 neighbor + if (rtnl_neigh_get_ifindex(neigh_iter) == rtnl_link_get_ifindex(link) && rtnl_neigh_get_family(neigh_iter) == AF_INET) { + SRPLG_LOG_INF(PLUGIN_NAME, "Found IPv4 neighbor for %s", rtnl_link_get_name(link)); + + // IP + SRPC_SAFE_CALL_PTR(dst_addr, rtnl_neigh_get_dst(neigh_iter), error_out); + SRPC_SAFE_CALL_PTR(error_ptr, nl_addr2str(dst_addr, dst_buffer, sizeof(dst_buffer)), error_out); + + // link-layer-address + SRPC_SAFE_CALL_PTR(ll_addr, rtnl_neigh_get_lladdr(neigh_iter), error_out); + SRPC_SAFE_CALL_PTR(error_ptr, nl_addr2str(ll_addr, ll_buffer, sizeof(ll_buffer)), error_out); + + // remove prefix from IP + char* prefix = strchr(dst_buffer, '/'); + if (prefix) { + *prefix = 0; + } + + SRPLG_LOG_INF(PLUGIN_NAME, "ipv4:neighbor(%s) = %s | %s", rtnl_link_get_name(link), dst_buffer, ll_buffer); + + // neighbor IP + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_neighbor(ly_ctx, *parent, &address_node, dst_buffer), error_out); + + // link-layer-address + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_neighbor_link_layer_address(ly_ctx, address_node, ll_buffer), error_out); + } + + neigh_iter = (struct rtnl_neigh*)nl_cache_get_next((struct nl_object*)neigh_iter); + } + goto out; error_out: @@ -1759,12 +1818,16 @@ int interfaces_subscription_operational_interfaces_interface(sr_session_ctx_t* s if (nl_ctx->link_cache) { nl_cache_refill(nl_ctx->socket, nl_ctx->link_cache); nl_cache_refill(nl_ctx->socket, nl_ctx->addr_cache); + nl_cache_refill(nl_ctx->socket, nl_ctx->neigh_cache); } else { // allocate new link cache SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(nl_ctx->socket, AF_UNSPEC, &nl_ctx->link_cache), error_out); // allocate new address cache SRPC_SAFE_CALL_ERR(error, rtnl_addr_alloc_cache(nl_ctx->socket, &nl_ctx->addr_cache), error_out); + + // allocate new neighbor cache + SRPC_SAFE_CALL_ERR(error, rtnl_neigh_alloc_cache(nl_ctx->socket, &nl_ctx->neigh_cache), error_out); } if (*parent == NULL) { From 121b3817b57f4f210e2c57b9c126987aec384c8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 14:33:50 +0200 Subject: [PATCH 143/247] interfaces-plugin: implement operational IPv6 neighbor list --- .../src/plugin/subscription/operational.c | 58 ++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index c9f77733..23a2aaef 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -1445,7 +1445,6 @@ int interfaces_subscription_operational_interfaces_interface_ipv4_neighbor_origi int interfaces_subscription_operational_interfaces_interface_ipv4_neighbor(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; - int rc = 0; void* error_ptr = NULL; interfaces_ctx_t* ctx = private_data; @@ -1774,7 +1773,21 @@ int interfaces_subscription_operational_interfaces_interface_ipv6_neighbor_state int interfaces_subscription_operational_interfaces_interface_ipv6_neighbor(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; + + interfaces_ctx_t* ctx = private_data; + interfaces_oper_ctx_t* oper_ctx = &ctx->oper_ctx; + + char xpath_buffer[PATH_MAX] = { 0 }; + char dst_buffer[100] = { 0 }; + char ll_buffer[100] = { 0 }; + const struct ly_ctx* ly_ctx = NULL; + struct lyd_node* address_node = NULL; + + struct rtnl_link* link = NULL; + struct rtnl_neigh* neigh_iter = NULL; + struct nl_addr *dst_addr = NULL, *ll_addr = NULL; if (*parent == NULL) { ly_ctx = sr_acquire_context(sr_session_get_connection(session)); @@ -1784,6 +1797,49 @@ int interfaces_subscription_operational_interfaces_interface_ipv6_neighbor(sr_se } } + // there needs to be an allocated link cache in memory + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "ipv6") == 0); + + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); + + neigh_iter = (struct rtnl_neigh*)nl_cache_get_first(oper_ctx->nl_ctx.neigh_cache); + + while (neigh_iter) { + // check for interface IPv6 neighbor + if (rtnl_neigh_get_ifindex(neigh_iter) == rtnl_link_get_ifindex(link) && rtnl_neigh_get_family(neigh_iter) == AF_INET6) { + SRPLG_LOG_INF(PLUGIN_NAME, "Found IPv6 neighbor for %s", rtnl_link_get_name(link)); + + // IP + SRPC_SAFE_CALL_PTR(dst_addr, rtnl_neigh_get_dst(neigh_iter), error_out); + SRPC_SAFE_CALL_PTR(error_ptr, nl_addr2str(dst_addr, dst_buffer, sizeof(dst_buffer)), error_out); + + // link-layer-address + SRPC_SAFE_CALL_PTR(ll_addr, rtnl_neigh_get_lladdr(neigh_iter), error_out); + SRPC_SAFE_CALL_PTR(error_ptr, nl_addr2str(ll_addr, ll_buffer, sizeof(ll_buffer)), error_out); + + // remove prefix from IP + char* prefix = strchr(dst_buffer, '/'); + if (prefix) { + *prefix = 0; + } + + SRPLG_LOG_INF(PLUGIN_NAME, "ipv6:neighbor(%s) = %s | %s", rtnl_link_get_name(link), dst_buffer, ll_buffer); + + // neighbor IP + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv6_neighbor(ly_ctx, *parent, &address_node, dst_buffer), error_out); + + // link-layer-address + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv6_neighbor_link_layer_address(ly_ctx, address_node, ll_buffer), error_out); + } + + neigh_iter = (struct rtnl_neigh*)nl_cache_get_next((struct nl_object*)neigh_iter); + } + goto out; error_out: From 9a011c6d0f50777fb061486ba83c06b28b169d68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 14:58:16 +0200 Subject: [PATCH 144/247] interfaces-plugin: implement operational IPv4 neighbor origin leaf --- .../src/plugin/subscription/operational.c | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 23a2aaef..6e41fbaa 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -36,6 +36,7 @@ static struct rtnl_link* interfaces_get_current_link(interfaces_ctx_t* ctx, sr_session_ctx_t* session, const char* xpath); static int interfaces_extract_interface_name(sr_session_ctx_t* session, const char* xpath, char* buffer, size_t buffer_size); static int interfaces_extract_interface_address_ip(sr_session_ctx_t* session, const char* xpath, char* buffer, size_t buffer_size); +static int interfaces_extract_interface_neighbor_ip(sr_session_ctx_t* session, const char* xpath, char* buffer, size_t buffer_size); static int interfaces_get_system_boot_time(char* buffer, size_t buffer_size); int interfaces_subscription_operational_interfaces_interface_admin_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) @@ -1423,8 +1424,20 @@ int interfaces_subscription_operational_interfaces_interface_ipv4_address(sr_ses int interfaces_subscription_operational_interfaces_interface_ipv4_neighbor_origin(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; + + interfaces_ctx_t* ctx = private_data; + interfaces_oper_ctx_t* oper_ctx = &ctx->oper_ctx; + + char xpath_buffer[PATH_MAX] = { 0 }; + char ip_buffer[20] = { 0 }; + const struct ly_ctx* ly_ctx = NULL; + struct rtnl_link* link = NULL; + struct rtnl_neigh* neigh = NULL; + struct nl_addr* neigh_addr = NULL; + if (*parent == NULL) { ly_ctx = sr_acquire_context(sr_session_get_connection(session)); if (ly_ctx == NULL) { @@ -1433,12 +1446,39 @@ int interfaces_subscription_operational_interfaces_interface_ipv4_neighbor_origi } } + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "neighbor") == 0); + + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); + + // get IP + SRPC_SAFE_CALL_ERR(error, interfaces_extract_interface_neighbor_ip(session, xpath_buffer, ip_buffer, sizeof(ip_buffer)), error_out); + + // parse address + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(ip_buffer, AF_INET, &neigh_addr), error_out); + + // get neighbor + SRPC_SAFE_CALL_PTR(neigh, rtnl_neigh_get(oper_ctx->nl_ctx.neigh_cache, rtnl_link_get_ifindex(link), neigh_addr), error_out); + + // get address origin - static or dynamic + const char* origin = (rtnl_neigh_get_flags(neigh) & NTF_ROUTER) > 0 ? "dynamic" : "static"; + + SRPLG_LOG_INF(PLUGIN_NAME, "origin(interface[%s]:neighbor[%s]) = %s", rtnl_link_get_name(link), ip_buffer, origin); + + // add origin + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_neighbor_origin(ly_ctx, *parent, origin), error_out); + goto out; error_out: error = SR_ERR_CALLBACK_FAILED; out: + return error; } @@ -2013,6 +2053,39 @@ static int interfaces_extract_interface_address_ip(sr_session_ctx_t* session, co return error; } +static int interfaces_extract_interface_neighbor_ip(sr_session_ctx_t* session, const char* xpath, char* buffer, size_t buffer_size) +{ + int error = 0; + + const char* ip = NULL; + char* xpath_copy = NULL; + + sr_xpath_ctx_t xpath_ctx = { 0 }; + + // copy xpath due to changing it when using xpath_ctx from sysrepo + SRPC_SAFE_CALL_PTR(xpath_copy, strdup(xpath), error_out); + + // extract key + SRPC_SAFE_CALL_PTR(ip, sr_xpath_key_value(xpath_copy, "neighbor", "ip", &xpath_ctx), error_out); + + // store to buffer + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(buffer, buffer_size, "%s", ip), error_out); + + error = 0; + + goto out; + +error_out: + error = -1; + +out: + if (xpath_copy) { + free(xpath_copy); + } + + return error; +} + static int interfaces_get_system_boot_time(char* buffer, size_t buffer_size) { time_t now = 0; From 4f9f91e79193fcc3b58b0e519a8b19e209a2bf09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 14:59:01 +0200 Subject: [PATCH 145/247] interfaces-plugin: implement operational IPv6 neighbor origin leaf --- .../src/plugin/subscription/operational.c | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 6e41fbaa..74e09f2b 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -1747,8 +1747,20 @@ int interfaces_subscription_operational_interfaces_interface_ipv6_address(sr_ses int interfaces_subscription_operational_interfaces_interface_ipv6_neighbor_origin(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; + + interfaces_ctx_t* ctx = private_data; + interfaces_oper_ctx_t* oper_ctx = &ctx->oper_ctx; + + char xpath_buffer[PATH_MAX] = { 0 }; + char ip_buffer[100] = { 0 }; + const struct ly_ctx* ly_ctx = NULL; + struct rtnl_link* link = NULL; + struct rtnl_neigh* neigh = NULL; + struct nl_addr* neigh_addr = NULL; + if (*parent == NULL) { ly_ctx = sr_acquire_context(sr_session_get_connection(session)); if (ly_ctx == NULL) { @@ -1757,12 +1769,39 @@ int interfaces_subscription_operational_interfaces_interface_ipv6_neighbor_origi } } + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "neighbor") == 0); + + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); + + // get IP + SRPC_SAFE_CALL_ERR(error, interfaces_extract_interface_neighbor_ip(session, xpath_buffer, ip_buffer, sizeof(ip_buffer)), error_out); + + // parse address + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(ip_buffer, AF_INET6, &neigh_addr), error_out); + + // get neighbor + SRPC_SAFE_CALL_PTR(neigh, rtnl_neigh_get(oper_ctx->nl_ctx.neigh_cache, rtnl_link_get_ifindex(link), neigh_addr), error_out); + + // get address origin - static or dynamic + const char* origin = (rtnl_neigh_get_flags(neigh) & NTF_ROUTER) > 0 ? "dynamic" : "static"; + + SRPLG_LOG_INF(PLUGIN_NAME, "origin(interface[%s]:neighbor[%s]) = %s", rtnl_link_get_name(link), ip_buffer, origin); + + // add origin + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_neighbor_origin(ly_ctx, *parent, origin), error_out); + goto out; error_out: error = SR_ERR_CALLBACK_FAILED; out: + return error; } From 029848350c992d212db3c979de5c80c271189725 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 15:00:03 +0200 Subject: [PATCH 146/247] interfaces-plugin: fix IPv6 address origin log message --- src/interfaces/src/plugin/subscription/operational.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 74e09f2b..85f2dfc2 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -1611,8 +1611,6 @@ int interfaces_subscription_operational_interfaces_interface_ipv6_address_origin // get IP SRPC_SAFE_CALL_ERR(error, interfaces_extract_interface_address_ip(session, xpath_buffer, ip_buffer, sizeof(ip_buffer)), error_out); - SRPLG_LOG_INF(PLUGIN_NAME, "origin(interface[%s]:address[%s]) = %s", rtnl_link_get_name(link), ip_buffer, ip_buffer); - // get prefix length from the operational DS SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(prefix_path_buffer, sizeof(prefix_path_buffer), "/ietf-interfaces:interfaces/interface[name=\"%s\"]/ietf-ip:ipv6/address[ip=\"%s\"]/prefix-length", rtnl_link_get_name(link), ip_buffer), error_out); SRPC_SAFE_CALL_ERR(error, sr_get_item(running_session, prefix_path_buffer, 0, &prefix_length_val), error_out); @@ -1629,6 +1627,8 @@ int interfaces_subscription_operational_interfaces_interface_ipv6_address_origin // get address origin - static or dynamic const char* origin = (rtnl_addr_get_flags(addr) & IFA_F_PERMANENT) > 0 ? "static" : "dhcp"; + SRPLG_LOG_INF(PLUGIN_NAME, "origin(interface[%s]:address[%s]) = %s", rtnl_link_get_name(link), ip_buffer, origin); + // add origin SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_address_origin(ly_ctx, *parent, origin), error_out); From d1c4e4cbfcefcea1fe58b558f98e0b5161312f32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 15:00:43 +0200 Subject: [PATCH 147/247] interfaces-plugin: fix IPv4 address origin log message --- src/interfaces/src/plugin/subscription/operational.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 85f2dfc2..5f6d8bb6 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -1309,8 +1309,6 @@ int interfaces_subscription_operational_interfaces_interface_ipv4_address_origin // get IP SRPC_SAFE_CALL_ERR(error, interfaces_extract_interface_address_ip(session, xpath_buffer, ip_buffer, sizeof(ip_buffer)), error_out); - SRPLG_LOG_INF(PLUGIN_NAME, "origin(interface[%s]:address[%s]) = %s", rtnl_link_get_name(link), ip_buffer, ip_buffer); - // get prefix length from the operational DS SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(prefix_path_buffer, sizeof(prefix_path_buffer), "/ietf-interfaces:interfaces/interface[name=\"%s\"]/ietf-ip:ipv4/address[ip=\"%s\"]/prefix-length", rtnl_link_get_name(link), ip_buffer), error_out); SRPC_SAFE_CALL_ERR(error, sr_get_item(running_session, prefix_path_buffer, 0, &prefix_length_val), error_out); @@ -1327,6 +1325,8 @@ int interfaces_subscription_operational_interfaces_interface_ipv4_address_origin // get address origin - static or dynamic const char* origin = (rtnl_addr_get_flags(addr) & IFA_F_PERMANENT) > 0 ? "static" : "dhcp"; + SRPLG_LOG_INF(PLUGIN_NAME, "origin(interface[%s]:address[%s]) = %s", rtnl_link_get_name(link), ip_buffer, origin); + // add origin SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_address_origin(ly_ctx, *parent, origin), error_out); From 604e6cdddfd3c6634bcf8f3e913968787dc035e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 15:03:51 +0200 Subject: [PATCH 148/247] interfaces-plugin: fix IPv6 address origin setting bug --- src/interfaces/src/plugin/subscription/operational.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 5f6d8bb6..a5338c6c 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -1630,7 +1630,7 @@ int interfaces_subscription_operational_interfaces_interface_ipv6_address_origin SRPLG_LOG_INF(PLUGIN_NAME, "origin(interface[%s]:address[%s]) = %s", rtnl_link_get_name(link), ip_buffer, origin); // add origin - SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_address_origin(ly_ctx, *parent, origin), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv6_address_origin(ly_ctx, *parent, origin), error_out); goto out; From 909f3c6638de7b78907b6ee874b1f07f297331ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 15:04:53 +0200 Subject: [PATCH 149/247] interfaces-plugin: fix IPv6 neighbor origin setting bug --- src/interfaces/src/plugin/subscription/operational.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index a5338c6c..234bf7a4 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -1793,7 +1793,7 @@ int interfaces_subscription_operational_interfaces_interface_ipv6_neighbor_origi SRPLG_LOG_INF(PLUGIN_NAME, "origin(interface[%s]:neighbor[%s]) = %s", rtnl_link_get_name(link), ip_buffer, origin); // add origin - SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_neighbor_origin(ly_ctx, *parent, origin), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv6_neighbor_origin(ly_ctx, *parent, origin), error_out); goto out; From 5bf8924bcd3d914fdda0dba322dd10d4d2afcb8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 15:12:05 +0200 Subject: [PATCH 150/247] interfaces-plugin: implement IPv6 neighbor state operational leaf --- .../src/plugin/subscription/operational.c | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 234bf7a4..39b90e2b 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -1830,8 +1830,20 @@ int interfaces_subscription_operational_interfaces_interface_ipv6_neighbor_is_ro int interfaces_subscription_operational_interfaces_interface_ipv6_neighbor_state(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; + + interfaces_ctx_t* ctx = private_data; + interfaces_oper_ctx_t* oper_ctx = &ctx->oper_ctx; + + char xpath_buffer[PATH_MAX] = { 0 }; + char ip_buffer[100] = { 0 }; + const struct ly_ctx* ly_ctx = NULL; + struct rtnl_link* link = NULL; + struct rtnl_neigh* neigh = NULL; + struct nl_addr* neigh_addr = NULL; + if (*parent == NULL) { ly_ctx = sr_acquire_context(sr_session_get_connection(session)); if (ly_ctx == NULL) { @@ -1840,12 +1852,52 @@ int interfaces_subscription_operational_interfaces_interface_ipv6_neighbor_state } } + const char* state_map[] = { + [NUD_INCOMPLETE] = "incomplete", + [NUD_REACHABLE] = "reachable", + [NUD_STALE] = "stale", + [NUD_DELAY] = "delay", + [NUD_PROBE] = "probe", + [NUD_FAILED] = "failed", + [NUD_NOARP] = "noarp", + [NUD_PERMANENT] = "permanent", + }; + + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "neighbor") == 0); + + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); + + // get IP + SRPC_SAFE_CALL_ERR(error, interfaces_extract_interface_neighbor_ip(session, xpath_buffer, ip_buffer, sizeof(ip_buffer)), error_out); + + // parse address + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(ip_buffer, AF_INET6, &neigh_addr), error_out); + + // get neighbor + SRPC_SAFE_CALL_PTR(neigh, rtnl_neigh_get(oper_ctx->nl_ctx.neigh_cache, rtnl_link_get_ifindex(link), neigh_addr), error_out); + + // get neighbor state - static or dynamic + const char* state = state_map[rtnl_neigh_get_state(neigh)]; + + SRPLG_LOG_INF(PLUGIN_NAME, "state(interface[%s]:neighbor[%s]) = %s", rtnl_link_get_name(link), ip_buffer, state); + + if (rtnl_neigh_get_state(neigh) != NUD_FAILED && rtnl_neigh_get_state(neigh) != NUD_NOARP && rtnl_neigh_get_state(neigh) != NUD_PERMANENT) { + // add state + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv6_neighbor_state(ly_ctx, *parent, state), error_out); + } + goto out; error_out: error = SR_ERR_CALLBACK_FAILED; out: + return error; } From ca16ff613a25245472573b3f7b32c106ac5d4f8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 15:15:13 +0200 Subject: [PATCH 151/247] interfaces-plugin: implement IPv6 neighbor is-router operational leaf --- .../src/plugin/subscription/operational.c | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index 39b90e2b..f1489f15 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -1808,8 +1808,20 @@ int interfaces_subscription_operational_interfaces_interface_ipv6_neighbor_origi int interfaces_subscription_operational_interfaces_interface_ipv6_neighbor_is_router(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + void* error_ptr = NULL; + + interfaces_ctx_t* ctx = private_data; + interfaces_oper_ctx_t* oper_ctx = &ctx->oper_ctx; + + char xpath_buffer[PATH_MAX] = { 0 }; + char ip_buffer[100] = { 0 }; + const struct ly_ctx* ly_ctx = NULL; + struct rtnl_link* link = NULL; + struct rtnl_neigh* neigh = NULL; + struct nl_addr* neigh_addr = NULL; + if (*parent == NULL) { ly_ctx = sr_acquire_context(sr_session_get_connection(session)); if (ly_ctx == NULL) { @@ -1818,12 +1830,41 @@ int interfaces_subscription_operational_interfaces_interface_ipv6_neighbor_is_ro } } + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "neighbor") == 0); + + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); + + // get IP + SRPC_SAFE_CALL_ERR(error, interfaces_extract_interface_neighbor_ip(session, xpath_buffer, ip_buffer, sizeof(ip_buffer)), error_out); + + // parse address + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(ip_buffer, AF_INET6, &neigh_addr), error_out); + + // get neighbor + SRPC_SAFE_CALL_PTR(neigh, rtnl_neigh_get(oper_ctx->nl_ctx.neigh_cache, rtnl_link_get_ifindex(link), neigh_addr), error_out); + + // check if is-router + const bool is_router = (rtnl_neigh_get_flags(neigh) & NTF_ROUTER) > 0; + + SRPLG_LOG_INF(PLUGIN_NAME, "is-router(interface[%s]:neighbor[%s]) = %s", rtnl_link_get_name(link), ip_buffer, is_router ? "true" : "false"); + + // add is-router + if (is_router) { + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv6_neighbor_is_router(ly_ctx, *parent, ""), error_out); + } + goto out; error_out: error = SR_ERR_CALLBACK_FAILED; out: + return error; } From 3ec8ccb93d269eff08b9cee0efec143df006b9ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 15:21:26 +0200 Subject: [PATCH 152/247] interfaces-plugin: implement IPv6 address status operational leaf --- .../src/plugin/subscription/operational.c | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/interfaces/src/plugin/subscription/operational.c b/src/interfaces/src/plugin/subscription/operational.c index f1489f15..843b1f04 100644 --- a/src/interfaces/src/plugin/subscription/operational.c +++ b/src/interfaces/src/plugin/subscription/operational.c @@ -1648,8 +1648,29 @@ int interfaces_subscription_operational_interfaces_interface_ipv6_address_origin int interfaces_subscription_operational_interfaces_interface_ipv6_address_status(sr_session_ctx_t* session, uint32_t sub_id, const char* module_name, const char* path, const char* request_xpath, uint32_t request_id, struct lyd_node** parent, void* private_data) { int error = SR_ERR_OK; + int rc = 0; + void* error_ptr = NULL; + + sr_session_ctx_t* running_session = NULL; + sr_conn_ctx_t* connection = NULL; + + sr_val_t* prefix_length_val = NULL; + + interfaces_ctx_t* ctx = private_data; + interfaces_oper_ctx_t* oper_ctx = &ctx->oper_ctx; + + char xpath_buffer[PATH_MAX] = { 0 }; + char ip_buffer[100] = { 0 }; + char address_buffer[100] = { 0 }; + + char prefix_path_buffer[PATH_MAX] = { 0 }; + const struct ly_ctx* ly_ctx = NULL; + struct rtnl_link* link = NULL; + struct nl_addr* local = NULL; + struct rtnl_addr* addr = NULL; + if (*parent == NULL) { ly_ctx = sr_acquire_context(sr_session_get_connection(session)); if (ly_ctx == NULL) { @@ -1658,12 +1679,53 @@ int interfaces_subscription_operational_interfaces_interface_ipv6_address_status } } + // connect to the operational DS + SRPC_SAFE_CALL_PTR(connection, sr_session_get_connection(session), error_out); + SRPC_SAFE_CALL_ERR(error, sr_session_start(connection, SR_DS_RUNNING, &running_session), error_out); + + assert(*parent != NULL); + assert(strcmp(LYD_NAME(*parent), "address") == 0); + + // get node xpath + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(*parent, LYD_PATH_STD, xpath_buffer, sizeof(xpath_buffer)), error_out); + + // get link + SRPC_SAFE_CALL_PTR(link, interfaces_get_current_link(ctx, session, xpath_buffer), error_out); + + // get IP + SRPC_SAFE_CALL_ERR(error, interfaces_extract_interface_address_ip(session, xpath_buffer, ip_buffer, sizeof(ip_buffer)), error_out); + + // get prefix length from the operational DS + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(prefix_path_buffer, sizeof(prefix_path_buffer), "/ietf-interfaces:interfaces/interface[name=\"%s\"]/ietf-ip:ipv6/address[ip=\"%s\"]/prefix-length", rtnl_link_get_name(link), ip_buffer), error_out); + SRPC_SAFE_CALL_ERR(error, sr_get_item(running_session, prefix_path_buffer, 0, &prefix_length_val), error_out); + + // create an address + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(address_buffer, sizeof(address_buffer), "%s/%d", ip_buffer, prefix_length_val->data.uint8_val), error_out); + + // parse address + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(address_buffer, AF_INET6, &local), error_out); + + // get rtnl address + SRPC_SAFE_CALL_PTR(addr, rtnl_addr_get(oper_ctx->nl_ctx.addr_cache, rtnl_link_get_ifindex(link), local), error_out); + + // get address status + const char* status = "preferred"; + + SRPLG_LOG_INF(PLUGIN_NAME, "status(interface[%s]:address[%s]) = %s", rtnl_link_get_name(link), ip_buffer, status); + + // add origin + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv6_address_status(ly_ctx, *parent, status), error_out); + goto out; error_out: error = SR_ERR_CALLBACK_FAILED; out: + if (running_session) { + sr_session_stop(running_session); + } + return error; } From e1d6753c79d7e4a3832a4bfdfcc860c6781afc31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 21:03:37 +0200 Subject: [PATCH 153/247] interfaces-plugin: remove unused type --- src/interfaces/src/plugin/types.h | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/interfaces/src/plugin/types.h b/src/interfaces/src/plugin/types.h index 7fa5ff5a..a9c9ef75 100644 --- a/src/interfaces/src/plugin/types.h +++ b/src/interfaces/src/plugin/types.h @@ -29,14 +29,13 @@ typedef struct interfaces_interface_ipv6 interfaces_interface_ipv6_t; typedef struct interfaces_interface interfaces_interface_t; typedef struct interfaces_interface_element interfaces_interface_element_t; typedef struct interfaces interfaces_t; -typedef struct interface_ht_element interface_ht_element_t; typedef struct interfaces_interface_state interfaces_interface_state_t; typedef struct interfaces_interface_state_hash_element interfaces_interface_state_hash_element_t; typedef struct interfaces_interface_hash_element interfaces_interface_hash_element_t; enum interfaces_interface_enable { interfaces_interface_enable_disabled = 0, - interfaces_interface_enable_enabled = 1, + interfaces_interface_enable_enabled = 1, }; enum interfaces_interface_link_up_down_trap_enable { @@ -175,16 +174,6 @@ struct interfaces_interface_element { interfaces_interface_t interface; }; -/* - * - interface hash table element - * - used due to interface name indexing - */ -struct interface_ht_element { - interfaces_interface_t interface; - /* makes the structure hashable */ - UT_hash_handle hh; -}; - struct interfaces { interfaces_interface_element_t* interface; }; From 802e90206f8feb1e23fc4c6a09b50f4f713fe791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 27 Sep 2022 21:52:18 +0200 Subject: [PATCH 154/247] interfaces-plugin: implement IPv4 MTU change callback --- .../api/interfaces/interface/ipv4/change.c | 63 +++++++++++++++++-- .../api/interfaces/interface/ipv4/change.h | 4 ++ .../src/plugin/subscription/change.c | 5 ++ 3 files changed, 68 insertions(+), 4 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c index 3080e3d5..be939305 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c @@ -1,6 +1,13 @@ #include "change.h" +#include "libyang/tree_data.h" +#include "netlink/route/link.h" #include "plugin/common.h" +#include "plugin/context.h" +#include "sysrepo_types.h" +#include +#include +#include #include int interfaces_interface_ipv4_change_neighbor_init(void* priv) @@ -75,23 +82,71 @@ int interfaces_interface_ipv4_change_mtu_init(void* priv) int interfaces_interface_ipv4_change_mtu(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) { - int error = 0; + int error = SR_ERR_OK; + void* error_ptr = NULL; const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); + char path_buffer[PATH_MAX] = { 0 }; + char interface_name_buffer[100] = { 0 }; - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + // app context + interfaces_ctx_t* ctx = priv; + + // mod changes context + interfaces_mod_changes_ctx_t* mod_ctx = &ctx->mod_ctx; + + // libnl + struct rtnl_link* current_link = NULL; + struct rtnl_link* request_link = NULL; + + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + // get node path + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(change_ctx->node, LYD_PATH_STD, path_buffer, sizeof(path_buffer)), error_out); + + // get interface name + SRPC_SAFE_CALL_ERR(error, srpc_extract_xpath_key_value(path_buffer, "interface", "name", interface_name_buffer, sizeof(interface_name_buffer)), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "Node Path: %s; Interface Name: %s", path_buffer, interface_name_buffer); + + // get link + SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->nl_ctx.link_cache, interface_name_buffer), error_out); + + // create request + request_link = rtnl_link_alloc(); + rtnl_link_set_name(request_link, rtnl_link_get_name(current_link)); + SRPC_SAFE_CALL_ERR(error, rtnl_link_set_type(request_link, rtnl_link_get_type(current_link)), error_out); switch (change_ctx->operation) { case SR_OP_CREATED: + case SR_OP_MODIFIED: { + // convert to int + uint16_t mtu = (uint16_t)atoi(node_value); + + // set data + rtnl_link_set_mtu(request_link, mtu); break; - case SR_OP_MODIFIED: - break; + } case SR_OP_DELETED: + // set default MTU + rtnl_link_set_mtu(request_link, 1500); break; case SR_OP_MOVED: break; } + // apply changes + SRPC_SAFE_CALL_ERR(error, rtnl_link_change(mod_ctx->nl_ctx.socket, current_link, request_link, 0), error_out); + + goto out; + +error_out: + if (error < 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "nl_geterror(): %s", nl_geterror(error)); + } + error = -1; + +out: return error; } diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.h b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.h index 16524db5..016e4c0f 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.h +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.h @@ -7,15 +7,19 @@ int interfaces_interface_ipv4_change_neighbor_init(void* priv); int interfaces_interface_ipv4_change_neighbor(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); void interfaces_interface_ipv4_change_neighbor_free(void* priv); + int interfaces_interface_ipv4_change_address_init(void* priv); int interfaces_interface_ipv4_change_address(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); void interfaces_interface_ipv4_change_address_free(void* priv); + int interfaces_interface_ipv4_change_mtu_init(void* priv); int interfaces_interface_ipv4_change_mtu(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); void interfaces_interface_ipv4_change_mtu_free(void* priv); + int interfaces_interface_ipv4_change_forwarding_init(void* priv); int interfaces_interface_ipv4_change_forwarding(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); void interfaces_interface_ipv4_change_forwarding_free(void* priv); + int interfaces_interface_ipv4_change_enabled_init(void* priv); int interfaces_interface_ipv4_change_enabled(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); void interfaces_interface_ipv4_change_enabled_free(void* priv); diff --git a/src/interfaces/src/plugin/subscription/change.c b/src/interfaces/src/plugin/subscription/change.c index 9872cf7d..e2ebd5a5 100644 --- a/src/interfaces/src/plugin/subscription/change.c +++ b/src/interfaces/src/plugin/subscription/change.c @@ -10,6 +10,7 @@ // change API #include "plugin/api/interfaces/change.h" #include "plugin/api/interfaces/interface/change.h" +#include "plugin/api/interfaces/interface/ipv4/change.h" int interfaces_subscription_change_interfaces_interface(sr_session_ctx_t* session, uint32_t subscription_id, const char* module_name, const char* xpath, sr_event_t event, uint32_t request_id, void* private_data) { @@ -47,6 +48,10 @@ int interfaces_subscription_change_interfaces_interface(sr_session_ctx_t* sessio // link-up-down-trap-enable SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/link-up-down-trap-enable", xpath), error_out); SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_change_link_up_down_trap_enable, interfaces_change_interface_init, interfaces_change_interface_free), error_out); + + // ipv4/mtu + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/ipv4/mtu", xpath), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_ipv4_change_mtu, interfaces_change_interface_init, interfaces_change_interface_free), error_out); } goto out; From 49ac8b9f680c330d745355801c8b3b82f93ffe87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Wed, 28 Sep 2022 12:48:47 +0200 Subject: [PATCH 155/247] interfaces-plugin: replace all error checking with SRPC safe call API --- src/interfaces/src/plugin.c | 19 +++++++------------ src/interfaces/src/plugin/startup/load.c | 6 +----- src/interfaces/src/plugin/startup/store.c | 13 ++----------- .../src/plugin/subscription/change.c | 6 +----- 4 files changed, 11 insertions(+), 33 deletions(-) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index b62da816..ce466628 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -276,20 +276,15 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) }, }; - connection = sr_session_get_connection(running_session); - error = sr_session_start(connection, SR_DS_STARTUP, &startup_session); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_session_start() error (%d): %s", error, sr_strerror(error)); - goto error_out; - } + // get connection + SRPC_SAFE_CALL_PTR(connection, sr_session_get_connection(running_session), error_out); + + // start a session + SRPC_SAFE_CALL_ERR(error, sr_session_start(connection, SR_DS_STARTUP, &startup_session), error_out); ctx->startup_session = startup_session; - error = srpc_check_empty_datastore(startup_session, INTERFACES_INTERFACES_INTERFACE_YANG_PATH, &empty_startup); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "Failed checking datastore contents: %d", error); - goto error_out; - } + SRPC_SAFE_CALL_ERR(error, srpc_check_empty_datastore(startup_session, INTERFACES_INTERFACES_INTERFACE_YANG_PATH, &empty_startup), error_out); if (empty_startup) { SRPLG_LOG_INF(PLUGIN_NAME, "Startup datastore is empty"); @@ -338,7 +333,7 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) if (op->cb) { error = sr_oper_get_subscribe(running_session, op->module, op->path, op->cb, *private_data, SR_SUBSCR_DEFAULT, &subscription); if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_oper_get_subscribe() error (%d): %s", error, sr_strerror(error)); + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_oper_get_subscribe() error for \"%s\" (%d): %s", op->path, error, sr_strerror(error)); goto error_out; } } diff --git a/src/interfaces/src/plugin/startup/load.c b/src/interfaces/src/plugin/startup/load.c index 99b7db6d..7f0255c1 100644 --- a/src/interfaces/src/plugin/startup/load.c +++ b/src/interfaces/src/plugin/startup/load.c @@ -82,11 +82,7 @@ static int interfaces_startup_load_interface(void* priv, sr_session_ctx_t* sessi interfaces_ctx_t* ctx = (interfaces_ctx_t*)priv; interfaces_interface_hash_element_t* interface_head = NULL; - error = interfaces_load_interface(ctx, &interface_head); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "interfaces_load_interface() error (%d)", error); - goto error_out; - } + SRPC_SAFE_CALL_ERR(error, interfaces_load_interface(ctx, &interface_head), error_out); goto out; diff --git a/src/interfaces/src/plugin/startup/store.c b/src/interfaces/src/plugin/startup/store.c index 133be4fd..0d12d885 100644 --- a/src/interfaces/src/plugin/startup/store.c +++ b/src/interfaces/src/plugin/startup/store.c @@ -17,11 +17,7 @@ int interfaces_startup_store(interfaces_ctx_t* ctx, sr_session_ctx_t* session) int error = 0; sr_data_t* subtree = NULL; - error = sr_get_subtree(session, INTERFACES_INTERFACES_CONTAINER_YANG_PATH, 0, &subtree); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_get_subtree() error (%d): %s", error, sr_strerror(error)); - goto error_out; - } + SRPC_SAFE_CALL_ERR(error, sr_get_subtree(session, INTERFACES_INTERFACES_CONTAINER_YANG_PATH, 0, &subtree), error_out); srpc_startup_store_t store_values[] = { { @@ -86,17 +82,12 @@ static int interfaces_startup_store_interface(void* priv, const struct lyd_node* case srpc_check_status_non_existant: SRPLG_LOG_INF(PLUGIN_NAME, "Storing interface array"); - error = interfaces_store_interface(ctx, if_hash); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "interfaces_store_interface() failed (%d)", error); - goto error_out; - } + SRPC_SAFE_CALL_ERR(error, interfaces_store_interface(ctx, if_hash), error_out); break; case srpc_check_status_equal: SRPLG_LOG_ERR(PLUGIN_NAME, "Startup interface array is already applied on the system"); break; case srpc_check_status_partial: - /* should not be returned - treat as an error */ SRPLG_LOG_ERR(PLUGIN_NAME, "Error loading current interface array"); goto error_out; } diff --git a/src/interfaces/src/plugin/subscription/change.c b/src/interfaces/src/plugin/subscription/change.c index e2ebd5a5..a98f55f0 100644 --- a/src/interfaces/src/plugin/subscription/change.c +++ b/src/interfaces/src/plugin/subscription/change.c @@ -23,11 +23,7 @@ int interfaces_subscription_change_interfaces_interface(sr_session_ctx_t* sessio SRPLG_LOG_ERR(PLUGIN_NAME, "Aborting changes for %s", xpath); goto error_out; } else if (event == SR_EV_DONE) { - error = sr_copy_config(ctx->startup_session, IETF_INTERFACES_YANG_MODULE, SR_DS_RUNNING, 0); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_copy_config() error (%d): %s", error, sr_strerror(error)); - goto error_out; - } + SRPC_SAFE_CALL_ERR(error, sr_copy_config(ctx->startup_session, IETF_INTERFACES_YANG_MODULE, SR_DS_RUNNING, 0), error_out); } else if (event == SR_EV_CHANGE) { // name SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/name", xpath), error_out); From b61b8aa0f2cfbdd54f5a2249c9800530097adb53 Mon Sep 17 00:00:00 2001 From: andrej Date: Thu, 29 Sep 2022 02:17:28 +0200 Subject: [PATCH 156/247] interfaces-plugin: fix segfaults, only if name required, don't free parsed data --- .../src/plugin/api/interfaces/load.c | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index 0c874fb6..3125bcdb 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -121,6 +121,7 @@ static char* interfaces_get_interface_type(struct rtnl_link* link, char* name) break; default: SRPLG_LOG_ERR(PLUGIN_NAME, "%s: unkown type_id: %d", __func__, type_id); + return NULL; } } @@ -154,9 +155,10 @@ static char* interfaces_get_interface_parent_interface(struct nl_cache* cache, s if (rtnl_link_is_vlan(link)) { parent_index = rtnl_link_get_link(link); parent_interface = rtnl_link_i2name(cache, parent_index, parent_buffer, IFNAMSIZ); + return xstrdup(parent_interface); } - return xstrdup(parent_interface); + return NULL; } /* TODO: outer tag, second id, tag - maybe refactor all to pass by reference, return error */ @@ -178,6 +180,7 @@ static int interfaces_get_interface_vlan_id(struct rtnl_link* link, interfaces_i second = strchr(first + 1, '.'); if (second != 0) { + // continue to the next interface return interfaces_load_continue; } } @@ -185,18 +188,22 @@ static int interfaces_get_interface_vlan_id(struct rtnl_link* link, interfaces_i return interfaces_load_success; } +/* + Parses the link for interface data +*/ static int interfaces_parse_link(interfaces_ctx_t* ctx, struct nl_sock* socket, struct nl_cache* cache, struct rtnl_link* link, interfaces_interface_t* interface) { int error = interfaces_load_success; *interface = (interfaces_interface_t) { 0 }; + // required SRPC_SAFE_CALL_PTR(interface->name, interfaces_get_interface_name(link), error_out); - SRPC_SAFE_CALL_PTR(interface->description, interfaces_get_interface_description(ctx, interface->name), error_out); + interfaces_get_interface_description(ctx, interface->name); - SRPC_SAFE_CALL_PTR(interface->type, interfaces_get_interface_type(link, interface->name), error_out); + interfaces_get_interface_type(link, interface->name); - SRPC_SAFE_CALL_PTR(interface->parent_interface, interfaces_get_interface_parent_interface(cache, link), error_out); + interfaces_get_interface_parent_interface(cache, link); error = interfaces_get_interface_vlan_id(link, interface); if (error != interfaces_load_success) { @@ -209,19 +216,8 @@ static int interfaces_parse_link(interfaces_ctx_t* ctx, struct nl_sock* socket, goto out; error_out: error = interfaces_load_failure; + // do not free the data, the interface data needs to be added in the interfaces hash table out: - if (interface->name != NULL) { - FREE_SAFE(interface->name); - } - if (interface->description != NULL) { - FREE_SAFE(interface->description); - } - if (interface->type != NULL) { - FREE_SAFE(interface->type); - } - if (interface->parent_interface != NULL) { - FREE_SAFE(interface->parent_interface); - } return error; } @@ -252,6 +248,19 @@ static int interfaces_add_link(interfaces_interface_hash_element_t** if_hash, in goto out; error_out: out: + if (interface->name != NULL) { + FREE_SAFE(interface->name); + } + if (interface->description != NULL) { + FREE_SAFE(interface->description); + } + if (interface->type != NULL) { + FREE_SAFE(interface->type); + } + if (interface->parent_interface != NULL) { + FREE_SAFE(interface->parent_interface); + } + return error; } From ac9ea2ed81fb30d14600cc660c3bbdebe08474d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Thu, 6 Oct 2022 14:53:55 +0200 Subject: [PATCH 157/247] interfaces-plugin: use SRPC safe call API in main.c --- src/interfaces/src/main.c | 23 ++++++------------- .../plugin/api/interfaces/interface/change.c | 1 + 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/interfaces/src/main.c b/src/interfaces/src/main.c index a8ea03cf..00236085 100644 --- a/src/interfaces/src/main.c +++ b/src/interfaces/src/main.c @@ -5,6 +5,8 @@ #include "plugin.h" #include "plugin/common.h" +#include + volatile int exit_application = 0; static void sigint_handler(__attribute__((unused)) int signum); @@ -19,23 +21,11 @@ int main(void) sr_log_stderr(SR_LL_INF); /* connect to sysrepo */ - error = sr_connect(SR_CONN_DEFAULT, &connection); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_connect error (%d): %s", error, sr_strerror(error)); - goto out; - } + SRPC_SAFE_CALL_ERR(error, sr_connect(SR_CONN_DEFAULT, &connection), out); + SRPC_SAFE_CALL_ERR(error, sr_session_start(connection, SR_DS_RUNNING, &session), out); - error = sr_session_start(connection, SR_DS_RUNNING, &session); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_session_start error (%d): %s", error, sr_strerror(error)); - goto out; - } - - error = sr_plugin_init_cb(session, &private_data); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_plugin_init_cb error"); - goto out; - } + /* init plugin */ + SRPC_SAFE_CALL_ERR(error, sr_plugin_init_cb(session, &private_data), out); /* loop until ctrl-c is pressed / SIGINT is received */ signal(SIGINT, sigint_handler); @@ -45,6 +35,7 @@ int main(void) } out: + /* cleanup plugin */ sr_plugin_cleanup_cb(session, private_data); sr_disconnect(connection); diff --git a/src/interfaces/src/plugin/api/interfaces/interface/change.c b/src/interfaces/src/plugin/api/interfaces/interface/change.c index 6cbd5c04..c35ffa1f 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/change.c @@ -134,6 +134,7 @@ int interfaces_interface_change_enabled(void* priv, sr_session_ctx_t* session, c // set name rtnl_link_set_name(request_link, interface_name_buffer); rtnl_link_set_type(request_link, rtnl_link_get_type(current_link)); + // set operstate rtnl_link_set_flags(request_link, (strcmp(node_value, "true") == 0) ? (unsigned int)rtnl_link_str2flags("up") : (unsigned int)rtnl_link_str2flags("down")); rtnl_link_unset_flags(request_link, (strcmp(node_value, "true") == 0) ? (unsigned int)rtnl_link_str2flags("down") : (unsigned int)rtnl_link_str2flags("up")); From fca26d05633aed8e753e49cc5c42dadfee3d3530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Thu, 6 Oct 2022 14:56:12 +0200 Subject: [PATCH 158/247] interfaces-plugin: disable non-implemented IPv4 callbacks --- .../src/plugin/api/interfaces/interface/ipv4/change.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c index be939305..aa63dfcb 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c @@ -35,7 +35,7 @@ int interfaces_interface_ipv4_change_neighbor(void* priv, sr_session_ctx_t* sess break; } - return error; + return -1; } void interfaces_interface_ipv4_change_neighbor_free(void* priv) @@ -67,7 +67,7 @@ int interfaces_interface_ipv4_change_address(void* priv, sr_session_ctx_t* sessi break; } - return error; + return -1; } void interfaces_interface_ipv4_change_address_free(void* priv) @@ -179,7 +179,7 @@ int interfaces_interface_ipv4_change_forwarding(void* priv, sr_session_ctx_t* se break; } - return error; + return -1; } void interfaces_interface_ipv4_change_forwarding_free(void* priv) From 13d288a80f085c992207a6edadedca4cb37ec36e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Thu, 6 Oct 2022 15:12:24 +0200 Subject: [PATCH 159/247] interfaces-plugin: remove DBG logging from all files --- .../api/interfaces/interface/carrier-delay/change.c | 4 ++-- .../api/interfaces/interface/dampening/change.c | 8 ++++---- .../encapsulation/dot1q-vlan/outer-tag/change.c | 4 ++-- .../encapsulation/dot1q-vlan/second-tag/change.c | 4 ++-- .../api/interfaces/interface/ipv4/address/change.c | 6 +++--- .../plugin/api/interfaces/interface/ipv4/change.c | 10 +++++----- .../api/interfaces/interface/ipv4/neighbor/change.c | 4 ++-- .../api/interfaces/interface/ipv6/address/change.c | 4 ++-- .../api/interfaces/interface/ipv6/autoconf/change.c | 8 ++++---- .../plugin/api/interfaces/interface/ipv6/change.c | 12 ++++++------ .../api/interfaces/interface/ipv6/neighbor/change.c | 4 ++-- src/interfaces/src/plugin/subscription/change.c | 13 +++++++++++++ 12 files changed, 47 insertions(+), 34 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/carrier-delay/change.c b/src/interfaces/src/plugin/api/interfaces/interface/carrier-delay/change.c index 0160254f..240ffa3c 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/carrier-delay/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/carrier-delay/change.c @@ -9,7 +9,7 @@ int interfaces_interface_carrier_delay_change_up(void* priv, sr_session_ctx_t* s const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -31,7 +31,7 @@ int interfaces_interface_carrier_delay_change_down(void* priv, sr_session_ctx_t* const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: diff --git a/src/interfaces/src/plugin/api/interfaces/interface/dampening/change.c b/src/interfaces/src/plugin/api/interfaces/interface/dampening/change.c index 1d19c74e..0ef5e8d6 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/dampening/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/dampening/change.c @@ -9,7 +9,7 @@ int interfaces_interface_dampening_change_max_suppress_time(void* priv, sr_sessi const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -31,7 +31,7 @@ int interfaces_interface_dampening_change_suppress(void* priv, sr_session_ctx_t* const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -53,7 +53,7 @@ int interfaces_interface_dampening_change_reuse(void* priv, sr_session_ctx_t* se const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -75,7 +75,7 @@ int interfaces_interface_dampening_change_half_life(void* priv, sr_session_ctx_t const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: diff --git a/src/interfaces/src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/outer-tag/change.c b/src/interfaces/src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/outer-tag/change.c index bf909c58..bc8aecf0 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/outer-tag/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/outer-tag/change.c @@ -9,7 +9,7 @@ int interfaces_interface_encapsulation_dot1q_vlan_outer_tag_change_vlan_id(void* const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -31,7 +31,7 @@ int interfaces_interface_encapsulation_dot1q_vlan_outer_tag_change_tag_type(void const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: diff --git a/src/interfaces/src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/second-tag/change.c b/src/interfaces/src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/second-tag/change.c index 5feeccb6..5562ac57 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/second-tag/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/second-tag/change.c @@ -9,7 +9,7 @@ int interfaces_interface_encapsulation_dot1q_vlan_second_tag_change_vlan_id(void const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -31,7 +31,7 @@ int interfaces_interface_encapsulation_dot1q_vlan_second_tag_change_tag_type(voi const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c index a032b5ee..a4e6f68c 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c @@ -15,7 +15,7 @@ int interfaces_interface_ipv4_address_change_netmask(void* priv, sr_session_ctx_ const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -47,7 +47,7 @@ int interfaces_interface_ipv4_address_change_prefix_length(void* priv, sr_sessio const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -79,7 +79,7 @@ int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* se const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c index aa63dfcb..e5be4363 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c @@ -22,7 +22,7 @@ int interfaces_interface_ipv4_change_neighbor(void* priv, sr_session_ctx_t* sess const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -54,7 +54,7 @@ int interfaces_interface_ipv4_change_address(void* priv, sr_session_ctx_t* sessi const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -166,7 +166,7 @@ int interfaces_interface_ipv4_change_forwarding(void* priv, sr_session_ctx_t* se const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -198,7 +198,7 @@ int interfaces_interface_ipv4_change_enabled(void* priv, sr_session_ctx_t* sessi const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -211,7 +211,7 @@ int interfaces_interface_ipv4_change_enabled(void* priv, sr_session_ctx_t* sessi break; } - return error; + return -1; } void interfaces_interface_ipv4_change_enabled_free(void* priv) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c index 8485bbdb..047ac005 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c @@ -15,7 +15,7 @@ int interfaces_interface_ipv4_neighbor_change_link_layer_address(void* priv, sr_ const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -47,7 +47,7 @@ int interfaces_interface_ipv4_neighbor_change_ip(void* priv, sr_session_ctx_t* s const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.c index 8e9b88fd..c7ccab0d 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.c @@ -15,7 +15,7 @@ int interfaces_interface_ipv6_address_change_prefix_length(void* priv, sr_sessio const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -47,7 +47,7 @@ int interfaces_interface_ipv6_address_change_ip(void* priv, sr_session_ctx_t* se const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/autoconf/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/autoconf/change.c index eac37112..3414625b 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/autoconf/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/autoconf/change.c @@ -15,7 +15,7 @@ int interfaces_interface_ipv6_autoconf_change_temporary_preferred_lifetime(void* const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -47,7 +47,7 @@ int interfaces_interface_ipv6_autoconf_change_temporary_valid_lifetime(void* pri const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -79,7 +79,7 @@ int interfaces_interface_ipv6_autoconf_change_create_temporary_addresses(void* p const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -111,7 +111,7 @@ int interfaces_interface_ipv6_autoconf_change_create_global_addresses(void* priv const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/change.c index eef313fe..9fd99278 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/change.c @@ -15,7 +15,7 @@ int interfaces_interface_ipv6_change_dup_addr_detect_transmits(void* priv, sr_se const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -47,7 +47,7 @@ int interfaces_interface_ipv6_change_neighbor(void* priv, sr_session_ctx_t* sess const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -79,7 +79,7 @@ int interfaces_interface_ipv6_change_address(void* priv, sr_session_ctx_t* sessi const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -111,7 +111,7 @@ int interfaces_interface_ipv6_change_mtu(void* priv, sr_session_ctx_t* session, const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -143,7 +143,7 @@ int interfaces_interface_ipv6_change_forwarding(void* priv, sr_session_ctx_t* se const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -175,7 +175,7 @@ int interfaces_interface_ipv6_change_enabled(void* priv, sr_session_ctx_t* sessi const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/change.c index 8fa2ffe1..d43d4dec 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/change.c @@ -15,7 +15,7 @@ int interfaces_interface_ipv6_neighbor_change_link_layer_address(void* priv, sr_ const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: @@ -47,7 +47,7 @@ int interfaces_interface_ipv6_neighbor_change_ip(void* priv, sr_session_ctx_t* s const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); - SRPLG_LOG_DBG(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { case SR_OP_CREATED: diff --git a/src/interfaces/src/plugin/subscription/change.c b/src/interfaces/src/plugin/subscription/change.c index a98f55f0..c18c7dfb 100644 --- a/src/interfaces/src/plugin/subscription/change.c +++ b/src/interfaces/src/plugin/subscription/change.c @@ -23,6 +23,7 @@ int interfaces_subscription_change_interfaces_interface(sr_session_ctx_t* sessio SRPLG_LOG_ERR(PLUGIN_NAME, "Aborting changes for %s", xpath); goto error_out; } else if (event == SR_EV_DONE) { + // when all changes processed - copy running DS contents to startup SRPC_SAFE_CALL_ERR(error, sr_copy_config(ctx->startup_session, IETF_INTERFACES_YANG_MODULE, SR_DS_RUNNING, 0), error_out); } else if (event == SR_EV_CHANGE) { // name @@ -48,6 +49,18 @@ int interfaces_subscription_change_interfaces_interface(sr_session_ctx_t* sessio // ipv4/mtu SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/ipv4/mtu", xpath), error_out); SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_ipv4_change_mtu, interfaces_change_interface_init, interfaces_change_interface_free), error_out); + + // ipv4/enabled + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/ipv4/enabled", xpath), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_ipv4_change_enabled, interfaces_change_interface_init, interfaces_change_interface_free), error_out); + + // ipv4/address + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/ipv4/address", xpath), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_ipv4_change_address, interfaces_change_interface_init, interfaces_change_interface_free), error_out); + + // ipv4/neighbor + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/ipv4/neighbor", xpath), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_ipv4_change_neighbor, interfaces_change_interface_init, interfaces_change_interface_free), error_out); } goto out; From e2b45610e73a1c1f794d4b56a0399a8349ea4d16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Thu, 6 Oct 2022 15:24:35 +0200 Subject: [PATCH 160/247] interfaces-plugin: disable IPv4 "enabled" leaf change callback --- .../src/plugin/api/interfaces/interface/ipv4/change.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c index e5be4363..70a0873e 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c @@ -198,6 +198,8 @@ int interfaces_interface_ipv4_change_enabled(void* priv, sr_session_ctx_t* sessi const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); + // IPv4 can be disabled by deleting all IPv4 addresses associated with the interface + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); switch (change_ctx->operation) { From fbc1e3c2f920bf9237770168fdda1e194a25f3f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Thu, 6 Oct 2022 15:28:37 +0200 Subject: [PATCH 161/247] interfaces-plugin: extract interface name when changing enabled IPv4 value --- .../api/interfaces/interface/ipv4/change.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c index 70a0873e..bdcd19ad 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c @@ -195,13 +195,25 @@ int interfaces_interface_ipv4_change_enabled_init(void* priv) int interfaces_interface_ipv4_change_enabled(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) { int error = 0; + void* error_ptr = NULL; const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); + char path_buffer[PATH_MAX] = { 0 }; + char interface_name_buffer[100] = { 0 }; + // IPv4 can be disabled by deleting all IPv4 addresses associated with the interface SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + // get node path + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(change_ctx->node, LYD_PATH_STD, path_buffer, sizeof(path_buffer)), error_out); + + // get interface name + SRPC_SAFE_CALL_ERR(error, srpc_extract_xpath_key_value(path_buffer, "interface", "name", interface_name_buffer, sizeof(interface_name_buffer)), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "Node Path: %s; Interface Name: %s", path_buffer, interface_name_buffer); + switch (change_ctx->operation) { case SR_OP_CREATED: break; @@ -213,6 +225,12 @@ int interfaces_interface_ipv4_change_enabled(void* priv, sr_session_ctx_t* sessi break; } + goto out; + +error_out: + error = -1; + +out: return -1; } From b19486023ce1d2ed89aa4863e5368811af54df72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Thu, 6 Oct 2022 16:13:15 +0200 Subject: [PATCH 162/247] interfaces-plugin: implement base for enabled IPv4 leaf change --- .../src/plugin/api/interfaces/change.c | 9 +++++ .../api/interfaces/interface/ipv4/change.c | 40 +++++++++++++++++-- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/change.c b/src/interfaces/src/plugin/api/interfaces/change.c index 896699bd..fc8fa98b 100644 --- a/src/interfaces/src/plugin/api/interfaces/change.c +++ b/src/interfaces/src/plugin/api/interfaces/change.c @@ -1,4 +1,5 @@ #include "change.h" +#include "netlink/route/addr.h" #include "plugin/common.h" #include "plugin/context.h" @@ -25,6 +26,9 @@ int interfaces_change_interface_init(void* priv) // allocate link cache SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(mod_ctx->nl_ctx.socket, AF_UNSPEC, &mod_ctx->nl_ctx.link_cache), error_out); + // allocate address cache + SRPC_SAFE_CALL_ERR(error, rtnl_addr_alloc_cache(mod_ctx->nl_ctx.socket, &mod_ctx->nl_ctx.addr_cache), error_out); + goto out; error_out: @@ -91,6 +95,11 @@ void interfaces_change_interface_free(void* priv) if (mod_ctx->nl_ctx.link_cache) { nl_cache_put(mod_ctx->nl_ctx.link_cache); } + + if (mod_ctx->nl_ctx.addr_cache) { + nl_cache_put(mod_ctx->nl_ctx.addr_cache); + } + if (mod_ctx->nl_ctx.socket) { nl_socket_free(mod_ctx->nl_ctx.socket); } diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c index bdcd19ad..9469376f 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c @@ -1,5 +1,6 @@ #include "change.h" #include "libyang/tree_data.h" +#include "netlink/cache.h" #include "netlink/route/link.h" #include "plugin/common.h" #include "plugin/context.h" @@ -67,7 +68,7 @@ int interfaces_interface_ipv4_change_address(void* priv, sr_session_ctx_t* sessi break; } - return -1; + return error; } void interfaces_interface_ipv4_change_address_free(void* priv) @@ -196,12 +197,22 @@ int interfaces_interface_ipv4_change_enabled(void* priv, sr_session_ctx_t* sessi { int error = 0; void* error_ptr = NULL; + interfaces_ctx_t* ctx = priv; + interfaces_mod_changes_ctx_t* mod_ctx = &ctx->mod_ctx; + + // sysrepo + sr_conn_ctx_t* conn = NULL; + sr_session_ctx_t* running_session = NULL; + const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); char path_buffer[PATH_MAX] = { 0 }; char interface_name_buffer[100] = { 0 }; + struct rtnl_link* current_link = NULL; + struct rtnl_addr* addr_iter = NULL; + // IPv4 can be disabled by deleting all IPv4 addresses associated with the interface SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); @@ -214,12 +225,31 @@ int interfaces_interface_ipv4_change_enabled(void* priv, sr_session_ctx_t* sessi SRPLG_LOG_INF(PLUGIN_NAME, "Node Path: %s; Interface Name: %s", path_buffer, interface_name_buffer); + // get link + SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->nl_ctx.link_cache, interface_name_buffer), error_out); + + // get address iterator + SRPC_SAFE_CALL_PTR(addr_iter, (struct rtnl_addr*)nl_cache_get_first(mod_ctx->nl_ctx.addr_cache), error_out); + + // get connection + SRPC_SAFE_CALL_PTR(conn, sr_session_get_connection(session), error_out); + + // start running session + SRPC_SAFE_CALL_ERR(error, sr_session_start(conn, SR_DS_RUNNING, &running_session), error_out); + switch (change_ctx->operation) { case SR_OP_CREATED: - break; case SR_OP_MODIFIED: + // if IPv4 disabled - delete all v4 addresses on the interface + if (!strcmp(node_value, "false")) { + // configure path buffer + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(path_buffer, sizeof(path_buffer), "%s[name=\"%s\"]/ietf-ip:ipv4/address", INTERFACES_INTERFACES_LIST_YANG_PATH, interface_name_buffer), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "Deleting every IPv4 address for interface %s: path = %s", interface_name_buffer, path_buffer); + } break; case SR_OP_DELETED: + // default value = true, don't do anything break; case SR_OP_MOVED: break; @@ -231,7 +261,11 @@ int interfaces_interface_ipv4_change_enabled(void* priv, sr_session_ctx_t* sessi error = -1; out: - return -1; + if (running_session) { + sr_session_stop(running_session); + } + + return error; } void interfaces_interface_ipv4_change_enabled_free(void* priv) From 9b7e76c433c3e36d708feca7520557a4815aeae5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Thu, 6 Oct 2022 16:19:10 +0200 Subject: [PATCH 163/247] interfaces-plugin: disable IPv4 address properties change callbacks --- .../api/interfaces/interface/ipv4/address/change.c | 6 +++--- .../api/interfaces/interface/ipv4/address/change.h | 2 ++ src/interfaces/src/plugin/subscription/change.c | 13 +++++++++++++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c index a4e6f68c..3b2c6c9c 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c @@ -28,7 +28,7 @@ int interfaces_interface_ipv4_address_change_netmask(void* priv, sr_session_ctx_ break; } - return error; + return -1; } void interfaces_interface_ipv4_address_change_netmask_free(void* priv) @@ -60,7 +60,7 @@ int interfaces_interface_ipv4_address_change_prefix_length(void* priv, sr_sessio break; } - return error; + return -1; } void interfaces_interface_ipv4_address_change_prefix_length_free(void* priv) @@ -92,7 +92,7 @@ int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* se break; } - return error; + return -1; } void interfaces_interface_ipv4_address_change_ip_free(void* priv) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.h b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.h index d40b23da..a4c807af 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.h +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.h @@ -7,9 +7,11 @@ int interfaces_interface_ipv4_address_change_netmask_init(void* priv); int interfaces_interface_ipv4_address_change_netmask(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); void interfaces_interface_ipv4_address_change_netmask_free(void* priv); + int interfaces_interface_ipv4_address_change_prefix_length_init(void* priv); int interfaces_interface_ipv4_address_change_prefix_length(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); void interfaces_interface_ipv4_address_change_prefix_length_free(void* priv); + int interfaces_interface_ipv4_address_change_ip_init(void* priv); int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); void interfaces_interface_ipv4_address_change_ip_free(void* priv); diff --git a/src/interfaces/src/plugin/subscription/change.c b/src/interfaces/src/plugin/subscription/change.c index c18c7dfb..01253afd 100644 --- a/src/interfaces/src/plugin/subscription/change.c +++ b/src/interfaces/src/plugin/subscription/change.c @@ -10,6 +10,7 @@ // change API #include "plugin/api/interfaces/change.h" #include "plugin/api/interfaces/interface/change.h" +#include "plugin/api/interfaces/interface/ipv4/address/change.h" #include "plugin/api/interfaces/interface/ipv4/change.h" int interfaces_subscription_change_interfaces_interface(sr_session_ctx_t* session, uint32_t subscription_id, const char* module_name, const char* xpath, sr_event_t event, uint32_t request_id, void* private_data) @@ -58,6 +59,18 @@ int interfaces_subscription_change_interfaces_interface(sr_session_ctx_t* sessio SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/ipv4/address", xpath), error_out); SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_ipv4_change_address, interfaces_change_interface_init, interfaces_change_interface_free), error_out); + // ipv4/address/ip + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/ipv4/address/ip", xpath), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_ipv4_address_change_ip, interfaces_change_interface_init, interfaces_change_interface_free), error_out); + + // ipv4/address/prefix-length + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/ipv4/address/prefix-length", xpath), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_ipv4_address_change_prefix_length, interfaces_change_interface_init, interfaces_change_interface_free), error_out); + + // ipv4/address/netmask + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/ipv4/address/netmask", xpath), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_ipv4_address_change_netmask, interfaces_change_interface_init, interfaces_change_interface_free), error_out); + // ipv4/neighbor SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/ipv4/neighbor", xpath), error_out); SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_ipv4_change_neighbor, interfaces_change_interface_init, interfaces_change_interface_free), error_out); From b1354f933399b74909fe0ca359f22f6e41ad0a2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Thu, 6 Oct 2022 19:20:22 +0200 Subject: [PATCH 164/247] interfaces-plugin: fix enabled libyang reading error --- .../src/plugin/api/interfaces/interface/ipv4/address/change.c | 2 ++ src/interfaces/src/plugin/data/interfaces/interface.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c index 3b2c6c9c..012efb1a 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c @@ -83,8 +83,10 @@ int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* se switch (change_ctx->operation) { case SR_OP_CREATED: + // new address break; case SR_OP_MODIFIED: + // should be impossible - address IP can only be created and deleted break; case SR_OP_DELETED: break; diff --git a/src/interfaces/src/plugin/data/interfaces/interface.c b/src/interfaces/src/plugin/data/interfaces/interface.c index 92cbf54d..1a6cccdb 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface.c +++ b/src/interfaces/src/plugin/data/interfaces/interface.c @@ -172,7 +172,7 @@ int interfaces_interface_hash_from_ly(interfaces_interface_hash_element_t** if_h } if (if_enabled_node) { - SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_enabled(&new_element, strcmp(lyd_get_value(if_enabled_node), "true") ? 1 : 0), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_enabled(&new_element, strcmp(lyd_get_value(if_enabled_node), "true") == 0 ? 1 : 0), error_out); } if (ipv4_enabled_node) { From c62c6f4c2bda08bf81beec74d5f0a5328f5a921b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Thu, 6 Oct 2022 19:50:59 +0200 Subject: [PATCH 165/247] interfaces-plugin: implement IPv4 address IP create functionality --- .../interface/ipv4/address/change.c | 68 ++++++++++++++++++- .../src/plugin/subscription/change.c | 4 -- 2 files changed, 67 insertions(+), 5 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c index 012efb1a..fa1120d8 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c @@ -1,8 +1,13 @@ #include "change.h" #include "plugin/common.h" +#include "plugin/context.h" #include +#include +#include +#include + int interfaces_interface_ipv4_address_change_netmask_init(void* priv) { int error = 0; @@ -76,25 +81,86 @@ int interfaces_interface_ipv4_address_change_ip_init(void* priv) int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) { int error = 0; + void* error_ptr = NULL; + + // sysrepo + sr_val_t* prefix_val = NULL; + sr_val_t* netmask_val = NULL; + + // strings and buffers const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); + char path_buffer[PATH_MAX] = { 0 }; + char interface_name_buffer[100] = { 0 }; + + // app context + interfaces_ctx_t* ctx = priv; + + // mod changes context + interfaces_mod_changes_ctx_t* mod_ctx = &ctx->mod_ctx; + + // libnl + struct rtnl_addr* request_addr = NULL; + struct rtnl_link* current_link = NULL; + struct nl_addr* local_addr = NULL; SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + // get node path + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(change_ctx->node, LYD_PATH_STD, path_buffer, sizeof(path_buffer)), error_out); + + // get interface name + SRPC_SAFE_CALL_ERR(error, srpc_extract_xpath_key_value(path_buffer, "interface", "name", interface_name_buffer, sizeof(interface_name_buffer)), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "Node Path: %s; Interface Name: %s", path_buffer, interface_name_buffer); + + // get link + SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->nl_ctx.link_cache, interface_name_buffer), error_out); + + // get interface index + const int ifindex = rtnl_link_get_ifindex(current_link); + switch (change_ctx->operation) { case SR_OP_CREATED: // new address + request_addr = rtnl_addr_alloc(); + + // parse local address + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(node_value, AF_INET, &local_addr), error_out); + + // set temporary prefix-length - "default" + nl_addr_set_prefixlen(local_addr, 24); + + // set to route address + SRPC_SAFE_CALL_ERR(error, rtnl_addr_set_local(request_addr, local_addr), error_out); + + // set interface + rtnl_addr_set_ifindex(request_addr, ifindex); + + // add address + SRPC_SAFE_CALL_ERR(error, rtnl_addr_add(mod_ctx->nl_ctx.socket, request_addr, 0), error_out); + break; case SR_OP_MODIFIED: // should be impossible - address IP can only be created and deleted + SRPLG_LOG_ERR(PLUGIN_NAME, "Unsuported operation MODIFY for ietf-ip:ipv4/address/ip"); + goto error_out; break; case SR_OP_DELETED: + // fetch info about prefix-length/netmask and use the pair address/prefix to delete address + // prefix is needed to find the appropriate address break; case SR_OP_MOVED: break; } - return -1; + goto out; + +error_out: + error = -1; + +out: + return error; } void interfaces_interface_ipv4_address_change_ip_free(void* priv) diff --git a/src/interfaces/src/plugin/subscription/change.c b/src/interfaces/src/plugin/subscription/change.c index 01253afd..400515be 100644 --- a/src/interfaces/src/plugin/subscription/change.c +++ b/src/interfaces/src/plugin/subscription/change.c @@ -55,10 +55,6 @@ int interfaces_subscription_change_interfaces_interface(sr_session_ctx_t* sessio SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/ipv4/enabled", xpath), error_out); SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_ipv4_change_enabled, interfaces_change_interface_init, interfaces_change_interface_free), error_out); - // ipv4/address - SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/ipv4/address", xpath), error_out); - SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_ipv4_change_address, interfaces_change_interface_init, interfaces_change_interface_free), error_out); - // ipv4/address/ip SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/ipv4/address/ip", xpath), error_out); SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_ipv4_address_change_ip, interfaces_change_interface_init, interfaces_change_interface_free), error_out); From f771ff6e94ccf9726fc56c653f73f015697c490d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Thu, 6 Oct 2022 19:54:28 +0200 Subject: [PATCH 166/247] interfaces-plugin: output libnl error info when unable to add address to the interface --- .../src/plugin/api/interfaces/interface/ipv4/address/change.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c index fa1120d8..ebfb3276 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c @@ -157,6 +157,9 @@ int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* se goto out; error_out: + if (error < 0) { + SRPLG_LOG_INF(PLUGIN_NAME, "nl_geterror(): %s", nl_geterror(error)); + } error = -1; out: From 6637c830b944bea5e9bf9f0ddd69a53d8acc117e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Thu, 6 Oct 2022 20:35:53 +0200 Subject: [PATCH 167/247] interfaces-plugin: implement prefix-length creation when IP address created --- .../interface/ipv4/address/change.c | 106 +++++++++++++++++- src/interfaces/src/plugin/context.h | 5 + 2 files changed, 107 insertions(+), 4 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c index ebfb3276..0cb9501e 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c @@ -1,13 +1,21 @@ #include "change.h" #include "plugin/common.h" #include "plugin/context.h" +#include "srpc/common.h" +#include "srpc/types.h" +#include "sysrepo_types.h" #include +#include + #include #include #include +static int interfaces_interface_ipv4_address_get_prefix_length(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +static int interfaces_interface_ipv4_address_get_netmask(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); + int interfaces_interface_ipv4_address_change_netmask_init(void* priv) { int error = 0; @@ -49,23 +57,81 @@ int interfaces_interface_ipv4_address_change_prefix_length_init(void* priv) int interfaces_interface_ipv4_address_change_prefix_length(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) { int error = 0; + void* error_ptr = NULL; + + // sysrepo + sr_val_t* prefix_val = NULL; + sr_val_t* netmask_val = NULL; + + // strings and buffers const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); + char path_buffer[PATH_MAX] = { 0 }; + char interface_name_buffer[100] = { 0 }; + char ip_buffer[100] = { 0 }; + char address_buffer[100] = { 0 }; + + // app context + interfaces_ctx_t* ctx = priv; + + // mod changes context + interfaces_mod_changes_ctx_t* mod_ctx = &ctx->mod_ctx; + + // libnl + struct rtnl_addr* request_addr = NULL; + struct rtnl_link* current_link = NULL; + struct nl_addr* local_addr = NULL; SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + // get node path + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(change_ctx->node, LYD_PATH_STD, path_buffer, sizeof(path_buffer)), error_out); + + // get interface name + SRPC_SAFE_CALL_ERR(error, srpc_extract_xpath_key_value(path_buffer, "interface", "name", interface_name_buffer, sizeof(interface_name_buffer)), error_out); + + // get IP + SRPC_SAFE_CALL_ERR(error, srpc_extract_xpath_key_value(path_buffer, "address", "ip", ip_buffer, sizeof(ip_buffer)), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "Node Path: %s; Interface Name: %s; Address IP: %s", path_buffer, interface_name_buffer, ip_buffer); + + // get link + SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->nl_ctx.link_cache, interface_name_buffer), error_out); + switch (change_ctx->operation) { case SR_OP_CREATED: + // this change case should be handled only when creating the whole address in the IP callback + // if handled in this callback - report an error break; case SR_OP_MODIFIED: + // change prefix length + + // get full address + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(address_buffer, sizeof(address_buffer), "%s/%s", ip_buffer, node_value), error_out); + + // create local address + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(address_buffer, AF_INET, &local_addr), error_out); + + // fetch rtnl_address break; case SR_OP_DELETED: + // fetch info about prefix-length/netmask and use the pair address/prefix to delete address + // prefix is needed to find the appropriate address break; case SR_OP_MOVED: break; } - return -1; + goto out; + +error_out: + if (error < 0) { + SRPLG_LOG_INF(PLUGIN_NAME, "nl_geterror(): %s", nl_geterror(error)); + } + error = -1; + +out: + return error; } void interfaces_interface_ipv4_address_change_prefix_length_free(void* priv) @@ -128,8 +194,14 @@ int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* se // parse local address SRPC_SAFE_CALL_ERR(error, nl_addr_parse(node_value, AF_INET, &local_addr), error_out); - // set temporary prefix-length - "default" - nl_addr_set_prefixlen(local_addr, 24); + // get prefix length by using prefix-length or netmask leafs + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(path_buffer, sizeof(path_buffer), "%s[name=\"%s\"]/ietf-ip:ipv4/address/prefix-length", INTERFACES_INTERFACES_LIST_YANG_PATH, interface_name_buffer), error_out); + SRPC_SAFE_CALL_ERR(error, srpc_iterate_changes(ctx, session, path_buffer, interfaces_interface_ipv4_address_get_prefix_length, NULL, NULL), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "prefix-length(%s) = %d", node_value, mod_ctx->mod_data.prefix_length); + + // set final prefix length + nl_addr_set_prefixlen(local_addr, mod_ctx->mod_data.prefix_length); // set to route address SRPC_SAFE_CALL_ERR(error, rtnl_addr_set_local(request_addr, local_addr), error_out); @@ -163,9 +235,35 @@ int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* se error = -1; out: - return error; + return -1; } void interfaces_interface_ipv4_address_change_ip_free(void* priv) { } + +static int interfaces_interface_ipv4_address_get_prefix_length(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + + // ctx + interfaces_ctx_t* ctx = priv; + interfaces_mod_changes_ctx_t* mod_ctx = &ctx->mod_ctx; + + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + // this callback should only be called on CREATED operation + assert(change_ctx->operation == SR_OP_CREATED); + + // parse prefix length + mod_ctx->mod_data.prefix_length = atoi(node_value); + + return 0; +} + +static int interfaces_interface_ipv4_address_get_netmask(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ +} \ No newline at end of file diff --git a/src/interfaces/src/plugin/context.h b/src/interfaces/src/plugin/context.h index 918e8ead..12492a85 100644 --- a/src/interfaces/src/plugin/context.h +++ b/src/interfaces/src/plugin/context.h @@ -35,6 +35,11 @@ struct interfaces_nl_ctx_s { struct interfaces_mod_changes_ctx_s { // libnl links data interfaces_nl_ctx_t nl_ctx; + + // data + struct { + int32_t prefix_length; + } mod_data; }; struct interfaces_state_changes_ctx_s { From bb39a5e5d278d96aefa9b077f57705e8f8bfc404 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Sat, 8 Oct 2022 22:30:54 +0200 Subject: [PATCH 168/247] interfaces-plugin: implement prefix-length modify operation --- .../interface/ipv4/address/change.c | 39 +++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c index 0cb9501e..c66c30c5 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c @@ -70,6 +70,7 @@ int interfaces_interface_ipv4_address_change_prefix_length(void* priv, sr_sessio char interface_name_buffer[100] = { 0 }; char ip_buffer[100] = { 0 }; char address_buffer[100] = { 0 }; + char old_address_buffer[100] = { 0 }; // app context interfaces_ctx_t* ctx = priv; @@ -79,8 +80,10 @@ int interfaces_interface_ipv4_address_change_prefix_length(void* priv, sr_sessio // libnl struct rtnl_addr* request_addr = NULL; + struct rtnl_addr* delete_addr = NULL; struct rtnl_link* current_link = NULL; struct nl_addr* local_addr = NULL; + struct nl_addr* old_local_addr = NULL; SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); @@ -101,22 +104,39 @@ int interfaces_interface_ipv4_address_change_prefix_length(void* priv, sr_sessio switch (change_ctx->operation) { case SR_OP_CREATED: // this change case should be handled only when creating the whole address in the IP callback - // if handled in this callback - report an error + // no need to process created change break; case SR_OP_MODIFIED: // change prefix length + request_addr = rtnl_addr_alloc(); + delete_addr = rtnl_addr_alloc(); // get full address SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(address_buffer, sizeof(address_buffer), "%s/%s", ip_buffer, node_value), error_out); + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(old_address_buffer, sizeof(old_address_buffer), "%s/%s", ip_buffer, change_ctx->previous_value), error_out); - // create local address + // parse local address SRPC_SAFE_CALL_ERR(error, nl_addr_parse(address_buffer, AF_INET, &local_addr), error_out); + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(old_address_buffer, AF_INET, &old_local_addr), error_out); + + // set to route address + SRPC_SAFE_CALL_ERR(error, rtnl_addr_set_local(request_addr, local_addr), error_out); + SRPC_SAFE_CALL_ERR(error, rtnl_addr_set_local(delete_addr, old_local_addr), error_out); + + // set interface + rtnl_addr_set_ifindex(request_addr, rtnl_link_get_ifindex(current_link)); + rtnl_addr_set_ifindex(delete_addr, rtnl_link_get_ifindex(current_link)); + + // delete old address + SRPC_SAFE_CALL_ERR(error, rtnl_addr_delete(mod_ctx->nl_ctx.socket, delete_addr, 0), error_out); + + // add new address + SRPC_SAFE_CALL_ERR(error, rtnl_addr_add(mod_ctx->nl_ctx.socket, request_addr, 0), error_out); - // fetch rtnl_address break; case SR_OP_DELETED: - // fetch info about prefix-length/netmask and use the pair address/prefix to delete address // prefix is needed to find the appropriate address + // should be processed when IP deleted break; case SR_OP_MOVED: break; @@ -183,9 +203,6 @@ int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* se // get link SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->nl_ctx.link_cache, interface_name_buffer), error_out); - // get interface index - const int ifindex = rtnl_link_get_ifindex(current_link); - switch (change_ctx->operation) { case SR_OP_CREATED: // new address @@ -198,8 +215,6 @@ int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* se SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(path_buffer, sizeof(path_buffer), "%s[name=\"%s\"]/ietf-ip:ipv4/address/prefix-length", INTERFACES_INTERFACES_LIST_YANG_PATH, interface_name_buffer), error_out); SRPC_SAFE_CALL_ERR(error, srpc_iterate_changes(ctx, session, path_buffer, interfaces_interface_ipv4_address_get_prefix_length, NULL, NULL), error_out); - SRPLG_LOG_INF(PLUGIN_NAME, "prefix-length(%s) = %d", node_value, mod_ctx->mod_data.prefix_length); - // set final prefix length nl_addr_set_prefixlen(local_addr, mod_ctx->mod_data.prefix_length); @@ -207,7 +222,7 @@ int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* se SRPC_SAFE_CALL_ERR(error, rtnl_addr_set_local(request_addr, local_addr), error_out); // set interface - rtnl_addr_set_ifindex(request_addr, ifindex); + rtnl_addr_set_ifindex(request_addr, rtnl_link_get_ifindex(current_link)); // add address SRPC_SAFE_CALL_ERR(error, rtnl_addr_add(mod_ctx->nl_ctx.socket, request_addr, 0), error_out); @@ -235,7 +250,7 @@ int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* se error = -1; out: - return -1; + return error; } void interfaces_interface_ipv4_address_change_ip_free(void* priv) @@ -261,7 +276,7 @@ static int interfaces_interface_ipv4_address_get_prefix_length(void* priv, sr_se // parse prefix length mod_ctx->mod_data.prefix_length = atoi(node_value); - return 0; + return error; } static int interfaces_interface_ipv4_address_get_netmask(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) From 63160957f48ab7d7f2fb3c755e63e29828bc3504 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Sat, 8 Oct 2022 22:36:00 +0200 Subject: [PATCH 169/247] interfaces-plugin: update log message --- .../src/plugin/api/interfaces/interface/ipv4/address/change.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c index c66c30c5..7d6a1db8 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c @@ -230,7 +230,7 @@ int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* se break; case SR_OP_MODIFIED: // should be impossible - address IP can only be created and deleted - SRPLG_LOG_ERR(PLUGIN_NAME, "Unsuported operation MODIFY for ietf-ip:ipv4/address/ip"); + SRPLG_LOG_ERR(PLUGIN_NAME, "Unsuported operation MODIFY for interface IPv4 address IP leaf"); goto error_out; break; case SR_OP_DELETED: From aea5bc15464b8680c149916befab7bae1408ee60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 10 Oct 2022 12:07:12 +0200 Subject: [PATCH 170/247] interfaces-plugin: implement delete functionality for the IPv4 address --- .../interface/ipv4/address/change.c | 84 +++++++++++++++++-- 1 file changed, 78 insertions(+), 6 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c index 7d6a1db8..df63be35 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c @@ -24,7 +24,7 @@ int interfaces_interface_ipv4_address_change_netmask_init(void* priv) int interfaces_interface_ipv4_address_change_netmask(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) { - int error = 0; + // int error = 0; const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); @@ -59,10 +59,6 @@ int interfaces_interface_ipv4_address_change_prefix_length(void* priv, sr_sessio int error = 0; void* error_ptr = NULL; - // sysrepo - sr_val_t* prefix_val = NULL; - sr_val_t* netmask_val = NULL; - // strings and buffers const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); @@ -172,12 +168,15 @@ int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* se // sysrepo sr_val_t* prefix_val = NULL; sr_val_t* netmask_val = NULL; + sr_conn_ctx_t* conn_ctx = NULL; + sr_session_ctx_t* running_session = NULL; // strings and buffers const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); char path_buffer[PATH_MAX] = { 0 }; char interface_name_buffer[100] = { 0 }; + char address_buffer[100] = { 0 }; // app context interfaces_ctx_t* ctx = priv; @@ -190,6 +189,9 @@ int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* se struct rtnl_link* current_link = NULL; struct nl_addr* local_addr = NULL; + // data + int prefix_length = 0; + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); // get node path @@ -203,6 +205,12 @@ int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* se // get link SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->nl_ctx.link_cache, interface_name_buffer), error_out); + // get connection + SRPC_SAFE_CALL_PTR(conn_ctx, sr_session_get_connection(session), error_out); + + // start a running DS session - fetching data about prefix when deleting the address + SRPC_SAFE_CALL_ERR(error, sr_session_start(conn_ctx, SR_DS_RUNNING, &running_session), error_out); + switch (change_ctx->operation) { case SR_OP_CREATED: // new address @@ -212,7 +220,7 @@ int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* se SRPC_SAFE_CALL_ERR(error, nl_addr_parse(node_value, AF_INET, &local_addr), error_out); // get prefix length by using prefix-length or netmask leafs - SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(path_buffer, sizeof(path_buffer), "%s[name=\"%s\"]/ietf-ip:ipv4/address/prefix-length", INTERFACES_INTERFACES_LIST_YANG_PATH, interface_name_buffer), error_out); + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(path_buffer, sizeof(path_buffer), "%s[name=\"%s\"]/ietf-ip:ipv4/address[ip=\"%s\"]/prefix-length", INTERFACES_INTERFACES_LIST_YANG_PATH, interface_name_buffer, node_value), error_out); SRPC_SAFE_CALL_ERR(error, srpc_iterate_changes(ctx, session, path_buffer, interfaces_interface_ipv4_address_get_prefix_length, NULL, NULL), error_out); // set final prefix length @@ -236,6 +244,48 @@ int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* se case SR_OP_DELETED: // fetch info about prefix-length/netmask and use the pair address/prefix to delete address // prefix is needed to find the appropriate address + request_addr = rtnl_addr_alloc(); + + // check for prefix-length + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(path_buffer, sizeof(path_buffer), INTERFACES_INTERFACES_INTERFACE_YANG_PATH "[name=\"%s\"]/ietf-ip:ipv4/address[ip=\"%s\"]/prefix-length", interface_name_buffer, node_value), error_out); + SRPLG_LOG_INF(PLUGIN_NAME, "Searching running DS for %s", path_buffer); + + error = sr_get_item(running_session, path_buffer, 0, &prefix_val); + if (error == SR_ERR_OK) { + // parse prefix-length + prefix_length = prefix_val->data.uint8_val; + } else if (error == SR_ERR_NOT_FOUND) { + // fetch netmask + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(path_buffer, sizeof(path_buffer), "%s[name=\"%s\"]/ietf-ip:ipv4/address[ip=\"%s\"]/netmask", INTERFACES_INTERFACES_LIST_YANG_PATH, interface_name_buffer, node_value), error_out); + SRPC_SAFE_CALL_ERR(error, sr_get_item(running_session, path_buffer, 0, &netmask_val), error_out); + + // TODO: convert netmask to prefix + + } else { + // other error - treat as invalid + SRPLG_LOG_ERR(PLUGIN_NAME, "Error retrieving prefix-length value for address %s", node_value); + goto error_out; + } + + SRPLG_LOG_INF(PLUGIN_NAME, "Recieved prefix for address %s: %d", node_value, prefix_length); + + // after getting the prefix length - remove address + + // get full address + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(address_buffer, sizeof(address_buffer), "%s/%d", node_value, prefix_length), error_out); + + // parse local address + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(address_buffer, AF_INET, &local_addr), error_out); + + // set to route address + SRPC_SAFE_CALL_ERR(error, rtnl_addr_set_local(request_addr, local_addr), error_out); + + // set interface + rtnl_addr_set_ifindex(request_addr, rtnl_link_get_ifindex(current_link)); + + // remove wanted address + SRPC_SAFE_CALL_ERR(error, rtnl_addr_delete(mod_ctx->nl_ctx.socket, request_addr, 0), error_out); + break; case SR_OP_MOVED: break; @@ -250,6 +300,10 @@ int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* se error = -1; out: + if (running_session) { + sr_session_stop(running_session); + } + return error; } @@ -281,4 +335,22 @@ static int interfaces_interface_ipv4_address_get_prefix_length(void* priv, sr_se static int interfaces_interface_ipv4_address_get_netmask(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) { + int error = 0; + + // ctx + interfaces_ctx_t* ctx = priv; + interfaces_mod_changes_ctx_t* mod_ctx = &ctx->mod_ctx; + + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + // this callback should only be called on CREATED operation + assert(change_ctx->operation == SR_OP_CREATED); + + // TODO: parse netmask into prefix length + (void)mod_ctx; + + return error; } \ No newline at end of file From 752e271b42e8b5fd27497917972e145cf4da8701 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 10 Oct 2022 12:18:25 +0200 Subject: [PATCH 171/247] interfaces-plugin: implement netmask to prefix-length conversion --- .../data/interfaces/interface/ipv4/address.c | 31 +++++++++++++++++++ .../data/interfaces/interface/ipv4/address.h | 6 ++++ 2 files changed, 37 insertions(+) diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c index 210dd74b..adfb3906 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c @@ -1,10 +1,14 @@ #include "address.h" #include "plugin/types.h" #include "src/utlist.h" + +#include #include #include #include +#include + interfaces_interface_ipv4_address_element_t* interfaces_interface_ipv4_address_new(void) { return NULL; @@ -105,3 +109,30 @@ int interfaces_interface_ipv4_address_element_set_netmask(interfaces_interface_i return 0; } + +int interfaces_interface_ipv4_address_netmask2prefix(const char* netmask, uint8_t* prefix_length) +{ + int error = 0; + struct in_addr addr = { 0 }; + uint8_t prefix = 0; + + // convert to bits (uint32_t -> addr.s_addr) + SRPC_SAFE_CALL_ERR_COND(error, error != 1, inet_pton(AF_INET, netmask, &addr), error_out); + + // count address bits + while (addr.s_addr) { + if (addr.s_addr & 0x1) { + ++prefix; + } + + addr.s_addr >>= 1; + } + + goto out; + +error_out: + error = -1; + +out: + return error; +} \ No newline at end of file diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.h b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.h index 820c1fc4..fa5c3e5d 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.h +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.h @@ -24,4 +24,10 @@ int interfaces_interface_ipv4_address_element_set_ip(interfaces_interface_ipv4_a int interfaces_interface_ipv4_address_element_set_prefix_length(interfaces_interface_ipv4_address_element_t** el, uint8_t prefix_length); int interfaces_interface_ipv4_address_element_set_netmask(interfaces_interface_ipv4_address_element_t** el, const char* netmask); +/* + Helper functions +*/ + +int interfaces_interface_ipv4_address_netmask2prefix(const char* netmask, uint8_t* prefix_length); + #endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV4_ADDRESS_H \ No newline at end of file From 11a39af036e8d3bae0ff9502a66b4cc17f786940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 10 Oct 2022 12:27:41 +0200 Subject: [PATCH 172/247] interfaces-plugin: implement netmask modify functionality --- .../interface/ipv4/address/change.c | 91 ++++++++++++++++++- src/interfaces/src/plugin/context.h | 3 +- 2 files changed, 90 insertions(+), 4 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c index df63be35..ea5bf5fb 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c @@ -1,6 +1,7 @@ #include "change.h" #include "plugin/common.h" #include "plugin/context.h" +#include "plugin/data/interfaces/interface/ipv4/address.h" #include "srpc/common.h" #include "srpc/types.h" #include "sysrepo_types.h" @@ -24,24 +25,107 @@ int interfaces_interface_ipv4_address_change_netmask_init(void* priv) int interfaces_interface_ipv4_address_change_netmask(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) { - // int error = 0; + int error = 0; + void* error_ptr = NULL; + + // strings and buffers const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); + char path_buffer[PATH_MAX] = { 0 }; + char interface_name_buffer[100] = { 0 }; + char ip_buffer[100] = { 0 }; + char address_buffer[100] = { 0 }; + char old_address_buffer[100] = { 0 }; + + // app context + interfaces_ctx_t* ctx = priv; + + // mod changes context + interfaces_mod_changes_ctx_t* mod_ctx = &ctx->mod_ctx; + + // libnl + struct rtnl_addr* request_addr = NULL; + struct rtnl_addr* delete_addr = NULL; + struct rtnl_link* current_link = NULL; + struct nl_addr* local_addr = NULL; + struct nl_addr* old_local_addr = NULL; + + // data + uint8_t prefix_length = 0; + uint8_t old_prefix_length = 0; SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + // get node path + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(change_ctx->node, LYD_PATH_STD, path_buffer, sizeof(path_buffer)), error_out); + + // get interface name + SRPC_SAFE_CALL_ERR(error, srpc_extract_xpath_key_value(path_buffer, "interface", "name", interface_name_buffer, sizeof(interface_name_buffer)), error_out); + + // get IP + SRPC_SAFE_CALL_ERR(error, srpc_extract_xpath_key_value(path_buffer, "address", "ip", ip_buffer, sizeof(ip_buffer)), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "Node Path: %s; Interface Name: %s; Address IP: %s", path_buffer, interface_name_buffer, ip_buffer); + + // get link + SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->nl_ctx.link_cache, interface_name_buffer), error_out); + switch (change_ctx->operation) { case SR_OP_CREATED: + // this change case should be handled only when creating the whole address in the IP callback + // no need to process created change break; case SR_OP_MODIFIED: + // change netmask/prefix length + request_addr = rtnl_addr_alloc(); + delete_addr = rtnl_addr_alloc(); + + // convert netmask to prefix length + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_address_netmask2prefix(node_value, &prefix_length), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_address_netmask2prefix(change_ctx->previous_value, &old_prefix_length), error_out); + + // get full address + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(address_buffer, sizeof(address_buffer), "%s/%d", ip_buffer, prefix_length), error_out); + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(old_address_buffer, sizeof(old_address_buffer), "%s/%d", ip_buffer, old_prefix_length), error_out); + + // parse local address + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(address_buffer, AF_INET, &local_addr), error_out); + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(old_address_buffer, AF_INET, &old_local_addr), error_out); + + // set to route address + SRPC_SAFE_CALL_ERR(error, rtnl_addr_set_local(request_addr, local_addr), error_out); + SRPC_SAFE_CALL_ERR(error, rtnl_addr_set_local(delete_addr, old_local_addr), error_out); + + // set interface + rtnl_addr_set_ifindex(request_addr, rtnl_link_get_ifindex(current_link)); + rtnl_addr_set_ifindex(delete_addr, rtnl_link_get_ifindex(current_link)); + + // delete old address + SRPC_SAFE_CALL_ERR(error, rtnl_addr_delete(mod_ctx->nl_ctx.socket, delete_addr, 0), error_out); + + // add new address + SRPC_SAFE_CALL_ERR(error, rtnl_addr_add(mod_ctx->nl_ctx.socket, request_addr, 0), error_out); + break; case SR_OP_DELETED: + // netmask is needed to find the appropriate address + // should be processed when IP deleted break; case SR_OP_MOVED: break; } - return -1; + goto out; + +error_out: + if (error < 0) { + // libnl error + SRPLG_LOG_INF(PLUGIN_NAME, "nl_geterror(): %s", nl_geterror(error)); + } + error = -1; + +out: + return error; } void interfaces_interface_ipv4_address_change_netmask_free(void* priv) @@ -328,7 +412,8 @@ static int interfaces_interface_ipv4_address_get_prefix_length(void* priv, sr_se assert(change_ctx->operation == SR_OP_CREATED); // parse prefix length - mod_ctx->mod_data.prefix_length = atoi(node_value); + mod_ctx->mod_data.prefix_length = (uint8_t)atoi(node_value); + mod_ctx->mod_data.prefix_set = true; return error; } diff --git a/src/interfaces/src/plugin/context.h b/src/interfaces/src/plugin/context.h index 12492a85..f1cdf216 100644 --- a/src/interfaces/src/plugin/context.h +++ b/src/interfaces/src/plugin/context.h @@ -38,7 +38,8 @@ struct interfaces_mod_changes_ctx_s { // data struct { - int32_t prefix_length; + uint8_t prefix_length; + uint8_t prefix_set; ///< prefix_length has been set } mod_data; }; From 1a639759484ae75ce04101bb46b37227c9fa4cd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 10 Oct 2022 12:42:24 +0200 Subject: [PATCH 173/247] interfaces-plugin: implement IPv4 address create functionality using netmasks --- .../interface/ipv4/address/change.c | 35 +++++++++++++++++-- .../data/interfaces/interface/ipv4/address.c | 4 +++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c index ea5bf5fb..2a0c6120 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c @@ -307,6 +307,21 @@ int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* se SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(path_buffer, sizeof(path_buffer), "%s[name=\"%s\"]/ietf-ip:ipv4/address[ip=\"%s\"]/prefix-length", INTERFACES_INTERFACES_LIST_YANG_PATH, interface_name_buffer, node_value), error_out); SRPC_SAFE_CALL_ERR(error, srpc_iterate_changes(ctx, session, path_buffer, interfaces_interface_ipv4_address_get_prefix_length, NULL, NULL), error_out); + if (!mod_ctx->mod_data.prefix_set) { + // prefix not found - check for netmask + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(path_buffer, sizeof(path_buffer), "%s[name=\"%s\"]/ietf-ip:ipv4/address[ip=\"%s\"]/netmask", INTERFACES_INTERFACES_LIST_YANG_PATH, interface_name_buffer, node_value), error_out); + SRPC_SAFE_CALL_ERR(error, srpc_iterate_changes(ctx, session, path_buffer, interfaces_interface_ipv4_address_get_netmask, NULL, NULL), error_out); + + if (!mod_ctx->mod_data.prefix_set) { + SRPLG_LOG_ERR(PLUGIN_NAME, "Unable to get prefix-length/netmask for address %s... Discarding changes", node_value); + goto error_out; + } + } + + SRPLG_LOG_INF(PLUGIN_NAME, "Recieved prefix-length of %d for address %s", mod_ctx->mod_data.prefix_length, node_value); + + // prefix was set and found + // set final prefix length nl_addr_set_prefixlen(local_addr, mod_ctx->mod_data.prefix_length); @@ -388,6 +403,10 @@ int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* se sr_session_stop(running_session); } + // re-initialize mod_ctx data + mod_ctx->mod_data.prefix_length = 0; + mod_ctx->mod_data.prefix_set = false; + return error; } @@ -426,6 +445,8 @@ static int interfaces_interface_ipv4_address_get_netmask(void* priv, sr_session_ interfaces_ctx_t* ctx = priv; interfaces_mod_changes_ctx_t* mod_ctx = &ctx->mod_ctx; + uint8_t prefix_length = 0; + const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); @@ -434,8 +455,18 @@ static int interfaces_interface_ipv4_address_get_netmask(void* priv, sr_session_ // this callback should only be called on CREATED operation assert(change_ctx->operation == SR_OP_CREATED); - // TODO: parse netmask into prefix length - (void)mod_ctx; + // parse netmask into prefix length + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_address_netmask2prefix(node_value, &prefix_length), error_out); + // set mod changes prefix length + mod_ctx->mod_data.prefix_length = prefix_length; + mod_ctx->mod_data.prefix_set = true; + + goto out; + +error_out: + error = -1; + +out: return error; } \ No newline at end of file diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c index adfb3906..06677ba2 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c @@ -128,6 +128,10 @@ int interfaces_interface_ipv4_address_netmask2prefix(const char* netmask, uint8_ addr.s_addr >>= 1; } + // set the provided value + *prefix_length = prefix; + + error = 0; goto out; error_out: From 47ed5f0efd8748d7cfa007c4e87a3ebfaffb7f70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 10 Oct 2022 12:45:44 +0200 Subject: [PATCH 174/247] interfaces-plugin: implement IPv4 address delete functionality using netmasks --- .../plugin/api/interfaces/interface/ipv4/address/change.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c index 2a0c6120..f58b2e8a 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c @@ -274,7 +274,7 @@ int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* se struct nl_addr* local_addr = NULL; // data - int prefix_length = 0; + uint8_t prefix_length = 0; SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); @@ -358,8 +358,8 @@ int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* se SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(path_buffer, sizeof(path_buffer), "%s[name=\"%s\"]/ietf-ip:ipv4/address[ip=\"%s\"]/netmask", INTERFACES_INTERFACES_LIST_YANG_PATH, interface_name_buffer, node_value), error_out); SRPC_SAFE_CALL_ERR(error, sr_get_item(running_session, path_buffer, 0, &netmask_val), error_out); - // TODO: convert netmask to prefix - + // convert netmask to prefix + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_address_netmask2prefix(netmask_val->data.string_val, &prefix_length), error_out); } else { // other error - treat as invalid SRPLG_LOG_ERR(PLUGIN_NAME, "Error retrieving prefix-length value for address %s", node_value); From 6e7bce1cbd89b6402d35282a404f37b33f0dd7ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 10 Oct 2022 14:09:47 +0200 Subject: [PATCH 175/247] interfaces-plugin: implement IPv4 neighbor create and delete functionality --- .../interface/ipv4/address/change.c | 21 +-- .../api/interfaces/interface/ipv4/change.c | 2 +- .../interface/ipv4/neighbor/change.c | 145 ++++++++++++++++++ .../interface/ipv4/neighbor/change.h | 1 + src/interfaces/src/plugin/context.h | 14 +- .../src/plugin/subscription/change.c | 11 +- 6 files changed, 177 insertions(+), 17 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c index f58b2e8a..6d570337 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c @@ -307,23 +307,23 @@ int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* se SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(path_buffer, sizeof(path_buffer), "%s[name=\"%s\"]/ietf-ip:ipv4/address[ip=\"%s\"]/prefix-length", INTERFACES_INTERFACES_LIST_YANG_PATH, interface_name_buffer, node_value), error_out); SRPC_SAFE_CALL_ERR(error, srpc_iterate_changes(ctx, session, path_buffer, interfaces_interface_ipv4_address_get_prefix_length, NULL, NULL), error_out); - if (!mod_ctx->mod_data.prefix_set) { + if (!mod_ctx->mod_data.ipv4.address.prefix_set) { // prefix not found - check for netmask SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(path_buffer, sizeof(path_buffer), "%s[name=\"%s\"]/ietf-ip:ipv4/address[ip=\"%s\"]/netmask", INTERFACES_INTERFACES_LIST_YANG_PATH, interface_name_buffer, node_value), error_out); SRPC_SAFE_CALL_ERR(error, srpc_iterate_changes(ctx, session, path_buffer, interfaces_interface_ipv4_address_get_netmask, NULL, NULL), error_out); - if (!mod_ctx->mod_data.prefix_set) { + if (!mod_ctx->mod_data.ipv4.address.prefix_set) { SRPLG_LOG_ERR(PLUGIN_NAME, "Unable to get prefix-length/netmask for address %s... Discarding changes", node_value); goto error_out; } } - SRPLG_LOG_INF(PLUGIN_NAME, "Recieved prefix-length of %d for address %s", mod_ctx->mod_data.prefix_length, node_value); + SRPLG_LOG_INF(PLUGIN_NAME, "Recieved prefix-length of %d for address %s", mod_ctx->mod_data.ipv4.address.prefix_length, node_value); // prefix was set and found // set final prefix length - nl_addr_set_prefixlen(local_addr, mod_ctx->mod_data.prefix_length); + nl_addr_set_prefixlen(local_addr, mod_ctx->mod_data.ipv4.address.prefix_length); // set to route address SRPC_SAFE_CALL_ERR(error, rtnl_addr_set_local(request_addr, local_addr), error_out); @@ -404,8 +404,8 @@ int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* se } // re-initialize mod_ctx data - mod_ctx->mod_data.prefix_length = 0; - mod_ctx->mod_data.prefix_set = false; + mod_ctx->mod_data.ipv4.address.prefix_length = 0; + mod_ctx->mod_data.ipv4.address.prefix_set = false; return error; } @@ -431,8 +431,8 @@ static int interfaces_interface_ipv4_address_get_prefix_length(void* priv, sr_se assert(change_ctx->operation == SR_OP_CREATED); // parse prefix length - mod_ctx->mod_data.prefix_length = (uint8_t)atoi(node_value); - mod_ctx->mod_data.prefix_set = true; + mod_ctx->mod_data.ipv4.address.prefix_length = (uint8_t)atoi(node_value); + mod_ctx->mod_data.ipv4.address.prefix_set = true; return error; } @@ -459,13 +459,14 @@ static int interfaces_interface_ipv4_address_get_netmask(void* priv, sr_session_ SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_address_netmask2prefix(node_value, &prefix_length), error_out); // set mod changes prefix length - mod_ctx->mod_data.prefix_length = prefix_length; - mod_ctx->mod_data.prefix_set = true; + mod_ctx->mod_data.ipv4.address.prefix_length = prefix_length; + mod_ctx->mod_data.ipv4.address.prefix_set = true; goto out; error_out: error = -1; + mod_ctx->mod_data.ipv4.address.prefix_set = false; out: return error; diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c index 9469376f..0b322347 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c @@ -36,7 +36,7 @@ int interfaces_interface_ipv4_change_neighbor(void* priv, sr_session_ctx_t* sess break; } - return -1; + return error; } void interfaces_interface_ipv4_change_neighbor_free(void* priv) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c index 047ac005..067c5f98 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c @@ -1,8 +1,17 @@ #include "change.h" +#include "netlink/addr.h" #include "plugin/common.h" +#include "plugin/context.h" +#include #include +#include +#include +#include + +static int interfaces_interface_ipv4_address_get_link_layer_address(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); + int interfaces_interface_ipv4_neighbor_change_link_layer_address_init(void* priv) { int error = 0; @@ -44,25 +53,161 @@ int interfaces_interface_ipv4_neighbor_change_ip_init(void* priv) int interfaces_interface_ipv4_neighbor_change_ip(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) { int error = 0; + void* error_ptr = NULL; + + // sysrepo + // sr_val_t* link_layer_address_val = NULL; + sr_conn_ctx_t* conn_ctx = NULL; + sr_session_ctx_t* running_session = NULL; + + // strings and buffers const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); + char path_buffer[PATH_MAX] = { 0 }; + char interface_name_buffer[100] = { 0 }; + // char address_buffer[100] = { 0 }; + + // app context + interfaces_ctx_t* ctx = priv; + + // mod changes context + interfaces_mod_changes_ctx_t* mod_ctx = &ctx->mod_ctx; + + // libnl + struct rtnl_neigh* request_neigh = NULL; + struct rtnl_link* current_link = NULL; + struct nl_addr* dst_addr = NULL; + struct nl_addr* ll_addr = NULL; SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + // get node path + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(change_ctx->node, LYD_PATH_STD, path_buffer, sizeof(path_buffer)), error_out); + + // get interface name + SRPC_SAFE_CALL_ERR(error, srpc_extract_xpath_key_value(path_buffer, "interface", "name", interface_name_buffer, sizeof(interface_name_buffer)), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "Node Path: %s; Interface Name: %s", path_buffer, interface_name_buffer); + + // get link + SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->nl_ctx.link_cache, interface_name_buffer), error_out); + + // get connection + SRPC_SAFE_CALL_PTR(conn_ctx, sr_session_get_connection(session), error_out); + + // start a running DS session - fetching data about prefix when deleting the address + SRPC_SAFE_CALL_ERR(error, sr_session_start(conn_ctx, SR_DS_RUNNING, &running_session), error_out); + switch (change_ctx->operation) { case SR_OP_CREATED: + // new neighbor + request_neigh = rtnl_neigh_alloc(); + + // parse destination address + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(node_value, AF_INET, &dst_addr), error_out); + + // get prefix length by using prefix-length or netmask leafs + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(path_buffer, sizeof(path_buffer), INTERFACES_INTERFACES_INTERFACE_YANG_PATH "[name=\"%s\"]/ietf-ip:ipv4/neighbor[ip=\"%s\"]/link-layer-address", interface_name_buffer, node_value), error_out); + SRPC_SAFE_CALL_ERR(error, srpc_iterate_changes(ctx, session, path_buffer, interfaces_interface_ipv4_address_get_link_layer_address, NULL, NULL), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "Recieved link-layer-address %s for neighbor address %s", mod_ctx->mod_data.ipv4.neighbor.link_layer_address, node_value); + + // parse link-layer address + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(mod_ctx->mod_data.ipv4.neighbor.link_layer_address, AF_LLC, &ll_addr), error_out); + + // set addresses to the new neighbor + SRPC_SAFE_CALL_ERR(error, rtnl_neigh_set_dst(request_neigh, dst_addr), error_out); + rtnl_neigh_set_lladdr(request_neigh, ll_addr); + + // set interface + rtnl_neigh_set_ifindex(request_neigh, rtnl_link_get_ifindex(current_link)); + + // add neighbor + SRPC_SAFE_CALL_ERR(error, rtnl_neigh_add(mod_ctx->nl_ctx.socket, request_neigh, NLM_F_CREATE), error_out); + break; case SR_OP_MODIFIED: + // should be impossible - address IP can only be created and deleted + SRPLG_LOG_ERR(PLUGIN_NAME, "Unsuported operation MODIFY for interface IPv4 neighbor IP leaf"); + goto error_out; break; case SR_OP_DELETED: + request_neigh = rtnl_neigh_alloc(); + + // set interface + rtnl_neigh_set_ifindex(request_neigh, rtnl_link_get_ifindex(current_link)); + + // parse destination + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(node_value, AF_INET, &dst_addr), error_out); + + // set destination + SRPC_SAFE_CALL_ERR(error, rtnl_neigh_set_dst(request_neigh, dst_addr), error_out); + + // remove wanted neighbor + SRPC_SAFE_CALL_ERR(error, rtnl_neigh_delete(mod_ctx->nl_ctx.socket, request_neigh, 0), error_out); + break; case SR_OP_MOVED: break; } + goto out; + +error_out: + if (error < 0) { + SRPLG_LOG_INF(PLUGIN_NAME, "nl_geterror(): %s", nl_geterror(error)); + } + error = -1; + +out: + if (running_session) { + sr_session_stop(running_session); + } + + // re-initialize mod_ctx data + if (mod_ctx->mod_data.ipv4.neighbor.link_layer_address) { + free(mod_ctx->mod_data.ipv4.neighbor.link_layer_address); + } + mod_ctx->mod_data.ipv4.neighbor.link_layer_address = NULL; + mod_ctx->mod_data.ipv4.neighbor.link_layer_set = false; + return error; } void interfaces_interface_ipv4_neighbor_change_ip_free(void* priv) { } + +static int interfaces_interface_ipv4_address_get_link_layer_address(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + + // ctx + interfaces_ctx_t* ctx = priv; + interfaces_mod_changes_ctx_t* mod_ctx = &ctx->mod_ctx; + + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + // this callback should only be called on CREATED operation + assert(change_ctx->operation == SR_OP_CREATED); + + // set mod changes prefix length + mod_ctx->mod_data.ipv4.neighbor.link_layer_address = strdup(node_value); + if (!mod_ctx->mod_data.ipv4.neighbor.link_layer_address) { + SRPLG_LOG_ERR(PLUGIN_NAME, "Unable to set link-layer-address value for module changes context"); + goto error_out; + } + mod_ctx->mod_data.ipv4.neighbor.link_layer_set = true; + + goto out; + +error_out: + error = -1; + mod_ctx->mod_data.ipv4.neighbor.link_layer_set = false; + +out: + return error; +} \ No newline at end of file diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.h b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.h index 9169ddbc..96fc4108 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.h +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.h @@ -7,6 +7,7 @@ int interfaces_interface_ipv4_neighbor_change_link_layer_address_init(void* priv); int interfaces_interface_ipv4_neighbor_change_link_layer_address(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); void interfaces_interface_ipv4_neighbor_change_link_layer_address_free(void* priv); + int interfaces_interface_ipv4_neighbor_change_ip_init(void* priv); int interfaces_interface_ipv4_neighbor_change_ip(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); void interfaces_interface_ipv4_neighbor_change_ip_free(void* priv); diff --git a/src/interfaces/src/plugin/context.h b/src/interfaces/src/plugin/context.h index f1cdf216..e7b48b0f 100644 --- a/src/interfaces/src/plugin/context.h +++ b/src/interfaces/src/plugin/context.h @@ -36,10 +36,18 @@ struct interfaces_mod_changes_ctx_s { // libnl links data interfaces_nl_ctx_t nl_ctx; - // data + // temporary module changing data struct { - uint8_t prefix_length; - uint8_t prefix_set; ///< prefix_length has been set + struct { + struct { + uint8_t prefix_length; + uint8_t prefix_set; ///< prefix_length has been set + } address; + struct { + char* link_layer_address; + uint8_t link_layer_set; ///< link_layer_address has been set + } neighbor; + } ipv4; } mod_data; }; diff --git a/src/interfaces/src/plugin/subscription/change.c b/src/interfaces/src/plugin/subscription/change.c index 400515be..56674380 100644 --- a/src/interfaces/src/plugin/subscription/change.c +++ b/src/interfaces/src/plugin/subscription/change.c @@ -1,4 +1,5 @@ #include "change.h" +#include "plugin/api/interfaces/interface/ipv4/neighbor/change.h" #include "plugin/common.h" #include "plugin/context.h" @@ -67,9 +68,13 @@ int interfaces_subscription_change_interfaces_interface(sr_session_ctx_t* sessio SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/ipv4/address/netmask", xpath), error_out); SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_ipv4_address_change_netmask, interfaces_change_interface_init, interfaces_change_interface_free), error_out); - // ipv4/neighbor - SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/ipv4/neighbor", xpath), error_out); - SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_ipv4_change_neighbor, interfaces_change_interface_init, interfaces_change_interface_free), error_out); + // ipv4/neighbor/ip + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/ipv4/neighbor/ip", xpath), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_ipv4_neighbor_change_ip, interfaces_change_interface_init, interfaces_change_interface_free), error_out); + + // ipv4/neighbor/link-layer-address + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/ipv4/neighbor/link-layer-address", xpath), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_ipv4_neighbor_change_link_layer_address, interfaces_change_interface_init, interfaces_change_interface_free), error_out); } goto out; From 7d740453e4eb81cd83e4daa7ca76327a34b87f25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Mon, 10 Oct 2022 14:11:22 +0200 Subject: [PATCH 176/247] interfaces-plugin: cleanup code --- .../src/plugin/api/interfaces/interface/ipv4/neighbor/change.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c index 067c5f98..43f118bf 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c @@ -56,7 +56,6 @@ int interfaces_interface_ipv4_neighbor_change_ip(void* priv, sr_session_ctx_t* s void* error_ptr = NULL; // sysrepo - // sr_val_t* link_layer_address_val = NULL; sr_conn_ctx_t* conn_ctx = NULL; sr_session_ctx_t* running_session = NULL; @@ -65,7 +64,6 @@ int interfaces_interface_ipv4_neighbor_change_ip(void* priv, sr_session_ctx_t* s const char* node_value = lyd_get_value(change_ctx->node); char path_buffer[PATH_MAX] = { 0 }; char interface_name_buffer[100] = { 0 }; - // char address_buffer[100] = { 0 }; // app context interfaces_ctx_t* ctx = priv; From dddd6729aaef45e1e2cf428ac375d66bc3d6c609 Mon Sep 17 00:00:00 2001 From: andrej Date: Tue, 11 Oct 2022 11:34:11 +0200 Subject: [PATCH 177/247] interfaces-plugin: add ipv4/6, address, neighbor load --- .../src/plugin/api/interfaces/load.c | 311 +++++++++++++++++- 1 file changed, 302 insertions(+), 9 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index 3125bcdb..c401726f 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -8,26 +8,300 @@ #include +#include +#include +#include +#include +#include #include +#include +#include #include +#include +#include +#include +#include #include enum interfaces_load_exit_status { - interfaces_load_failure = -1, - interfaces_load_success = 0, - interfaces_load_continue = 1, + interfaces_load_failure = -1, + interfaces_load_success = 0, + interfaces_load_continue = 1, }; +static int interfaces_add_address_ipv4(interfaces_interface_ipv4_address_element_t **address, char *ip, char *netmask) +{ + interfaces_interface_ipv4_address_element_t* new_element = NULL; + + new_element = interfaces_interface_ipv4_address_element_new(); + + interfaces_interface_ipv4_address_element_set_ip(&new_element, ip); + interfaces_interface_ipv4_address_element_set_subnet(&new_element, netmask, interfaces_interface_ipv4_address_subnet_netmask); + interfaces_interface_ipv4_address_add_element(address, new_element); + +} + +static int interfaces_add_address_ipv6(interfaces_interface_ipv6_address_element_t **address, char *ip, char *netmask) +{ + int prefix_length = 0; + + interfaces_interface_ipv6_address_element_t* new_element = NULL; + + new_element = interfaces_interface_ipv6_address_element_new(); + + interfaces_interface_ipv6_address_element_set_ip(&new_element, ip); + prefix_length = interfaces_interface_netmask_to_prefix_length(netmask); + interfaces_interface_ipv6_address_element_set_prefix_length(&new_element, prefix_length); + interfaces_interface_ipv6_address_add_element(address, new_element); + +} + +static int interfaces_add_ips(interfaces_interface_t* interface, char *ip, int netmask, int addr_family) +{ + switch (addr_family) { + case AF_INET: + interfaces_add_address_ipv4(&interface->ipv4.address, ip, netmask); + break; + case AF_INET6: + interfaces_add_address_ipv6(&interface->ipv6.address, ip, netmask); + break; + default: + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: invalid address family", __func__); + return -1; + } + + return 0; +} + +static int interfaces_get_ips(struct nl_sock* socket, struct rtnl_link* link, interfaces_interface_t* interface) +{ + struct nl_object *nl_object = NULL; + struct nl_cache *addr_cache = NULL; + struct nl_addr *nl_addr_local = NULL; + struct rtnl_addr *addr = { 0 }; + char *address = NULL; + char *subnet = NULL; + char *addr_s = NULL; + char *token = NULL; + char *str = NULL; + char addr_str[ADDR_STR_BUF_SIZE] = { 0 }; + + unsigned int mtu = 0; + int addr_count = 0; + int addr_family = 0; + int if_index = 0; + int cur_if_index = 0; + int error = 0; + + mtu = rtnl_link_get_mtu(link); + + if_index = rtnl_link_get_ifindex(link); + + SRPC_SAFE_CALL(rtnl_neigh_alloc_cache(socket, &addr_cache), error_out); + + /* get ipv4 and ipv6 addresses */ + addr_count = nl_cache_nitems(addr_cache); + + nl_object = nl_cache_get_first(addr_cache); + addr = (struct rtnl_addr *) nl_object; + + for (int i = 0; i < addr_count; ++i) { + SRPC_SAFE_CALL_PTR(nl_addr_local, rtnl_addr_get_local(addr), error_out); + + cur_if_index = rtnl_addr_get_ifindex(addr); + + if (if_index != cur_if_index) { + goto next_address; + } + + SRPC_SAFE_CALL_PTR(addr_s, nl_addr2str(nl_addr_local, addr_str, sizeof(addr_str)), error_out); + + str = xstrdup(addr_s); + SRPC_SAFE_CALL_PTR(token, strtok(str, "/"), error_out); + + address = xstrdup(token); + + /* get subnet */ + token = strtok(NULL, "/"); + if (token == NULL) { + /* + the address exists + skip it + we didn't add this address + e.g.: ::1 + */ + FREE_SAFE(str); + FREE_SAFE(address); + continue; + } + + subnet = xstrdup(token); + + /* check if ipv4 or ipv6 */ + addr_family = rtnl_addr_get_family(addr); + + interfaces_add_ips(interface, address, subnet, addr_family); + + next_address: + nl_object = nl_cache_get_next(nl_object); + addr = (struct rtnl_addr *) nl_object; + + FREE_SAFE(subnet); + FREE_SAFE(str); + FREE_SAFE(address); +} + + goto out; +error_out: +out: + if (addr_cache) { + nl_cache_free(addr_cache); + } + if (str) { + FREE_SAFE(str); + } + if (address) { + FREE_SAFE(address); + } + + return interfaces_load_success; +} + +static int interfaces_add_neighbor_ipv4(interfaces_interface_ipv4_neighbor_element_t** neighbor, char *dst_addr, char *ll_addr) +{ + interfaces_interface_ipv4_neighbor_element_t* new_element = NULL; + + new_element = interfaces_interface_ipv4_neighbor_element_new(); + + interfaces_interface_ipv4_neighbor_element_set_ip(&new_element, dst_addr); + interfaces_interface_ipv4_neighbor_element_set_link_layer_address(&new_element, ll_addr); + interfaces_interface_ipv4_neighbor_add_element(neighbor, new_element); + + return 0; +} + +static int interfaces_add_neighbor_ipv6(interfaces_interface_ipv6_neighbor_element_t** neighbor, char *dst_addr, char *ll_addr) +{ + interfaces_interface_ipv6_neighbor_element_t* new_element = NULL; + + new_element = interfaces_interface_ipv6_neighbor_element_new(); + + interfaces_interface_ipv6_neighbor_element_set_ip(&new_element, dst_addr); + interfaces_interface_ipv6_neighbor_element_set_link_layer_address(&new_element, ll_addr); + interfaces_interface_ipv6_neighbor_add_element(neighbor, new_element); + + return 0; +} + +static int interfaces_add_neighbor(interfaces_interface_t* interface, char *dst_addr, char *ll_addr, int addr_family) +{ + switch (addr_family) { + case AF_INET: + interfaces_add_neighbor_ipv4(&interface->ipv4.neighbor, dst_addr, ll_addr); + break; + case AF_INET6: + interfaces_add_neighbor_ipv6(&interface->ipv6.neighbor, dst_addr, ll_addr); + break; + default: + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: invalid address family", __func__); + return -1; + } + + return 0; +} + +static int interfaces_get_neighbors(struct nl_sock* socket, struct rtnl_link* link, interfaces_interface_t* interface) +{ + struct nl_cache *neigh_cache = NULL; + struct nl_object *nl_neigh_object = NULL; + struct nl_addr *nl_dst_addr = NULL; + struct nl_addr *ll_addr = NULL; + struct rtnl_neigh *neigh = NULL; + + int error = 0; + int if_index = 0; + int addr_family = 0; + int neigh_state = 0; + int neigh_count = 0; + char *dst_addr = NULL; + char *ll_addr_s = NULL; + char dst_addr_str[ADDR_STR_BUF_SIZE] = { 0 }; + char ll_addr_str[ADDR_STR_BUF_SIZE] = { 0 }; + + INTERFACES_INTERFACE_LIST_NEW(interface->ipv4.neighbor); + INTERFACES_INTERFACE_LIST_NEW(interface->ipv6.neighbor); + + if_index = rtnl_link_get_ifindex(link); + + SRPC_SAFE_CALL(rtnl_neigh_alloc_cache(socket, &neigh_cache), error_out); + + neigh_count = nl_cache_nitems(neigh_cache); + + nl_neigh_object = nl_cache_get_first(neigh_cache); + + for (int i = 0; i < neigh_count; ++i) { + nl_dst_addr = rtnl_neigh_get_dst((struct rtnl_neigh *) nl_neigh_object); + + SRPC_SAFE_CALL_PTR(dst_addr, nl_addr2str(nl_dst_addr, dst_addr_str, sizeof(dst_addr_str)), error_out); + + neigh = rtnl_neigh_get(neigh_cache, if_index, nl_dst_addr); + + if (neigh != NULL) { + // get neigh state + neigh_state = rtnl_neigh_get_state(neigh); + + // skip neighs with no arp state + if (NUD_NOARP == neigh_state) { + nl_neigh_object = nl_cache_get_next(nl_neigh_object); + continue; + } + + int cur_neigh_index = rtnl_neigh_get_ifindex(neigh); + + if (if_index != cur_neigh_index) { + nl_neigh_object = nl_cache_get_next(nl_neigh_object); + continue; + } + + ll_addr = rtnl_neigh_get_lladdr(neigh); + + SRPC_SAFE_CALL_PTR(ll_addr_s, nl_addr2str(ll_addr, ll_addr_str, sizeof(ll_addr_str)), error_out); + + // check if ipv4 or ipv6 + addr_family = rtnl_neigh_get_family(neigh); + + // switch based on address family, add to the neighbor linked list + SRPC_SAFE_CALL(interfaces_add_neighbor(interface, dst_addr, ll_addr_s, addr_family), error_out); + + rtnl_neigh_put(neigh); + } + + nl_neigh_object = nl_cache_get_next(nl_neigh_object); + } + + + goto out; + +error_out: +out: + if (neigh_cache) { + nl_cache_free(neigh_cache); + } + if (neigh) { + rtnl_neigh_put(neigh); + } + + return interfaces_load_success; +} + static char* interfaces_get_interface_name(struct rtnl_link* link) { char* name = NULL; - name = rtnl_link_get_name(link); - if (name == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "rtnl_link_get_name error"); - } + SRPC_SAFE_CALL_PTR(name, rtnl_link_get_name(link), error_out); +error_out: return xstrdup(name); } @@ -194,9 +468,8 @@ static int interfaces_get_interface_vlan_id(struct rtnl_link* link, interfaces_i static int interfaces_parse_link(interfaces_ctx_t* ctx, struct nl_sock* socket, struct nl_cache* cache, struct rtnl_link* link, interfaces_interface_t* interface) { int error = interfaces_load_success; - *interface = (interfaces_interface_t) { 0 }; - // required + // required, fail if NULL SRPC_SAFE_CALL_PTR(interface->name, interfaces_get_interface_name(link), error_out); interfaces_get_interface_description(ctx, interface->name); @@ -213,6 +486,10 @@ static int interfaces_parse_link(interfaces_ctx_t* ctx, struct nl_sock* socket, interface->enabled = interfaces_get_interface_enabled(link); + interfaces_get_neighbors(socket, link, interface); + + interfaces_get_ips(socket, link, interface); + goto out; error_out: error = interfaces_load_failure; @@ -245,6 +522,10 @@ static int interfaces_add_link(interfaces_interface_hash_element_t** if_hash, in interfaces_interface_hash_element_set_enabled(&new_if_hash_elem, interface->enabled); + interfaces_interface_hash_element_set_ipv4(&new_if_hash_elem, interface->ipv4); + + interfaces_interface_hash_element_set_ipv6(&new_if_hash_elem, interface->ipv6); + goto out; error_out: out: @@ -260,6 +541,18 @@ static int interfaces_add_link(interfaces_interface_hash_element_t** if_hash, in if (interface->parent_interface != NULL) { FREE_SAFE(interface->parent_interface); } + if (interface->ipv4.neighbor != NULL) { + INTERFACES_INTERFACE_LIST_FREE(interface->ipv4.neighbor); + } + if (interface->ipv4.address != NULL) { + INTERFACES_INTERFACE_LIST_FREE(interface->ipv4.address); + } + if (interface->ipv6.neighbor != NULL) { + INTERFACES_INTERFACE_LIST_FREE(interface->ipv6.neighbor); + } + if (interface->ipv6.address != NULL) { + INTERFACES_INTERFACE_LIST_FREE(interface->ipv6.address); + } return error; } From 76d1a6fff2f8a30c44abf8e91498635365788df7 Mon Sep 17 00:00:00 2001 From: andrej Date: Tue, 11 Oct 2022 11:34:31 +0200 Subject: [PATCH 178/247] interfaces-plugin: add max ip string length constant --- src/interfaces/src/plugin/common.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/interfaces/src/plugin/common.h b/src/interfaces/src/plugin/common.h index e80ca480..cf58aa40 100644 --- a/src/interfaces/src/plugin/common.h +++ b/src/interfaces/src/plugin/common.h @@ -156,4 +156,6 @@ #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) +#define ADDR_STR_BUF_SIZE 45 // max ip string length (15 for ipv4 and 45 for ipv6) + #endif // INTERFACES_PLUGIN_COMMON_H From 1af9c91969920d54b7236a0000e38e16662775c0 Mon Sep 17 00:00:00 2001 From: andrej Date: Tue, 11 Oct 2022 11:35:11 +0200 Subject: [PATCH 179/247] interfaces-plugin: add ipv4 set subnet based on subnet type --- .../data/interfaces/interface/ipv4/address.c | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c index 210dd74b..3b39d211 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c @@ -1,9 +1,11 @@ #include "address.h" #include "plugin/types.h" +#include "srpc/common.h" #include "src/utlist.h" #include #include #include +#include interfaces_interface_ipv4_address_element_t* interfaces_interface_ipv4_address_new(void) { @@ -75,6 +77,56 @@ int interfaces_interface_ipv4_address_element_set_ip(interfaces_interface_ipv4_a return 0; } +int interfaces_interface_netmask_to_prefix_length(const char *netmask) +{ + int error = 0; + + struct sockaddr_in sa = { 0 }; + struct sockaddr_in6 sa6 = { 0 }; + + // IPv6 if a ':' is found + if (strchr(netmask, ':')) { + SRPC_SAFE_CALL(inet_pton(AF_INET6, netmask, &(sa6.sin6_addr)), error_out); + + // s6_addr is a uint8_t array of length 16, all the byte popcounts need to be summarized + // avoid branching, use popcountll's 64 bits minimum + uint64_t *s6_addr64 = (uint64_t *) sa6.sin6_addr.s6_addr; + + return __builtin_popcountll(s6_addr64[0]) + __builtin_popcountll(s6_addr64[1]); + + } + + // IPv4 otherwise + SRPC_SAFE_CALL(inet_pton(AF_INET, netmask, &(sa.sin_addr)), error_out); + + return __builtin_popcountl(sa.sin_addr.s_addr); + +error_out: + return -1; +} + +int interfaces_interface_ipv4_address_element_set_subnet(interfaces_interface_ipv4_address_element_t** el, char *netmask, enum interfaces_interface_ipv4_address_subnet subtype) +{ + int error = 0; + int prefix_length = 0; + + switch (subtype) { + case interfaces_interface_ipv4_address_subnet_netmask: + interfaces_interface_ipv4_address_element_set_netmask(el, netmask); + break; + case interfaces_interface_ipv4_address_subnet_prefix_length: + prefix_length = interfaces_interface_netmask_to_prefix_length(netmask); + interfaces_interface_ipv4_address_element_set_prefix_length(el, prefix_length); + break; + case interfaces_interface_ipv4_address_subnet_none: + break; + default: + error = -1; + } + + return error; +} + int interfaces_interface_ipv4_address_element_set_prefix_length(interfaces_interface_ipv4_address_element_t** el, uint8_t prefix_length) { (*el)->address.subnet.prefix_length = prefix_length; From 7610ffb990e8c83b9ea8934e331bdb45bc4febcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 11 Oct 2022 12:02:43 +0200 Subject: [PATCH 180/247] interfaces-plugin: remove unused variables for sysrepo session and connection --- .../interfaces/interface/ipv4/neighbor/change.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c index 43f118bf..cc1386f3 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c @@ -28,10 +28,14 @@ int interfaces_interface_ipv4_neighbor_change_link_layer_address(void* priv, sr_ switch (change_ctx->operation) { case SR_OP_CREATED: + // not used - used only in IP change callback break; case SR_OP_MODIFIED: + // change lladdr + break; case SR_OP_DELETED: + // not used - used only in IP change callback break; case SR_OP_MOVED: break; @@ -55,10 +59,6 @@ int interfaces_interface_ipv4_neighbor_change_ip(void* priv, sr_session_ctx_t* s int error = 0; void* error_ptr = NULL; - // sysrepo - sr_conn_ctx_t* conn_ctx = NULL; - sr_session_ctx_t* running_session = NULL; - // strings and buffers const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); @@ -90,12 +90,6 @@ int interfaces_interface_ipv4_neighbor_change_ip(void* priv, sr_session_ctx_t* s // get link SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->nl_ctx.link_cache, interface_name_buffer), error_out); - // get connection - SRPC_SAFE_CALL_PTR(conn_ctx, sr_session_get_connection(session), error_out); - - // start a running DS session - fetching data about prefix when deleting the address - SRPC_SAFE_CALL_ERR(error, sr_session_start(conn_ctx, SR_DS_RUNNING, &running_session), error_out); - switch (change_ctx->operation) { case SR_OP_CREATED: // new neighbor @@ -158,9 +152,6 @@ int interfaces_interface_ipv4_neighbor_change_ip(void* priv, sr_session_ctx_t* s error = -1; out: - if (running_session) { - sr_session_stop(running_session); - } // re-initialize mod_ctx data if (mod_ctx->mod_data.ipv4.neighbor.link_layer_address) { From b412a8517ab4b3de255a6cd2df0b77513eb7b2fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 11 Oct 2022 12:18:54 +0200 Subject: [PATCH 181/247] interfaces-plugin: implement modify functionality for IPv4 neighbor link-layer-address leaf --- .../interface/ipv4/neighbor/change.c | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c index cc1386f3..4da4be09 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c @@ -4,6 +4,7 @@ #include "plugin/context.h" #include +#include #include #include @@ -21,17 +22,64 @@ int interfaces_interface_ipv4_neighbor_change_link_layer_address_init(void* priv int interfaces_interface_ipv4_neighbor_change_link_layer_address(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) { int error = 0; + void* error_ptr = NULL; + + // strings and buffers const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); + char path_buffer[PATH_MAX] = { 0 }; + char interface_name_buffer[100] = { 0 }; + char ip_buffer[100] = { 0 }; + + // app context + interfaces_ctx_t* ctx = priv; + + // mod changes context + interfaces_mod_changes_ctx_t* mod_ctx = &ctx->mod_ctx; + + // libnl + struct rtnl_neigh* request_neigh = NULL; + struct rtnl_link* current_link = NULL; + struct nl_addr* dst_addr = NULL; + struct nl_addr* ll_addr = NULL; SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + // get node path + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(change_ctx->node, LYD_PATH_STD, path_buffer, sizeof(path_buffer)), error_out); + + // get interface name + SRPC_SAFE_CALL_ERR(error, srpc_extract_xpath_key_value(path_buffer, "interface", "name", interface_name_buffer, sizeof(interface_name_buffer)), error_out); + + // get IP + SRPC_SAFE_CALL_ERR(error, srpc_extract_xpath_key_value(path_buffer, "neighbor", "ip", ip_buffer, sizeof(ip_buffer)), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "Node Path: %s; Interface Name: %s; Neighbor IP: %s", path_buffer, interface_name_buffer, ip_buffer); + + // get link + SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->nl_ctx.link_cache, interface_name_buffer), error_out); + switch (change_ctx->operation) { case SR_OP_CREATED: // not used - used only in IP change callback break; case SR_OP_MODIFIED: // change lladdr + request_neigh = rtnl_neigh_alloc(); + + // set interface + rtnl_neigh_set_ifindex(request_neigh, rtnl_link_get_ifindex(current_link)); + + // parse destination and LL address + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(ip_buffer, AF_INET, &dst_addr), error_out); + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(node_value, AF_LLC, &ll_addr), error_out); + + // set destination and LL address + SRPC_SAFE_CALL_ERR(error, rtnl_neigh_set_dst(request_neigh, dst_addr), error_out); + rtnl_neigh_set_lladdr(request_neigh, ll_addr); + + // change neighbor + SRPC_SAFE_CALL_ERR(error, rtnl_neigh_add(mod_ctx->nl_ctx.socket, request_neigh, NLM_F_REPLACE), error_out); break; case SR_OP_DELETED: @@ -41,6 +89,13 @@ int interfaces_interface_ipv4_neighbor_change_link_layer_address(void* priv, sr_ break; } + goto out; + +error_out: + error = -1; + +out: + return error; } From 08742f1671f62a2c8a40574c3a023893d7daa8b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 11 Oct 2022 12:19:22 +0200 Subject: [PATCH 182/247] interfaces-plugin: free allocated neighbor libnl data --- .../src/plugin/api/interfaces/interface/ipv4/neighbor/change.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c index 4da4be09..068d7bd0 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c @@ -95,6 +95,9 @@ int interfaces_interface_ipv4_neighbor_change_link_layer_address(void* priv, sr_ error = -1; out: + if (request_neigh) { + rtnl_neigh_put(request_neigh); + } return error; } From 638a0cb2212b4c65a548e1292ce6b9fbf47391f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 11 Oct 2022 12:20:03 +0200 Subject: [PATCH 183/247] interfaces-plugin: free allocated neighbor libnl data in neighbor IP change callback --- .../plugin/api/interfaces/interface/ipv4/neighbor/change.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c index 068d7bd0..c4269282 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c @@ -218,6 +218,10 @@ int interfaces_interface_ipv4_neighbor_change_ip(void* priv, sr_session_ctx_t* s mod_ctx->mod_data.ipv4.neighbor.link_layer_address = NULL; mod_ctx->mod_data.ipv4.neighbor.link_layer_set = false; + if (request_neigh) { + rtnl_neigh_put(request_neigh); + } + return error; } From f8f3c9c23448476faf211ae9f721ccbc3cd8a896 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 11 Oct 2022 12:24:09 +0200 Subject: [PATCH 184/247] interfaces-plugin: free allocated address libnl data in address IP change callback --- .../src/plugin/api/interfaces/interface/ipv4/address/change.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c index 6d570337..74630fea 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c @@ -403,6 +403,10 @@ int interfaces_interface_ipv4_address_change_ip(void* priv, sr_session_ctx_t* se sr_session_stop(running_session); } + if (request_addr) { + rtnl_addr_put(request_addr); + } + // re-initialize mod_ctx data mod_ctx->mod_data.ipv4.address.prefix_length = 0; mod_ctx->mod_data.ipv4.address.prefix_set = false; From e551a8ae18156a7f6c366fc71498b852587a5ff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 11 Oct 2022 12:25:08 +0200 Subject: [PATCH 185/247] interfaces-plugin: free allocated request address libnl data in prefix-length and netmask change callbacks --- .../plugin/api/interfaces/interface/ipv4/address/change.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c index 74630fea..ac5b169c 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c @@ -125,6 +125,10 @@ int interfaces_interface_ipv4_address_change_netmask(void* priv, sr_session_ctx_ error = -1; out: + if (request_addr) { + rtnl_addr_put(request_addr); + } + return error; } @@ -231,6 +235,10 @@ int interfaces_interface_ipv4_address_change_prefix_length(void* priv, sr_sessio error = -1; out: + if (request_addr) { + rtnl_addr_put(request_addr); + } + return error; } From f23c9520fb2009640a26d5bf7d7d5eec50c4ca15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Tue, 11 Oct 2022 12:30:41 +0200 Subject: [PATCH 186/247] interfaces-plugin: free all allocated address libnl data in prefix-length and netmask callbacks --- .../interface/ipv4/address/change.c | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c index ac5b169c..9db2ad73 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/change.c @@ -129,6 +129,18 @@ int interfaces_interface_ipv4_address_change_netmask(void* priv, sr_session_ctx_ rtnl_addr_put(request_addr); } + if (delete_addr) { + rtnl_addr_put(delete_addr); + } + + if (old_local_addr) { + nl_addr_put(old_local_addr); + } + + if (local_addr) { + nl_addr_put(local_addr); + } + return error; } @@ -239,6 +251,18 @@ int interfaces_interface_ipv4_address_change_prefix_length(void* priv, sr_sessio rtnl_addr_put(request_addr); } + if (delete_addr) { + rtnl_addr_put(delete_addr); + } + + if (old_local_addr) { + nl_addr_put(old_local_addr); + } + + if (local_addr) { + nl_addr_put(local_addr); + } + return error; } From 0303f27a247cc61e77b5ab87217601d66c7c5816 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Wed, 12 Oct 2022 20:20:52 +0200 Subject: [PATCH 187/247] interfaces-plugin: iterate IPv6 address changes --- .../api/interfaces/interface/ipv6/address/change.c | 4 ++-- .../api/interfaces/interface/ipv6/address/change.h | 1 + src/interfaces/src/plugin/subscription/change.c | 12 +++++++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.c index c7ccab0d..5d7f77fa 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.c @@ -28,7 +28,7 @@ int interfaces_interface_ipv6_address_change_prefix_length(void* priv, sr_sessio break; } - return error; + return -1; } void interfaces_interface_ipv6_address_change_prefix_length_free(void* priv) @@ -60,7 +60,7 @@ int interfaces_interface_ipv6_address_change_ip(void* priv, sr_session_ctx_t* se break; } - return error; + return -1; } void interfaces_interface_ipv6_address_change_ip_free(void* priv) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.h b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.h index e90bac00..884a1701 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.h +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.h @@ -7,6 +7,7 @@ int interfaces_interface_ipv6_address_change_prefix_length_init(void* priv); int interfaces_interface_ipv6_address_change_prefix_length(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); void interfaces_interface_ipv6_address_change_prefix_length_free(void* priv); + int interfaces_interface_ipv6_address_change_ip_init(void* priv); int interfaces_interface_ipv6_address_change_ip(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); void interfaces_interface_ipv6_address_change_ip_free(void* priv); diff --git a/src/interfaces/src/plugin/subscription/change.c b/src/interfaces/src/plugin/subscription/change.c index 56674380..3368a4f0 100644 --- a/src/interfaces/src/plugin/subscription/change.c +++ b/src/interfaces/src/plugin/subscription/change.c @@ -1,5 +1,4 @@ #include "change.h" -#include "plugin/api/interfaces/interface/ipv4/neighbor/change.h" #include "plugin/common.h" #include "plugin/context.h" @@ -13,6 +12,9 @@ #include "plugin/api/interfaces/interface/change.h" #include "plugin/api/interfaces/interface/ipv4/address/change.h" #include "plugin/api/interfaces/interface/ipv4/change.h" +#include "plugin/api/interfaces/interface/ipv4/neighbor/change.h" +#include "plugin/api/interfaces/interface/ipv6/address/change.h" +#include "plugin/api/interfaces/interface/ipv6/neighbor/change.h" int interfaces_subscription_change_interfaces_interface(sr_session_ctx_t* session, uint32_t subscription_id, const char* module_name, const char* xpath, sr_event_t event, uint32_t request_id, void* private_data) { @@ -75,6 +77,14 @@ int interfaces_subscription_change_interfaces_interface(sr_session_ctx_t* sessio // ipv4/neighbor/link-layer-address SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/ipv4/neighbor/link-layer-address", xpath), error_out); SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_ipv4_neighbor_change_link_layer_address, interfaces_change_interface_init, interfaces_change_interface_free), error_out); + + // ipv6/address/ip + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/ipv6/address/ip", xpath), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_ipv6_address_change_ip, interfaces_change_interface_init, interfaces_change_interface_free), error_out); + + // ipv6/address/prefix-length + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/ipv6/address/prefix-length", xpath), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_ipv6_address_change_prefix_length, interfaces_change_interface_init, interfaces_change_interface_free), error_out); } goto out; From 85803d46e1cb51424baa54b40c2df89aa3fd319c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Wed, 12 Oct 2022 20:34:38 +0200 Subject: [PATCH 188/247] interfaces-plugin: implement IPv6 IP address change callback --- .../interface/ipv6/address/change.c | 155 +++++++++++++++++- src/interfaces/src/plugin/context.h | 10 ++ 2 files changed, 164 insertions(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.c index 5d7f77fa..9911c213 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.c @@ -1,8 +1,15 @@ #include "change.h" #include "plugin/common.h" +#include "plugin/context.h" +#include #include +#include +#include + +static int interfaces_interface_ipv6_address_get_prefix_length(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); + int interfaces_interface_ipv6_address_change_prefix_length_init(void* priv) { int error = 0; @@ -44,25 +51,171 @@ int interfaces_interface_ipv6_address_change_ip_init(void* priv) int interfaces_interface_ipv6_address_change_ip(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) { int error = 0; + void* error_ptr = NULL; + + // sysrepo + sr_val_t* prefix_val = NULL; + sr_conn_ctx_t* conn_ctx = NULL; + sr_session_ctx_t* running_session = NULL; + + // strings and buffers const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); + char path_buffer[PATH_MAX] = { 0 }; + char interface_name_buffer[100] = { 0 }; + char address_buffer[100] = { 0 }; + + // app context + interfaces_ctx_t* ctx = priv; + + // mod changes context + interfaces_mod_changes_ctx_t* mod_ctx = &ctx->mod_ctx; + + // libnl + struct rtnl_addr* request_addr = NULL; + struct rtnl_link* current_link = NULL; + struct nl_addr* local_addr = NULL; + + // data + uint8_t prefix_length = 0; SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + // get node path + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(change_ctx->node, LYD_PATH_STD, path_buffer, sizeof(path_buffer)), error_out); + + // get interface name + SRPC_SAFE_CALL_ERR(error, srpc_extract_xpath_key_value(path_buffer, "interface", "name", interface_name_buffer, sizeof(interface_name_buffer)), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "Node Path: %s; Interface Name: %s", path_buffer, interface_name_buffer); + + // get link + SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->nl_ctx.link_cache, interface_name_buffer), error_out); + + // get connection + SRPC_SAFE_CALL_PTR(conn_ctx, sr_session_get_connection(session), error_out); + + // start a running DS session - fetching data about prefix when deleting the address + SRPC_SAFE_CALL_ERR(error, sr_session_start(conn_ctx, SR_DS_RUNNING, &running_session), error_out); + switch (change_ctx->operation) { case SR_OP_CREATED: + // new address + request_addr = rtnl_addr_alloc(); + + // parse local address + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(node_value, AF_INET6, &local_addr), error_out); + + // get prefix length by using prefix-length or netmask leafs + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(path_buffer, sizeof(path_buffer), "%s[name=\"%s\"]/ietf-ip:ipv6/address[ip=\"%s\"]/prefix-length", INTERFACES_INTERFACES_LIST_YANG_PATH, interface_name_buffer, node_value), error_out); + SRPC_SAFE_CALL_ERR(error, srpc_iterate_changes(ctx, session, path_buffer, interfaces_interface_ipv6_address_get_prefix_length, NULL, NULL), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "Recieved prefix-length of %d for address %s", mod_ctx->mod_data.ipv6.address.prefix_length, node_value); + + // prefix was set and found + + // set final prefix length + nl_addr_set_prefixlen(local_addr, mod_ctx->mod_data.ipv6.address.prefix_length); + + // set to route address + SRPC_SAFE_CALL_ERR(error, rtnl_addr_set_local(request_addr, local_addr), error_out); + + // set interface + rtnl_addr_set_ifindex(request_addr, rtnl_link_get_ifindex(current_link)); + + // add address + SRPC_SAFE_CALL_ERR(error, rtnl_addr_add(mod_ctx->nl_ctx.socket, request_addr, 0), error_out); + break; case SR_OP_MODIFIED: + // should be impossible - address IP can only be created and deleted + SRPLG_LOG_ERR(PLUGIN_NAME, "Unsuported operation MODIFY for interface IPv4 address IP leaf"); + goto error_out; break; case SR_OP_DELETED: + // fetch info about prefix-length/netmask and use the pair address/prefix to delete address + // prefix is needed to find the appropriate address + request_addr = rtnl_addr_alloc(); + + // check for prefix-length + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(path_buffer, sizeof(path_buffer), INTERFACES_INTERFACES_INTERFACE_YANG_PATH "[name=\"%s\"]/ietf-ip:ipv6/address[ip=\"%s\"]/prefix-length", interface_name_buffer, node_value), error_out); + SRPLG_LOG_INF(PLUGIN_NAME, "Searching running DS for %s", path_buffer); + SRPC_SAFE_CALL_ERR(error, sr_get_item(running_session, path_buffer, 0, &prefix_val), error_out); + + // set data + prefix_length = prefix_val->data.uint8_val; + + SRPLG_LOG_INF(PLUGIN_NAME, "Recieved prefix for address %s: %d", node_value, prefix_length); + + // after getting the prefix length - remove address + + // get full address + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(address_buffer, sizeof(address_buffer), "%s/%d", node_value, prefix_length), error_out); + + // parse local address + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(address_buffer, AF_INET6, &local_addr), error_out); + + // set to route address + SRPC_SAFE_CALL_ERR(error, rtnl_addr_set_local(request_addr, local_addr), error_out); + + // set interface + rtnl_addr_set_ifindex(request_addr, rtnl_link_get_ifindex(current_link)); + + // remove wanted address + SRPC_SAFE_CALL_ERR(error, rtnl_addr_delete(mod_ctx->nl_ctx.socket, request_addr, 0), error_out); + break; case SR_OP_MOVED: break; } - return -1; + goto out; + +error_out: + if (error < 0) { + SRPLG_LOG_INF(PLUGIN_NAME, "nl_geterror(): %s", nl_geterror(error)); + } + error = -1; + +out: + if (running_session) { + sr_session_stop(running_session); + } + + if (request_addr) { + rtnl_addr_put(request_addr); + } + + // re-initialize mod_ctx data + mod_ctx->mod_data.ipv6.address.prefix_length = 0; + mod_ctx->mod_data.ipv6.address.prefix_set = false; + + return error; } void interfaces_interface_ipv6_address_change_ip_free(void* priv) { } + +static int interfaces_interface_ipv6_address_get_prefix_length(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + + // ctx + interfaces_ctx_t* ctx = priv; + interfaces_mod_changes_ctx_t* mod_ctx = &ctx->mod_ctx; + + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + // this callback should only be called on CREATED operation + assert(change_ctx->operation == SR_OP_CREATED); + + // parse prefix length + mod_ctx->mod_data.ipv6.address.prefix_length = (uint8_t)atoi(node_value); + mod_ctx->mod_data.ipv6.address.prefix_set = true; + + return error; +} \ No newline at end of file diff --git a/src/interfaces/src/plugin/context.h b/src/interfaces/src/plugin/context.h index e7b48b0f..f34160c0 100644 --- a/src/interfaces/src/plugin/context.h +++ b/src/interfaces/src/plugin/context.h @@ -48,6 +48,16 @@ struct interfaces_mod_changes_ctx_s { uint8_t link_layer_set; ///< link_layer_address has been set } neighbor; } ipv4; + struct { + struct { + uint8_t prefix_length; + uint8_t prefix_set; ///< prefix_length has been set + } address; + struct { + char* link_layer_address; + uint8_t link_layer_set; ///< link_layer_address has been set + } neighbor; + } ipv6; } mod_data; }; From b9d7b84ee0329b12e16b45c22a08c419ae20c0cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Wed, 12 Oct 2022 20:37:38 +0200 Subject: [PATCH 189/247] interfaces-plugin: implement IPv6 address prefix-length change callback --- .../interface/ipv6/address/change.c | 92 ++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.c index 9911c213..46ef9a5f 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.c @@ -19,23 +19,113 @@ int interfaces_interface_ipv6_address_change_prefix_length_init(void* priv) int interfaces_interface_ipv6_address_change_prefix_length(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) { int error = 0; + void* error_ptr = NULL; + + // strings and buffers const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); + char path_buffer[PATH_MAX] = { 0 }; + char interface_name_buffer[100] = { 0 }; + char ip_buffer[100] = { 0 }; + char address_buffer[100] = { 0 }; + char old_address_buffer[100] = { 0 }; + + // app context + interfaces_ctx_t* ctx = priv; + + // mod changes context + interfaces_mod_changes_ctx_t* mod_ctx = &ctx->mod_ctx; + + // libnl + struct rtnl_addr* request_addr = NULL; + struct rtnl_addr* delete_addr = NULL; + struct rtnl_link* current_link = NULL; + struct nl_addr* local_addr = NULL; + struct nl_addr* old_local_addr = NULL; SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + // get node path + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(change_ctx->node, LYD_PATH_STD, path_buffer, sizeof(path_buffer)), error_out); + + // get interface name + SRPC_SAFE_CALL_ERR(error, srpc_extract_xpath_key_value(path_buffer, "interface", "name", interface_name_buffer, sizeof(interface_name_buffer)), error_out); + + // get IP + SRPC_SAFE_CALL_ERR(error, srpc_extract_xpath_key_value(path_buffer, "address", "ip", ip_buffer, sizeof(ip_buffer)), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "Node Path: %s; Interface Name: %s; Address IP: %s", path_buffer, interface_name_buffer, ip_buffer); + + // get link + SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->nl_ctx.link_cache, interface_name_buffer), error_out); + switch (change_ctx->operation) { case SR_OP_CREATED: + // this change case should be handled only when creating the whole address in the IP callback + // no need to process created change break; case SR_OP_MODIFIED: + // change prefix length + request_addr = rtnl_addr_alloc(); + delete_addr = rtnl_addr_alloc(); + + // get full address + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(address_buffer, sizeof(address_buffer), "%s/%s", ip_buffer, node_value), error_out); + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(old_address_buffer, sizeof(old_address_buffer), "%s/%s", ip_buffer, change_ctx->previous_value), error_out); + + // parse local address + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(address_buffer, AF_INET6, &local_addr), error_out); + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(old_address_buffer, AF_INET6, &old_local_addr), error_out); + + // set to route address + SRPC_SAFE_CALL_ERR(error, rtnl_addr_set_local(request_addr, local_addr), error_out); + SRPC_SAFE_CALL_ERR(error, rtnl_addr_set_local(delete_addr, old_local_addr), error_out); + + // set interface + rtnl_addr_set_ifindex(request_addr, rtnl_link_get_ifindex(current_link)); + rtnl_addr_set_ifindex(delete_addr, rtnl_link_get_ifindex(current_link)); + + // delete old address + SRPC_SAFE_CALL_ERR(error, rtnl_addr_delete(mod_ctx->nl_ctx.socket, delete_addr, 0), error_out); + + // add new address + SRPC_SAFE_CALL_ERR(error, rtnl_addr_add(mod_ctx->nl_ctx.socket, request_addr, 0), error_out); + break; case SR_OP_DELETED: + // prefix is needed to find the appropriate address + // should be processed when IP deleted break; case SR_OP_MOVED: break; } - return -1; + goto out; + +error_out: + if (error < 0) { + SRPLG_LOG_INF(PLUGIN_NAME, "nl_geterror(): %s", nl_geterror(error)); + } + error = -1; + +out: + if (request_addr) { + rtnl_addr_put(request_addr); + } + + if (delete_addr) { + rtnl_addr_put(delete_addr); + } + + if (old_local_addr) { + nl_addr_put(old_local_addr); + } + + if (local_addr) { + nl_addr_put(local_addr); + } + + return error; } void interfaces_interface_ipv6_address_change_prefix_length_free(void* priv) From eb0fccead0e671ddcebfe3834ce57901d6f1b27f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Wed, 12 Oct 2022 20:50:13 +0200 Subject: [PATCH 190/247] interfaces-plugin: fix formatting --- .../src/plugin/api/interfaces/interface/ipv6/change.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/change.h b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/change.h index dc9d2584..a594cb14 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/change.h +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/change.h @@ -7,18 +7,23 @@ int interfaces_interface_ipv6_change_dup_addr_detect_transmits_init(void* priv); int interfaces_interface_ipv6_change_dup_addr_detect_transmits(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); void interfaces_interface_ipv6_change_dup_addr_detect_transmits_free(void* priv); + int interfaces_interface_ipv6_change_neighbor_init(void* priv); int interfaces_interface_ipv6_change_neighbor(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); void interfaces_interface_ipv6_change_neighbor_free(void* priv); + int interfaces_interface_ipv6_change_address_init(void* priv); int interfaces_interface_ipv6_change_address(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); void interfaces_interface_ipv6_change_address_free(void* priv); + int interfaces_interface_ipv6_change_mtu_init(void* priv); int interfaces_interface_ipv6_change_mtu(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); void interfaces_interface_ipv6_change_mtu_free(void* priv); + int interfaces_interface_ipv6_change_forwarding_init(void* priv); int interfaces_interface_ipv6_change_forwarding(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); void interfaces_interface_ipv6_change_forwarding_free(void* priv); + int interfaces_interface_ipv6_change_enabled_init(void* priv); int interfaces_interface_ipv6_change_enabled(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); void interfaces_interface_ipv6_change_enabled_free(void* priv); From 510af20e2635a6871d1b5d1b87215d25399df1d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Wed, 12 Oct 2022 20:54:02 +0200 Subject: [PATCH 191/247] interfaces-plugin: implement IPv6 neighbor IP change callback --- .../interface/ipv6/neighbor/change.c | 133 ++++++++++++++++++ .../interface/ipv6/neighbor/change.h | 1 + 2 files changed, 134 insertions(+) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/change.c index d43d4dec..80ff8fce 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/change.c @@ -1,8 +1,16 @@ #include "change.h" #include "plugin/common.h" +#include "plugin/context.h" +#include #include +#include +#include +#include + +static int interfaces_interface_ipv6_neighbor_get_link_layer_address(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); + int interfaces_interface_ipv6_neighbor_change_link_layer_address_init(void* priv) { int error = 0; @@ -44,25 +52,150 @@ int interfaces_interface_ipv6_neighbor_change_ip_init(void* priv) int interfaces_interface_ipv6_neighbor_change_ip(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) { int error = 0; + void* error_ptr = NULL; + + // strings and buffers const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); + char path_buffer[PATH_MAX] = { 0 }; + char interface_name_buffer[100] = { 0 }; + + // app context + interfaces_ctx_t* ctx = priv; + + // mod changes context + interfaces_mod_changes_ctx_t* mod_ctx = &ctx->mod_ctx; + + // libnl + struct rtnl_neigh* request_neigh = NULL; + struct rtnl_link* current_link = NULL; + struct nl_addr* dst_addr = NULL; + struct nl_addr* ll_addr = NULL; SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + // get node path + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(change_ctx->node, LYD_PATH_STD, path_buffer, sizeof(path_buffer)), error_out); + + // get interface name + SRPC_SAFE_CALL_ERR(error, srpc_extract_xpath_key_value(path_buffer, "interface", "name", interface_name_buffer, sizeof(interface_name_buffer)), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "Node Path: %s; Interface Name: %s", path_buffer, interface_name_buffer); + + // get link + SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->nl_ctx.link_cache, interface_name_buffer), error_out); + switch (change_ctx->operation) { case SR_OP_CREATED: + // new neighbor + request_neigh = rtnl_neigh_alloc(); + + // parse destination address + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(node_value, AF_INET6, &dst_addr), error_out); + + // get prefix length by using prefix-length or netmask leafs + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(path_buffer, sizeof(path_buffer), INTERFACES_INTERFACES_INTERFACE_YANG_PATH "[name=\"%s\"]/ietf-ip:ipv6/neighbor[ip=\"%s\"]/link-layer-address", interface_name_buffer, node_value), error_out); + SRPC_SAFE_CALL_ERR(error, srpc_iterate_changes(ctx, session, path_buffer, interfaces_interface_ipv6_neighbor_get_link_layer_address, NULL, NULL), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "Recieved link-layer-address %s for neighbor address %s", mod_ctx->mod_data.ipv6.neighbor.link_layer_address, node_value); + + // parse link-layer address + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(mod_ctx->mod_data.ipv6.neighbor.link_layer_address, AF_LLC, &ll_addr), error_out); + + // set addresses to the new neighbor + SRPC_SAFE_CALL_ERR(error, rtnl_neigh_set_dst(request_neigh, dst_addr), error_out); + rtnl_neigh_set_lladdr(request_neigh, ll_addr); + + // set interface + rtnl_neigh_set_ifindex(request_neigh, rtnl_link_get_ifindex(current_link)); + + // add neighbor + SRPC_SAFE_CALL_ERR(error, rtnl_neigh_add(mod_ctx->nl_ctx.socket, request_neigh, NLM_F_CREATE), error_out); + break; case SR_OP_MODIFIED: + // should be impossible - address IP can only be created and deleted + SRPLG_LOG_ERR(PLUGIN_NAME, "Unsuported operation MODIFY for interface IPv6 neighbor IP leaf"); + goto error_out; break; case SR_OP_DELETED: + request_neigh = rtnl_neigh_alloc(); + + // set interface + rtnl_neigh_set_ifindex(request_neigh, rtnl_link_get_ifindex(current_link)); + + // parse destination + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(node_value, AF_INET6, &dst_addr), error_out); + + // set destination + SRPC_SAFE_CALL_ERR(error, rtnl_neigh_set_dst(request_neigh, dst_addr), error_out); + + // remove wanted neighbor + SRPC_SAFE_CALL_ERR(error, rtnl_neigh_delete(mod_ctx->nl_ctx.socket, request_neigh, 0), error_out); + break; case SR_OP_MOVED: break; } + goto out; + +error_out: + if (error < 0) { + SRPLG_LOG_INF(PLUGIN_NAME, "nl_geterror(): %s", nl_geterror(error)); + } + error = -1; + +out: + + // re-initialize mod_ctx data + if (mod_ctx->mod_data.ipv6.neighbor.link_layer_address) { + free(mod_ctx->mod_data.ipv6.neighbor.link_layer_address); + } + mod_ctx->mod_data.ipv6.neighbor.link_layer_address = NULL; + mod_ctx->mod_data.ipv6.neighbor.link_layer_set = false; + + if (request_neigh) { + rtnl_neigh_put(request_neigh); + } + return error; } void interfaces_interface_ipv6_neighbor_change_ip_free(void* priv) { } + +static int interfaces_interface_ipv6_neighbor_get_link_layer_address(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +{ + int error = 0; + + // ctx + interfaces_ctx_t* ctx = priv; + interfaces_mod_changes_ctx_t* mod_ctx = &ctx->mod_ctx; + + const char* node_name = LYD_NAME(change_ctx->node); + const char* node_value = lyd_get_value(change_ctx->node); + + SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + + // this callback should only be called on CREATED operation + assert(change_ctx->operation == SR_OP_CREATED); + + // set mod changes prefix length + mod_ctx->mod_data.ipv6.neighbor.link_layer_address = strdup(node_value); + if (!mod_ctx->mod_data.ipv6.neighbor.link_layer_address) { + SRPLG_LOG_ERR(PLUGIN_NAME, "Unable to set link-layer-address value for module changes context"); + goto error_out; + } + mod_ctx->mod_data.ipv6.neighbor.link_layer_set = true; + + goto out; + +error_out: + error = -1; + mod_ctx->mod_data.ipv6.neighbor.link_layer_set = false; + +out: + return error; +} \ No newline at end of file diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/change.h b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/change.h index b3c6b129..ac15a9ab 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/change.h +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/change.h @@ -7,6 +7,7 @@ int interfaces_interface_ipv6_neighbor_change_link_layer_address_init(void* priv); int interfaces_interface_ipv6_neighbor_change_link_layer_address(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); void interfaces_interface_ipv6_neighbor_change_link_layer_address_free(void* priv); + int interfaces_interface_ipv6_neighbor_change_ip_init(void* priv); int interfaces_interface_ipv6_neighbor_change_ip(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); void interfaces_interface_ipv6_neighbor_change_ip_free(void* priv); From 4da801607c76ef7535fa0cb23c5afec005160b36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Wed, 12 Oct 2022 20:54:24 +0200 Subject: [PATCH 192/247] interfaces-plugin: fix log message --- .../src/plugin/api/interfaces/interface/ipv6/address/change.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.c index 46ef9a5f..25456806 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/change.c @@ -219,7 +219,7 @@ int interfaces_interface_ipv6_address_change_ip(void* priv, sr_session_ctx_t* se break; case SR_OP_MODIFIED: // should be impossible - address IP can only be created and deleted - SRPLG_LOG_ERR(PLUGIN_NAME, "Unsuported operation MODIFY for interface IPv4 address IP leaf"); + SRPLG_LOG_ERR(PLUGIN_NAME, "Unsuported operation MODIFY for interface IPv6 address IP leaf"); goto error_out; break; case SR_OP_DELETED: From 4b74aaa396c01162ea6b10e67748a3225c9dcbad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Wed, 12 Oct 2022 20:54:54 +0200 Subject: [PATCH 193/247] interfaces-plugin: fix function name --- .../plugin/api/interfaces/interface/ipv4/neighbor/change.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c index c4269282..b32722d3 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/change.c @@ -11,7 +11,7 @@ #include #include -static int interfaces_interface_ipv4_address_get_link_layer_address(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); +static int interfaces_interface_ipv4_neighbor_get_link_layer_address(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx); int interfaces_interface_ipv4_neighbor_change_link_layer_address_init(void* priv) { @@ -158,7 +158,7 @@ int interfaces_interface_ipv4_neighbor_change_ip(void* priv, sr_session_ctx_t* s // get prefix length by using prefix-length or netmask leafs SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(path_buffer, sizeof(path_buffer), INTERFACES_INTERFACES_INTERFACE_YANG_PATH "[name=\"%s\"]/ietf-ip:ipv4/neighbor[ip=\"%s\"]/link-layer-address", interface_name_buffer, node_value), error_out); - SRPC_SAFE_CALL_ERR(error, srpc_iterate_changes(ctx, session, path_buffer, interfaces_interface_ipv4_address_get_link_layer_address, NULL, NULL), error_out); + SRPC_SAFE_CALL_ERR(error, srpc_iterate_changes(ctx, session, path_buffer, interfaces_interface_ipv4_neighbor_get_link_layer_address, NULL, NULL), error_out); SRPLG_LOG_INF(PLUGIN_NAME, "Recieved link-layer-address %s for neighbor address %s", mod_ctx->mod_data.ipv4.neighbor.link_layer_address, node_value); @@ -229,7 +229,7 @@ void interfaces_interface_ipv4_neighbor_change_ip_free(void* priv) { } -static int interfaces_interface_ipv4_address_get_link_layer_address(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) +static int interfaces_interface_ipv4_neighbor_get_link_layer_address(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) { int error = 0; From 57888931516fa19530ee7907b91958f2f2e6842c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Wed, 12 Oct 2022 20:56:39 +0200 Subject: [PATCH 194/247] interfaces-plugin: implement IPv6 neighbor link-layer-address change callback --- .../interface/ipv6/neighbor/change.c | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/change.c index 80ff8fce..9850f038 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/change.c @@ -20,22 +20,83 @@ int interfaces_interface_ipv6_neighbor_change_link_layer_address_init(void* priv int interfaces_interface_ipv6_neighbor_change_link_layer_address(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) { int error = 0; + void* error_ptr = NULL; + + // strings and buffers const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); + char path_buffer[PATH_MAX] = { 0 }; + char interface_name_buffer[100] = { 0 }; + char ip_buffer[100] = { 0 }; + + // app context + interfaces_ctx_t* ctx = priv; + + // mod changes context + interfaces_mod_changes_ctx_t* mod_ctx = &ctx->mod_ctx; + + // libnl + struct rtnl_neigh* request_neigh = NULL; + struct rtnl_link* current_link = NULL; + struct nl_addr* dst_addr = NULL; + struct nl_addr* ll_addr = NULL; SRPLG_LOG_INF(PLUGIN_NAME, "Node Name: %s; Previous Value: %s, Value: %s; Operation: %d", node_name, change_ctx->previous_value, node_value, change_ctx->operation); + // get node path + SRPC_SAFE_CALL_PTR(error_ptr, lyd_path(change_ctx->node, LYD_PATH_STD, path_buffer, sizeof(path_buffer)), error_out); + + // get interface name + SRPC_SAFE_CALL_ERR(error, srpc_extract_xpath_key_value(path_buffer, "interface", "name", interface_name_buffer, sizeof(interface_name_buffer)), error_out); + + // get IP + SRPC_SAFE_CALL_ERR(error, srpc_extract_xpath_key_value(path_buffer, "neighbor", "ip", ip_buffer, sizeof(ip_buffer)), error_out); + + SRPLG_LOG_INF(PLUGIN_NAME, "Node Path: %s; Interface Name: %s; Neighbor IP: %s", path_buffer, interface_name_buffer, ip_buffer); + + // get link + SRPC_SAFE_CALL_PTR(current_link, rtnl_link_get_by_name(mod_ctx->nl_ctx.link_cache, interface_name_buffer), error_out); + switch (change_ctx->operation) { case SR_OP_CREATED: + // not used - used only in IP change callback break; case SR_OP_MODIFIED: + // change lladdr + request_neigh = rtnl_neigh_alloc(); + + // set interface + rtnl_neigh_set_ifindex(request_neigh, rtnl_link_get_ifindex(current_link)); + + // parse destination and LL address + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(ip_buffer, AF_INET6, &dst_addr), error_out); + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(node_value, AF_LLC, &ll_addr), error_out); + + // set destination and LL address + SRPC_SAFE_CALL_ERR(error, rtnl_neigh_set_dst(request_neigh, dst_addr), error_out); + rtnl_neigh_set_lladdr(request_neigh, ll_addr); + + // change neighbor + SRPC_SAFE_CALL_ERR(error, rtnl_neigh_add(mod_ctx->nl_ctx.socket, request_neigh, NLM_F_REPLACE), error_out); + break; case SR_OP_DELETED: + // not used - used only in IP change callback break; case SR_OP_MOVED: break; } + goto out; + +error_out: + error = -1; + +out: + if (request_neigh) { + rtnl_neigh_put(request_neigh); + } + return error; } From 1afc2588e05ec6f92d3b36b4c5a818bd7dc93a0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateo=20Cindri=C4=87?= Date: Wed, 12 Oct 2022 21:02:23 +0200 Subject: [PATCH 195/247] interfaces-plugin: iterate IPv6 neighbor changes --- src/interfaces/src/plugin/subscription/change.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/interfaces/src/plugin/subscription/change.c b/src/interfaces/src/plugin/subscription/change.c index 3368a4f0..5643f899 100644 --- a/src/interfaces/src/plugin/subscription/change.c +++ b/src/interfaces/src/plugin/subscription/change.c @@ -85,6 +85,14 @@ int interfaces_subscription_change_interfaces_interface(sr_session_ctx_t* sessio // ipv6/address/prefix-length SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/ipv6/address/prefix-length", xpath), error_out); SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_ipv6_address_change_prefix_length, interfaces_change_interface_init, interfaces_change_interface_free), error_out); + + // ipv6/neighbor/ip + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/ipv6/neighbor/ip", xpath), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_ipv6_neighbor_change_ip, interfaces_change_interface_init, interfaces_change_interface_free), error_out); + + // ipv6/neighbor/link-layer-address + SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/ipv6/neighbor/link-layer-address", xpath), error_out); + SRPC_SAFE_CALL_ERR(rc, srpc_iterate_changes(ctx, session, change_xpath_buffer, interfaces_interface_ipv6_neighbor_change_link_layer_address, interfaces_change_interface_init, interfaces_change_interface_free), error_out); } goto out; From a8c2dc6a1c1afc5e30d57aaa0ef9f83319aeeb86 Mon Sep 17 00:00:00 2001 From: andrej Date: Thu, 13 Oct 2022 15:02:59 +0200 Subject: [PATCH 196/247] interfaces-plugin: add mtu, split read sys, proc functionality --- .../src/plugin/api/interfaces/load.c | 105 ++++++++---------- 1 file changed, 48 insertions(+), 57 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index c401726f..1500c7a0 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -1,4 +1,5 @@ #include "load.h" +#include "read.h" #include "plugin/common.h" #include "utils/memory.h" #include "utlist.h" @@ -87,15 +88,12 @@ static int interfaces_get_ips(struct nl_sock* socket, struct rtnl_link* link, in char *str = NULL; char addr_str[ADDR_STR_BUF_SIZE] = { 0 }; - unsigned int mtu = 0; int addr_count = 0; int addr_family = 0; int if_index = 0; int cur_if_index = 0; int error = 0; - mtu = rtnl_link_get_mtu(link); - if_index = rtnl_link_get_ifindex(link); SRPC_SAFE_CALL(rtnl_neigh_alloc_cache(socket, &addr_cache), error_out); @@ -295,6 +293,36 @@ static int interfaces_get_neighbors(struct nl_sock* socket, struct rtnl_link* li return interfaces_load_success; } +static unsigned int interfaces_get_ipv4_mtu(struct rtnl_link* link, interfaces_interface_t* interface) +{ + unsigned int mtu = 0; + + mtu = rtnl_link_get_mtu(link); + + interface->ipv4.mtu = mtu; + + return 0; +} + +static unsigned int interfaces_get_ipv6_mtu(struct rtnl_link* link, interfaces_interface_t* interface) +{ + unsigned int mtu = 0; + + mtu = rtnl_link_get_mtu(link); + + interface->ipv6.mtu = mtu; + + return 0; + +} + +static unsigned int interfaces_get_mtu(struct rtnl_link* link, interfaces_interface_t* interface) +{ + interfaces_get_ipv4_mtu(link, interface); + + interfaces_get_ipv6_mtu(link, interface); +} + static char* interfaces_get_interface_name(struct rtnl_link* link) { char* name = NULL; @@ -334,41 +362,6 @@ static char* interfaces_get_interface_description(interfaces_ctx_t* ctx, char* n return description; } -static int read_from_sys_file(const char* dir_path, char* interface, int* val) -{ - int error = 0; - char tmp_buffer[PATH_MAX]; - FILE* fptr = NULL; - char tmp_val[4] = { 0 }; - - error = snprintf(tmp_buffer, sizeof(tmp_buffer), "%s/%s/type", dir_path, interface); - if (error < 0) { - // snprintf error - SRPLG_LOG_ERR(PLUGIN_NAME, "%s: snprintf failed", __func__); - goto out; - } - - /* snprintf returns return the number of bytes that are written - reset error to 0 */ - error = 0; - - fptr = fopen((const char*)tmp_buffer, "r"); - - if (fptr != NULL) { - fgets(tmp_val, sizeof(tmp_val), fptr); - - *val = atoi(tmp_val); - - fclose(fptr); - } else { - SRPLG_LOG_ERR(PLUGIN_NAME, "%s: failed to open %s: %s", __func__, tmp_buffer, strerror(errno)); - error = -1; - goto out; - } - -out: - return error; -} - static char* interfaces_get_interface_type(struct rtnl_link* link, char* name) { int error = 0; @@ -403,7 +396,7 @@ static char* interfaces_get_interface_type(struct rtnl_link* link, char* name) return xstrdup(type); } -static uint8_t interfaces_get_interface_enabled(struct rtnl_link* link) +static int interfaces_get_interface_enabled(struct rtnl_link* link, interfaces_interface_t *interface) { uint8_t enabled = rtnl_link_get_operstate(link); @@ -417,10 +410,12 @@ static uint8_t interfaces_get_interface_enabled(struct rtnl_link* link) enabled = interfaces_interface_enable_disabled; } - return enabled; + interface->enabled = enabled; + + return 0; } -static char* interfaces_get_interface_parent_interface(struct nl_cache* cache, struct rtnl_link* link) +static int interfaces_get_interface_parent_interface(struct nl_cache* cache, struct rtnl_link* link, interfaces_interface_t* interface) { int parent_index = 0; char parent_buffer[IFNAMSIZ] = { 0 }; @@ -429,10 +424,12 @@ static char* interfaces_get_interface_parent_interface(struct nl_cache* cache, s if (rtnl_link_is_vlan(link)) { parent_index = rtnl_link_get_link(link); parent_interface = rtnl_link_i2name(cache, parent_index, parent_buffer, IFNAMSIZ); - return xstrdup(parent_interface); + interface->parent_interface = xstrdup(parent_interface); + + return 0; } - return NULL; + return -1; } /* TODO: outer tag, second id, tag - maybe refactor all to pass by reference, return error */ @@ -476,7 +473,7 @@ static int interfaces_parse_link(interfaces_ctx_t* ctx, struct nl_sock* socket, interfaces_get_interface_type(link, interface->name); - interfaces_get_interface_parent_interface(cache, link); + interfaces_get_interface_parent_interface(cache, link, interface); error = interfaces_get_interface_vlan_id(link, interface); if (error != interfaces_load_success) { @@ -484,12 +481,14 @@ static int interfaces_parse_link(interfaces_ctx_t* ctx, struct nl_sock* socket, goto out; // error_out would possibly change the error } - interface->enabled = interfaces_get_interface_enabled(link); + interface->enabled = interfaces_get_interface_enabled(link, interface); interfaces_get_neighbors(socket, link, interface); interfaces_get_ips(socket, link, interface); + interfaces_get_mtu(link, interface); + goto out; error_out: error = interfaces_load_failure; @@ -523,8 +522,12 @@ static int interfaces_add_link(interfaces_interface_hash_element_t** if_hash, in interfaces_interface_hash_element_set_enabled(&new_if_hash_elem, interface->enabled); interfaces_interface_hash_element_set_ipv4(&new_if_hash_elem, interface->ipv4); + interfaces_interface_hash_element_set_ipv4_mtu(&new_if_hash_elem, interface->ipv4.mtu); interfaces_interface_hash_element_set_ipv6(&new_if_hash_elem, interface->ipv6); + interfaces_interface_hash_element_set_ipv6_mtu(&new_if_hash_elem, interface->ipv6.mtu); + + interfaces_interface_hash_element_set_enabled(&new_if_hash_elem, interface->enabled); goto out; error_out: @@ -541,18 +544,6 @@ static int interfaces_add_link(interfaces_interface_hash_element_t** if_hash, in if (interface->parent_interface != NULL) { FREE_SAFE(interface->parent_interface); } - if (interface->ipv4.neighbor != NULL) { - INTERFACES_INTERFACE_LIST_FREE(interface->ipv4.neighbor); - } - if (interface->ipv4.address != NULL) { - INTERFACES_INTERFACE_LIST_FREE(interface->ipv4.address); - } - if (interface->ipv6.neighbor != NULL) { - INTERFACES_INTERFACE_LIST_FREE(interface->ipv6.neighbor); - } - if (interface->ipv6.address != NULL) { - INTERFACES_INTERFACE_LIST_FREE(interface->ipv6.address); - } return error; } From 90815019e393700d9ba6e529525c044dfaafdb81 Mon Sep 17 00:00:00 2001 From: andrej Date: Thu, 13 Oct 2022 15:03:24 +0200 Subject: [PATCH 197/247] interfaces-plugin: add read sys, proc --- .../src/plugin/api/interfaces/read.c | 75 +++++++++++++++++++ .../src/plugin/api/interfaces/read.h | 8 ++ 2 files changed, 83 insertions(+) create mode 100644 src/interfaces/src/plugin/api/interfaces/read.c create mode 100644 src/interfaces/src/plugin/api/interfaces/read.h diff --git a/src/interfaces/src/plugin/api/interfaces/read.c b/src/interfaces/src/plugin/api/interfaces/read.c new file mode 100644 index 00000000..91af20de --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/read.c @@ -0,0 +1,75 @@ +#include "plugin/common.h" +#include "srpc/common.h" + +#include + +int read_from_proc_file(const char *dir_path, char *interface, const char *fn, int *val) +{ + int error = 0; + char tmp_buffer[PATH_MAX]; + FILE *fptr = NULL; + char tmp_val[2] = {0}; + + error = snprintf(tmp_buffer, sizeof(tmp_buffer), "%s/%s/%s", dir_path, interface, fn); + if (error < 0) { + // snprintf error + SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf failed"); + goto out; + } + + // snprintf returns return the number of bytes that are written + // reset error to 0 + error = 0; + + fptr = fopen((const char *) tmp_buffer, "r"); + + if (fptr != NULL) { + fgets(tmp_val, sizeof(tmp_val), fptr); + + *val = atoi(tmp_val); + + fclose(fptr); + } else { + SRPLG_LOG_ERR(PLUGIN_NAME, "failed to open %s: %s", tmp_buffer, strerror(errno)); + error = -1; + goto out; + } + +out: + return error; +} + +int read_from_sys_file(const char* dir_path, char* interface, int* val) +{ + int error = 0; + char tmp_buffer[PATH_MAX]; + FILE* fptr = NULL; + char tmp_val[4] = { 0 }; + + error = snprintf(tmp_buffer, sizeof(tmp_buffer), "%s/%s/type", dir_path, interface); + if (error < 0) { + // snprintf error + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: snprintf failed", __func__); + goto out; + } + + /* snprintf returns return the number of bytes that are written - reset error to 0 */ + error = 0; + + fptr = fopen((const char*)tmp_buffer, "r"); + + if (fptr != NULL) { + fgets(tmp_val, sizeof(tmp_val), fptr); + + *val = atoi(tmp_val); + + fclose(fptr); + } else { + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: failed to open %s: %s", __func__, tmp_buffer, strerror(errno)); + error = -1; + goto out; + } + +out: + return error; +} diff --git a/src/interfaces/src/plugin/api/interfaces/read.h b/src/interfaces/src/plugin/api/interfaces/read.h new file mode 100644 index 00000000..5ea196aa --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/read.h @@ -0,0 +1,8 @@ +#ifndef READ_H +#define READ_H + +int read_from_proc_file(const char *dir_path, char *interface, const char *fn, int *val); + +int read_from_sys_file(const char* dir_path, char* interface, int* val); + +#endif /* READ_H */ From 22f6deb9e89c91dfe02c29ca56ff65dfc4dca5e0 Mon Sep 17 00:00:00 2001 From: andrej Date: Thu, 13 Oct 2022 15:04:53 +0200 Subject: [PATCH 198/247] interfaces-plugin: add read to cmake sources --- src/interfaces/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/interfaces/CMakeLists.txt b/src/interfaces/CMakeLists.txt index a63db8c7..89a64b82 100644 --- a/src/interfaces/CMakeLists.txt +++ b/src/interfaces/CMakeLists.txt @@ -29,6 +29,7 @@ set( # API src/plugin/api/interfaces/check.c src/plugin/api/interfaces/load.c + src/plugin/api/interfaces/read.c src/plugin/api/interfaces/store.c src/plugin/api/interfaces/change.c src/plugin/api/interfaces/interface/change.c From 4e7ed987f9b0042f6d46621b2651a41707b1f815 Mon Sep 17 00:00:00 2001 From: andrej Date: Thu, 13 Oct 2022 15:37:46 +0200 Subject: [PATCH 199/247] interfaces-plugin: add load ipv4/6 forwarding, enabled --- .../src/plugin/api/interfaces/load.c | 78 ++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index 1500c7a0..4aa666c3 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -323,6 +323,75 @@ static unsigned int interfaces_get_mtu(struct rtnl_link* link, interfaces_interf interfaces_get_ipv6_mtu(link, interface); } +static unsigned int interfaces_get_ipv4_enabled(interfaces_interface_t* interface) +{ + const char *ipv4_base = "/proc/sys/net/ipv4/conf"; + + /* TODO: figure out how to enable/disable ipv4 */ + /* since disable_ipv4 doesn't exist in /proc/sys/net/ipv6/conf/interface_name */ + +} + +static unsigned int interfaces_get_ipv6_enabled(interfaces_interface_t* interface) +{ + int error = 0; + int enabled = 0; + + const char *ipv6_base = "/proc/sys/net/ipv6/conf"; + + SRPC_SAFE_CALL(read_from_proc_file(ipv6_base, interface->name, "disable_ipv6", enabled), out); + + interface->ipv6.enabled = enabled; + +out: + return error; +} + +static unsigned int interfaces_get_enabled(interfaces_interface_t* interface) +{ + interfaces_get_ipv4_enabled(interface); + + interfaces_get_ipv6_enabled(interface); +} + +static unsigned int interfaces_get_ipv4_forwarding(interfaces_interface_t* interface) +{ + int error = 0; + int forwarding = 0; + + const char *ipv4_base = "/proc/sys/net/ipv4/conf"; + + SRPC_SAFE_CALL(read_from_proc_file(ipv4_base, interface->name, "forwarding", forwarding), out); + + interface->ipv4.forwarding = forwarding; + +out: + return error; +} + +static unsigned int interfaces_get_ipv6_forwarding(interfaces_interface_t* interface) +{ + int error = 0; + int forwarding = 0; + + const char *ipv6_base = "/proc/sys/net/ipv6/conf"; + + SRPC_SAFE_CALL(read_from_proc_file(ipv6_base, interface->name, "forwarding", forwarding), out); + + interface->ipv6.forwarding = forwarding; + +out: + return error; +} + + +static unsigned int interfaces_get_forwarding(interfaces_interface_t* interface) +{ + interfaces_get_ipv4_forwarding(interface); + + interfaces_get_ipv6_forwarding(interface); +} + static char* interfaces_get_interface_name(struct rtnl_link* link) { char* name = NULL; @@ -475,6 +544,7 @@ static int interfaces_parse_link(interfaces_ctx_t* ctx, struct nl_sock* socket, interfaces_get_interface_parent_interface(cache, link, interface); + /* interface can be skipped - interface_load_continue*/ error = interfaces_get_interface_vlan_id(link, interface); if (error != interfaces_load_success) { SRPLG_LOG_ERR(PLUGIN_NAME, "%s: vlan id error", __func__); @@ -489,11 +559,15 @@ static int interfaces_parse_link(interfaces_ctx_t* ctx, struct nl_sock* socket, interfaces_get_mtu(link, interface); + interfaces_get_enabled(interface); + + interfaces_get_forwarding(interface); + goto out; error_out: error = interfaces_load_failure; - // do not free the data, the interface data needs to be added in the interfaces hash table out: + /* do not free the data, the interface data needs to be added in the interfaces hash table */ return error; } @@ -523,9 +597,11 @@ static int interfaces_add_link(interfaces_interface_hash_element_t** if_hash, in interfaces_interface_hash_element_set_ipv4(&new_if_hash_elem, interface->ipv4); interfaces_interface_hash_element_set_ipv4_mtu(&new_if_hash_elem, interface->ipv4.mtu); + interfaces_interface_hash_element_set_ipv4_enabled(&new_if_hash_elem, interface->ipv4.enabled); interfaces_interface_hash_element_set_ipv6(&new_if_hash_elem, interface->ipv6); interfaces_interface_hash_element_set_ipv6_mtu(&new_if_hash_elem, interface->ipv6.mtu); + interfaces_interface_hash_element_set_ipv6_enabled(&new_if_hash_elem, interface->ipv6.enabled); interfaces_interface_hash_element_set_enabled(&new_if_hash_elem, interface->enabled); From c1db1a07c0be57964a21d72c2d6db9bed3db8f20 Mon Sep 17 00:00:00 2001 From: andrej Date: Thu, 13 Oct 2022 15:53:37 +0200 Subject: [PATCH 200/247] interfaces-plugin: pass pointer to out proc variable --- .../src/plugin/api/interfaces/load.c | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index 4aa666c3..54ac7bce 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -75,7 +75,7 @@ static int interfaces_add_ips(interfaces_interface_t* interface, char *ip, int n return 0; } -static int interfaces_get_ips(struct nl_sock* socket, struct rtnl_link* link, interfaces_interface_t* interface) +static int interfaces_get_interface_ips(struct nl_sock* socket, struct rtnl_link* link, interfaces_interface_t* interface) { struct nl_object *nl_object = NULL; struct nl_cache *addr_cache = NULL; @@ -209,7 +209,7 @@ static int interfaces_add_neighbor(interfaces_interface_t* interface, char *dst_ return 0; } -static int interfaces_get_neighbors(struct nl_sock* socket, struct rtnl_link* link, interfaces_interface_t* interface) +static int interfaces_get_interface_ip_neighbors(struct nl_sock* socket, struct rtnl_link* link, interfaces_interface_t* interface) { struct nl_cache *neigh_cache = NULL; struct nl_object *nl_neigh_object = NULL; @@ -316,7 +316,7 @@ static unsigned int interfaces_get_ipv6_mtu(struct rtnl_link* link, interfaces_i } -static unsigned int interfaces_get_mtu(struct rtnl_link* link, interfaces_interface_t* interface) +static unsigned int interfaces_get_interface_ip_mtu(struct rtnl_link* link, interfaces_interface_t* interface) { interfaces_get_ipv4_mtu(link, interface); @@ -339,7 +339,7 @@ static unsigned int interfaces_get_ipv6_enabled(interfaces_interface_t* interfac const char *ipv6_base = "/proc/sys/net/ipv6/conf"; - SRPC_SAFE_CALL(read_from_proc_file(ipv6_base, interface->name, "disable_ipv6", enabled), out); + SRPC_SAFE_CALL(read_from_proc_file(ipv6_base, interface->name, "disable_ipv6", &enabled), out); interface->ipv6.enabled = enabled; @@ -347,7 +347,7 @@ static unsigned int interfaces_get_ipv6_enabled(interfaces_interface_t* interfac return error; } -static unsigned int interfaces_get_enabled(interfaces_interface_t* interface) +static unsigned int interfaces_get_interface_ip_enabled(interfaces_interface_t* interface) { interfaces_get_ipv4_enabled(interface); @@ -361,7 +361,7 @@ static unsigned int interfaces_get_ipv4_forwarding(interfaces_interface_t* inter const char *ipv4_base = "/proc/sys/net/ipv4/conf"; - SRPC_SAFE_CALL(read_from_proc_file(ipv4_base, interface->name, "forwarding", forwarding), out); + SRPC_SAFE_CALL(read_from_proc_file(ipv4_base, interface->name, "forwarding", &forwarding), out); interface->ipv4.forwarding = forwarding; @@ -376,7 +376,7 @@ static unsigned int interfaces_get_ipv6_forwarding(interfaces_interface_t* inter const char *ipv6_base = "/proc/sys/net/ipv6/conf"; - SRPC_SAFE_CALL(read_from_proc_file(ipv6_base, interface->name, "forwarding", forwarding), out); + SRPC_SAFE_CALL(read_from_proc_file(ipv6_base, interface->name, "forwarding", &forwarding), out); interface->ipv6.forwarding = forwarding; @@ -385,7 +385,7 @@ static unsigned int interfaces_get_ipv6_forwarding(interfaces_interface_t* inter } -static unsigned int interfaces_get_forwarding(interfaces_interface_t* interface) +static unsigned int interfaces_get_interface_ip_forwarding(interfaces_interface_t* interface) { interfaces_get_ipv4_forwarding(interface); @@ -538,7 +538,7 @@ static int interfaces_parse_link(interfaces_ctx_t* ctx, struct nl_sock* socket, // required, fail if NULL SRPC_SAFE_CALL_PTR(interface->name, interfaces_get_interface_name(link), error_out); - interfaces_get_interface_description(ctx, interface->name); + /* interfaces_get_interface_description(ctx, interface->name); */ interfaces_get_interface_type(link, interface->name); @@ -547,21 +547,20 @@ static int interfaces_parse_link(interfaces_ctx_t* ctx, struct nl_sock* socket, /* interface can be skipped - interface_load_continue*/ error = interfaces_get_interface_vlan_id(link, interface); if (error != interfaces_load_success) { - SRPLG_LOG_ERR(PLUGIN_NAME, "%s: vlan id error", __func__); goto out; // error_out would possibly change the error } - interface->enabled = interfaces_get_interface_enabled(link, interface); + interfaces_get_interface_enabled(link, interface); - interfaces_get_neighbors(socket, link, interface); + interfaces_get_interface_ips(socket, link, interface); - interfaces_get_ips(socket, link, interface); + interfaces_get_interface_ip_neighbors(socket, link, interface); - interfaces_get_mtu(link, interface); + interfaces_get_interface_ip_mtu(link, interface); - interfaces_get_enabled(interface); + //interfaces_get_interface_ip_enabled(interface); - interfaces_get_forwarding(interface); + interfaces_get_interface_ip_forwarding(interface); goto out; error_out: @@ -598,10 +597,12 @@ static int interfaces_add_link(interfaces_interface_hash_element_t** if_hash, in interfaces_interface_hash_element_set_ipv4(&new_if_hash_elem, interface->ipv4); interfaces_interface_hash_element_set_ipv4_mtu(&new_if_hash_elem, interface->ipv4.mtu); interfaces_interface_hash_element_set_ipv4_enabled(&new_if_hash_elem, interface->ipv4.enabled); + interfaces_interface_hash_element_set_ipv4_forwarding(&new_if_hash_elem, interface->ipv4.forwarding); interfaces_interface_hash_element_set_ipv6(&new_if_hash_elem, interface->ipv6); interfaces_interface_hash_element_set_ipv6_mtu(&new_if_hash_elem, interface->ipv6.mtu); interfaces_interface_hash_element_set_ipv6_enabled(&new_if_hash_elem, interface->ipv6.enabled); + interfaces_interface_hash_element_set_ipv6_forwarding(&new_if_hash_elem, interface->ipv6.forwarding); interfaces_interface_hash_element_set_enabled(&new_if_hash_elem, interface->enabled); From 84c994311094d250de43a574797834c47d964491 Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Sat, 15 Oct 2022 13:32:24 +0000 Subject: [PATCH 201/247] interfaces-plugin: update CMake libnl find script to include local install paths --- CMakeModules/FindNL.cmake | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/CMakeModules/FindNL.cmake b/CMakeModules/FindNL.cmake index 6131ffcb..2b1bdd39 100644 --- a/CMakeModules/FindNL.cmake +++ b/CMakeModules/FindNL.cmake @@ -5,12 +5,30 @@ find_path(NL_INCLUDE_DIRS netlink/netlink.h /usr/include/libnl3 /usr/local/include /usr/local/include/libnl3 + ${CMAKE_INCLUDE_PATH} + ${CMAKE_PREFIX_PATH}/include/libnl3 ) -find_library(NL_LIBRARY NAMES nl nl-3) -find_library(NL_ROUTE_LIBRARY NAMES nl-route nl-route-3) -find_library(NL_NETFILTER_LIBRARY NAMES nl-nf nl-nf-3) -find_library(NL_GENL_LIBRARY NAMES nl-genl nl-genl-3) +find_library( + NL_LIBRARY + NAMES nl nl-3 + PATHS /usr/lib /usr/lib64 /usr/local/lib /usr/local/lib64 /opt/local/lib /sw/lib ${CMAKE_LIBRARY_PATH} ${CMAKE_INSTALL_PREFIX}/lib +) +find_library( + NL_ROUTE_LIBRARY + NAMES nl-route nl-route-3 + PATHS /usr/lib /usr/lib64 /usr/local/lib /usr/local/lib64 /opt/local/lib /sw/lib ${CMAKE_LIBRARY_PATH} ${CMAKE_INSTALL_PREFIX}/lib +) +find_library( + NL_NETFILTER_LIBRARY + NAMES nl-nf nl-nf-3 + PATHS /usr/lib /usr/lib64 /usr/local/lib /usr/local/lib64 /opt/local/lib /sw/lib ${CMAKE_LIBRARY_PATH} ${CMAKE_INSTALL_PREFIX}/lib +) +find_library( + NL_GENL_LIBRARY + NAMES nl-genl nl-genl-3 + PATHS /usr/lib /usr/lib64 /usr/local/lib /usr/local/lib64 /opt/local/lib /sw/lib ${CMAKE_LIBRARY_PATH} ${CMAKE_INSTALL_PREFIX}/lib +) if (NL_INCLUDE_DIRS AND NL_LIBRARY) set(NL_FOUND TRUE) From 6b1a067bdb33d99c91dbe3bdcb74b49fa95a2ed6 Mon Sep 17 00:00:00 2001 From: andrej Date: Mon, 17 Oct 2022 13:18:12 +0200 Subject: [PATCH 202/247] interfaces-plugin: remove duplicate netmask to prefix length function --- .../data/interfaces/interface/ipv4/address.c | 30 +------------------ 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c index ef38543b..e6624c18 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c @@ -81,34 +81,6 @@ int interfaces_interface_ipv4_address_element_set_ip(interfaces_interface_ipv4_a return 0; } -int interfaces_interface_netmask_to_prefix_length(const char *netmask) -{ - int error = 0; - - struct sockaddr_in sa = { 0 }; - struct sockaddr_in6 sa6 = { 0 }; - - // IPv6 if a ':' is found - if (strchr(netmask, ':')) { - SRPC_SAFE_CALL(inet_pton(AF_INET6, netmask, &(sa6.sin6_addr)), error_out); - - // s6_addr is a uint8_t array of length 16, all the byte popcounts need to be summarized - // avoid branching, use popcountll's 64 bits minimum - uint64_t *s6_addr64 = (uint64_t *) sa6.sin6_addr.s6_addr; - - return __builtin_popcountll(s6_addr64[0]) + __builtin_popcountll(s6_addr64[1]); - - } - - // IPv4 otherwise - SRPC_SAFE_CALL(inet_pton(AF_INET, netmask, &(sa.sin_addr)), error_out); - - return __builtin_popcountl(sa.sin_addr.s_addr); - -error_out: - return -1; -} - int interfaces_interface_ipv4_address_element_set_subnet(interfaces_interface_ipv4_address_element_t** el, char *netmask, enum interfaces_interface_ipv4_address_subnet subtype) { int error = 0; @@ -191,4 +163,4 @@ int interfaces_interface_ipv4_address_netmask2prefix(const char* netmask, uint8_ out: return error; -} \ No newline at end of file +} From 9dfe5985e0f52b83b2c09b580bc2e84494ccfc41 Mon Sep 17 00:00:00 2001 From: andrej Date: Mon, 17 Oct 2022 13:18:30 +0200 Subject: [PATCH 203/247] interfaces-plugin: set prefix length instead of netmask --- src/interfaces/src/plugin/api/interfaces/load.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index 54ac7bce..6f917421 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -33,14 +33,20 @@ enum interfaces_load_exit_status { static int interfaces_add_address_ipv4(interfaces_interface_ipv4_address_element_t **address, char *ip, char *netmask) { + int prefix_length = 0; + int error = 0; + interfaces_interface_ipv4_address_element_t* new_element = NULL; new_element = interfaces_interface_ipv4_address_element_new(); interfaces_interface_ipv4_address_element_set_ip(&new_element, ip); - interfaces_interface_ipv4_address_element_set_subnet(&new_element, netmask, interfaces_interface_ipv4_address_subnet_netmask); + SRPC_SAFE_CALL(interfaces_interface_ipv4_address_netmask2prefix(netmask, prefix_length), out); + interfaces_interface_ipv4_address_element_set_subnet(&new_element, netmask, interfaces_interface_ipv4_address_subnet_prefix_length); interfaces_interface_ipv4_address_add_element(address, new_element); +out: + return error; } static int interfaces_add_address_ipv6(interfaces_interface_ipv6_address_element_t **address, char *ip, char *netmask) From aabca2047837ae414bc060c3565b6a1933a8dfc2 Mon Sep 17 00:00:00 2001 From: andrej Date: Mon, 17 Oct 2022 19:30:23 +0200 Subject: [PATCH 204/247] interfaces-plugin: split ipv4/6 load functionality --- .../api/interfaces/interface/ipv4/load.c | 68 +++++++++ .../api/interfaces/interface/ipv4/load.h | 21 +++ .../api/interfaces/interface/ipv6/load.c | 75 ++++++++++ .../api/interfaces/interface/ipv6/load.h | 20 +++ .../src/plugin/api/interfaces/load.c | 139 +----------------- .../src/plugin/api/interfaces/load.h | 5 +- 6 files changed, 187 insertions(+), 141 deletions(-) create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.h create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.c create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.h diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c new file mode 100644 index 00000000..23f9d527 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c @@ -0,0 +1,68 @@ +#include "load.h" + + +int interfaces_add_address_ipv4(interfaces_interface_ipv4_address_element_t **address, char *ip, char *netmask) +{ + int prefix_length = 0; + int error = 0; + + interfaces_interface_ipv4_address_element_t* new_element = NULL; + + new_element = interfaces_interface_ipv4_address_element_new(); + + interfaces_interface_ipv4_address_element_set_ip(&new_element, ip); + SRPC_SAFE_CALL(interfaces_interface_ipv4_address_netmask2prefix(netmask, prefix_length), out); + interfaces_interface_ipv4_address_element_set_subnet(&new_element, netmask, interfaces_interface_ipv4_address_subnet_prefix_length); + interfaces_interface_ipv4_address_add_element(address, new_element); + +out: + return error; +} + +int interfaces_add_neighbor_ipv4(interfaces_interface_ipv4_neighbor_element_t** neighbor, char *dst_addr, char *ll_addr) +{ + interfaces_interface_ipv4_neighbor_element_t* new_element = NULL; + + new_element = interfaces_interface_ipv4_neighbor_element_new(); + + interfaces_interface_ipv4_neighbor_element_set_ip(&new_element, dst_addr); + interfaces_interface_ipv4_neighbor_element_set_link_layer_address(&new_element, ll_addr); + interfaces_interface_ipv4_neighbor_add_element(neighbor, new_element); + + return 0; +} + +unsigned int interfaces_get_ipv4_mtu(struct rtnl_link* link, interfaces_interface_t* interface) +{ + unsigned int mtu = 0; + + mtu = rtnl_link_get_mtu(link); + + interface->ipv4.mtu = mtu; + + return 0; +} + +unsigned int interfaces_get_ipv4_enabled(interfaces_interface_t* interface) +{ + const char *ipv4_base = "/proc/sys/net/ipv4/conf"; + + /* TODO: figure out how to enable/disable ipv4 */ + /* since disable_ipv4 doesn't exist in /proc/sys/net/ipv6/conf/interface_name */ + +} + +unsigned int interfaces_get_ipv4_forwarding(interfaces_interface_t* interface) +{ + int error = 0; + int forwarding = 0; + + const char *ipv4_base = "/proc/sys/net/ipv4/conf"; + + SRPC_SAFE_CALL(read_from_proc_file(ipv4_base, interface->name, "forwarding", &forwarding), out); + + interface->ipv4.forwarding = forwarding; + +out: + return error; +} diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.h b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.h new file mode 100644 index 00000000..47904e13 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.h @@ -0,0 +1,21 @@ +#ifndef INTERFACES_PLUGIN_API_INTERFACES_IPV4_LOAD_H +#define INTERFACES_PLUGIN_API_INTERFACES_IPV4_LOAD_H + +#include "plugin/context.h" +#include "plugin/data/interfaces/interface.h" +#include "plugin/data/interfaces/interface/linked_list.h" +#include "plugin/types.h" + +int interfaces_add_address_ipv4(interfaces_interface_ipv4_address_element_t **address, char *ip, char *netmask); + +int interfaces_add_neighbor_ipv4(interfaces_interface_ipv4_neighbor_element_t** neighbor, char *dst_addr, char *ll_addr); + +unsigned int interfaces_get_ipv4_mtu(struct rtnl_link* link, interfaces_interface_t* interface); + +unsigned int interfaces_get_ipv4_enabled(interfaces_interface_t* interface); + +unsigned int interfaces_get_ipv4_forwarding(interfaces_interface_t* interface); + + +#endif /* INTERFACES_PLUGIN_API_INTERFACES_IPV4_LOAD_H */ + diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.c new file mode 100644 index 00000000..afa854b3 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.c @@ -0,0 +1,75 @@ +#include "load.h" + +int interfaces_add_address_ipv6(interfaces_interface_ipv6_address_element_t **address, char *ip, char *netmask) +{ + int error = 0; + uint8_t prefix_length = 0; + + interfaces_interface_ipv6_address_element_t* new_element = NULL; + + new_element = interfaces_interface_ipv6_address_element_new(); + + interfaces_interface_ipv6_address_element_set_ip(&new_element, ip); + SRPC_SAFE_CALL(interfaces_interface_ipv4_address_netmask2prefix(netmask, prefix_length), out); + interfaces_interface_ipv6_address_element_set_prefix_length(&new_element, prefix_length); + interfaces_interface_ipv6_address_add_element(address, new_element); + +out: + return error; +} + +int interfaces_add_neighbor_ipv6(interfaces_interface_ipv6_neighbor_element_t** neighbor, char *dst_addr, char *ll_addr) +{ + interfaces_interface_ipv6_neighbor_element_t* new_element = NULL; + + new_element = interfaces_interface_ipv6_neighbor_element_new(); + + interfaces_interface_ipv6_neighbor_element_set_ip(&new_element, dst_addr); + interfaces_interface_ipv6_neighbor_element_set_link_layer_address(&new_element, ll_addr); + interfaces_interface_ipv6_neighbor_add_element(neighbor, new_element); + + return 0; +} + +unsigned int interfaces_get_ipv6_mtu(struct rtnl_link* link, interfaces_interface_t* interface) +{ + unsigned int mtu = 0; + + mtu = rtnl_link_get_mtu(link); + + interface->ipv6.mtu = mtu; + + return 0; + +} + +unsigned int interfaces_get_ipv6_enabled(interfaces_interface_t* interface) +{ + int error = 0; + int enabled = 0; + + const char *ipv6_base = "/proc/sys/net/ipv6/conf"; + + SRPC_SAFE_CALL(read_from_proc_file(ipv6_base, interface->name, "disable_ipv6", &enabled), out); + + interface->ipv6.enabled = enabled; + +out: + return error; +} + +unsigned int interfaces_get_ipv6_forwarding(interfaces_interface_t* interface) +{ + int error = 0; + int forwarding = 0; + + const char *ipv6_base = "/proc/sys/net/ipv6/conf"; + + SRPC_SAFE_CALL(read_from_proc_file(ipv6_base, interface->name, "forwarding", &forwarding), out); + + interface->ipv6.forwarding = forwarding; + +out: + return error; +} + diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.h b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.h new file mode 100644 index 00000000..80a9daa4 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.h @@ -0,0 +1,20 @@ +#ifndef INTERFACES_PLUGIN_API_INTERFACES_IPV6_LOAD_H +#define INTERFACES_PLUGIN_API_INTERFACES_IPV6_LOAD_H + +#include "plugin/context.h" +#include "plugin/data/interfaces/interface.h" +#include "plugin/data/interfaces/interface/linked_list.h" +#include "plugin/types.h" + +int interfaces_add_address_ipv6(interfaces_interface_ipv6_address_element_t **address, char *ip, char *netmask); + +int interfaces_add_neighbor_ipv6(interfaces_interface_ipv6_neighbor_element_t** neighbor, char *dst_addr, char *ll_addr); + +unsigned int interfaces_get_ipv6_mtu(struct rtnl_link* link, interfaces_interface_t* interface); + +unsigned int interfaces_get_ipv6_enabled(interfaces_interface_t* interface); + +unsigned int interfaces_get_ipv6_forwarding(interfaces_interface_t* interface); + +#endif /* INTERFACES_PLUGIN_API_INTERFACES_IPV6_LOAD_H */ + diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index 6f917421..1a92d996 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -1,6 +1,8 @@ #include "load.h" #include "read.h" #include "plugin/common.h" +#include "interface/ipv4/load.h" +#include "interface/ipv6/load.h" #include "utils/memory.h" #include "utlist.h" @@ -31,39 +33,6 @@ enum interfaces_load_exit_status { interfaces_load_continue = 1, }; -static int interfaces_add_address_ipv4(interfaces_interface_ipv4_address_element_t **address, char *ip, char *netmask) -{ - int prefix_length = 0; - int error = 0; - - interfaces_interface_ipv4_address_element_t* new_element = NULL; - - new_element = interfaces_interface_ipv4_address_element_new(); - - interfaces_interface_ipv4_address_element_set_ip(&new_element, ip); - SRPC_SAFE_CALL(interfaces_interface_ipv4_address_netmask2prefix(netmask, prefix_length), out); - interfaces_interface_ipv4_address_element_set_subnet(&new_element, netmask, interfaces_interface_ipv4_address_subnet_prefix_length); - interfaces_interface_ipv4_address_add_element(address, new_element); - -out: - return error; -} - -static int interfaces_add_address_ipv6(interfaces_interface_ipv6_address_element_t **address, char *ip, char *netmask) -{ - int prefix_length = 0; - - interfaces_interface_ipv6_address_element_t* new_element = NULL; - - new_element = interfaces_interface_ipv6_address_element_new(); - - interfaces_interface_ipv6_address_element_set_ip(&new_element, ip); - prefix_length = interfaces_interface_netmask_to_prefix_length(netmask); - interfaces_interface_ipv6_address_element_set_prefix_length(&new_element, prefix_length); - interfaces_interface_ipv6_address_add_element(address, new_element); - -} - static int interfaces_add_ips(interfaces_interface_t* interface, char *ip, int netmask, int addr_family) { switch (addr_family) { @@ -172,32 +141,6 @@ static int interfaces_get_interface_ips(struct nl_sock* socket, struct rtnl_link return interfaces_load_success; } -static int interfaces_add_neighbor_ipv4(interfaces_interface_ipv4_neighbor_element_t** neighbor, char *dst_addr, char *ll_addr) -{ - interfaces_interface_ipv4_neighbor_element_t* new_element = NULL; - - new_element = interfaces_interface_ipv4_neighbor_element_new(); - - interfaces_interface_ipv4_neighbor_element_set_ip(&new_element, dst_addr); - interfaces_interface_ipv4_neighbor_element_set_link_layer_address(&new_element, ll_addr); - interfaces_interface_ipv4_neighbor_add_element(neighbor, new_element); - - return 0; -} - -static int interfaces_add_neighbor_ipv6(interfaces_interface_ipv6_neighbor_element_t** neighbor, char *dst_addr, char *ll_addr) -{ - interfaces_interface_ipv6_neighbor_element_t* new_element = NULL; - - new_element = interfaces_interface_ipv6_neighbor_element_new(); - - interfaces_interface_ipv6_neighbor_element_set_ip(&new_element, dst_addr); - interfaces_interface_ipv6_neighbor_element_set_link_layer_address(&new_element, ll_addr); - interfaces_interface_ipv6_neighbor_add_element(neighbor, new_element); - - return 0; -} - static int interfaces_add_neighbor(interfaces_interface_t* interface, char *dst_addr, char *ll_addr, int addr_family) { switch (addr_family) { @@ -299,29 +242,6 @@ static int interfaces_get_interface_ip_neighbors(struct nl_sock* socket, struct return interfaces_load_success; } -static unsigned int interfaces_get_ipv4_mtu(struct rtnl_link* link, interfaces_interface_t* interface) -{ - unsigned int mtu = 0; - - mtu = rtnl_link_get_mtu(link); - - interface->ipv4.mtu = mtu; - - return 0; -} - -static unsigned int interfaces_get_ipv6_mtu(struct rtnl_link* link, interfaces_interface_t* interface) -{ - unsigned int mtu = 0; - - mtu = rtnl_link_get_mtu(link); - - interface->ipv6.mtu = mtu; - - return 0; - -} - static unsigned int interfaces_get_interface_ip_mtu(struct rtnl_link* link, interfaces_interface_t* interface) { interfaces_get_ipv4_mtu(link, interface); @@ -329,30 +249,6 @@ static unsigned int interfaces_get_interface_ip_mtu(struct rtnl_link* link, inte interfaces_get_ipv6_mtu(link, interface); } -static unsigned int interfaces_get_ipv4_enabled(interfaces_interface_t* interface) -{ - const char *ipv4_base = "/proc/sys/net/ipv4/conf"; - - /* TODO: figure out how to enable/disable ipv4 */ - /* since disable_ipv4 doesn't exist in /proc/sys/net/ipv6/conf/interface_name */ - -} - -static unsigned int interfaces_get_ipv6_enabled(interfaces_interface_t* interface) -{ - int error = 0; - int enabled = 0; - - const char *ipv6_base = "/proc/sys/net/ipv6/conf"; - - SRPC_SAFE_CALL(read_from_proc_file(ipv6_base, interface->name, "disable_ipv6", &enabled), out); - - interface->ipv6.enabled = enabled; - -out: - return error; -} - static unsigned int interfaces_get_interface_ip_enabled(interfaces_interface_t* interface) { interfaces_get_ipv4_enabled(interface); @@ -360,37 +256,6 @@ static unsigned int interfaces_get_interface_ip_enabled(interfaces_interface_t* interfaces_get_ipv6_enabled(interface); } -static unsigned int interfaces_get_ipv4_forwarding(interfaces_interface_t* interface) -{ - int error = 0; - int forwarding = 0; - - const char *ipv4_base = "/proc/sys/net/ipv4/conf"; - - SRPC_SAFE_CALL(read_from_proc_file(ipv4_base, interface->name, "forwarding", &forwarding), out); - - interface->ipv4.forwarding = forwarding; - -out: - return error; -} - -static unsigned int interfaces_get_ipv6_forwarding(interfaces_interface_t* interface) -{ - int error = 0; - int forwarding = 0; - - const char *ipv6_base = "/proc/sys/net/ipv6/conf"; - - SRPC_SAFE_CALL(read_from_proc_file(ipv6_base, interface->name, "forwarding", &forwarding), out); - - interface->ipv6.forwarding = forwarding; - -out: - return error; -} - - static unsigned int interfaces_get_interface_ip_forwarding(interfaces_interface_t* interface) { interfaces_get_ipv4_forwarding(interface); diff --git a/src/interfaces/src/plugin/api/interfaces/load.h b/src/interfaces/src/plugin/api/interfaces/load.h index 158f3874..ad6f009c 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.h +++ b/src/interfaces/src/plugin/api/interfaces/load.h @@ -1,10 +1,7 @@ #ifndef INTERFACES_PLUGIN_API_INTERFACES_LOAD_H #define INTERFACES_PLUGIN_API_INTERFACES_LOAD_H -#include "plugin/context.h" -#include "plugin/data/interfaces/interface.h" -#include "plugin/data/interfaces/interface/linked_list.h" +#include "plugin/common.h" -int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** if_hash); #endif // INTERFACES_PLUGIN_API_INTERFACES_LOAD_H From 5ea8bb38fe763f002dd0392e059b24d5c276ee40 Mon Sep 17 00:00:00 2001 From: andrej Date: Mon, 17 Oct 2022 19:30:45 +0200 Subject: [PATCH 205/247] interfaces-plugin: add split ipv4/6 load to cmake sources --- src/interfaces/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/interfaces/CMakeLists.txt b/src/interfaces/CMakeLists.txt index 89a64b82..349b4fd1 100644 --- a/src/interfaces/CMakeLists.txt +++ b/src/interfaces/CMakeLists.txt @@ -33,11 +33,13 @@ set( src/plugin/api/interfaces/store.c src/plugin/api/interfaces/change.c src/plugin/api/interfaces/interface/change.c + src/plugin/api/interfaces/interface/ipv6/load.c src/plugin/api/interfaces/interface/ipv6/change.c src/plugin/api/interfaces/interface/ipv6/autoconf/change.c src/plugin/api/interfaces/interface/ipv6/neighbor/change.c src/plugin/api/interfaces/interface/ipv6/address/change.c src/plugin/api/interfaces/interface/ipv4/change.c + src/plugin/api/interfaces/interface/ipv4/load.c src/plugin/api/interfaces/interface/ipv4/neighbor/change.c src/plugin/api/interfaces/interface/ipv4/address/change.c src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/second-tag/change.c From 785c820b5a169b2278bc98dc1a06dec4681a0234 Mon Sep 17 00:00:00 2001 From: andrej Date: Tue, 18 Oct 2022 17:12:51 +0200 Subject: [PATCH 206/247] interfaces-plugin: add deepcopy for ipv4/6 address, neighbor --- .../src/plugin/api/interfaces/load.c | 9 ++++++-- .../data/interfaces/interface/ipv4/address.c | 23 ++++++++++++++++++- .../data/interfaces/interface/ipv4/address.h | 3 ++- .../data/interfaces/interface/ipv4/neighbor.c | 19 +++++++++++++++ .../data/interfaces/interface/ipv4/neighbor.h | 3 ++- .../data/interfaces/interface/ipv6/address.c | 20 ++++++++++++++++ .../data/interfaces/interface/ipv6/address.h | 3 ++- .../data/interfaces/interface/ipv6/neighbor.c | 19 +++++++++++++++ .../data/interfaces/interface/ipv6/neighbor.h | 3 ++- 9 files changed, 95 insertions(+), 7 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index 1a92d996..35c7b2cb 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -465,12 +465,17 @@ static int interfaces_add_link(interfaces_interface_hash_element_t** if_hash, in interfaces_interface_hash_element_set_enabled(&new_if_hash_elem, interface->enabled); - interfaces_interface_hash_element_set_ipv4(&new_if_hash_elem, interface->ipv4); + //interfaces_interface_hash_element_set_ipv4(&new_if_hash_elem, interface->ipv4); + interfaces_interface_ipv4_address_element_set(&interface->ipv4.address, &new_if_hash_elem->interface.ipv4.address); + interfaces_interface_ipv4_neighbor_element_set(&interface->ipv4.neighbor, &new_if_hash_elem->interface.ipv4.neighbor); + interfaces_interface_hash_element_set_ipv4_mtu(&new_if_hash_elem, interface->ipv4.mtu); interfaces_interface_hash_element_set_ipv4_enabled(&new_if_hash_elem, interface->ipv4.enabled); interfaces_interface_hash_element_set_ipv4_forwarding(&new_if_hash_elem, interface->ipv4.forwarding); - interfaces_interface_hash_element_set_ipv6(&new_if_hash_elem, interface->ipv6); + //interfaces_interface_hash_element_set_ipv6(&new_if_hash_elem, interface->ipv6); + interfaces_interface_ipv6_address_element_set(&interface->ipv6.address, &new_if_hash_elem->interface.ipv6.address); + interfaces_interface_ipv6_neighbor_element_set(&interface->ipv6.neighbor, &new_if_hash_elem->interface.ipv6.neighbor); interfaces_interface_hash_element_set_ipv6_mtu(&new_if_hash_elem, interface->ipv6.mtu); interfaces_interface_hash_element_set_ipv6_enabled(&new_if_hash_elem, interface->ipv6.enabled); interfaces_interface_hash_element_set_ipv6_forwarding(&new_if_hash_elem, interface->ipv6.forwarding); diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c index e6624c18..79e23c84 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c @@ -81,6 +81,25 @@ int interfaces_interface_ipv4_address_element_set_ip(interfaces_interface_ipv4_a return 0; } +/* set (deepcopy) an IPv4 address list */ +int interfaces_interface_ipv4_address_element_set(interfaces_interface_ipv4_address_element_t** src, + interfaces_interface_ipv4_address_element_t **dst) +{ + interfaces_interface_ipv4_address_element_t *src_iter = NULL; + interfaces_interface_ipv4_address_element_t *new_elem = NULL; + + LL_FOREACH(*src, src_iter) { + new_elem = interfaces_interface_ipv4_address_element_new(); + interfaces_interface_ipv4_address_element_set_ip(&new_elem, src_iter->address.ip); + interfaces_interface_ipv4_address_element_set_prefix_length(&new_elem, + src_iter->address.subnet.prefix_length); + + interfaces_interface_ipv4_address_add_element(dst, new_elem); + } + + return 0; +} + int interfaces_interface_ipv4_address_element_set_subnet(interfaces_interface_ipv4_address_element_t** el, char *netmask, enum interfaces_interface_ipv4_address_subnet subtype) { int error = 0; @@ -91,7 +110,7 @@ int interfaces_interface_ipv4_address_element_set_subnet(interfaces_interface_ip interfaces_interface_ipv4_address_element_set_netmask(el, netmask); break; case interfaces_interface_ipv4_address_subnet_prefix_length: - prefix_length = interfaces_interface_netmask_to_prefix_length(netmask); + SRPC_SAFE_CALL(interfaces_interface_ipv4_address_netmask2prefix(netmask, prefix_length), out); interfaces_interface_ipv4_address_element_set_prefix_length(el, prefix_length); break; case interfaces_interface_ipv4_address_subnet_none: @@ -100,6 +119,8 @@ int interfaces_interface_ipv4_address_element_set_subnet(interfaces_interface_ip error = -1; } +out: + return error; } diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.h b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.h index fa5c3e5d..fc80b240 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.h +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.h @@ -23,6 +23,7 @@ void interfaces_interface_ipv4_address_element_free(interfaces_interface_ipv4_ad int interfaces_interface_ipv4_address_element_set_ip(interfaces_interface_ipv4_address_element_t** el, const char* ip); int interfaces_interface_ipv4_address_element_set_prefix_length(interfaces_interface_ipv4_address_element_t** el, uint8_t prefix_length); int interfaces_interface_ipv4_address_element_set_netmask(interfaces_interface_ipv4_address_element_t** el, const char* netmask); +int interfaces_interface_ipv4_address_element_set(interfaces_interface_ipv4_address_element_t** src, interfaces_interface_ipv4_address_element_t **dst); /* Helper functions @@ -30,4 +31,4 @@ int interfaces_interface_ipv4_address_element_set_netmask(interfaces_interface_i int interfaces_interface_ipv4_address_netmask2prefix(const char* netmask, uint8_t* prefix_length); -#endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV4_ADDRESS_H \ No newline at end of file +#endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV4_ADDRESS_H diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/neighbor.c b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/neighbor.c index 3522207e..0d251b9c 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/neighbor.c +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/neighbor.c @@ -53,6 +53,25 @@ void interfaces_interface_ipv4_neighbor_element_free(interfaces_interface_ipv4_n } } +/* set (deepcopy) an IPv4 neighbor list */ +int interfaces_interface_ipv4_neighbor_element_set(interfaces_interface_ipv4_neighbor_element_t** src, + interfaces_interface_ipv4_neighbor_element_t **dst) +{ + interfaces_interface_ipv4_neighbor_element_t *src_iter = NULL; + interfaces_interface_ipv4_neighbor_element_t *new_elem = NULL; + + LL_FOREACH(*src, src_iter) { + new_elem = interfaces_interface_ipv4_neighbor_element_new(); + interfaces_interface_ipv4_neighbor_element_set_ip(&new_elem, src_iter->neighbor.ip); + interfaces_interface_ipv4_neighbor_element_set_link_layer_address(&new_elem, + src_iter->neighbor.link_layer_address); + + interfaces_interface_ipv4_neighbor_add_element(dst, new_elem); + } + + return 0; +} + int interfaces_interface_ipv4_neighbor_element_set_ip(interfaces_interface_ipv4_neighbor_element_t** el, const char* ip) { if ((*el)->neighbor.ip) { diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/neighbor.h b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/neighbor.h index 17c5045e..1616958f 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/neighbor.h +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/neighbor.h @@ -22,5 +22,6 @@ interfaces_interface_ipv4_neighbor_element_t* interfaces_interface_ipv4_neighbor void interfaces_interface_ipv4_neighbor_element_free(interfaces_interface_ipv4_neighbor_element_t** el); int interfaces_interface_ipv4_neighbor_element_set_ip(interfaces_interface_ipv4_neighbor_element_t** el, const char* ip); int interfaces_interface_ipv4_neighbor_element_set_link_layer_address(interfaces_interface_ipv4_neighbor_element_t** el, const char* link_layer_address); +int interfaces_interface_ipv4_neighbor_element_set(interfaces_interface_ipv4_neighbor_element_t** src, interfaces_interface_ipv4_neighbor_element_t **dst); -#endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV4_NEIGHBOR_H \ No newline at end of file +#endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV4_NEIGHBOR_H diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv6/address.c b/src/interfaces/src/plugin/data/interfaces/interface/ipv6/address.c index 956d586e..d7dc4a97 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/ipv6/address.c +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv6/address.c @@ -38,6 +38,26 @@ interfaces_interface_ipv6_address_element_t* interfaces_interface_ipv6_address_e return new_element; } +int interfaces_interface_ipv6_address_element_set(interfaces_interface_ipv6_address_element_t** src, + interfaces_interface_ipv6_address_element_t **dst) +{ + interfaces_interface_ipv6_address_element_t *src_iter = NULL; + interfaces_interface_ipv6_address_element_t *new_elem = NULL; + + LL_FOREACH(*src, src_iter) { + new_elem = interfaces_interface_ipv6_address_element_new(); + interfaces_interface_ipv6_address_element_set_ip(&new_elem, src_iter->address.ip); + interfaces_interface_ipv6_address_element_set_prefix_length(&new_elem, + src_iter->address.prefix_length); + + interfaces_interface_ipv6_address_add_element(dst, new_elem); + } + + return 0; + +} + + void interfaces_interface_ipv6_address_element_free(interfaces_interface_ipv6_address_element_t** el) { if (*el) { diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv6/address.h b/src/interfaces/src/plugin/data/interfaces/interface/ipv6/address.h index 7e38aa08..13761fb0 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/ipv6/address.h +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv6/address.h @@ -22,5 +22,6 @@ interfaces_interface_ipv6_address_element_t* interfaces_interface_ipv6_address_e void interfaces_interface_ipv6_address_element_free(interfaces_interface_ipv6_address_element_t** el); int interfaces_interface_ipv6_address_element_set_ip(interfaces_interface_ipv6_address_element_t** el, const char* ip); int interfaces_interface_ipv6_address_element_set_prefix_length(interfaces_interface_ipv6_address_element_t** el, uint8_t prefix_length); +int interfaces_interface_ipv6_address_element_set(interfaces_interface_ipv6_address_element_t** src, interfaces_interface_ipv6_address_element_t **dst); -#endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV6_ADDRESS_H \ No newline at end of file +#endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV6_ADDRESS_H diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv6/neighbor.c b/src/interfaces/src/plugin/data/interfaces/interface/ipv6/neighbor.c index 0b672390..a702abe4 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/ipv6/neighbor.c +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv6/neighbor.c @@ -80,3 +80,22 @@ int interfaces_interface_ipv6_neighbor_element_set_link_layer_address(interfaces return 0; } + +/* set (deepcopy) an ipv6 neighbor list */ +int interfaces_interface_ipv6_neighbor_element_set(interfaces_interface_ipv6_neighbor_element_t** src, + interfaces_interface_ipv6_neighbor_element_t **dst) +{ + interfaces_interface_ipv6_neighbor_element_t *src_iter = NULL; + interfaces_interface_ipv6_neighbor_element_t *new_elem = NULL; + + LL_FOREACH(*src, src_iter) { + new_elem = interfaces_interface_ipv6_neighbor_element_new(); + interfaces_interface_ipv6_neighbor_element_set_ip(&new_elem, src_iter->neighbor.ip); + interfaces_interface_ipv6_neighbor_element_set_link_layer_address(&new_elem, + src_iter->neighbor.link_layer_address); + + interfaces_interface_ipv6_neighbor_add_element(dst, new_elem); + } + + return 0; +} diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv6/neighbor.h b/src/interfaces/src/plugin/data/interfaces/interface/ipv6/neighbor.h index 012aba1b..467e8012 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/ipv6/neighbor.h +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv6/neighbor.h @@ -22,5 +22,6 @@ interfaces_interface_ipv6_neighbor_element_t* interfaces_interface_ipv6_neighbor void interfaces_interface_ipv6_neighbor_element_free(interfaces_interface_ipv6_neighbor_element_t** el); int interfaces_interface_ipv6_neighbor_element_set_ip(interfaces_interface_ipv6_neighbor_element_t** el, const char* ip); int interfaces_interface_ipv6_neighbor_element_set_link_layer_address(interfaces_interface_ipv6_neighbor_element_t** el, const char* link_layer_address); +int interfaces_interface_ipv6_neighbor_element_set(interfaces_interface_ipv6_neighbor_element_t** src, interfaces_interface_ipv6_neighbor_element_t **dst); -#endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV6_NEIGHBOR_H \ No newline at end of file +#endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV6_NEIGHBOR_H From 1f7d12d06bf29beaad84ca90418c02ad46ea4e21 Mon Sep 17 00:00:00 2001 From: andrej Date: Wed, 19 Oct 2022 09:26:40 +0200 Subject: [PATCH 207/247] interfaces-plugin: add removed header interface --- src/interfaces/src/plugin/api/interfaces/load.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/interfaces/src/plugin/api/interfaces/load.h b/src/interfaces/src/plugin/api/interfaces/load.h index ad6f009c..7d274578 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.h +++ b/src/interfaces/src/plugin/api/interfaces/load.h @@ -3,5 +3,6 @@ #include "plugin/common.h" +int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** if_hash); #endif // INTERFACES_PLUGIN_API_INTERFACES_LOAD_H From 073ecc43e4a352c0ccdf32c80b9e249550f69ef0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jurica=20Kule=C5=A1?= Date: Tue, 25 Oct 2022 13:56:30 +0200 Subject: [PATCH 208/247] sysrepo-plugin-interfaces: implement interface store API --- .../src/plugin/api/interfaces/store.c | 136 +++++++++++++++++- 1 file changed, 129 insertions(+), 7 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/store.c b/src/interfaces/src/plugin/api/interfaces/store.c index f27652de..8890653a 100644 --- a/src/interfaces/src/plugin/api/interfaces/store.c +++ b/src/interfaces/src/plugin/api/interfaces/store.c @@ -1,39 +1,160 @@ #include "store.h" +#include "netlink/addr.h" +#include "netlink/cache.h" +#include "netlink/object.h" +#include "netlink/route/addr.h" +#include "netlink/socket.h" +#include "plugin/data/interfaces/interface/ipv4/address.h" +#include "srpc/common.h" #include "utlist.h" #include "uthash.h" -#include "types.h" +#include "plugin/types.h" #include -#include "sysrepo/xpath.h" #include "plugin/common.h" #include "plugin/context.h" #include +#include "sysrepo/xpath.h" #include "netlink/errno.h" #include "netlink/route/link.h" +#include "/usr/include/linux/if.h" int interfaces_store_interface(interfaces_ctx_t* ctx, const interfaces_interface_hash_element_t* if_hash) { int error = 0; - interfaces_interface_hash_element_t *i = NULL, *tmp = NULL; + uint8_t if_status, prefix_length; + uint32_t mtu; + char *if_type = NULL; + char *if_type_libnl = NULL; + const interfaces_interface_hash_element_t *i = NULL, *tmp = NULL; struct nl_sock *sk = NULL; + struct nl_addr* local_addr = NULL; + struct nl_cache* link_cache = NULL; struct rtnl_link* new_link = NULL; + struct rtnl_addr *link_ipv4_addr = NULL; + struct rtnl_addr *link_ipv6_addr = NULL; // setup nl socket - SRPC_SAFE_CALL_PTR(sk, nl_socket_alloc(), error_out); // connect SRPC_SAFE_CALL_ERR(error, nl_connect(sk, NETLINK_ROUTE), error_out); + // allocate link cache + SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache), error_out); + HASH_ITER (hh, if_hash, i, tmp) { + if_type = i->interface.type; + if_status = i->interface.enabled; + mtu = i->interface.ipv4.mtu < i->interface.ipv6.mtu ? i->interface.ipv4.mtu : i->interface.ipv6.mtu; + // create a new link SRPC_SAFE_CALL_PTR(new_link, rtnl_link_alloc(), error_out); + + //determine link type + if (strcmp(if_type, "iana-if-type:ethernetCsmacd") == 0) { + if_type_libnl = "veth"; + // !! ADS 2 INTERFACES (one without ip addresses) + } else if (strcmp(if_type, "iana-if-type:softwareLoopback") == 0) { + if_type_libnl = "vcan"; + //!! vcan INSTEAD OF lo + } else if (strcmp(if_type, "iana-if-type:l2vlan") == 0) { + if_type_libnl = "vlan"; + //!! doesn't work + } else if (strcmp(if_type, "iana-if-type:other") == 0) { + if_type_libnl = "dummy"; + } + + // set link type + SRPC_SAFE_CALL_ERR(error, rtnl_link_set_type(new_link, if_type_libnl), error_out); - // setup link and add it to the system + // setup link name rtnl_link_set_name(new_link, i->interface.name); - SRPC_SAFE_CALL_ERR(error, rtnl_link_set_type(new_link, i->interface.type), error_out); + + // initialize desired link status + if (if_status) { + rtnl_link_set_flags(new_link, IFF_UP); + } else { + rtnl_link_unset_flags(new_link, IFF_UP); + } + rtnl_link_set_operstate(new_link, if_status ? IF_OPER_UP : IF_OPER_DOWN); + + // set MTU + if (mtu) { + rtnl_link_set_mtu(new_link, mtu); + } + + // add link SRPC_SAFE_CALL_ERR(error, rtnl_link_add(sk, new_link, NLM_F_CREATE), error_out); + // update link cache + SRPC_SAFE_CALL_ERR(error, nl_cache_refill(sk, link_cache), error_out); + + // get updated new_link + SRPC_SAFE_CALL_PTR(new_link, rtnl_link_get_by_name(link_cache, i->interface.name), error_out); + + for(interfaces_interface_ipv4_address_element_t *addr_ptr = i->interface.ipv4.address; addr_ptr != NULL; addr_ptr = addr_ptr->next) { + link_ipv4_addr = rtnl_addr_alloc(); + + //parse local ipv4 address + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(addr_ptr->address.ip, AF_INET, &local_addr), error_out); + + // get ipv4 prefix length by using prefix-length or netmask + switch (addr_ptr->address.subnet_type) { + case interfaces_interface_ipv4_address_subnet_none: + SRPLG_LOG_ERR(PLUGIN_NAME, "Unable to get prefix-length/netmask for address %s", addr_ptr->address.ip); + break; + case interfaces_interface_ipv4_address_subnet_prefix_length: + prefix_length = addr_ptr->address.subnet.prefix_length; + break; + case interfaces_interface_ipv4_address_subnet_netmask: + interfaces_interface_ipv4_address_netmask2prefix(addr_ptr->address.subnet.netmask, &prefix_length); + break; + default: + SRPLG_LOG_ERR(PLUGIN_NAME, "Unable to get prefix-length/netmask for address %s", addr_ptr->address.ip); + } + + // set ipv4 prefix length + nl_addr_set_prefixlen(local_addr, prefix_length); + + //set to route address + SRPC_SAFE_CALL_ERR(error, rtnl_addr_set_local(link_ipv4_addr, local_addr), error_out); + + // set interface + rtnl_addr_set_ifindex(link_ipv4_addr, rtnl_link_get_ifindex(new_link)); + + // add ipv4 address + SRPC_SAFE_CALL_ERR(error, rtnl_addr_add(sk, link_ipv4_addr, 0), error_out); + + nl_addr_put(local_addr); + rtnl_addr_put(link_ipv4_addr); + } + + + for(interfaces_interface_ipv6_address_element_t *addr_ptr = i->interface.ipv6.address; addr_ptr != NULL; addr_ptr = addr_ptr->next) { + link_ipv6_addr = rtnl_addr_alloc(); + + // parse local ipv6 address + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(addr_ptr->address.ip, AF_INET6, &local_addr), error_out); + + // set ipv6 prefix length + nl_addr_set_prefixlen(local_addr, addr_ptr->address.prefix_length); + + //set to route address + SRPC_SAFE_CALL_ERR(error, rtnl_addr_set_local(link_ipv6_addr, local_addr), error_out); + + // set interface + rtnl_addr_set_ifindex(link_ipv6_addr, rtnl_link_get_ifindex(new_link)); + + //add ipv6 address + SRPC_SAFE_CALL_ERR(error, rtnl_addr_add(sk, link_ipv6_addr, 0), error_out); + + nl_addr_put(local_addr); + rtnl_addr_put(link_ipv6_addr); + } + } + + goto out; error_out: if (error < 0) { @@ -41,6 +162,7 @@ int interfaces_store_interface(interfaces_ctx_t* ctx, const interfaces_interface } error = -1; -error: +out: + nl_socket_free(sk); return error; } From 4996e6a9a445349865569498f57f10d4c9c702e1 Mon Sep 17 00:00:00 2001 From: andrej Date: Wed, 26 Oct 2022 15:51:56 +0200 Subject: [PATCH 209/247] interfaces-plugin: switch to SRP_SAFE_CALL_ERR --- .../api/interfaces/interface/ipv4/load.c | 4 ++-- .../api/interfaces/interface/ipv6/load.c | 6 ++--- .../src/plugin/api/interfaces/load.c | 24 +++++++++---------- .../src/plugin/api/interfaces/load.h | 3 +++ .../data/interfaces/interface/ipv4/address.c | 2 +- src/interfaces/src/plugin/startup/load.c | 1 + 6 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c index 23f9d527..e5c72b87 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c @@ -11,7 +11,7 @@ int interfaces_add_address_ipv4(interfaces_interface_ipv4_address_element_t **ad new_element = interfaces_interface_ipv4_address_element_new(); interfaces_interface_ipv4_address_element_set_ip(&new_element, ip); - SRPC_SAFE_CALL(interfaces_interface_ipv4_address_netmask2prefix(netmask, prefix_length), out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_address_netmask2prefix(netmask, prefix_length), out); interfaces_interface_ipv4_address_element_set_subnet(&new_element, netmask, interfaces_interface_ipv4_address_subnet_prefix_length); interfaces_interface_ipv4_address_add_element(address, new_element); @@ -59,7 +59,7 @@ unsigned int interfaces_get_ipv4_forwarding(interfaces_interface_t* interface) const char *ipv4_base = "/proc/sys/net/ipv4/conf"; - SRPC_SAFE_CALL(read_from_proc_file(ipv4_base, interface->name, "forwarding", &forwarding), out); + SRPC_SAFE_CALL_ERR(error, read_from_proc_file(ipv4_base, interface->name, "forwarding", &forwarding), out); interface->ipv4.forwarding = forwarding; diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.c index afa854b3..edc995ee 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.c @@ -10,7 +10,7 @@ int interfaces_add_address_ipv6(interfaces_interface_ipv6_address_element_t **ad new_element = interfaces_interface_ipv6_address_element_new(); interfaces_interface_ipv6_address_element_set_ip(&new_element, ip); - SRPC_SAFE_CALL(interfaces_interface_ipv4_address_netmask2prefix(netmask, prefix_length), out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_address_netmask2prefix(netmask, prefix_length), out); interfaces_interface_ipv6_address_element_set_prefix_length(&new_element, prefix_length); interfaces_interface_ipv6_address_add_element(address, new_element); @@ -50,7 +50,7 @@ unsigned int interfaces_get_ipv6_enabled(interfaces_interface_t* interface) const char *ipv6_base = "/proc/sys/net/ipv6/conf"; - SRPC_SAFE_CALL(read_from_proc_file(ipv6_base, interface->name, "disable_ipv6", &enabled), out); + SRPC_SAFE_CALL_ERR(error, read_from_proc_file(ipv6_base, interface->name, "disable_ipv6", &enabled), out); interface->ipv6.enabled = enabled; @@ -65,7 +65,7 @@ unsigned int interfaces_get_ipv6_forwarding(interfaces_interface_t* interface) const char *ipv6_base = "/proc/sys/net/ipv6/conf"; - SRPC_SAFE_CALL(read_from_proc_file(ipv6_base, interface->name, "forwarding", &forwarding), out); + SRPC_SAFE_CALL_ERR(error, read_from_proc_file(ipv6_base, interface->name, "forwarding", &forwarding), out); interface->ipv6.forwarding = forwarding; diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index 35c7b2cb..6ea1c820 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -71,7 +71,7 @@ static int interfaces_get_interface_ips(struct nl_sock* socket, struct rtnl_link if_index = rtnl_link_get_ifindex(link); - SRPC_SAFE_CALL(rtnl_neigh_alloc_cache(socket, &addr_cache), error_out); + SRPC_SAFE_CALL_ERR(error, rtnl_neigh_alloc_cache(socket, &addr_cache), error_out); /* get ipv4 and ipv6 addresses */ addr_count = nl_cache_nitems(addr_cache); @@ -181,7 +181,7 @@ static int interfaces_get_interface_ip_neighbors(struct nl_sock* socket, struct if_index = rtnl_link_get_ifindex(link); - SRPC_SAFE_CALL(rtnl_neigh_alloc_cache(socket, &neigh_cache), error_out); + SRPC_SAFE_CALL_ERR(error, rtnl_neigh_alloc_cache(socket, &neigh_cache), error_out); neigh_count = nl_cache_nitems(neigh_cache); @@ -219,7 +219,7 @@ static int interfaces_get_interface_ip_neighbors(struct nl_sock* socket, struct addr_family = rtnl_neigh_get_family(neigh); // switch based on address family, add to the neighbor linked list - SRPC_SAFE_CALL(interfaces_add_neighbor(interface, dst_addr, ll_addr_s, addr_family), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_add_neighbor(interface, dst_addr, ll_addr_s, addr_family), error_out); rtnl_neigh_put(neigh); } @@ -317,7 +317,7 @@ static char* interfaces_get_interface_type(struct rtnl_link* link, char* name) const char* path_to_sys = "/sys/class/net/"; int type_id = 0; - SRPC_SAFE_CALL(read_from_sys_file(path_to_sys, name, &type_id), error_out); + SRPC_SAFE_CALL_ERR(error, read_from_sys_file(path_to_sys, name, &type_id), error_out); switch (type_id) { case ARPHRD_ETHER: @@ -449,18 +449,18 @@ static int interfaces_add_link(interfaces_interface_hash_element_t** if_hash, in interfaces_interface_hash_element_t* new_if_hash_elem = interfaces_interface_hash_element_new(); interfaces_interface_hash_element_set_name(&new_if_hash_elem, interface->name); - SRPC_SAFE_CALL(interfaces_interface_hash_add_element(if_hash, new_if_hash_elem), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_add_element(if_hash, new_if_hash_elem), error_out); if (interface->description != NULL) { - SRPC_SAFE_CALL(interfaces_interface_hash_element_set_description(&new_if_hash_elem, interface->description), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_description(&new_if_hash_elem, interface->description), error_out); } if (interface->type != NULL) { - SRPC_SAFE_CALL(interfaces_interface_hash_element_set_type(&new_if_hash_elem, interface->type), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_type(&new_if_hash_elem, interface->type), error_out); } if (interface->parent_interface != NULL) { - SRPC_SAFE_CALL(interfaces_interface_hash_element_set_parent_interface(&new_if_hash_elem, interface->parent_interface), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_parent_interface(&new_if_hash_elem, interface->parent_interface), error_out); } interfaces_interface_hash_element_set_enabled(&new_if_hash_elem, interface->enabled); @@ -518,7 +518,7 @@ static int interfaces_interfaces_worker(interfaces_ctx_t* ctx, struct nl_sock* s error = interfaces_parse_link(ctx, socket, cache, link, &interface); switch (error) { case interfaces_load_success: - SRPC_SAFE_CALL(interfaces_add_link(if_hash, &interface), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_add_link(if_hash, &interface), error_out); break; case interfaces_load_continue: break; @@ -555,11 +555,11 @@ int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_e goto error_out; } - SRPC_SAFE_CALL(nl_connect(socket, NETLINK_ROUTE), error_out); + SRPC_SAFE_CALL_ERR(error, nl_connect(socket, NETLINK_ROUTE), error_out); - SRPC_SAFE_CALL(rtnl_link_alloc_cache(socket, AF_UNSPEC, &cache), error_out); + SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(socket, AF_UNSPEC, &cache), error_out); - SRPC_SAFE_CALL(interfaces_interfaces_worker(ctx, socket, cache, if_hash), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interfaces_worker(ctx, socket, cache, if_hash), error_out); goto out; error_out: diff --git a/src/interfaces/src/plugin/api/interfaces/load.h b/src/interfaces/src/plugin/api/interfaces/load.h index 7d274578..10bd3328 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.h +++ b/src/interfaces/src/plugin/api/interfaces/load.h @@ -2,6 +2,9 @@ #define INTERFACES_PLUGIN_API_INTERFACES_LOAD_H #include "plugin/common.h" +#include "plugin/context.h" +#include "plugin/data/interfaces/interface.h" +#include "plugin/data/interfaces/interface/linked_list.h" int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** if_hash); diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c index 79e23c84..39f1b508 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c @@ -110,7 +110,7 @@ int interfaces_interface_ipv4_address_element_set_subnet(interfaces_interface_ip interfaces_interface_ipv4_address_element_set_netmask(el, netmask); break; case interfaces_interface_ipv4_address_subnet_prefix_length: - SRPC_SAFE_CALL(interfaces_interface_ipv4_address_netmask2prefix(netmask, prefix_length), out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_address_netmask2prefix(netmask, prefix_length), out); interfaces_interface_ipv4_address_element_set_prefix_length(el, prefix_length); break; case interfaces_interface_ipv4_address_subnet_none: diff --git a/src/interfaces/src/plugin/startup/load.c b/src/interfaces/src/plugin/startup/load.c index 7f0255c1..39f96bc2 100644 --- a/src/interfaces/src/plugin/startup/load.c +++ b/src/interfaces/src/plugin/startup/load.c @@ -91,3 +91,4 @@ static int interfaces_startup_load_interface(void* priv, sr_session_ctx_t* sessi out: return error; } + From fdb7581add3426b5eb0f247eb1d69fa4cb6c31a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jurica=20Kule=C5=A1?= Date: Thu, 27 Oct 2022 00:46:29 +0200 Subject: [PATCH 210/247] sysrepo-plugin-interfaces: implement interface store API --- .../src/plugin/api/interfaces/store.c | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/store.c b/src/interfaces/src/plugin/api/interfaces/store.c index 8890653a..2bfceba1 100644 --- a/src/interfaces/src/plugin/api/interfaces/store.c +++ b/src/interfaces/src/plugin/api/interfaces/store.c @@ -5,6 +5,7 @@ #include "netlink/route/addr.h" #include "netlink/socket.h" #include "plugin/data/interfaces/interface/ipv4/address.h" +#include "src/utlist.h" #include "srpc/common.h" #include "utlist.h" #include "uthash.h" @@ -26,6 +27,8 @@ int interfaces_store_interface(interfaces_ctx_t* ctx, const interfaces_interface char *if_type = NULL; char *if_type_libnl = NULL; const interfaces_interface_hash_element_t *i = NULL, *tmp = NULL; + interfaces_interface_ipv4_address_element_t *ipv4_iter = NULL; + interfaces_interface_ipv6_address_element_t *ipv6_iter = NULL; struct nl_sock *sk = NULL; struct nl_addr* local_addr = NULL; struct nl_cache* link_cache = NULL; @@ -53,7 +56,7 @@ int interfaces_store_interface(interfaces_ctx_t* ctx, const interfaces_interface //determine link type if (strcmp(if_type, "iana-if-type:ethernetCsmacd") == 0) { if_type_libnl = "veth"; - // !! ADS 2 INTERFACES (one without ip addresses) + // !! ADDS 2 INTERFACES (one without ip addresses) } else if (strcmp(if_type, "iana-if-type:softwareLoopback") == 0) { if_type_libnl = "vcan"; //!! vcan INSTEAD OF lo @@ -92,25 +95,25 @@ int interfaces_store_interface(interfaces_ctx_t* ctx, const interfaces_interface // get updated new_link SRPC_SAFE_CALL_PTR(new_link, rtnl_link_get_by_name(link_cache, i->interface.name), error_out); - for(interfaces_interface_ipv4_address_element_t *addr_ptr = i->interface.ipv4.address; addr_ptr != NULL; addr_ptr = addr_ptr->next) { + LL_FOREACH (i->interface.ipv4.address, ipv4_iter) { link_ipv4_addr = rtnl_addr_alloc(); //parse local ipv4 address - SRPC_SAFE_CALL_ERR(error, nl_addr_parse(addr_ptr->address.ip, AF_INET, &local_addr), error_out); + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(ipv4_iter->address.ip, AF_INET, &local_addr), error_out); // get ipv4 prefix length by using prefix-length or netmask - switch (addr_ptr->address.subnet_type) { + switch (ipv4_iter->address.subnet_type) { case interfaces_interface_ipv4_address_subnet_none: - SRPLG_LOG_ERR(PLUGIN_NAME, "Unable to get prefix-length/netmask for address %s", addr_ptr->address.ip); + SRPLG_LOG_ERR(PLUGIN_NAME, "Unable to get prefix-length/netmask for address %s", ipv4_iter->address.ip); break; case interfaces_interface_ipv4_address_subnet_prefix_length: - prefix_length = addr_ptr->address.subnet.prefix_length; + prefix_length = ipv4_iter->address.subnet.prefix_length; break; case interfaces_interface_ipv4_address_subnet_netmask: - interfaces_interface_ipv4_address_netmask2prefix(addr_ptr->address.subnet.netmask, &prefix_length); + interfaces_interface_ipv4_address_netmask2prefix(ipv4_iter->address.subnet.netmask, &prefix_length); break; default: - SRPLG_LOG_ERR(PLUGIN_NAME, "Unable to get prefix-length/netmask for address %s", addr_ptr->address.ip); + SRPLG_LOG_ERR(PLUGIN_NAME, "Unable to get prefix-length/netmask for address %s", ipv4_iter->address.ip); } // set ipv4 prefix length @@ -130,14 +133,14 @@ int interfaces_store_interface(interfaces_ctx_t* ctx, const interfaces_interface } - for(interfaces_interface_ipv6_address_element_t *addr_ptr = i->interface.ipv6.address; addr_ptr != NULL; addr_ptr = addr_ptr->next) { + LL_FOREACH (i->interface.ipv6.address, ipv6_iter) { link_ipv6_addr = rtnl_addr_alloc(); // parse local ipv6 address - SRPC_SAFE_CALL_ERR(error, nl_addr_parse(addr_ptr->address.ip, AF_INET6, &local_addr), error_out); + SRPC_SAFE_CALL_ERR(error, nl_addr_parse(ipv6_iter->address.ip, AF_INET6, &local_addr), error_out); // set ipv6 prefix length - nl_addr_set_prefixlen(local_addr, addr_ptr->address.prefix_length); + nl_addr_set_prefixlen(local_addr, ipv6_iter->address.prefix_length); //set to route address SRPC_SAFE_CALL_ERR(error, rtnl_addr_set_local(link_ipv6_addr, local_addr), error_out); From dee97eb5272df11c6aa2bf31bf885240bdf3b816 Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Mon, 31 Oct 2022 11:18:10 +0000 Subject: [PATCH 211/247] interfaces-plugin: remove sr_copy_config() call from interface change subscription SR_EV_DONE event --- src/interfaces/src/plugin/subscription/change.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/interfaces/src/plugin/subscription/change.c b/src/interfaces/src/plugin/subscription/change.c index 5643f899..f3312256 100644 --- a/src/interfaces/src/plugin/subscription/change.c +++ b/src/interfaces/src/plugin/subscription/change.c @@ -26,9 +26,6 @@ int interfaces_subscription_change_interfaces_interface(sr_session_ctx_t* sessio if (event == SR_EV_ABORT) { SRPLG_LOG_ERR(PLUGIN_NAME, "Aborting changes for %s", xpath); goto error_out; - } else if (event == SR_EV_DONE) { - // when all changes processed - copy running DS contents to startup - SRPC_SAFE_CALL_ERR(error, sr_copy_config(ctx->startup_session, IETF_INTERFACES_YANG_MODULE, SR_DS_RUNNING, 0), error_out); } else if (event == SR_EV_CHANGE) { // name SRPC_SAFE_CALL_ERR_COND(rc, rc < 0, snprintf(change_xpath_buffer, sizeof(change_xpath_buffer), "%s/name", xpath), error_out); From 2a9fb2d34e6fdee3f19db8e53bc2f43eedcdee52 Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Mon, 31 Oct 2022 11:19:57 +0000 Subject: [PATCH 212/247] interfaces-plugin: remove sr_copy_config() call from plugin cleanup callback --- src/interfaces/src/plugin.c | 20 ++++++------------- .../api/interfaces/interface/ipv4/change.c | 2 +- .../src/plugin/api/interfaces/load.c | 18 ++++++++--------- 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index ce466628..d900a087 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -80,7 +80,7 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) }, { IETF_INTERFACES_YANG_MODULE, - //depends on if-mib feature + // depends on if-mib feature INTERFACES_INTERFACES_INTERFACE_IF_INDEX_YANG_PATH, srpc_feature_status_hash_check(ctx->features.ietf_interfaces_features, "if-mib") ? interfaces_subscription_operational_interfaces_interface_if_index : NULL, }, @@ -181,31 +181,31 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) }, { IETF_INTERFACES_YANG_MODULE, - //depends on carrier-delay feature + // depends on carrier-delay feature INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_CARRIER_TRANSITIONS_YANG_PATH, srpc_feature_status_hash_check(ctx->features.ietf_if_extensions_features, "carrier-delay") ? interfaces_subscription_operational_interfaces_interface_carrier_delay_carrier_transitions : NULL, }, { IETF_INTERFACES_YANG_MODULE, - //depends on carrier-delay feature + // depends on carrier-delay feature INTERFACES_INTERFACES_INTERFACE_CARRIER_DELAY_TIMER_RUNNING_YANG_PATH, srpc_feature_status_hash_check(ctx->features.ietf_if_extensions_features, "carrier-delay") ? interfaces_subscription_operational_interfaces_interface_carrier_delay_timer_running : NULL, }, { IETF_INTERFACES_YANG_MODULE, - //depends on dampening feature + // depends on dampening feature INTERFACES_INTERFACES_INTERFACE_DAMPENING_PENALTY_YANG_PATH, srpc_feature_status_hash_check(ctx->features.ietf_if_extensions_features, "dampening") ? interfaces_subscription_operational_interfaces_interface_dampening_penalty : NULL, }, { IETF_INTERFACES_YANG_MODULE, - //depends on dampening feature + // depends on dampening feature INTERFACES_INTERFACES_INTERFACE_DAMPENING_SUPPRESSED_YANG_PATH, srpc_feature_status_hash_check(ctx->features.ietf_if_extensions_features, "dampening") ? interfaces_subscription_operational_interfaces_interface_dampening_suppressed : NULL, }, { IETF_INTERFACES_YANG_MODULE, - //depends on dampening feature + // depends on dampening feature INTERFACES_INTERFACES_INTERFACE_DAMPENING_TIME_REMAINING_YANG_PATH, srpc_feature_status_hash_check(ctx->features.ietf_if_extensions_features, "dampening") ? interfaces_subscription_operational_interfaces_interface_dampening_time_remaining : NULL, }, @@ -355,16 +355,8 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) void sr_plugin_cleanup_cb(sr_session_ctx_t* running_session, void* private_data) { - int error = 0; - interfaces_ctx_t* ctx = (interfaces_ctx_t*)private_data; - // save current running configuration into startup for next time when the plugin starts - error = sr_copy_config(ctx->startup_session, IETF_INTERFACES_YANG_MODULE, SR_DS_RUNNING, 0); - if (error) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_copy_config() error (%d): %s", error, sr_strerror(error)); - } - if (ctx->oper_ctx.nl_ctx.link_cache) { nl_cache_put(ctx->oper_ctx.nl_ctx.link_cache); } diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c index 0b322347..5fda0cfe 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/change.c @@ -163,7 +163,7 @@ int interfaces_interface_ipv4_change_forwarding_init(void* priv) int interfaces_interface_ipv4_change_forwarding(void* priv, sr_session_ctx_t* session, const srpc_change_ctx_t* change_ctx) { - int error = 0; + // int error = 0; const char* node_name = LYD_NAME(change_ctx->node); const char* node_value = lyd_get_value(change_ctx->node); diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index 3125bcdb..8b908346 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -110,7 +110,7 @@ static char* interfaces_get_interface_type(struct rtnl_link* link, char* name) const char* path_to_sys = "/sys/class/net/"; int type_id = 0; - SRPC_SAFE_CALL(read_from_sys_file(path_to_sys, name, &type_id), error_out); + SRPC_SAFE_CALL_ERR(error, read_from_sys_file(path_to_sys, name, &type_id), error_out); switch (type_id) { case ARPHRD_ETHER: @@ -229,18 +229,18 @@ static int interfaces_add_link(interfaces_interface_hash_element_t** if_hash, in interfaces_interface_hash_element_t* new_if_hash_elem = interfaces_interface_hash_element_new(); interfaces_interface_hash_element_set_name(&new_if_hash_elem, interface->name); - SRPC_SAFE_CALL(interfaces_interface_hash_add_element(if_hash, new_if_hash_elem), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_add_element(if_hash, new_if_hash_elem), error_out); if (interface->description != NULL) { - SRPC_SAFE_CALL(interfaces_interface_hash_element_set_description(&new_if_hash_elem, interface->description), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_description(&new_if_hash_elem, interface->description), error_out); } if (interface->type != NULL) { - SRPC_SAFE_CALL(interfaces_interface_hash_element_set_type(&new_if_hash_elem, interface->type), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_type(&new_if_hash_elem, interface->type), error_out); } if (interface->parent_interface != NULL) { - SRPC_SAFE_CALL(interfaces_interface_hash_element_set_parent_interface(&new_if_hash_elem, interface->parent_interface), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_parent_interface(&new_if_hash_elem, interface->parent_interface), error_out); } interfaces_interface_hash_element_set_enabled(&new_if_hash_elem, interface->enabled); @@ -281,7 +281,7 @@ static int interfaces_interfaces_worker(interfaces_ctx_t* ctx, struct nl_sock* s error = interfaces_parse_link(ctx, socket, cache, link, &interface); switch (error) { case interfaces_load_success: - SRPC_SAFE_CALL(interfaces_add_link(if_hash, &interface), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_add_link(if_hash, &interface), error_out); break; case interfaces_load_continue: break; @@ -318,11 +318,11 @@ int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_e goto error_out; } - SRPC_SAFE_CALL(nl_connect(socket, NETLINK_ROUTE), error_out); + SRPC_SAFE_CALL_ERR(error, nl_connect(socket, NETLINK_ROUTE), error_out); - SRPC_SAFE_CALL(rtnl_link_alloc_cache(socket, AF_UNSPEC, &cache), error_out); + SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(socket, AF_UNSPEC, &cache), error_out); - SRPC_SAFE_CALL(interfaces_interfaces_worker(ctx, socket, cache, if_hash), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interfaces_worker(ctx, socket, cache, if_hash), error_out); goto out; error_out: From 74df93aa39561e02c29191b9292b84c39e90fb63 Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Mon, 31 Oct 2022 11:20:58 +0000 Subject: [PATCH 213/247] interfaces-plugin: remove unnecessary sr_copy_config() call --- src/interfaces/src/plugin.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index d900a087..e514bfa6 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -302,9 +302,6 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) // check and store startup data on the system SRPC_SAFE_CALL_ERR(error, interfaces_startup_store(ctx, startup_session), error_out); - - // copy contents of the startup session to the current running session - SRPC_SAFE_CALL_ERR(error, sr_copy_config(running_session, IETF_INTERFACES_YANG_MODULE, SR_DS_STARTUP, 0), error_out); } // subscribe every module change From 51de996c24bc56eb451d82f7bc771add7f16f3a9 Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Mon, 31 Oct 2022 11:21:38 +0000 Subject: [PATCH 214/247] interfaces-plugin: fix initial loading - load into running instead of startup --- src/interfaces/src/plugin.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index e514bfa6..8d5da0fa 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -290,11 +290,8 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) SRPLG_LOG_INF(PLUGIN_NAME, "Startup datastore is empty"); SRPLG_LOG_INF(PLUGIN_NAME, "Loading initial system data"); - // load startup data on the system - SRPC_SAFE_CALL_ERR(error, interfaces_startup_load(ctx, startup_session), error_out); - - // copy contents of the startup session to the current running session - SRPC_SAFE_CALL_ERR(error, sr_copy_config(running_session, IETF_INTERFACES_YANG_MODULE, SR_DS_STARTUP, 0), error_out); + // load initial data on the system + SRPC_SAFE_CALL_ERR(error, interfaces_startup_load(ctx, running_session), error_out); } else { // make sure the data from startup DS is stored in the interfaces SRPLG_LOG_INF(PLUGIN_NAME, "Startup datastore contains data"); From b17b76caec4d21660e6d2e3bbd0cc1d53df239f4 Mon Sep 17 00:00:00 2001 From: andrej Date: Mon, 31 Oct 2022 15:54:38 +0100 Subject: [PATCH 215/247] interfaces-plugin: reorganize unit tests, add hash new unit test --- src/interfaces/CMakeLists.txt | 6 +++++ .../interfaces/tests}/CMakeLists.txt | 3 ++- .../interfaces/tests}/interfaces_utest.c | 24 +++++++++++++++++++ .../interfaces/tests}/manual_tests.md | 0 4 files changed, 32 insertions(+), 1 deletion(-) rename {tests/interfaces => src/interfaces/tests}/CMakeLists.txt (86%) rename {tests/interfaces => src/interfaces/tests}/interfaces_utest.c (63%) rename {tests/interfaces => src/interfaces/tests}/manual_tests.md (100%) diff --git a/src/interfaces/CMakeLists.txt b/src/interfaces/CMakeLists.txt index 349b4fd1..5a9119e0 100644 --- a/src/interfaces/CMakeLists.txt +++ b/src/interfaces/CMakeLists.txt @@ -133,3 +133,9 @@ if(AUGYANG_FOUND) else(AUGYANG_FOUND) message(WARNING "AUGYANG not found - augeas support will be disabled") endif() + +if(ENABLE_BUILD_TESTS) + find_package(CMOCKA REQUIRED) + include(CTest) + include(tests/CMakeLists.txt) +endif() diff --git a/tests/interfaces/CMakeLists.txt b/src/interfaces/tests/CMakeLists.txt similarity index 86% rename from tests/interfaces/CMakeLists.txt rename to src/interfaces/tests/CMakeLists.txt index ad2c002b..c0d717b5 100644 --- a/tests/interfaces/CMakeLists.txt +++ b/src/interfaces/tests/CMakeLists.txt @@ -4,7 +4,7 @@ set(UTILS_MEMORY_LIBRARY_NAME "utils_memory") add_executable( ${INTERFACES_UTEST_NAME} - "interfaces_utest.c" + ${CMAKE_SOURCE_DIR}/src/interfaces/tests/interfaces_utest.c ) target_include_directories( ${INTERFACES_UTEST_NAME} @@ -19,6 +19,7 @@ target_link_libraries( ${INTERFACES_UTEST_NAME} ${CMOCKA_LIBRARIES} + ${PLUGIN_LIBRARY_NAME} ${SYSREPO_LIBRARIES} ${LIBYANG_LIBRARIES} ${UTILS_MEMORY_LIBRARY_NAME} diff --git a/tests/interfaces/interfaces_utest.c b/src/interfaces/tests/interfaces_utest.c similarity index 63% rename from tests/interfaces/interfaces_utest.c rename to src/interfaces/tests/interfaces_utest.c index 2b3ff80f..93aee787 100644 --- a/tests/interfaces/interfaces_utest.c +++ b/src/interfaces/tests/interfaces_utest.c @@ -12,12 +12,21 @@ /* load api */ #include "plugin/api/interfaces/load.h" +/* interfaces hash table state */ +#include "plugin/data/interfaces/interface_state.h" + +/* interfaces interface linked list */ +#include "plugin/data/interfaces/interface/linked_list.h" + /* init functionality */ static int setup(void **state); static int teardown(void **state); /* tests */ +/** interface hash table state **/ +static void test_hash_new_correct(void **state); + /* load */ static void test_correct_load_interface(void **state); @@ -25,6 +34,7 @@ int main(void) { const struct CMUnitTest tests[] = { cmocka_unit_test(test_correct_load_interface), + cmocka_unit_test(test_hash_new_correct), }; return cmocka_run_group_tests(tests, setup, teardown); @@ -60,3 +70,17 @@ static void test_correct_load_interface(void **state) assert_int_equal(rc, 0); } +static void test_hash_new_correct(void **state) +{ + interfaces_ctx_t *ctx = *state; + int rc = 0; + + interfaces_interface_state_hash_element_t *if_root; + + if_root = interfaces_interface_state_hash_new(); + + assert_null(if_root); + + assert_int_equal(rc, 0); +} + diff --git a/tests/interfaces/manual_tests.md b/src/interfaces/tests/manual_tests.md similarity index 100% rename from tests/interfaces/manual_tests.md rename to src/interfaces/tests/manual_tests.md From a4c3334e40ee5bab70aa6df9646f61ff63297524 Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Mon, 31 Oct 2022 17:19:05 +0000 Subject: [PATCH 216/247] interfaces-plugin: remove unused header --- src/interfaces/src/plugin/api/interfaces/load.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/interfaces/src/plugin/api/interfaces/load.h b/src/interfaces/src/plugin/api/interfaces/load.h index 10bd3328..b3103459 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.h +++ b/src/interfaces/src/plugin/api/interfaces/load.h @@ -4,7 +4,6 @@ #include "plugin/common.h" #include "plugin/context.h" #include "plugin/data/interfaces/interface.h" -#include "plugin/data/interfaces/interface/linked_list.h" int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** if_hash); From b09523103cc70c8a1a5929cc5fe0ade162eb0619 Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Mon, 31 Oct 2022 17:35:14 +0000 Subject: [PATCH 217/247] interfaces-plugin: add helpers for converting libnl and libyang interface types --- .../src/plugin/api/interfaces/load.c | 255 +++++++++--------- .../src/plugin/data/interfaces/interface.c | 46 ++++ .../src/plugin/data/interfaces/interface.h | 7 + 3 files changed, 176 insertions(+), 132 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index 6ea1c820..e7cd5ffe 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -1,8 +1,10 @@ #include "load.h" -#include "read.h" -#include "plugin/common.h" #include "interface/ipv4/load.h" #include "interface/ipv6/load.h" +#include "plugin/common.h" +#include "plugin/data/interfaces/interface.h" +#include "plugin/types.h" +#include "read.h" #include "utils/memory.h" #include "utlist.h" @@ -28,23 +30,23 @@ #include enum interfaces_load_exit_status { - interfaces_load_failure = -1, - interfaces_load_success = 0, - interfaces_load_continue = 1, + interfaces_load_failure = -1, + interfaces_load_success = 0, + interfaces_load_continue = 1, }; -static int interfaces_add_ips(interfaces_interface_t* interface, char *ip, int netmask, int addr_family) +static int interfaces_add_ips(interfaces_interface_t* interface, char* ip, int netmask, int addr_family) { switch (addr_family) { - case AF_INET: - interfaces_add_address_ipv4(&interface->ipv4.address, ip, netmask); - break; - case AF_INET6: - interfaces_add_address_ipv6(&interface->ipv6.address, ip, netmask); - break; - default: - SRPLG_LOG_ERR(PLUGIN_NAME, "%s: invalid address family", __func__); - return -1; + case AF_INET: + interfaces_add_address_ipv4(&interface->ipv4.address, ip, netmask); + break; + case AF_INET6: + interfaces_add_address_ipv6(&interface->ipv6.address, ip, netmask); + break; + default: + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: invalid address family", __func__); + return -1; } return 0; @@ -52,16 +54,16 @@ static int interfaces_add_ips(interfaces_interface_t* interface, char *ip, int n static int interfaces_get_interface_ips(struct nl_sock* socket, struct rtnl_link* link, interfaces_interface_t* interface) { - struct nl_object *nl_object = NULL; - struct nl_cache *addr_cache = NULL; - struct nl_addr *nl_addr_local = NULL; - struct rtnl_addr *addr = { 0 }; - char *address = NULL; - char *subnet = NULL; - char *addr_s = NULL; - char *token = NULL; - char *str = NULL; - char addr_str[ADDR_STR_BUF_SIZE] = { 0 }; + struct nl_object* nl_object = NULL; + struct nl_cache* addr_cache = NULL; + struct nl_addr* nl_addr_local = NULL; + struct rtnl_addr* addr = { 0 }; + char* address = NULL; + char* subnet = NULL; + char* addr_s = NULL; + char* token = NULL; + char* str = NULL; + char addr_str[ADDR_STR_BUF_SIZE] = { 0 }; int addr_count = 0; int addr_family = 0; @@ -77,11 +79,11 @@ static int interfaces_get_interface_ips(struct nl_sock* socket, struct rtnl_link addr_count = nl_cache_nitems(addr_cache); nl_object = nl_cache_get_first(addr_cache); - addr = (struct rtnl_addr *) nl_object; + addr = (struct rtnl_addr*)nl_object; for (int i = 0; i < addr_count; ++i) { SRPC_SAFE_CALL_PTR(nl_addr_local, rtnl_addr_get_local(addr), error_out); - + cur_if_index = rtnl_addr_get_ifindex(addr); if (if_index != cur_if_index) { @@ -92,7 +94,7 @@ static int interfaces_get_interface_ips(struct nl_sock* socket, struct rtnl_link str = xstrdup(addr_s); SRPC_SAFE_CALL_PTR(token, strtok(str, "/"), error_out); - + address = xstrdup(token); /* get subnet */ @@ -102,7 +104,7 @@ static int interfaces_get_interface_ips(struct nl_sock* socket, struct rtnl_link the address exists skip it we didn't add this address - e.g.: ::1 + e.g.: ::1 */ FREE_SAFE(str); FREE_SAFE(address); @@ -112,73 +114,73 @@ static int interfaces_get_interface_ips(struct nl_sock* socket, struct rtnl_link subnet = xstrdup(token); /* check if ipv4 or ipv6 */ - addr_family = rtnl_addr_get_family(addr); + addr_family = rtnl_addr_get_family(addr); interfaces_add_ips(interface, address, subnet, addr_family); next_address: nl_object = nl_cache_get_next(nl_object); - addr = (struct rtnl_addr *) nl_object; + addr = (struct rtnl_addr*)nl_object; FREE_SAFE(subnet); FREE_SAFE(str); FREE_SAFE(address); -} + } goto out; error_out: out: if (addr_cache) { nl_cache_free(addr_cache); - } + } if (str) { FREE_SAFE(str); - } + } if (address) { FREE_SAFE(address); - } + } return interfaces_load_success; } -static int interfaces_add_neighbor(interfaces_interface_t* interface, char *dst_addr, char *ll_addr, int addr_family) +static int interfaces_add_neighbor(interfaces_interface_t* interface, char* dst_addr, char* ll_addr, int addr_family) { switch (addr_family) { - case AF_INET: - interfaces_add_neighbor_ipv4(&interface->ipv4.neighbor, dst_addr, ll_addr); - break; - case AF_INET6: - interfaces_add_neighbor_ipv6(&interface->ipv6.neighbor, dst_addr, ll_addr); - break; - default: - SRPLG_LOG_ERR(PLUGIN_NAME, "%s: invalid address family", __func__); - return -1; + case AF_INET: + interfaces_add_neighbor_ipv4(&interface->ipv4.neighbor, dst_addr, ll_addr); + break; + case AF_INET6: + interfaces_add_neighbor_ipv6(&interface->ipv6.neighbor, dst_addr, ll_addr); + break; + default: + SRPLG_LOG_ERR(PLUGIN_NAME, "%s: invalid address family", __func__); + return -1; } return 0; } -static int interfaces_get_interface_ip_neighbors(struct nl_sock* socket, struct rtnl_link* link, interfaces_interface_t* interface) +static int interfaces_get_interface_ip_neighbors(struct nl_sock* socket, struct rtnl_link* link, interfaces_interface_t* interface) { - struct nl_cache *neigh_cache = NULL; - struct nl_object *nl_neigh_object = NULL; - struct nl_addr *nl_dst_addr = NULL; - struct nl_addr *ll_addr = NULL; - struct rtnl_neigh *neigh = NULL; + struct nl_cache* neigh_cache = NULL; + struct nl_object* nl_neigh_object = NULL; + struct nl_addr* nl_dst_addr = NULL; + struct nl_addr* ll_addr = NULL; + struct rtnl_neigh* neigh = NULL; int error = 0; int if_index = 0; int addr_family = 0; int neigh_state = 0; int neigh_count = 0; - char *dst_addr = NULL; - char *ll_addr_s = NULL; + char* dst_addr = NULL; + char* ll_addr_s = NULL; char dst_addr_str[ADDR_STR_BUF_SIZE] = { 0 }; - char ll_addr_str[ADDR_STR_BUF_SIZE] = { 0 }; + char ll_addr_str[ADDR_STR_BUF_SIZE] = { 0 }; INTERFACES_INTERFACE_LIST_NEW(interface->ipv4.neighbor); INTERFACES_INTERFACE_LIST_NEW(interface->ipv6.neighbor); - + if_index = rtnl_link_get_ifindex(link); SRPC_SAFE_CALL_ERR(error, rtnl_neigh_alloc_cache(socket, &neigh_cache), error_out); @@ -188,45 +190,44 @@ static int interfaces_get_interface_ip_neighbors(struct nl_sock* socket, struct nl_neigh_object = nl_cache_get_first(neigh_cache); for (int i = 0; i < neigh_count; ++i) { - nl_dst_addr = rtnl_neigh_get_dst((struct rtnl_neigh *) nl_neigh_object); + nl_dst_addr = rtnl_neigh_get_dst((struct rtnl_neigh*)nl_neigh_object); SRPC_SAFE_CALL_PTR(dst_addr, nl_addr2str(nl_dst_addr, dst_addr_str, sizeof(dst_addr_str)), error_out); neigh = rtnl_neigh_get(neigh_cache, if_index, nl_dst_addr); if (neigh != NULL) { - // get neigh state - neigh_state = rtnl_neigh_get_state(neigh); + // get neigh state + neigh_state = rtnl_neigh_get_state(neigh); - // skip neighs with no arp state - if (NUD_NOARP == neigh_state) { - nl_neigh_object = nl_cache_get_next(nl_neigh_object); - continue; - } + // skip neighs with no arp state + if (NUD_NOARP == neigh_state) { + nl_neigh_object = nl_cache_get_next(nl_neigh_object); + continue; + } - int cur_neigh_index = rtnl_neigh_get_ifindex(neigh); + int cur_neigh_index = rtnl_neigh_get_ifindex(neigh); - if (if_index != cur_neigh_index) { - nl_neigh_object = nl_cache_get_next(nl_neigh_object); - continue; - } + if (if_index != cur_neigh_index) { + nl_neigh_object = nl_cache_get_next(nl_neigh_object); + continue; + } - ll_addr = rtnl_neigh_get_lladdr(neigh); + ll_addr = rtnl_neigh_get_lladdr(neigh); - SRPC_SAFE_CALL_PTR(ll_addr_s, nl_addr2str(ll_addr, ll_addr_str, sizeof(ll_addr_str)), error_out); + SRPC_SAFE_CALL_PTR(ll_addr_s, nl_addr2str(ll_addr, ll_addr_str, sizeof(ll_addr_str)), error_out); - // check if ipv4 or ipv6 - addr_family = rtnl_neigh_get_family(neigh); + // check if ipv4 or ipv6 + addr_family = rtnl_neigh_get_family(neigh); - // switch based on address family, add to the neighbor linked list - SRPC_SAFE_CALL_ERR(error, interfaces_add_neighbor(interface, dst_addr, ll_addr_s, addr_family), error_out); - - rtnl_neigh_put(neigh); + // switch based on address family, add to the neighbor linked list + SRPC_SAFE_CALL_ERR(error, interfaces_add_neighbor(interface, dst_addr, ll_addr_s, addr_family), error_out); + + rtnl_neigh_put(neigh); } - + nl_neigh_object = nl_cache_get_next(nl_neigh_object); } - goto out; @@ -234,10 +235,10 @@ static int interfaces_get_interface_ip_neighbors(struct nl_sock* socket, struct out: if (neigh_cache) { nl_cache_free(neigh_cache); - } + } if (neigh) { rtnl_neigh_put(neigh); - } + } return interfaces_load_success; } @@ -249,13 +250,6 @@ static unsigned int interfaces_get_interface_ip_mtu(struct rtnl_link* link, inte interfaces_get_ipv6_mtu(link, interface); } -static unsigned int interfaces_get_interface_ip_enabled(interfaces_interface_t* interface) -{ - interfaces_get_ipv4_enabled(interface); - - interfaces_get_ipv6_enabled(interface); -} - static unsigned int interfaces_get_interface_ip_forwarding(interfaces_interface_t* interface) { interfaces_get_ipv4_forwarding(interface); @@ -273,35 +267,6 @@ static char* interfaces_get_interface_name(struct rtnl_link* link) return xstrdup(name); } -static char* interfaces_get_interface_description(interfaces_ctx_t* ctx, char* name) -{ - int error = SR_ERR_OK; - char path_buffer[PATH_MAX] = { 0 }; - sr_val_t* val = { 0 }; - char* description = NULL; - - /* conjure description path for this interface: /ietf-interfaces:interfaces/interface[name='test_interface']/description */ - error = snprintf(path_buffer, sizeof(path_buffer) / sizeof(char), "%s[name=\"%s\"]/description", INTERFACES_INTERFACES_LIST_YANG_PATH, name); - if (error < 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "snprintf error"); - goto error_out; - } - - // get the interface description value - error = sr_get_item(ctx->startup_session, path_buffer, 0, &val); - if (error != SR_ERR_OK) { - SRPLG_LOG_ERR(PLUGIN_NAME, "sr_get_item error (%d): %s", error, sr_strerror(error)); - goto error_out; - } - - if (strlen(val->data.string_val) > 0) { - description = xstrdup(val->data.string_val); - } - -error_out: - return description; -} - static char* interfaces_get_interface_type(struct rtnl_link* link, char* name) { int error = 0; @@ -336,7 +301,7 @@ static char* interfaces_get_interface_type(struct rtnl_link* link, char* name) return xstrdup(type); } -static int interfaces_get_interface_enabled(struct rtnl_link* link, interfaces_interface_t *interface) +static int interfaces_get_interface_enabled(struct rtnl_link* link, interfaces_interface_t* interface) { uint8_t enabled = rtnl_link_get_operstate(link); @@ -429,7 +394,7 @@ static int interfaces_parse_link(interfaces_ctx_t* ctx, struct nl_sock* socket, interfaces_get_interface_ip_mtu(link, interface); - //interfaces_get_interface_ip_enabled(interface); + // interfaces_get_interface_ip_enabled(interface); interfaces_get_interface_ip_forwarding(interface); @@ -465,15 +430,15 @@ static int interfaces_add_link(interfaces_interface_hash_element_t** if_hash, in interfaces_interface_hash_element_set_enabled(&new_if_hash_elem, interface->enabled); - //interfaces_interface_hash_element_set_ipv4(&new_if_hash_elem, interface->ipv4); + // interfaces_interface_hash_element_set_ipv4(&new_if_hash_elem, interface->ipv4); interfaces_interface_ipv4_address_element_set(&interface->ipv4.address, &new_if_hash_elem->interface.ipv4.address); interfaces_interface_ipv4_neighbor_element_set(&interface->ipv4.neighbor, &new_if_hash_elem->interface.ipv4.neighbor); - + interfaces_interface_hash_element_set_ipv4_mtu(&new_if_hash_elem, interface->ipv4.mtu); interfaces_interface_hash_element_set_ipv4_enabled(&new_if_hash_elem, interface->ipv4.enabled); interfaces_interface_hash_element_set_ipv4_forwarding(&new_if_hash_elem, interface->ipv4.forwarding); - //interfaces_interface_hash_element_set_ipv6(&new_if_hash_elem, interface->ipv6); + // interfaces_interface_hash_element_set_ipv6(&new_if_hash_elem, interface->ipv6); interfaces_interface_ipv6_address_element_set(&interface->ipv6.address, &new_if_hash_elem->interface.ipv6.address); interfaces_interface_ipv6_neighbor_element_set(&interface->ipv6.neighbor, &new_if_hash_elem->interface.ipv6.neighbor); interfaces_interface_hash_element_set_ipv6_mtu(&new_if_hash_elem, interface->ipv6.mtu); @@ -545,32 +510,58 @@ int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_e { int error = 0; struct nl_sock* socket = NULL; - struct nl_cache* cache = NULL; + struct nl_cache* link_cache = NULL; + struct rtnl_link* link_iter = NULL; - *if_hash = interfaces_interface_hash_new(); + // temp data + interfaces_interface_hash_element_t* new_element = NULL; + const char* nl_if_name = NULL; + const char* nl_if_type = NULL; + const char* ly_if_type = NULL; - socket = nl_socket_alloc(); - if (socket == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "nl_socket_alloc error: invalid socket"); - goto error_out; - } + // init hash + *if_hash = interfaces_interface_hash_new(); + // socket + cache + SRPC_SAFE_CALL_PTR(socket, nl_socket_alloc(), error_out); SRPC_SAFE_CALL_ERR(error, nl_connect(socket, NETLINK_ROUTE), error_out); + SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(socket, AF_UNSPEC, &link_cache), error_out); + + // get link iterator + SRPC_SAFE_CALL_PTR(link_iter, (struct rtnl_link*)nl_cache_get_first(link_cache), error_out); + + // iterate links + while (link_iter) { + // extract link info and add a new element to the interfaces hash - SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(socket, AF_UNSPEC, &cache), error_out); + // allocate new element + SRPC_SAFE_CALL_PTR(new_element, interfaces_interface_hash_element_new(), error_out); - SRPC_SAFE_CALL_ERR(error, interfaces_interfaces_worker(ctx, socket, cache, if_hash), error_out); + // 1. interface name + nl_if_name = rtnl_link_get_name(link_iter); + + // 2. interface type - nl version + nl_if_type = rtnl_link_get_type(link_iter); + + // set element values + interfaces_interface_hash_element_set_name(&new_element, nl_if_name); + + // iterate + SRPC_SAFE_CALL_PTR(link_iter, (struct rtnl_link*)nl_cache_get_next((struct nl_object*)link_iter), error_out); + } goto out; + error_out: error = -1; + out: if (socket != NULL) { nl_socket_free(socket); } - if (cache != NULL) { - nl_cache_free(cache); + if (link_cache != NULL) { + nl_cache_free(link_cache); } return error; diff --git a/src/interfaces/src/plugin/data/interfaces/interface.c b/src/interfaces/src/plugin/data/interfaces/interface.c index 1a6cccdb..e26432cd 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface.c +++ b/src/interfaces/src/plugin/data/interfaces/interface.c @@ -524,3 +524,49 @@ int interfaces_interface_hash_element_set_ipv6_mtu(interfaces_interface_hash_ele return 0; } + +int interfaces_interface_type_nl2ly(const char* nl_type, const char** ly_type) +{ + int error = 0; + + if (nl_type == NULL) { + return -1; + } + + if (strcmp(nl_type, "veth") == 0) { + *ly_type = "iana-if-type:ethernetCsmacd"; + } else if (strcmp(nl_type, "vcan") == 0) { + *ly_type = "iana-if-type:softwareLoopback"; + } else if (strcmp(nl_type, "vlan") == 0) { + *ly_type = "iana-if-type:l2vlan"; + } else if (strcmp(nl_type, "dummy") == 0) { + *ly_type = "iana-if-type:other"; + } else { + error = -2; + } + + return error; +} + +int interfaces_interface_type_ly2nl(const char* ly_type, const char** nl_type) +{ + int error = 0; + + if (ly_type == NULL) { + return -1; + } + + if (strcmp(ly_type, "iana-if-type:ethernetCsmacd") == 0) { + *nl_type = "veth"; + } else if (strcmp(ly_type, "iana-if-type:softwareLoopback") == 0) { + *nl_type = "vcan"; + } else if (strcmp(ly_type, "iana-if-type:l2vlan") == 0) { + *nl_type = "vlan"; + } else if (strcmp(ly_type, "iana-if-type:other") == 0) { + *nl_type = "dummy"; + } else { + error = -2; + } + + return error; +} diff --git a/src/interfaces/src/plugin/data/interfaces/interface.h b/src/interfaces/src/plugin/data/interfaces/interface.h index 80e450c1..e65fd969 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface.h +++ b/src/interfaces/src/plugin/data/interfaces/interface.h @@ -51,4 +51,11 @@ int interfaces_interface_hash_element_set_ipv6_enabled(interfaces_interface_hash int interfaces_interface_hash_element_set_ipv6_forwarding(interfaces_interface_hash_element_t** el, uint8_t forwarding); int interfaces_interface_hash_element_set_ipv6_mtu(interfaces_interface_hash_element_t** el, uint16_t mtu); +/* + Helper functionality. +*/ + +int interfaces_interface_type_nl2ly(const char* nl_type, const char** ly_type); +int interfaces_interface_type_ly2nl(const char* ly_type, const char** nl_type); + #endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_H From e4a93e7a26476f7d2638e289df0cb57ebace1ec0 Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Mon, 31 Oct 2022 18:50:17 +0000 Subject: [PATCH 218/247] interfaces-plugin: remove static helpers from interface load.c --- .../src/plugin/api/interfaces/load.c | 519 ++---------------- 1 file changed, 38 insertions(+), 481 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index e7cd5ffe..aa53c9b9 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -9,6 +9,7 @@ #include "utlist.h" #include +#include #include #include @@ -35,476 +36,11 @@ enum interfaces_load_exit_status { interfaces_load_continue = 1, }; -static int interfaces_add_ips(interfaces_interface_t* interface, char* ip, int netmask, int addr_family) -{ - switch (addr_family) { - case AF_INET: - interfaces_add_address_ipv4(&interface->ipv4.address, ip, netmask); - break; - case AF_INET6: - interfaces_add_address_ipv6(&interface->ipv6.address, ip, netmask); - break; - default: - SRPLG_LOG_ERR(PLUGIN_NAME, "%s: invalid address family", __func__); - return -1; - } - - return 0; -} - -static int interfaces_get_interface_ips(struct nl_sock* socket, struct rtnl_link* link, interfaces_interface_t* interface) -{ - struct nl_object* nl_object = NULL; - struct nl_cache* addr_cache = NULL; - struct nl_addr* nl_addr_local = NULL; - struct rtnl_addr* addr = { 0 }; - char* address = NULL; - char* subnet = NULL; - char* addr_s = NULL; - char* token = NULL; - char* str = NULL; - char addr_str[ADDR_STR_BUF_SIZE] = { 0 }; - - int addr_count = 0; - int addr_family = 0; - int if_index = 0; - int cur_if_index = 0; - int error = 0; - - if_index = rtnl_link_get_ifindex(link); - - SRPC_SAFE_CALL_ERR(error, rtnl_neigh_alloc_cache(socket, &addr_cache), error_out); - - /* get ipv4 and ipv6 addresses */ - addr_count = nl_cache_nitems(addr_cache); - - nl_object = nl_cache_get_first(addr_cache); - addr = (struct rtnl_addr*)nl_object; - - for (int i = 0; i < addr_count; ++i) { - SRPC_SAFE_CALL_PTR(nl_addr_local, rtnl_addr_get_local(addr), error_out); - - cur_if_index = rtnl_addr_get_ifindex(addr); - - if (if_index != cur_if_index) { - goto next_address; - } - - SRPC_SAFE_CALL_PTR(addr_s, nl_addr2str(nl_addr_local, addr_str, sizeof(addr_str)), error_out); - - str = xstrdup(addr_s); - SRPC_SAFE_CALL_PTR(token, strtok(str, "/"), error_out); - - address = xstrdup(token); - - /* get subnet */ - token = strtok(NULL, "/"); - if (token == NULL) { - /* - the address exists - skip it - we didn't add this address - e.g.: ::1 - */ - FREE_SAFE(str); - FREE_SAFE(address); - continue; - } - - subnet = xstrdup(token); - - /* check if ipv4 or ipv6 */ - addr_family = rtnl_addr_get_family(addr); - - interfaces_add_ips(interface, address, subnet, addr_family); - - next_address: - nl_object = nl_cache_get_next(nl_object); - addr = (struct rtnl_addr*)nl_object; - - FREE_SAFE(subnet); - FREE_SAFE(str); - FREE_SAFE(address); - } - - goto out; -error_out: -out: - if (addr_cache) { - nl_cache_free(addr_cache); - } - if (str) { - FREE_SAFE(str); - } - if (address) { - FREE_SAFE(address); - } - - return interfaces_load_success; -} - -static int interfaces_add_neighbor(interfaces_interface_t* interface, char* dst_addr, char* ll_addr, int addr_family) -{ - switch (addr_family) { - case AF_INET: - interfaces_add_neighbor_ipv4(&interface->ipv4.neighbor, dst_addr, ll_addr); - break; - case AF_INET6: - interfaces_add_neighbor_ipv6(&interface->ipv6.neighbor, dst_addr, ll_addr); - break; - default: - SRPLG_LOG_ERR(PLUGIN_NAME, "%s: invalid address family", __func__); - return -1; - } - - return 0; -} - -static int interfaces_get_interface_ip_neighbors(struct nl_sock* socket, struct rtnl_link* link, interfaces_interface_t* interface) -{ - struct nl_cache* neigh_cache = NULL; - struct nl_object* nl_neigh_object = NULL; - struct nl_addr* nl_dst_addr = NULL; - struct nl_addr* ll_addr = NULL; - struct rtnl_neigh* neigh = NULL; - - int error = 0; - int if_index = 0; - int addr_family = 0; - int neigh_state = 0; - int neigh_count = 0; - char* dst_addr = NULL; - char* ll_addr_s = NULL; - char dst_addr_str[ADDR_STR_BUF_SIZE] = { 0 }; - char ll_addr_str[ADDR_STR_BUF_SIZE] = { 0 }; - - INTERFACES_INTERFACE_LIST_NEW(interface->ipv4.neighbor); - INTERFACES_INTERFACE_LIST_NEW(interface->ipv6.neighbor); - - if_index = rtnl_link_get_ifindex(link); - - SRPC_SAFE_CALL_ERR(error, rtnl_neigh_alloc_cache(socket, &neigh_cache), error_out); - - neigh_count = nl_cache_nitems(neigh_cache); - - nl_neigh_object = nl_cache_get_first(neigh_cache); - - for (int i = 0; i < neigh_count; ++i) { - nl_dst_addr = rtnl_neigh_get_dst((struct rtnl_neigh*)nl_neigh_object); - - SRPC_SAFE_CALL_PTR(dst_addr, nl_addr2str(nl_dst_addr, dst_addr_str, sizeof(dst_addr_str)), error_out); - - neigh = rtnl_neigh_get(neigh_cache, if_index, nl_dst_addr); - - if (neigh != NULL) { - // get neigh state - neigh_state = rtnl_neigh_get_state(neigh); - - // skip neighs with no arp state - if (NUD_NOARP == neigh_state) { - nl_neigh_object = nl_cache_get_next(nl_neigh_object); - continue; - } - - int cur_neigh_index = rtnl_neigh_get_ifindex(neigh); - - if (if_index != cur_neigh_index) { - nl_neigh_object = nl_cache_get_next(nl_neigh_object); - continue; - } - - ll_addr = rtnl_neigh_get_lladdr(neigh); - - SRPC_SAFE_CALL_PTR(ll_addr_s, nl_addr2str(ll_addr, ll_addr_str, sizeof(ll_addr_str)), error_out); - - // check if ipv4 or ipv6 - addr_family = rtnl_neigh_get_family(neigh); - - // switch based on address family, add to the neighbor linked list - SRPC_SAFE_CALL_ERR(error, interfaces_add_neighbor(interface, dst_addr, ll_addr_s, addr_family), error_out); - - rtnl_neigh_put(neigh); - } - - nl_neigh_object = nl_cache_get_next(nl_neigh_object); - } - - goto out; - -error_out: -out: - if (neigh_cache) { - nl_cache_free(neigh_cache); - } - if (neigh) { - rtnl_neigh_put(neigh); - } - - return interfaces_load_success; -} - -static unsigned int interfaces_get_interface_ip_mtu(struct rtnl_link* link, interfaces_interface_t* interface) -{ - interfaces_get_ipv4_mtu(link, interface); - - interfaces_get_ipv6_mtu(link, interface); -} - -static unsigned int interfaces_get_interface_ip_forwarding(interfaces_interface_t* interface) -{ - interfaces_get_ipv4_forwarding(interface); - - interfaces_get_ipv6_forwarding(interface); -} - -static char* interfaces_get_interface_name(struct rtnl_link* link) -{ - char* name = NULL; - - SRPC_SAFE_CALL_PTR(name, rtnl_link_get_name(link), error_out); - -error_out: - return xstrdup(name); -} - -static char* interfaces_get_interface_type(struct rtnl_link* link, char* name) -{ - int error = 0; - char* type = NULL; - - type = rtnl_link_get_type(link); - if (type == NULL) { - /* rtnl_link_get_type() will return NULL for interfaces that were not - * set with rtnl_link_set_type() - * - * get the type from: /sys/class/net//type - */ - const char* path_to_sys = "/sys/class/net/"; - int type_id = 0; - - SRPC_SAFE_CALL_ERR(error, read_from_sys_file(path_to_sys, name, &type_id), error_out); - - switch (type_id) { - case ARPHRD_ETHER: - type = "eth"; - break; - case ARPHRD_LOOPBACK: - type = "lo"; - break; - default: - SRPLG_LOG_ERR(PLUGIN_NAME, "%s: unkown type_id: %d", __func__, type_id); - return NULL; - } - } - -error_out: - return xstrdup(type); -} - -static int interfaces_get_interface_enabled(struct rtnl_link* link, interfaces_interface_t* interface) -{ - uint8_t enabled = rtnl_link_get_operstate(link); - - /* - * if the lo interface state is unknown, treat it as enabled - * otherwise it will be set to down, and dns resolution won't work - */ - if (IF_OPER_UP == enabled || IF_OPER_UNKNOWN == enabled) { - enabled = interfaces_interface_enable_enabled; - } else if (IF_OPER_DOWN == enabled) { - enabled = interfaces_interface_enable_disabled; - } - - interface->enabled = enabled; - - return 0; -} - -static int interfaces_get_interface_parent_interface(struct nl_cache* cache, struct rtnl_link* link, interfaces_interface_t* interface) -{ - int parent_index = 0; - char parent_buffer[IFNAMSIZ] = { 0 }; - char* parent_interface = NULL; - - if (rtnl_link_is_vlan(link)) { - parent_index = rtnl_link_get_link(link); - parent_interface = rtnl_link_i2name(cache, parent_index, parent_buffer, IFNAMSIZ); - interface->parent_interface = xstrdup(parent_interface); - - return 0; - } - - return -1; -} - -/* TODO: outer tag, second id, tag - maybe refactor all to pass by reference, return error */ -static int interfaces_get_interface_vlan_id(struct rtnl_link* link, interfaces_interface_t* interface) -{ - uint16_t* outer_vlan_id = &interface->encapsulation.dot1q_vlan.outer_tag.vlan_id; - char* first = NULL; - char* second = NULL; - - if (rtnl_link_is_vlan(link)) { - *outer_vlan_id = (uint16_t)rtnl_link_vlan_get_id(link); - if (*outer_vlan_id <= 0) { - SRPLG_LOG_ERR(PLUGIN_NAME, "%s: couldn't get vlan ID", __func__); - return interfaces_load_failure; - } - - /* check if vlan_id in name, if it is this is the QinQ interface, skip it */ - first = strchr(interface->name, '.'); - second = strchr(first + 1, '.'); - - if (second != 0) { - // continue to the next interface - return interfaces_load_continue; - } - } - - return interfaces_load_success; -} - /* - Parses the link for interface data + Interface Data Loading (name, type, enabled etc.) */ -static int interfaces_parse_link(interfaces_ctx_t* ctx, struct nl_sock* socket, struct nl_cache* cache, struct rtnl_link* link, interfaces_interface_t* interface) -{ - int error = interfaces_load_success; - - // required, fail if NULL - SRPC_SAFE_CALL_PTR(interface->name, interfaces_get_interface_name(link), error_out); - - /* interfaces_get_interface_description(ctx, interface->name); */ - - interfaces_get_interface_type(link, interface->name); - - interfaces_get_interface_parent_interface(cache, link, interface); - - /* interface can be skipped - interface_load_continue*/ - error = interfaces_get_interface_vlan_id(link, interface); - if (error != interfaces_load_success) { - goto out; // error_out would possibly change the error - } - - interfaces_get_interface_enabled(link, interface); - - interfaces_get_interface_ips(socket, link, interface); - - interfaces_get_interface_ip_neighbors(socket, link, interface); - - interfaces_get_interface_ip_mtu(link, interface); - - // interfaces_get_interface_ip_enabled(interface); - - interfaces_get_interface_ip_forwarding(interface); - - goto out; -error_out: - error = interfaces_load_failure; -out: - /* do not free the data, the interface data needs to be added in the interfaces hash table */ - - return error; -} - -static int interfaces_add_link(interfaces_interface_hash_element_t** if_hash, interfaces_interface_t* interface) -{ - int error = 0; - - interfaces_interface_hash_element_t* new_if_hash_elem = interfaces_interface_hash_element_new(); - interfaces_interface_hash_element_set_name(&new_if_hash_elem, interface->name); - - SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_add_element(if_hash, new_if_hash_elem), error_out); - - if (interface->description != NULL) { - SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_description(&new_if_hash_elem, interface->description), error_out); - } - - if (interface->type != NULL) { - SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_type(&new_if_hash_elem, interface->type), error_out); - } - - if (interface->parent_interface != NULL) { - SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_parent_interface(&new_if_hash_elem, interface->parent_interface), error_out); - } - - interfaces_interface_hash_element_set_enabled(&new_if_hash_elem, interface->enabled); - - // interfaces_interface_hash_element_set_ipv4(&new_if_hash_elem, interface->ipv4); - interfaces_interface_ipv4_address_element_set(&interface->ipv4.address, &new_if_hash_elem->interface.ipv4.address); - interfaces_interface_ipv4_neighbor_element_set(&interface->ipv4.neighbor, &new_if_hash_elem->interface.ipv4.neighbor); - - interfaces_interface_hash_element_set_ipv4_mtu(&new_if_hash_elem, interface->ipv4.mtu); - interfaces_interface_hash_element_set_ipv4_enabled(&new_if_hash_elem, interface->ipv4.enabled); - interfaces_interface_hash_element_set_ipv4_forwarding(&new_if_hash_elem, interface->ipv4.forwarding); - - // interfaces_interface_hash_element_set_ipv6(&new_if_hash_elem, interface->ipv6); - interfaces_interface_ipv6_address_element_set(&interface->ipv6.address, &new_if_hash_elem->interface.ipv6.address); - interfaces_interface_ipv6_neighbor_element_set(&interface->ipv6.neighbor, &new_if_hash_elem->interface.ipv6.neighbor); - interfaces_interface_hash_element_set_ipv6_mtu(&new_if_hash_elem, interface->ipv6.mtu); - interfaces_interface_hash_element_set_ipv6_enabled(&new_if_hash_elem, interface->ipv6.enabled); - interfaces_interface_hash_element_set_ipv6_forwarding(&new_if_hash_elem, interface->ipv6.forwarding); - - interfaces_interface_hash_element_set_enabled(&new_if_hash_elem, interface->enabled); - - goto out; -error_out: -out: - if (interface->name != NULL) { - FREE_SAFE(interface->name); - } - if (interface->description != NULL) { - FREE_SAFE(interface->description); - } - if (interface->type != NULL) { - FREE_SAFE(interface->type); - } - if (interface->parent_interface != NULL) { - FREE_SAFE(interface->parent_interface); - } - - return error; -} - -static struct rtnl_link* interfaces_get_next_link(struct rtnl_link* link) -{ - return (struct rtnl_link*)nl_cache_get_next((struct nl_object*)link); -} - -static int interfaces_interfaces_worker(interfaces_ctx_t* ctx, struct nl_sock* socket, struct nl_cache* cache, interfaces_interface_hash_element_t** if_hash) -{ - int error = 0; - struct rtnl_link* link = NULL; - interfaces_interface_t interface = { 0 }; - - link = (struct rtnl_link*)nl_cache_get_first(cache); - - while (link != NULL) { - error = interfaces_parse_link(ctx, socket, cache, link, &interface); - switch (error) { - case interfaces_load_success: - SRPC_SAFE_CALL_ERR(error, interfaces_add_link(if_hash, &interface), error_out); - break; - case interfaces_load_continue: - break; - default: - SRPLG_LOG_ERR(PLUGIN_NAME, "%s: error parsing link (%d)", __func__, error); - goto error_out; - } - link = interfaces_get_next_link(link); - } - - goto out; -error_out: - error = -1; -out: - if (link != NULL) { - rtnl_link_put(link); - } - - return error; -} +static int interfaces_load_interface_info(struct rtnl_link* link, interfaces_interface_hash_element_t** new_element); int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** if_hash) { @@ -515,9 +51,6 @@ int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_e // temp data interfaces_interface_hash_element_t* new_element = NULL; - const char* nl_if_name = NULL; - const char* nl_if_type = NULL; - const char* ly_if_type = NULL; // init hash *if_hash = interfaces_interface_hash_new(); @@ -537,17 +70,8 @@ int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_e // allocate new element SRPC_SAFE_CALL_PTR(new_element, interfaces_interface_hash_element_new(), error_out); - // 1. interface name - nl_if_name = rtnl_link_get_name(link_iter); - - // 2. interface type - nl version - nl_if_type = rtnl_link_get_type(link_iter); - - // set element values - interfaces_interface_hash_element_set_name(&new_element, nl_if_name); - - // iterate - SRPC_SAFE_CALL_PTR(link_iter, (struct rtnl_link*)nl_cache_get_next((struct nl_object*)link_iter), error_out); + // load interface data + SRPC_SAFE_CALL_ERR(error, interfaces_load_interface_info(link_iter, &new_element), error_out); } goto out; @@ -566,3 +90,36 @@ int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_e return error; } + +static int interfaces_load_interface_info(struct rtnl_link* link, interfaces_interface_hash_element_t** new_element) +{ + int error = 0; + + const char* nl_if_name = NULL; + const char* nl_if_type = NULL; + const char* ly_if_type = NULL; + uint8_t nl_enabled = 0; + + // 1. interface name + nl_if_name = rtnl_link_get_name(link); + + // 2. interface type - nl version -> convert to libyang version + nl_if_type = rtnl_link_get_type(link); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_type_nl2ly(nl_if_type, &ly_if_type), error_out); + + // enabled + nl_enabled = (rtnl_link_get_operstate(link) == IF_OPER_UP || rtnl_link_get_operstate(link) == IF_OPER_UNKNOWN); + + // set element values + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_name(new_element, nl_if_name), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_type(new_element, ly_if_type), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_enabled(new_element, nl_enabled), error_out); + + goto out; + +error_out: + error = -1; + +out: + return error; +} \ No newline at end of file From 34a04b56bf5e3a4ea42ec78a46704cd9d4c42631 Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Mon, 31 Oct 2022 19:33:13 +0000 Subject: [PATCH 219/247] interfaces-plugin: reorganize interface info loading code into interface load API --- src/interfaces/CMakeLists.txt | 1 + .../plugin/api/interfaces/interface/load.c | 66 +++++++++++++++++++ .../plugin/api/interfaces/interface/load.h | 13 ++++ .../src/plugin/api/interfaces/load.c | 56 +++------------- 4 files changed, 88 insertions(+), 48 deletions(-) create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/load.c create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/load.h diff --git a/src/interfaces/CMakeLists.txt b/src/interfaces/CMakeLists.txt index 349b4fd1..c24be20b 100644 --- a/src/interfaces/CMakeLists.txt +++ b/src/interfaces/CMakeLists.txt @@ -32,6 +32,7 @@ set( src/plugin/api/interfaces/read.c src/plugin/api/interfaces/store.c src/plugin/api/interfaces/change.c + src/plugin/api/interfaces/interface/load.c src/plugin/api/interfaces/interface/change.c src/plugin/api/interfaces/interface/ipv6/load.c src/plugin/api/interfaces/interface/ipv6/change.c diff --git a/src/interfaces/src/plugin/api/interfaces/interface/load.c b/src/interfaces/src/plugin/api/interfaces/interface/load.c new file mode 100644 index 00000000..109841a7 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/load.c @@ -0,0 +1,66 @@ +#include "load.h" +#include "plugin/data/interfaces/interface.h" + +#include +#include + +int interfaces_interface_load_name(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** element, struct rtnl_link* link) +{ + int error = 0; + + const char* nl_if_name = NULL; + + nl_if_name = rtnl_link_get_name(link); + + // set element values + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_name(element, nl_if_name), error_out); + + goto out; + +error_out: + error = -1; + +out: + return error; +} + +int interfaces_interface_load_type(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** element, struct rtnl_link* link) +{ + int error = 0; + + const char* nl_if_type = NULL; + const char* ly_if_type = NULL; + + // 2. interface type - nl version -> convert to libyang version + nl_if_type = rtnl_link_get_type(link); + + SRPC_SAFE_CALL_ERR(error, interfaces_interface_type_nl2ly(nl_if_type, &ly_if_type), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_type(element, ly_if_type), error_out); + + goto out; + +error_out: + error = -1; + +out: + + return error; +} + +int interfaces_interface_load_enabled(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** element, struct rtnl_link* link) +{ + int error = 0; + + uint8_t nl_enabled = (rtnl_link_get_operstate(link) == IF_OPER_UP || rtnl_link_get_operstate(link) == IF_OPER_UNKNOWN); + + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_enabled(element, nl_enabled), error_out); + + goto out; + +error_out: + error = -1; + +out: + + return error; +} diff --git a/src/interfaces/src/plugin/api/interfaces/interface/load.h b/src/interfaces/src/plugin/api/interfaces/interface/load.h new file mode 100644 index 00000000..0920c2af --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/load.h @@ -0,0 +1,13 @@ +#ifndef INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_LOAD_H +#define INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_LOAD_H + +#include "plugin/context.h" +#include "plugin/types.h" + +#include + +int interfaces_interface_load_name(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** element, struct rtnl_link* link); +int interfaces_interface_load_type(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** element, struct rtnl_link* link); +int interfaces_interface_load_enabled(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** element, struct rtnl_link* link); + +#endif // INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_LOAD_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index aa53c9b9..e2ee6234 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -8,6 +8,9 @@ #include "utils/memory.h" #include "utlist.h" +// load APIs +#include "interface/load.h" + #include #include #include @@ -30,18 +33,6 @@ #include -enum interfaces_load_exit_status { - interfaces_load_failure = -1, - interfaces_load_success = 0, - interfaces_load_continue = 1, -}; - -/* - Interface Data Loading (name, type, enabled etc.) -*/ - -static int interfaces_load_interface_info(struct rtnl_link* link, interfaces_interface_hash_element_t** new_element); - int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** if_hash) { int error = 0; @@ -65,13 +56,15 @@ int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_e // iterate links while (link_iter) { - // extract link info and add a new element to the interfaces hash - // allocate new element SRPC_SAFE_CALL_PTR(new_element, interfaces_interface_hash_element_new(), error_out); // load interface data - SRPC_SAFE_CALL_ERR(error, interfaces_load_interface_info(link_iter, &new_element), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_load_name(ctx, &new_element, link_iter), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_load_type(ctx, &new_element, link_iter), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_load_enabled(ctx, &new_element, link_iter), error_out); + + // load interface IPv4 data } goto out; @@ -88,38 +81,5 @@ int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_e nl_cache_free(link_cache); } - return error; -} - -static int interfaces_load_interface_info(struct rtnl_link* link, interfaces_interface_hash_element_t** new_element) -{ - int error = 0; - - const char* nl_if_name = NULL; - const char* nl_if_type = NULL; - const char* ly_if_type = NULL; - uint8_t nl_enabled = 0; - - // 1. interface name - nl_if_name = rtnl_link_get_name(link); - - // 2. interface type - nl version -> convert to libyang version - nl_if_type = rtnl_link_get_type(link); - SRPC_SAFE_CALL_ERR(error, interfaces_interface_type_nl2ly(nl_if_type, &ly_if_type), error_out); - - // enabled - nl_enabled = (rtnl_link_get_operstate(link) == IF_OPER_UP || rtnl_link_get_operstate(link) == IF_OPER_UNKNOWN); - - // set element values - SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_name(new_element, nl_if_name), error_out); - SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_type(new_element, ly_if_type), error_out); - SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_enabled(new_element, nl_enabled), error_out); - - goto out; - -error_out: - error = -1; - -out: return error; } \ No newline at end of file From 060b0c5ad6d6d2fec75c496758e2db675f3f7084 Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Mon, 31 Oct 2022 19:40:47 +0000 Subject: [PATCH 220/247] interfaces-plugin: add IPv4 info loading code --- .../api/interfaces/interface/ipv4/load.c | 63 +++++++------------ .../api/interfaces/interface/ipv4/load.h | 20 ++---- 2 files changed, 27 insertions(+), 56 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c index e5c72b87..e9b519c9 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c @@ -1,68 +1,47 @@ #include "load.h" +#include "netlink/route/link.h" +#include "plugin/data/interfaces/interface.h" - -int interfaces_add_address_ipv4(interfaces_interface_ipv4_address_element_t **address, char *ip, char *netmask) +int interfaces_interface_ipv4_load_enabled(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** element, struct rtnl_link* link) { - int prefix_length = 0; int error = 0; - interfaces_interface_ipv4_address_element_t* new_element = NULL; + // enabled by default + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_ipv4_enabled(element, 1), error_out); - new_element = interfaces_interface_ipv4_address_element_new(); + goto out; - interfaces_interface_ipv4_address_element_set_ip(&new_element, ip); - SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_address_netmask2prefix(netmask, prefix_length), out); - interfaces_interface_ipv4_address_element_set_subnet(&new_element, netmask, interfaces_interface_ipv4_address_subnet_prefix_length); - interfaces_interface_ipv4_address_add_element(address, new_element); +error_out: + error = -1; out: - return error; -} - -int interfaces_add_neighbor_ipv4(interfaces_interface_ipv4_neighbor_element_t** neighbor, char *dst_addr, char *ll_addr) -{ - interfaces_interface_ipv4_neighbor_element_t* new_element = NULL; - new_element = interfaces_interface_ipv4_neighbor_element_new(); - - interfaces_interface_ipv4_neighbor_element_set_ip(&new_element, dst_addr); - interfaces_interface_ipv4_neighbor_element_set_link_layer_address(&new_element, ll_addr); - interfaces_interface_ipv4_neighbor_add_element(neighbor, new_element); - - return 0; + return error; } -unsigned int interfaces_get_ipv4_mtu(struct rtnl_link* link, interfaces_interface_t* interface) +int interfaces_interface_ipv4_load_forwarding(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** element, struct rtnl_link* link) { - unsigned int mtu = 0; - - mtu = rtnl_link_get_mtu(link); + int error = 0; - interface->ipv4.mtu = mtu; + // TODO: implement - return 0; + return error; } -unsigned int interfaces_get_ipv4_enabled(interfaces_interface_t* interface) +int interfaces_interface_ipv4_load_mtu(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** element, struct rtnl_link* link) { - const char *ipv4_base = "/proc/sys/net/ipv4/conf"; - - /* TODO: figure out how to enable/disable ipv4 */ - /* since disable_ipv4 doesn't exist in /proc/sys/net/ipv6/conf/interface_name */ + int error = 0; -} + const unsigned int mtu = rtnl_link_get_mtu(link); -unsigned int interfaces_get_ipv4_forwarding(interfaces_interface_t* interface) -{ - int error = 0; - int forwarding = 0; + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_ipv4_mtu(element, (uint16_t)mtu), error_out); - const char *ipv4_base = "/proc/sys/net/ipv4/conf"; - - SRPC_SAFE_CALL_ERR(error, read_from_proc_file(ipv4_base, interface->name, "forwarding", &forwarding), out); + goto out; - interface->ipv4.forwarding = forwarding; +error_out: + error = -1; out: + return error; } diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.h b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.h index 47904e13..378b33af 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.h +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.h @@ -1,21 +1,13 @@ -#ifndef INTERFACES_PLUGIN_API_INTERFACES_IPV4_LOAD_H -#define INTERFACES_PLUGIN_API_INTERFACES_IPV4_LOAD_H +#ifndef INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV4_LOAD_H +#define INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV4_LOAD_H #include "plugin/context.h" #include "plugin/data/interfaces/interface.h" #include "plugin/data/interfaces/interface/linked_list.h" #include "plugin/types.h" -int interfaces_add_address_ipv4(interfaces_interface_ipv4_address_element_t **address, char *ip, char *netmask); - -int interfaces_add_neighbor_ipv4(interfaces_interface_ipv4_neighbor_element_t** neighbor, char *dst_addr, char *ll_addr); - -unsigned int interfaces_get_ipv4_mtu(struct rtnl_link* link, interfaces_interface_t* interface); - -unsigned int interfaces_get_ipv4_enabled(interfaces_interface_t* interface); - -unsigned int interfaces_get_ipv4_forwarding(interfaces_interface_t* interface); - - -#endif /* INTERFACES_PLUGIN_API_INTERFACES_IPV4_LOAD_H */ +int interfaces_interface_ipv4_load_enabled(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** element, struct rtnl_link* link); +int interfaces_interface_ipv4_load_forwarding(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** element, struct rtnl_link* link); +int interfaces_interface_ipv4_load_mtu(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** element, struct rtnl_link* link); +#endif // INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV4_LOAD_H From 41e6ada582c868365345565dbf0a353aa49ec35f Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Mon, 31 Oct 2022 19:57:54 +0000 Subject: [PATCH 221/247] interfaces-plugin: refactor IPv4 and IPv6 data code --- src/interfaces/CMakeLists.txt | 2 + .../api/interfaces/interface/ipv4/load.c | 11 +-- .../api/interfaces/interface/ipv4/load.h | 6 +- .../api/interfaces/interface/ipv6/load.c | 69 ++++++------------- .../api/interfaces/interface/ipv6/load.h | 19 ++--- .../src/plugin/data/interfaces/interface.c | 64 ++--------------- .../src/plugin/data/interfaces/interface.h | 18 ----- .../plugin/data/interfaces/interface/ipv4.c | 22 ++++++ .../plugin/data/interfaces/interface/ipv4.h | 10 +++ .../plugin/data/interfaces/interface/ipv6.c | 22 ++++++ .../plugin/data/interfaces/interface/ipv6.h | 10 +++ 11 files changed, 107 insertions(+), 146 deletions(-) create mode 100644 src/interfaces/src/plugin/data/interfaces/interface/ipv4.c create mode 100644 src/interfaces/src/plugin/data/interfaces/interface/ipv4.h create mode 100644 src/interfaces/src/plugin/data/interfaces/interface/ipv6.c create mode 100644 src/interfaces/src/plugin/data/interfaces/interface/ipv6.h diff --git a/src/interfaces/CMakeLists.txt b/src/interfaces/CMakeLists.txt index c24be20b..41f1a22b 100644 --- a/src/interfaces/CMakeLists.txt +++ b/src/interfaces/CMakeLists.txt @@ -51,6 +51,8 @@ set( # data src/plugin/data/interfaces/interface.c src/plugin/data/interfaces/interface_state.c + src/plugin/data/interfaces/interface/ipv4.c + src/plugin/data/interfaces/interface/ipv6.c src/plugin/data/interfaces/interface/ipv4/address.c src/plugin/data/interfaces/interface/ipv4/neighbor.c src/plugin/data/interfaces/interface/ipv6/address.c diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c index e9b519c9..ed6c5ba8 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c @@ -1,13 +1,14 @@ #include "load.h" #include "netlink/route/link.h" #include "plugin/data/interfaces/interface.h" +#include "plugin/data/interfaces/interface/ipv4.h" -int interfaces_interface_ipv4_load_enabled(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** element, struct rtnl_link* link) +int interfaces_interface_ipv4_load_enabled(interfaces_ctx_t* ctx, interfaces_interface_ipv4_t* ipv4, struct rtnl_link* link) { int error = 0; // enabled by default - SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_ipv4_enabled(element, 1), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_ipv4_set_enabled(ipv4, 1), error_out); goto out; @@ -19,7 +20,7 @@ int interfaces_interface_ipv4_load_enabled(interfaces_ctx_t* ctx, interfaces_int return error; } -int interfaces_interface_ipv4_load_forwarding(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** element, struct rtnl_link* link) +int interfaces_interface_ipv4_load_forwarding(interfaces_ctx_t* ctx, interfaces_interface_ipv4_t* ipv4, struct rtnl_link* link) { int error = 0; @@ -28,13 +29,13 @@ int interfaces_interface_ipv4_load_forwarding(interfaces_ctx_t* ctx, interfaces_ return error; } -int interfaces_interface_ipv4_load_mtu(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** element, struct rtnl_link* link) +int interfaces_interface_ipv4_load_mtu(interfaces_ctx_t* ctx, interfaces_interface_ipv4_t* ipv4, struct rtnl_link* link) { int error = 0; const unsigned int mtu = rtnl_link_get_mtu(link); - SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_ipv4_mtu(element, (uint16_t)mtu), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_ipv4_set_mtu(ipv4, (uint16_t)mtu), error_out); goto out; diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.h b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.h index 378b33af..6adeff9f 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.h +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.h @@ -6,8 +6,8 @@ #include "plugin/data/interfaces/interface/linked_list.h" #include "plugin/types.h" -int interfaces_interface_ipv4_load_enabled(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** element, struct rtnl_link* link); -int interfaces_interface_ipv4_load_forwarding(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** element, struct rtnl_link* link); -int interfaces_interface_ipv4_load_mtu(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** element, struct rtnl_link* link); +int interfaces_interface_ipv4_load_enabled(interfaces_ctx_t* ctx, interfaces_interface_ipv4_t* ipv4, struct rtnl_link* link); +int interfaces_interface_ipv4_load_forwarding(interfaces_ctx_t* ctx, interfaces_interface_ipv4_t* ipv4, struct rtnl_link* link); +int interfaces_interface_ipv4_load_mtu(interfaces_ctx_t* ctx, interfaces_interface_ipv4_t* ipv4, struct rtnl_link* link); #endif // INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV4_LOAD_H diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.c index edc995ee..8e0e2a30 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.c @@ -1,75 +1,48 @@ #include "load.h" +#include "netlink/route/link.h" +#include "plugin/data/interfaces/interface.h" +#include "plugin/data/interfaces/interface/ipv6.h" -int interfaces_add_address_ipv6(interfaces_interface_ipv6_address_element_t **address, char *ip, char *netmask) +int interfaces_interface_ipv6_load_enabled(interfaces_ctx_t* ctx, interfaces_interface_ipv6_t* ipv6, struct rtnl_link* link) { int error = 0; - uint8_t prefix_length = 0; - interfaces_interface_ipv6_address_element_t* new_element = NULL; + // enabled by default + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_ipv6_set_enabled(ipv6, 1), error_out); - new_element = interfaces_interface_ipv6_address_element_new(); + goto out; - interfaces_interface_ipv6_address_element_set_ip(&new_element, ip); - SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_address_netmask2prefix(netmask, prefix_length), out); - interfaces_interface_ipv6_address_element_set_prefix_length(&new_element, prefix_length); - interfaces_interface_ipv6_address_add_element(address, new_element); +error_out: + error = -1; out: - return error; -} - -int interfaces_add_neighbor_ipv6(interfaces_interface_ipv6_neighbor_element_t** neighbor, char *dst_addr, char *ll_addr) -{ - interfaces_interface_ipv6_neighbor_element_t* new_element = NULL; - - new_element = interfaces_interface_ipv6_neighbor_element_new(); - - interfaces_interface_ipv6_neighbor_element_set_ip(&new_element, dst_addr); - interfaces_interface_ipv6_neighbor_element_set_link_layer_address(&new_element, ll_addr); - interfaces_interface_ipv6_neighbor_add_element(neighbor, new_element); - - return 0; -} - -unsigned int interfaces_get_ipv6_mtu(struct rtnl_link* link, interfaces_interface_t* interface) -{ - unsigned int mtu = 0; - mtu = rtnl_link_get_mtu(link); - - interface->ipv6.mtu = mtu; - - return 0; - + return error; } -unsigned int interfaces_get_ipv6_enabled(interfaces_interface_t* interface) +int interfaces_interface_ipv6_load_forwarding(interfaces_ctx_t* ctx, interfaces_interface_ipv6_t* ipv6, struct rtnl_link* link) { int error = 0; - int enabled = 0; - const char *ipv6_base = "/proc/sys/net/ipv6/conf"; - - SRPC_SAFE_CALL_ERR(error, read_from_proc_file(ipv6_base, interface->name, "disable_ipv6", &enabled), out); + // TODO: implement - interface->ipv6.enabled = enabled; - -out: return error; } -unsigned int interfaces_get_ipv6_forwarding(interfaces_interface_t* interface) +int interfaces_interface_ipv6_load_mtu(interfaces_ctx_t* ctx, interfaces_interface_ipv6_t* ipv6, struct rtnl_link* link) { int error = 0; - int forwarding = 0; - const char *ipv6_base = "/proc/sys/net/ipv6/conf"; - - SRPC_SAFE_CALL_ERR(error, read_from_proc_file(ipv6_base, interface->name, "forwarding", &forwarding), out); + const unsigned int mtu = rtnl_link_get_mtu(link); - interface->ipv6.forwarding = forwarding; + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_ipv6_set_mtu(ipv6, (uint16_t)mtu), error_out); + + goto out; + +error_out: + error = -1; out: + return error; } - diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.h b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.h index 80a9daa4..342f4e71 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.h +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.h @@ -1,20 +1,13 @@ -#ifndef INTERFACES_PLUGIN_API_INTERFACES_IPV6_LOAD_H -#define INTERFACES_PLUGIN_API_INTERFACES_IPV6_LOAD_H +#ifndef INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV6_LOAD_H +#define INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV6_LOAD_H #include "plugin/context.h" #include "plugin/data/interfaces/interface.h" #include "plugin/data/interfaces/interface/linked_list.h" #include "plugin/types.h" -int interfaces_add_address_ipv6(interfaces_interface_ipv6_address_element_t **address, char *ip, char *netmask); - -int interfaces_add_neighbor_ipv6(interfaces_interface_ipv6_neighbor_element_t** neighbor, char *dst_addr, char *ll_addr); - -unsigned int interfaces_get_ipv6_mtu(struct rtnl_link* link, interfaces_interface_t* interface); - -unsigned int interfaces_get_ipv6_enabled(interfaces_interface_t* interface); - -unsigned int interfaces_get_ipv6_forwarding(interfaces_interface_t* interface); - -#endif /* INTERFACES_PLUGIN_API_INTERFACES_IPV6_LOAD_H */ +int interfaces_interface_ipv6_load_enabled(interfaces_ctx_t* ctx, interfaces_interface_ipv6_t* ipv6, struct rtnl_link* link); +int interfaces_interface_ipv6_load_forwarding(interfaces_ctx_t* ctx, interfaces_interface_ipv6_t* ipv6, struct rtnl_link* link); +int interfaces_interface_ipv6_load_mtu(interfaces_ctx_t* ctx, interfaces_interface_ipv6_t* ipv6, struct rtnl_link* link); +#endif // INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV6_LOAD_H diff --git a/src/interfaces/src/plugin/data/interfaces/interface.c b/src/interfaces/src/plugin/data/interfaces/interface.c index e26432cd..086376c4 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface.c +++ b/src/interfaces/src/plugin/data/interfaces/interface.c @@ -1,4 +1,5 @@ #include "interface.h" +#include "interface/ipv4.h" #include "libyang/tree_data.h" #include "plugin/common.h" #include "srpc/ly_tree.h" @@ -176,18 +177,18 @@ int interfaces_interface_hash_from_ly(interfaces_interface_hash_element_t** if_h } if (ipv4_enabled_node) { - SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_ipv4_enabled(&new_element, strcmp(lyd_get_value(ipv4_enabled_node), "true") == 0 ? 1 : 0), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_ipv4_set_enabled(&new_element->interface.ipv4, strcmp(lyd_get_value(ipv4_enabled_node), "true") == 0 ? 1 : 0), error_out); } if (ipv4_forwarding_node) { - SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_ipv4_forwarding(&new_element, strcmp(lyd_get_value(ipv4_forwarding_node), "true") == 0 ? 1 : 0), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_ipv4_set_forwarding(&new_element->interface.ipv4, strcmp(lyd_get_value(ipv4_forwarding_node), "true") == 0 ? 1 : 0), error_out); } if (ipv4_mtu_node) { const char* mtu_str = lyd_get_value(ipv4_mtu_node); uint16_t mtu = (uint16_t)atoi(mtu_str); - SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_set_ipv4_mtu(&new_element, mtu), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_element_ipv4_set_mtu(&new_element->interface.ipv4, mtu), error_out); } // init every list @@ -432,6 +433,7 @@ int interfaces_interface_hash_element_set_encapsulation(interfaces_interface_has (*el)->interface.encapsulation = encapsulation; (*el)->interface.encapsulation.dot1q_vlan.outer_tag.tag_type = xstrdup(encapsulation.dot1q_vlan.outer_tag.tag_type); (*el)->interface.encapsulation.dot1q_vlan.second_tag.tag_type = xstrdup(encapsulation.dot1q_vlan.second_tag.tag_type); + return 0; } @@ -469,62 +471,6 @@ int interfaces_interface_hash_element_set_parent_interface(interfaces_interface_ return 0; } -int interfaces_interface_hash_element_set_ipv4(interfaces_interface_hash_element_t** el, interfaces_interface_ipv4_t ipv4) -{ - (*el)->interface.ipv4 = ipv4; - - return 0; -} - -int interfaces_interface_hash_element_set_ipv4_enabled(interfaces_interface_hash_element_t** el, uint8_t enabled) -{ - (*el)->interface.ipv4.enabled = enabled; - - return 0; -} - -int interfaces_interface_hash_element_set_ipv4_forwarding(interfaces_interface_hash_element_t** el, uint8_t forwarding) -{ - (*el)->interface.ipv4.forwarding = forwarding; - - return 0; -} - -int interfaces_interface_hash_element_set_ipv4_mtu(interfaces_interface_hash_element_t** el, uint16_t mtu) -{ - (*el)->interface.ipv4.mtu = mtu; - - return 0; -} - -int interfaces_interface_hash_element_set_ipv6(interfaces_interface_hash_element_t** el, interfaces_interface_ipv6_t ipv6) -{ - (*el)->interface.ipv6 = ipv6; - - return 0; -} - -int interfaces_interface_hash_element_set_ipv6_enabled(interfaces_interface_hash_element_t** el, uint8_t enabled) -{ - (*el)->interface.ipv6.enabled = enabled; - - return 0; -} - -int interfaces_interface_hash_element_set_ipv6_forwarding(interfaces_interface_hash_element_t** el, uint8_t forwarding) -{ - (*el)->interface.ipv6.forwarding = forwarding; - - return 0; -} - -int interfaces_interface_hash_element_set_ipv6_mtu(interfaces_interface_hash_element_t** el, uint16_t mtu) -{ - (*el)->interface.ipv6.mtu = mtu; - - return 0; -} - int interfaces_interface_type_nl2ly(const char* nl_type, const char** ly_type) { int error = 0; diff --git a/src/interfaces/src/plugin/data/interfaces/interface.h b/src/interfaces/src/plugin/data/interfaces/interface.h index e65fd969..2c62cff7 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface.h +++ b/src/interfaces/src/plugin/data/interfaces/interface.h @@ -33,24 +33,6 @@ int interfaces_interface_hash_element_set_loopback(interfaces_interface_hash_ele int interfaces_interface_hash_element_set_max_frame_size(interfaces_interface_hash_element_t** el, uint32_t max_frame_size); int interfaces_interface_hash_element_set_parent_interface(interfaces_interface_hash_element_t** el, const char* parent_interface); -/* - IPv4 -*/ - -int interfaces_interface_hash_element_set_ipv4(interfaces_interface_hash_element_t** el, interfaces_interface_ipv4_t ipv4); -int interfaces_interface_hash_element_set_ipv4_enabled(interfaces_interface_hash_element_t** el, uint8_t enabled); -int interfaces_interface_hash_element_set_ipv4_forwarding(interfaces_interface_hash_element_t** el, uint8_t forwarding); -int interfaces_interface_hash_element_set_ipv4_mtu(interfaces_interface_hash_element_t** el, uint16_t mtu); - -/* - IPv6 -*/ - -int interfaces_interface_hash_element_set_ipv6(interfaces_interface_hash_element_t** el, interfaces_interface_ipv6_t ipv6); -int interfaces_interface_hash_element_set_ipv6_enabled(interfaces_interface_hash_element_t** el, uint8_t enabled); -int interfaces_interface_hash_element_set_ipv6_forwarding(interfaces_interface_hash_element_t** el, uint8_t forwarding); -int interfaces_interface_hash_element_set_ipv6_mtu(interfaces_interface_hash_element_t** el, uint16_t mtu); - /* Helper functionality. */ diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv4.c b/src/interfaces/src/plugin/data/interfaces/interface/ipv4.c new file mode 100644 index 00000000..cbb7e4dd --- /dev/null +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv4.c @@ -0,0 +1,22 @@ +#include "ipv4.h" + +int interfaces_interface_hash_element_ipv4_set_enabled(interfaces_interface_ipv4_t* ipv4, uint8_t enabled) +{ + ipv4->enabled = enabled; + + return 0; +} + +int interfaces_interface_hash_element_ipv4_set_forwarding(interfaces_interface_ipv4_t* ipv4, uint8_t forwarding) +{ + ipv4->forwarding = forwarding; + + return 0; +} + +int interfaces_interface_hash_element_ipv4_set_mtu(interfaces_interface_ipv4_t* ipv4, uint16_t mtu) +{ + ipv4->mtu = mtu; + + return 0; +} diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv4.h b/src/interfaces/src/plugin/data/interfaces/interface/ipv4.h new file mode 100644 index 00000000..61fb3f4a --- /dev/null +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv4.h @@ -0,0 +1,10 @@ +#ifndef INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV4_H +#define INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV4_H + +#include "plugin/types.h" + +int interfaces_interface_hash_element_ipv4_set_enabled(interfaces_interface_ipv4_t* ipv4, uint8_t enabled); +int interfaces_interface_hash_element_ipv4_set_forwarding(interfaces_interface_ipv4_t* ipv4, uint8_t forwarding); +int interfaces_interface_hash_element_ipv4_set_mtu(interfaces_interface_ipv4_t* ipv4, uint16_t mtu); + +#endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV4_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv6.c b/src/interfaces/src/plugin/data/interfaces/interface/ipv6.c new file mode 100644 index 00000000..36dbbbe1 --- /dev/null +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv6.c @@ -0,0 +1,22 @@ +#include "ipv6.h" + +int interfaces_interface_hash_element_ipv6_set_enabled(interfaces_interface_ipv6_t* ipv6, uint8_t enabled) +{ + ipv6->enabled = enabled; + + return 0; +} + +int interfaces_interface_hash_element_ipv6_set_forwarding(interfaces_interface_ipv6_t* ipv6, uint8_t forwarding) +{ + ipv6->forwarding = forwarding; + + return 0; +} + +int interfaces_interface_hash_element_ipv6_set_mtu(interfaces_interface_ipv6_t* ipv6, uint16_t mtu) +{ + ipv6->mtu = mtu; + + return 0; +} diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv6.h b/src/interfaces/src/plugin/data/interfaces/interface/ipv6.h new file mode 100644 index 00000000..302671af --- /dev/null +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv6.h @@ -0,0 +1,10 @@ +#ifndef INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV6_H +#define INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV6_H + +#include "plugin/types.h" + +int interfaces_interface_hash_element_ipv6_set_enabled(interfaces_interface_ipv6_t* ipv6, uint8_t enabled); +int interfaces_interface_hash_element_ipv6_set_forwarding(interfaces_interface_ipv6_t* ipv6, uint8_t forwarding); +int interfaces_interface_hash_element_ipv6_set_mtu(interfaces_interface_ipv6_t* ipv6, uint16_t mtu); + +#endif // INTERFACES_PLUGIN_DATA_INTERFACES_INTERFACE_IPV6_H \ No newline at end of file From 7f8be4d902a76c26f6068837f5b6ac5bda7c043c Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Mon, 31 Oct 2022 20:09:41 +0000 Subject: [PATCH 222/247] interfaces-plugin: add startup context --- src/interfaces/src/plugin.c | 2 +- .../api/interfaces/interface/ipv4/load.c | 12 ++++++ .../api/interfaces/interface/ipv4/load.h | 2 + .../src/plugin/api/interfaces/load.c | 41 ++++++++++++++----- src/interfaces/src/plugin/context.h | 11 ++++- 5 files changed, 55 insertions(+), 13 deletions(-) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index 8d5da0fa..3e776bf4 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -282,7 +282,7 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) // start a session SRPC_SAFE_CALL_ERR(error, sr_session_start(connection, SR_DS_STARTUP, &startup_session), error_out); - ctx->startup_session = startup_session; + ctx->startup_ctx.startup_session = startup_session; SRPC_SAFE_CALL_ERR(error, srpc_check_empty_datastore(startup_session, INTERFACES_INTERFACES_INTERFACE_YANG_PATH, &empty_startup), error_out); diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c index ed6c5ba8..efbce678 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c @@ -46,3 +46,15 @@ int interfaces_interface_ipv4_load_mtu(interfaces_ctx_t* ctx, interfaces_interfa return error; } + +int interfaces_interface_ipv4_load_address(interfaces_ctx_t* ctx, interfaces_interface_ipv4_t* ipv4, struct rtnl_link* link) +{ + int error = 0; + return error; +} + +int interfaces_interface_ipv4_load_neighbor(interfaces_ctx_t* ctx, interfaces_interface_ipv4_t* ipv4, struct rtnl_link* link) +{ + int error = 0; + return error; +} diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.h b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.h index 6adeff9f..d8bbd4b2 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.h +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.h @@ -9,5 +9,7 @@ int interfaces_interface_ipv4_load_enabled(interfaces_ctx_t* ctx, interfaces_interface_ipv4_t* ipv4, struct rtnl_link* link); int interfaces_interface_ipv4_load_forwarding(interfaces_ctx_t* ctx, interfaces_interface_ipv4_t* ipv4, struct rtnl_link* link); int interfaces_interface_ipv4_load_mtu(interfaces_ctx_t* ctx, interfaces_interface_ipv4_t* ipv4, struct rtnl_link* link); +int interfaces_interface_ipv4_load_address(interfaces_ctx_t* ctx, interfaces_interface_ipv4_t* ipv4, struct rtnl_link* link); +int interfaces_interface_ipv4_load_neighbor(interfaces_ctx_t* ctx, interfaces_interface_ipv4_t* ipv4, struct rtnl_link* link); #endif // INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV4_LOAD_H diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index e2ee6234..aba97c39 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -2,6 +2,7 @@ #include "interface/ipv4/load.h" #include "interface/ipv6/load.h" #include "plugin/common.h" +#include "plugin/context.h" #include "plugin/data/interfaces/interface.h" #include "plugin/types.h" #include "read.h" @@ -36,23 +37,25 @@ int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_element_t** if_hash) { int error = 0; - struct nl_sock* socket = NULL; - struct nl_cache* link_cache = NULL; - struct rtnl_link* link_iter = NULL; + + // ctx + interfaces_startup_ctx_t* startup_ctx = &ctx->startup_ctx; + interfaces_nl_ctx_t* nl_ctx = &startup_ctx->nl_ctx; // temp data interfaces_interface_hash_element_t* new_element = NULL; + struct rtnl_link* link_iter = NULL; // init hash *if_hash = interfaces_interface_hash_new(); // socket + cache - SRPC_SAFE_CALL_PTR(socket, nl_socket_alloc(), error_out); - SRPC_SAFE_CALL_ERR(error, nl_connect(socket, NETLINK_ROUTE), error_out); - SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(socket, AF_UNSPEC, &link_cache), error_out); + SRPC_SAFE_CALL_PTR(nl_ctx->socket, nl_socket_alloc(), error_out); + SRPC_SAFE_CALL_ERR(error, nl_connect(nl_ctx->socket, NETLINK_ROUTE), error_out); + SRPC_SAFE_CALL_ERR(error, rtnl_link_alloc_cache(nl_ctx->socket, AF_UNSPEC, &nl_ctx->link_cache), error_out); // get link iterator - SRPC_SAFE_CALL_PTR(link_iter, (struct rtnl_link*)nl_cache_get_first(link_cache), error_out); + SRPC_SAFE_CALL_PTR(link_iter, (struct rtnl_link*)nl_cache_get_first(nl_ctx->link_cache), error_out); // iterate links while (link_iter) { @@ -65,6 +68,18 @@ int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_e SRPC_SAFE_CALL_ERR(error, interfaces_interface_load_enabled(ctx, &new_element, link_iter), error_out); // load interface IPv4 data + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_load_enabled(ctx, &new_element->interface.ipv4, link_iter), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_load_forwarding(ctx, &new_element->interface.ipv4, link_iter), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_load_mtu(ctx, &new_element->interface.ipv4, link_iter), error_out); + + // load interface IPv6 data + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv6_load_enabled(ctx, &new_element->interface.ipv6, link_iter), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv6_load_forwarding(ctx, &new_element->interface.ipv6, link_iter), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv6_load_mtu(ctx, &new_element->interface.ipv6, link_iter), error_out); + + // load IPv4 address and neighbor lists + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_load_address(ctx, &new_element->interface.ipv4, link_iter), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_load_neighbor(ctx, &new_element->interface.ipv4, link_iter), error_out); } goto out; @@ -73,13 +88,17 @@ int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_e error = -1; out: - if (socket != NULL) { - nl_socket_free(socket); + // dealloc nl_ctx data + + if (nl_ctx->socket != NULL) { + nl_socket_free(nl_ctx->socket); } - if (link_cache != NULL) { - nl_cache_free(link_cache); + if (nl_ctx->link_cache != NULL) { + nl_cache_free(nl_ctx->link_cache); } + // address and neighbor caches should be freed by their functions (_load_address and _load_neighbor) + return error; } \ No newline at end of file diff --git a/src/interfaces/src/plugin/context.h b/src/interfaces/src/plugin/context.h index f34160c0..f9fe3e41 100644 --- a/src/interfaces/src/plugin/context.h +++ b/src/interfaces/src/plugin/context.h @@ -16,6 +16,7 @@ typedef struct interfaces_ctx_s interfaces_ctx_t; typedef struct interfaces_state_changes_ctx_s interfaces_state_changes_ctx_t; typedef struct interfaces_mod_changes_ctx_s interfaces_mod_changes_ctx_t; typedef struct interfaces_oper_ctx_s interfaces_oper_ctx_t; +typedef struct interfaces_startup_ctx_s interfaces_startup_ctx_t; typedef struct interfaces_features_ctx_s interfaces_features_ctx_t; struct interfaces_features_ctx_s { @@ -83,10 +84,18 @@ struct interfaces_oper_ctx_s { interfaces_state_changes_ctx_t state_changes_ctx; }; -struct interfaces_ctx_s { +struct interfaces_startup_ctx_s { // startup DS sr_session_ctx_t* startup_session; + // libnl context + interfaces_nl_ctx_t nl_ctx; +}; + +struct interfaces_ctx_s { + // startup data + interfaces_startup_ctx_t startup_ctx; + // module changes data interfaces_mod_changes_ctx_t mod_ctx; From 43f3ce7e2b32e9bfa4d8c4730d83a883bd9dcd2b Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Mon, 31 Oct 2022 20:42:28 +0000 Subject: [PATCH 223/247] interfaces-plugin: add IPv4 and IPv6 address and neighbor load API --- src/interfaces/CMakeLists.txt | 4 + .../interfaces/interface/ipv4/address/load.c | 52 +++++++++ .../interfaces/interface/ipv4/address/load.h | 11 ++ .../api/interfaces/interface/ipv4/load.c | 105 ++++++++++++++++++ .../interfaces/interface/ipv4/neighbor/load.c | 58 ++++++++++ .../interfaces/interface/ipv4/neighbor/load.h | 11 ++ .../interfaces/interface/ipv6/address/load.c | 52 +++++++++ .../interfaces/interface/ipv6/address/load.h | 11 ++ .../interfaces/interface/ipv6/neighbor/load.c | 58 ++++++++++ .../interfaces/interface/ipv6/neighbor/load.h | 11 ++ .../src/plugin/api/interfaces/load.c | 3 + .../data/interfaces/interface/ipv4/address.c | 46 +------- .../data/interfaces/interface/ipv4/address.h | 1 - 13 files changed, 377 insertions(+), 46 deletions(-) create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/load.c create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/load.h create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/load.c create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/load.h create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/load.c create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/load.h create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/load.c create mode 100644 src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/load.h diff --git a/src/interfaces/CMakeLists.txt b/src/interfaces/CMakeLists.txt index 41f1a22b..96f1b6d5 100644 --- a/src/interfaces/CMakeLists.txt +++ b/src/interfaces/CMakeLists.txt @@ -38,11 +38,15 @@ set( src/plugin/api/interfaces/interface/ipv6/change.c src/plugin/api/interfaces/interface/ipv6/autoconf/change.c src/plugin/api/interfaces/interface/ipv6/neighbor/change.c + src/plugin/api/interfaces/interface/ipv6/neighbor/load.c src/plugin/api/interfaces/interface/ipv6/address/change.c + src/plugin/api/interfaces/interface/ipv6/address/load.c src/plugin/api/interfaces/interface/ipv4/change.c src/plugin/api/interfaces/interface/ipv4/load.c src/plugin/api/interfaces/interface/ipv4/neighbor/change.c + src/plugin/api/interfaces/interface/ipv4/neighbor/load.c src/plugin/api/interfaces/interface/ipv4/address/change.c + src/plugin/api/interfaces/interface/ipv4/address/load.c src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/second-tag/change.c src/plugin/api/interfaces/interface/encapsulation/dot1q-vlan/outer-tag/change.c src/plugin/api/interfaces/interface/dampening/change.c diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/load.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/load.c new file mode 100644 index 00000000..95985878 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/load.c @@ -0,0 +1,52 @@ +#include "load.h" +#include "netlink/addr.h" +#include "netlink/route/addr.h" +#include "plugin/data/interfaces/interface/ipv4/address.h" + +int interfaces_interface_ipv4_address_load_ip(interfaces_ctx_t* ctx, interfaces_interface_ipv4_address_element_t** element, struct rtnl_addr* addr) +{ + int error = 0; + void* error_ptr = NULL; + char ip_buffer[100] = { 0 }; + + // convert to nl_addr + struct nl_addr* local = rtnl_addr_get_local(addr); + + // parse to string + SRPC_SAFE_CALL_PTR(error_ptr, nl_addr2str(local, ip_buffer, sizeof(ip_buffer)), error_out); + + char* prefix = strchr(ip_buffer, '/'); + if (prefix) { + *prefix = 0; + } + + // set IP + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_address_element_set_ip(element, ip_buffer), error_out); + + goto out; + +error_out: + error = -1; + +out: + + return error; +} + +int interfaces_interface_ipv4_address_load_prefix_length(interfaces_ctx_t* ctx, interfaces_interface_ipv4_address_element_t** element, struct rtnl_addr* addr) +{ + int error = 0; + + const uint8_t prefix = (uint8_t)rtnl_addr_get_prefixlen(addr); + + // set prefix length + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_address_element_set_prefix_length(element, prefix), error_out); + + goto out; + +error_out: + error = -1; + +out: + return error; +} diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/load.h b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/load.h new file mode 100644 index 00000000..84288cea --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/address/load.h @@ -0,0 +1,11 @@ +#ifndef INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV4_ADDRESS_LOAD_H +#define INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV4_ADDRESS_LOAD_H + +#include "netlink/route/addr.h" +#include "plugin/context.h" +#include "plugin/types.h" + +int interfaces_interface_ipv4_address_load_ip(interfaces_ctx_t* ctx, interfaces_interface_ipv4_address_element_t** element, struct rtnl_addr* addr); +int interfaces_interface_ipv4_address_load_prefix_length(interfaces_ctx_t* ctx, interfaces_interface_ipv4_address_element_t** element, struct rtnl_addr* addr); + +#endif // INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV4_ADDRESS_LOAD_H diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c index efbce678..8d1b0ff7 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c @@ -1,7 +1,14 @@ #include "load.h" +#include "netlink/route/addr.h" #include "netlink/route/link.h" +#include "netlink/route/neighbour.h" +#include "plugin/api/interfaces/interface/ipv4/address/load.h" +#include "plugin/api/interfaces/interface/ipv4/neighbor/load.h" +#include "plugin/context.h" #include "plugin/data/interfaces/interface.h" #include "plugin/data/interfaces/interface/ipv4.h" +#include "plugin/data/interfaces/interface/ipv4/address.h" +#include "plugin/types.h" int interfaces_interface_ipv4_load_enabled(interfaces_ctx_t* ctx, interfaces_interface_ipv4_t* ipv4, struct rtnl_link* link) { @@ -50,11 +57,109 @@ int interfaces_interface_ipv4_load_mtu(interfaces_ctx_t* ctx, interfaces_interfa int interfaces_interface_ipv4_load_address(interfaces_ctx_t* ctx, interfaces_interface_ipv4_t* ipv4, struct rtnl_link* link) { int error = 0; + interfaces_nl_ctx_t* nl_ctx = &ctx->startup_ctx.nl_ctx; + struct rtnl_addr* addr_iter = NULL; + + // created element + interfaces_interface_ipv4_address_element_t* new_element = NULL; + uint8_t element_added = 0; + + // allocate address list + ipv4->address = interfaces_interface_ipv4_address_new(); + + // allocate cache + SRPC_SAFE_CALL_ERR(error, rtnl_addr_alloc_cache(nl_ctx->socket, &nl_ctx->addr_cache), error_out); + + // get link iterator + SRPC_SAFE_CALL_PTR(addr_iter, (struct rtnl_addr*)nl_cache_get_first(nl_ctx->addr_cache), error_out); + + // iterate links + while (addr_iter) { + // get all addresses from the link and extract info + if (rtnl_addr_get_ifindex(addr_iter) == rtnl_link_get_ifindex(link) && rtnl_addr_get_family(addr_iter) == AF_INET) { + // create new element + new_element = interfaces_interface_ipv4_address_element_new(); + element_added = 0; + + // load IP and prefix + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_address_load_ip(ctx, &new_element, addr_iter), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_address_load_prefix_length(ctx, &new_element, addr_iter), error_out); + + // add element to the list + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_address_add_element(&ipv4->address, new_element), error_out); + element_added = 1; + } + + // iterate + SRPC_SAFE_CALL_PTR(addr_iter, (struct rtnl_addr*)nl_cache_get_next((struct nl_object*)addr_iter), error_out); + } + + goto out; + +error_out: + error = -1; + + // if interrupted see if any memory is left over from the allocated element - free the element + if (!element_added) { + interfaces_interface_ipv4_address_element_free(&new_element); + } + +out: + return error; } int interfaces_interface_ipv4_load_neighbor(interfaces_ctx_t* ctx, interfaces_interface_ipv4_t* ipv4, struct rtnl_link* link) { int error = 0; + interfaces_nl_ctx_t* nl_ctx = &ctx->startup_ctx.nl_ctx; + struct rtnl_neigh* neigh_iter = NULL; + + // created element + interfaces_interface_ipv4_neighbor_element_t* new_element = NULL; + uint8_t element_added = 0; + + // allocate address list + ipv4->neighbor = interfaces_interface_ipv4_neighbor_new(); + + // allocate cache + SRPC_SAFE_CALL_ERR(error, rtnl_neigh_alloc_cache(nl_ctx->socket, &nl_ctx->neigh_cache), error_out); + + // get link iterator + SRPC_SAFE_CALL_PTR(neigh_iter, (struct rtnl_neigh*)nl_cache_get_first(nl_ctx->addr_cache), error_out); + + // iterate links + while (neigh_iter) { + // get all neighbors from the link and extract info + if (rtnl_neigh_get_ifindex(neigh_iter) == rtnl_link_get_ifindex(link) && rtnl_neigh_get_family(neigh_iter) == AF_INET) { + // create new element + new_element = interfaces_interface_ipv4_neighbor_element_new(); + element_added = 0; + + // load IP and prefix + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_neighbor_load_ip(ctx, &new_element, neigh_iter), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_neighbor_load_link_layer_address(ctx, &new_element, neigh_iter), error_out); + + // add element to the list + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_neighbor_add_element(&ipv4->neighbor, new_element), error_out); + element_added = 1; + } + + // iterate + SRPC_SAFE_CALL_PTR(neigh_iter, (struct rtnl_neigh*)nl_cache_get_next((struct nl_object*)neigh_iter), error_out); + } + + goto out; + +error_out: + error = -1; + + // if interrupted see if any memory is left over from the allocated element - free the element + if (!element_added) { + interfaces_interface_ipv4_neighbor_element_free(&new_element); + } + +out: + return error; } diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/load.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/load.c new file mode 100644 index 00000000..63540792 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/load.c @@ -0,0 +1,58 @@ +#include "load.h" +#include "netlink/route/neighbour.h" +#include "plugin/data/interfaces/interface/ipv4/neighbor.h" + +int interfaces_interface_ipv4_neighbor_load_ip(interfaces_ctx_t* ctx, interfaces_interface_ipv4_neighbor_element_t** element, struct rtnl_neigh* neigh) +{ + int error = 0; + void* error_ptr = NULL; + char ip_buffer[100] = { 0 }; + + // convert to nl_addr + struct nl_addr* dst = rtnl_neigh_get_dst(neigh); + + // parse to string + SRPC_SAFE_CALL_PTR(error_ptr, nl_addr2str(dst, ip_buffer, sizeof(ip_buffer)), error_out); + + char* prefix = strchr(ip_buffer, '/'); + if (prefix) { + *prefix = 0; + } + + // set IP + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_neighbor_element_set_ip(element, ip_buffer), error_out); + + goto out; + +error_out: + error = -1; + +out: + + return error; +} + +int interfaces_interface_ipv4_neighbor_load_link_layer_address(interfaces_ctx_t* ctx, interfaces_interface_ipv4_neighbor_element_t** element, struct rtnl_neigh* neigh) +{ + int error = 0; + void* error_ptr = NULL; + char lladdr_buffer[100] = { 0 }; + + // convert to nl_addr + struct nl_addr* dst = rtnl_neigh_get_lladdr(neigh); + + // parse to string + SRPC_SAFE_CALL_PTR(error_ptr, nl_addr2str(dst, lladdr_buffer, sizeof(lladdr_buffer)), error_out); + + // set lladdr + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_neighbor_element_set_link_layer_address(element, lladdr_buffer), error_out); + + goto out; + +error_out: + error = -1; + +out: + + return error; +} diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/load.h b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/load.h new file mode 100644 index 00000000..74dc942e --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/neighbor/load.h @@ -0,0 +1,11 @@ +#ifndef INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV4_NEIGHBOR_LOAD_H +#define INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV4_NEIGHBOR_LOAD_H + +#include "netlink/route/neighbour.h" +#include "plugin/context.h" +#include "plugin/types.h" + +int interfaces_interface_ipv4_neighbor_load_ip(interfaces_ctx_t* ctx, interfaces_interface_ipv4_neighbor_element_t** element, struct rtnl_neigh* neigh); +int interfaces_interface_ipv4_neighbor_load_link_layer_address(interfaces_ctx_t* ctx, interfaces_interface_ipv4_neighbor_element_t** element, struct rtnl_neigh* neigh); + +#endif // INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV4_NEIGHBOR_LOAD_H diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/load.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/load.c new file mode 100644 index 00000000..1dda97ff --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/load.c @@ -0,0 +1,52 @@ +#include "load.h" +#include "netlink/addr.h" +#include "netlink/route/addr.h" +#include "plugin/data/interfaces/interface/ipv6/address.h" + +int interfaces_interface_ipv6_address_load_ip(interfaces_ctx_t* ctx, interfaces_interface_ipv6_address_element_t** element, struct rtnl_addr* addr) +{ + int error = 0; + void* error_ptr = NULL; + char ip_buffer[100] = { 0 }; + + // convert to nl_addr + struct nl_addr* local = rtnl_addr_get_local(addr); + + // parse to string + SRPC_SAFE_CALL_PTR(error_ptr, nl_addr2str(local, ip_buffer, sizeof(ip_buffer)), error_out); + + char* prefix = strchr(ip_buffer, '/'); + if (prefix) { + *prefix = 0; + } + + // set IP + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv6_address_element_set_ip(element, ip_buffer), error_out); + + goto out; + +error_out: + error = -1; + +out: + + return error; +} + +int interfaces_interface_ipv6_address_load_prefix_length(interfaces_ctx_t* ctx, interfaces_interface_ipv6_address_element_t** element, struct rtnl_addr* addr) +{ + int error = 0; + + const uint8_t prefix = (uint8_t)rtnl_addr_get_prefixlen(addr); + + // set prefix length + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv6_address_element_set_prefix_length(element, prefix), error_out); + + goto out; + +error_out: + error = -1; + +out: + return error; +} diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/load.h b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/load.h new file mode 100644 index 00000000..140245fe --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/address/load.h @@ -0,0 +1,11 @@ +#ifndef INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV6_ADDRESS_LOAD_H +#define INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV6_ADDRESS_LOAD_H + +#include "netlink/route/addr.h" +#include "plugin/context.h" +#include "plugin/types.h" + +int interfaces_interface_ipv6_address_load_ip(interfaces_ctx_t* ctx, interfaces_interface_ipv6_address_element_t** element, struct rtnl_addr* addr); +int interfaces_interface_ipv6_address_load_prefix_length(interfaces_ctx_t* ctx, interfaces_interface_ipv6_address_element_t** element, struct rtnl_addr* addr); + +#endif // INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV6_ADDRESS_LOAD_H diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/load.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/load.c new file mode 100644 index 00000000..1301f6f8 --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/load.c @@ -0,0 +1,58 @@ +#include "load.h" +#include "netlink/route/neighbour.h" +#include "plugin/data/interfaces/interface/ipv6/neighbor.h" + +int interfaces_interface_ipv6_neighbor_load_ip(interfaces_ctx_t* ctx, interfaces_interface_ipv6_neighbor_element_t** element, struct rtnl_neigh* neigh) +{ + int error = 0; + void* error_ptr = NULL; + char ip_buffer[100] = { 0 }; + + // convert to nl_addr + struct nl_addr* dst = rtnl_neigh_get_dst(neigh); + + // parse to string + SRPC_SAFE_CALL_PTR(error_ptr, nl_addr2str(dst, ip_buffer, sizeof(ip_buffer)), error_out); + + char* prefix = strchr(ip_buffer, '/'); + if (prefix) { + *prefix = 0; + } + + // set IP + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv6_neighbor_element_set_ip(element, ip_buffer), error_out); + + goto out; + +error_out: + error = -1; + +out: + + return error; +} + +int interfaces_interface_ipv6_neighbor_load_link_layer_address(interfaces_ctx_t* ctx, interfaces_interface_ipv6_neighbor_element_t** element, struct rtnl_neigh* neigh) +{ + int error = 0; + void* error_ptr = NULL; + char lladdr_buffer[100] = { 0 }; + + // convert to nl_addr + struct nl_addr* dst = rtnl_neigh_get_lladdr(neigh); + + // parse to string + SRPC_SAFE_CALL_PTR(error_ptr, nl_addr2str(dst, lladdr_buffer, sizeof(lladdr_buffer)), error_out); + + // set lladdr + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv6_neighbor_element_set_link_layer_address(element, lladdr_buffer), error_out); + + goto out; + +error_out: + error = -1; + +out: + + return error; +} diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/load.h b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/load.h new file mode 100644 index 00000000..eb3aaa6b --- /dev/null +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/neighbor/load.h @@ -0,0 +1,11 @@ +#ifndef INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV6_NEIGHBOR_LOAD_H +#define INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV6_NEIGHBOR_LOAD_H + +#include "netlink/route/neighbour.h" +#include "plugin/context.h" +#include "plugin/types.h" + +int interfaces_interface_ipv6_neighbor_load_ip(interfaces_ctx_t* ctx, interfaces_interface_ipv6_neighbor_element_t** element, struct rtnl_neigh* neigh); +int interfaces_interface_ipv6_neighbor_load_link_layer_address(interfaces_ctx_t* ctx, interfaces_interface_ipv6_neighbor_element_t** element, struct rtnl_neigh* neigh); + +#endif // INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV6_NEIGHBOR_LOAD_H diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index aba97c39..c010ee12 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -80,6 +80,9 @@ int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_e // load IPv4 address and neighbor lists SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_load_address(ctx, &new_element->interface.ipv4, link_iter), error_out); SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_load_neighbor(ctx, &new_element->interface.ipv4, link_iter), error_out); + + // iterate + SRPC_SAFE_CALL_PTR(link_iter, (struct rtnl_link*)nl_cache_get_next((struct nl_object*)link_iter), error_out); } goto out; diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c index 39f1b508..ca810c2f 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.c @@ -1,13 +1,12 @@ #include "address.h" #include "plugin/types.h" -#include "srpc/common.h" #include "src/utlist.h" +#include "srpc/common.h" #include #include #include #include -#include #include @@ -81,49 +80,6 @@ int interfaces_interface_ipv4_address_element_set_ip(interfaces_interface_ipv4_a return 0; } -/* set (deepcopy) an IPv4 address list */ -int interfaces_interface_ipv4_address_element_set(interfaces_interface_ipv4_address_element_t** src, - interfaces_interface_ipv4_address_element_t **dst) -{ - interfaces_interface_ipv4_address_element_t *src_iter = NULL; - interfaces_interface_ipv4_address_element_t *new_elem = NULL; - - LL_FOREACH(*src, src_iter) { - new_elem = interfaces_interface_ipv4_address_element_new(); - interfaces_interface_ipv4_address_element_set_ip(&new_elem, src_iter->address.ip); - interfaces_interface_ipv4_address_element_set_prefix_length(&new_elem, - src_iter->address.subnet.prefix_length); - - interfaces_interface_ipv4_address_add_element(dst, new_elem); - } - - return 0; -} - -int interfaces_interface_ipv4_address_element_set_subnet(interfaces_interface_ipv4_address_element_t** el, char *netmask, enum interfaces_interface_ipv4_address_subnet subtype) -{ - int error = 0; - int prefix_length = 0; - - switch (subtype) { - case interfaces_interface_ipv4_address_subnet_netmask: - interfaces_interface_ipv4_address_element_set_netmask(el, netmask); - break; - case interfaces_interface_ipv4_address_subnet_prefix_length: - SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_address_netmask2prefix(netmask, prefix_length), out); - interfaces_interface_ipv4_address_element_set_prefix_length(el, prefix_length); - break; - case interfaces_interface_ipv4_address_subnet_none: - break; - default: - error = -1; - } - -out: - - return error; -} - int interfaces_interface_ipv4_address_element_set_prefix_length(interfaces_interface_ipv4_address_element_t** el, uint8_t prefix_length) { (*el)->address.subnet.prefix_length = prefix_length; diff --git a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.h b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.h index fc80b240..057cd8a0 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.h +++ b/src/interfaces/src/plugin/data/interfaces/interface/ipv4/address.h @@ -23,7 +23,6 @@ void interfaces_interface_ipv4_address_element_free(interfaces_interface_ipv4_ad int interfaces_interface_ipv4_address_element_set_ip(interfaces_interface_ipv4_address_element_t** el, const char* ip); int interfaces_interface_ipv4_address_element_set_prefix_length(interfaces_interface_ipv4_address_element_t** el, uint8_t prefix_length); int interfaces_interface_ipv4_address_element_set_netmask(interfaces_interface_ipv4_address_element_t** el, const char* netmask); -int interfaces_interface_ipv4_address_element_set(interfaces_interface_ipv4_address_element_t** src, interfaces_interface_ipv4_address_element_t **dst); /* Helper functions From 290bde5d528445190c480bbedee35b27118b2244 Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Mon, 31 Oct 2022 20:45:41 +0000 Subject: [PATCH 224/247] interfaces-plugin: load IPv6 address and neighbor list --- .../api/interfaces/interface/ipv6/load.c | 112 ++++++++++++++++++ .../api/interfaces/interface/ipv6/load.h | 2 + 2 files changed, 114 insertions(+) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.c index 8e0e2a30..3fa43d73 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.c @@ -1,5 +1,7 @@ #include "load.h" #include "netlink/route/link.h" +#include "plugin/api/interfaces/interface/ipv6/address/load.h" +#include "plugin/api/interfaces/interface/ipv6/neighbor/load.h" #include "plugin/data/interfaces/interface.h" #include "plugin/data/interfaces/interface/ipv6.h" @@ -46,3 +48,113 @@ int interfaces_interface_ipv6_load_mtu(interfaces_ctx_t* ctx, interfaces_interfa return error; } + +int interfaces_interface_ipv6_load_address(interfaces_ctx_t* ctx, interfaces_interface_ipv6_t* ipv6, struct rtnl_link* link) +{ + int error = 0; + interfaces_nl_ctx_t* nl_ctx = &ctx->startup_ctx.nl_ctx; + struct rtnl_addr* addr_iter = NULL; + + // created element + interfaces_interface_ipv6_address_element_t* new_element = NULL; + uint8_t element_added = 0; + + // allocate address list + ipv6->address = interfaces_interface_ipv6_address_new(); + + // allocate cache + SRPC_SAFE_CALL_ERR(error, rtnl_addr_alloc_cache(nl_ctx->socket, &nl_ctx->addr_cache), error_out); + + // get link iterator + SRPC_SAFE_CALL_PTR(addr_iter, (struct rtnl_addr*)nl_cache_get_first(nl_ctx->addr_cache), error_out); + + // iterate links + while (addr_iter) { + // get all addresses from the link and extract info + if (rtnl_addr_get_ifindex(addr_iter) == rtnl_link_get_ifindex(link) && rtnl_addr_get_family(addr_iter) == AF_INET6) { + // create new element + new_element = interfaces_interface_ipv6_address_element_new(); + element_added = 0; + + // load IP and prefix + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv6_address_load_ip(ctx, &new_element, addr_iter), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv6_address_load_prefix_length(ctx, &new_element, addr_iter), error_out); + + // add element to the list + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv6_address_add_element(&ipv6->address, new_element), error_out); + element_added = 1; + } + + // iterate + SRPC_SAFE_CALL_PTR(addr_iter, (struct rtnl_addr*)nl_cache_get_next((struct nl_object*)addr_iter), error_out); + } + + goto out; + +error_out: + error = -1; + + // if interrupted see if any memory is left over from the allocated element - free the element + if (!element_added) { + interfaces_interface_ipv6_address_element_free(&new_element); + } + +out: + + return error; +} + +int interfaces_interface_ipv6_load_neighbor(interfaces_ctx_t* ctx, interfaces_interface_ipv6_t* ipv6, struct rtnl_link* link) +{ + int error = 0; + interfaces_nl_ctx_t* nl_ctx = &ctx->startup_ctx.nl_ctx; + struct rtnl_neigh* neigh_iter = NULL; + + // created element + interfaces_interface_ipv6_neighbor_element_t* new_element = NULL; + uint8_t element_added = 0; + + // allocate address list + ipv6->neighbor = interfaces_interface_ipv6_neighbor_new(); + + // allocate cache + SRPC_SAFE_CALL_ERR(error, rtnl_neigh_alloc_cache(nl_ctx->socket, &nl_ctx->neigh_cache), error_out); + + // get link iterator + SRPC_SAFE_CALL_PTR(neigh_iter, (struct rtnl_neigh*)nl_cache_get_first(nl_ctx->addr_cache), error_out); + + // iterate links + while (neigh_iter) { + // get all neighbors from the link and extract info + if (rtnl_neigh_get_ifindex(neigh_iter) == rtnl_link_get_ifindex(link) && rtnl_neigh_get_family(neigh_iter) == AF_INET6) { + // create new element + new_element = interfaces_interface_ipv6_neighbor_element_new(); + element_added = 0; + + // load IP and prefix + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv6_neighbor_load_ip(ctx, &new_element, neigh_iter), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv6_neighbor_load_link_layer_address(ctx, &new_element, neigh_iter), error_out); + + // add element to the list + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv6_neighbor_add_element(&ipv6->neighbor, new_element), error_out); + element_added = 1; + } + + // iterate + SRPC_SAFE_CALL_PTR(neigh_iter, (struct rtnl_neigh*)nl_cache_get_next((struct nl_object*)neigh_iter), error_out); + } + + goto out; + +error_out: + error = -1; + + // if interrupted see if any memory is left over from the allocated element - free the element + if (!element_added) { + interfaces_interface_ipv6_neighbor_element_free(&new_element); + } + +out: + + return error; +} diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.h b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.h index 342f4e71..b92e7343 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.h +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.h @@ -9,5 +9,7 @@ int interfaces_interface_ipv6_load_enabled(interfaces_ctx_t* ctx, interfaces_interface_ipv6_t* ipv6, struct rtnl_link* link); int interfaces_interface_ipv6_load_forwarding(interfaces_ctx_t* ctx, interfaces_interface_ipv6_t* ipv6, struct rtnl_link* link); int interfaces_interface_ipv6_load_mtu(interfaces_ctx_t* ctx, interfaces_interface_ipv6_t* ipv6, struct rtnl_link* link); +int interfaces_interface_ipv6_load_address(interfaces_ctx_t* ctx, interfaces_interface_ipv6_t* ipv6, struct rtnl_link* link); +int interfaces_interface_ipv6_load_neighbor(interfaces_ctx_t* ctx, interfaces_interface_ipv6_t* ipv6, struct rtnl_link* link); #endif // INTERFACES_PLUGIN_API_INTERFACES_INTERFACE_IPV6_LOAD_H From 6ce174b395a999bc5fd78b6f29301bb8f0ee7ea3 Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Mon, 31 Oct 2022 21:17:56 +0000 Subject: [PATCH 225/247] interfaces-plugin: fix load issues --- .../api/interfaces/interface/ipv4/load.c | 6 ++- .../api/interfaces/interface/ipv6/load.c | 4 +- .../plugin/api/interfaces/interface/load.c | 4 +- .../src/plugin/api/interfaces/load.c | 17 ++++++- .../src/plugin/data/interfaces/interface.c | 4 +- src/interfaces/src/plugin/startup/load.c | 49 ++++++++++++++++++- 6 files changed, 76 insertions(+), 8 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c index 8d1b0ff7..a0641b40 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c @@ -4,11 +4,13 @@ #include "netlink/route/neighbour.h" #include "plugin/api/interfaces/interface/ipv4/address/load.h" #include "plugin/api/interfaces/interface/ipv4/neighbor/load.h" +#include "plugin/common.h" #include "plugin/context.h" #include "plugin/data/interfaces/interface.h" #include "plugin/data/interfaces/interface/ipv4.h" #include "plugin/data/interfaces/interface/ipv4/address.h" #include "plugin/types.h" +#include "sysrepo.h" int interfaces_interface_ipv4_load_enabled(interfaces_ctx_t* ctx, interfaces_interface_ipv4_t* ipv4, struct rtnl_link* link) { @@ -91,7 +93,7 @@ int interfaces_interface_ipv4_load_address(interfaces_ctx_t* ctx, interfaces_int } // iterate - SRPC_SAFE_CALL_PTR(addr_iter, (struct rtnl_addr*)nl_cache_get_next((struct nl_object*)addr_iter), error_out); + addr_iter = (struct rtnl_addr*)nl_cache_get_next((struct nl_object*)addr_iter); } goto out; @@ -146,7 +148,7 @@ int interfaces_interface_ipv4_load_neighbor(interfaces_ctx_t* ctx, interfaces_in } // iterate - SRPC_SAFE_CALL_PTR(neigh_iter, (struct rtnl_neigh*)nl_cache_get_next((struct nl_object*)neigh_iter), error_out); + neigh_iter = (struct rtnl_neigh*)nl_cache_get_next((struct nl_object*)neigh_iter); } goto out; diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.c index 3fa43d73..c467fd93 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.c @@ -86,7 +86,7 @@ int interfaces_interface_ipv6_load_address(interfaces_ctx_t* ctx, interfaces_int } // iterate - SRPC_SAFE_CALL_PTR(addr_iter, (struct rtnl_addr*)nl_cache_get_next((struct nl_object*)addr_iter), error_out); + addr_iter = (struct rtnl_addr*)nl_cache_get_next((struct nl_object*)addr_iter); } goto out; @@ -141,7 +141,7 @@ int interfaces_interface_ipv6_load_neighbor(interfaces_ctx_t* ctx, interfaces_in } // iterate - SRPC_SAFE_CALL_PTR(neigh_iter, (struct rtnl_neigh*)nl_cache_get_next((struct nl_object*)neigh_iter), error_out); + neigh_iter = (struct rtnl_neigh*)nl_cache_get_next((struct nl_object*)neigh_iter); } goto out; diff --git a/src/interfaces/src/plugin/api/interfaces/interface/load.c b/src/interfaces/src/plugin/api/interfaces/interface/load.c index 109841a7..d45c38c7 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/load.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/load.c @@ -1,5 +1,7 @@ #include "load.h" +#include "plugin/common.h" #include "plugin/data/interfaces/interface.h" +#include "sysrepo.h" #include #include @@ -31,7 +33,7 @@ int interfaces_interface_load_type(interfaces_ctx_t* ctx, interfaces_interface_h const char* nl_if_type = NULL; const char* ly_if_type = NULL; - // 2. interface type - nl version -> convert to libyang version + // interface type - nl version -> convert to libyang version nl_if_type = rtnl_link_get_type(link); SRPC_SAFE_CALL_ERR(error, interfaces_interface_type_nl2ly(nl_if_type, &ly_if_type), error_out); diff --git a/src/interfaces/src/plugin/api/interfaces/load.c b/src/interfaces/src/plugin/api/interfaces/load.c index c010ee12..2eb825de 100644 --- a/src/interfaces/src/plugin/api/interfaces/load.c +++ b/src/interfaces/src/plugin/api/interfaces/load.c @@ -44,6 +44,8 @@ int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_e // temp data interfaces_interface_hash_element_t* new_element = NULL; + uint8_t element_added = 0; + struct rtnl_link* link_iter = NULL; // init hash @@ -61,6 +63,7 @@ int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_e while (link_iter) { // allocate new element SRPC_SAFE_CALL_PTR(new_element, interfaces_interface_hash_element_new(), error_out); + element_added = 0; // load interface data SRPC_SAFE_CALL_ERR(error, interfaces_interface_load_name(ctx, &new_element, link_iter), error_out); @@ -81,8 +84,16 @@ int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_e SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_load_address(ctx, &new_element->interface.ipv4, link_iter), error_out); SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv4_load_neighbor(ctx, &new_element->interface.ipv4, link_iter), error_out); + // load IPv6 address and neighbor lists + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv6_load_address(ctx, &new_element->interface.ipv6, link_iter), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_ipv6_load_neighbor(ctx, &new_element->interface.ipv6, link_iter), error_out); + + // add element to the hash + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_add_element(if_hash, new_element), error_out); + element_added = 1; + // iterate - SRPC_SAFE_CALL_PTR(link_iter, (struct rtnl_link*)nl_cache_get_next((struct nl_object*)link_iter), error_out); + link_iter = (struct rtnl_link*)nl_cache_get_next((struct nl_object*)link_iter); } goto out; @@ -90,6 +101,10 @@ int interfaces_load_interface(interfaces_ctx_t* ctx, interfaces_interface_hash_e error_out: error = -1; + if (!element_added) { + interfaces_interface_hash_element_free(&new_element); + } + out: // dealloc nl_ctx data diff --git a/src/interfaces/src/plugin/data/interfaces/interface.c b/src/interfaces/src/plugin/data/interfaces/interface.c index 086376c4..8689497e 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface.c +++ b/src/interfaces/src/plugin/data/interfaces/interface.c @@ -476,7 +476,9 @@ int interfaces_interface_type_nl2ly(const char* nl_type, const char** ly_type) int error = 0; if (nl_type == NULL) { - return -1; + // fix for now - investigate more - lo interface has type == NULL + *ly_type = "iana-if-type:softwareLoopback"; + return 0; } if (strcmp(nl_type, "veth") == 0) { diff --git a/src/interfaces/src/plugin/startup/load.c b/src/interfaces/src/plugin/startup/load.c index 39f96bc2..0be82f13 100644 --- a/src/interfaces/src/plugin/startup/load.c +++ b/src/interfaces/src/plugin/startup/load.c @@ -1,8 +1,12 @@ #include "load.h" #include "plugin/common.h" +#include "plugin/data/interfaces/interface.h" #include "plugin/ly_tree.h" #include "plugin/api/interfaces/load.h" +#include "plugin/types.h" +#include "src/uthash.h" +#include "src/utlist.h" #include "srpc/common.h" #include @@ -81,14 +85,57 @@ static int interfaces_startup_load_interface(void* priv, sr_session_ctx_t* sessi int error = 0; interfaces_ctx_t* ctx = (interfaces_ctx_t*)priv; interfaces_interface_hash_element_t* interface_head = NULL; + // interfaces_interface_hash_element_t *iter = NULL, *tmp = NULL; + + // interfaces_interface_ipv4_address_element_t* v4_addr_iter = NULL; + // interfaces_interface_ipv6_address_element_t* v6_addr_iter = NULL; + + // interfaces_interface_ipv4_neighbor_element_t* v4_neigh_iter = NULL; + // interfaces_interface_ipv6_neighbor_element_t* v6_neigh_iter = NULL; SRPC_SAFE_CALL_ERR(error, interfaces_load_interface(ctx, &interface_head), error_out); + // HASH_ITER(hh, interface_head, iter, tmp) + // { + // SRPLG_LOG_INF(PLUGIN_NAME, "Name: %s", iter->interface.name); + // SRPLG_LOG_INF(PLUGIN_NAME, "Type: %s", iter->interface.type); + // SRPLG_LOG_INF(PLUGIN_NAME, "Enabled: %d", iter->interface.enabled); + + // // v4 + // SRPLG_LOG_INF(PLUGIN_NAME, "v4 MTU: %d", iter->interface.ipv4.mtu); + // SRPLG_LOG_INF(PLUGIN_NAME, "v4 Enabled: %d", iter->interface.ipv4.enabled); + // SRPLG_LOG_INF(PLUGIN_NAME, "v4 Forwarding: %d", iter->interface.ipv4.forwarding); + + // LL_FOREACH(iter->interface.ipv4.address, v4_addr_iter) + // { + // SRPLG_LOG_INF(PLUGIN_NAME, "v4 Address : %s/%d", v4_addr_iter->address.ip, v4_addr_iter->address.subnet.prefix_length); + // } + // LL_FOREACH(iter->interface.ipv4.neighbor, v4_neigh_iter) + // { + // SRPLG_LOG_INF(PLUGIN_NAME, "v4 Neighbor : %s : %s", v4_neigh_iter->neighbor.ip, v4_neigh_iter->neighbor.link_layer_address); + // } + + // // v6 + // SRPLG_LOG_INF(PLUGIN_NAME, "v6 MTU: %d", iter->interface.ipv6.mtu); + // SRPLG_LOG_INF(PLUGIN_NAME, "v6 Enabled: %d", iter->interface.ipv6.enabled); + // SRPLG_LOG_INF(PLUGIN_NAME, "v6 Forwarding: %d", iter->interface.ipv6.forwarding); + + // LL_FOREACH(iter->interface.ipv6.address, v6_addr_iter) + // { + // SRPLG_LOG_INF(PLUGIN_NAME, "v6 Address : %s/%d", v6_addr_iter->address.ip, v6_addr_iter->address.prefix_length); + // } + // LL_FOREACH(iter->interface.ipv6.neighbor, v6_neigh_iter) + // { + // SRPLG_LOG_INF(PLUGIN_NAME, "v6 Neighbor : %s : %s", v6_neigh_iter->neighbor.ip, v6_neigh_iter->neighbor.link_layer_address); + // } + // } + goto out; error_out: error = -1; out: + interfaces_interface_hash_free(&interface_head); + return error; } - From faf3b46d5bc54508d81a97c2aa2ba1b4fdcba2c9 Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Mon, 31 Oct 2022 21:19:54 +0000 Subject: [PATCH 226/247] interfaces-plugin: fix neighbor loading issues --- .../api/interfaces/interface/ipv4/load.c | 2 +- .../api/interfaces/interface/ipv6/load.c | 2 +- src/interfaces/src/plugin/startup/load.c | 78 +++++++++---------- 3 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c index a0641b40..dbecfd2c 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c @@ -128,7 +128,7 @@ int interfaces_interface_ipv4_load_neighbor(interfaces_ctx_t* ctx, interfaces_in SRPC_SAFE_CALL_ERR(error, rtnl_neigh_alloc_cache(nl_ctx->socket, &nl_ctx->neigh_cache), error_out); // get link iterator - SRPC_SAFE_CALL_PTR(neigh_iter, (struct rtnl_neigh*)nl_cache_get_first(nl_ctx->addr_cache), error_out); + SRPC_SAFE_CALL_PTR(neigh_iter, (struct rtnl_neigh*)nl_cache_get_first(nl_ctx->neigh_cache), error_out); // iterate links while (neigh_iter) { diff --git a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.c b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.c index c467fd93..a204546e 100644 --- a/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.c +++ b/src/interfaces/src/plugin/api/interfaces/interface/ipv6/load.c @@ -121,7 +121,7 @@ int interfaces_interface_ipv6_load_neighbor(interfaces_ctx_t* ctx, interfaces_in SRPC_SAFE_CALL_ERR(error, rtnl_neigh_alloc_cache(nl_ctx->socket, &nl_ctx->neigh_cache), error_out); // get link iterator - SRPC_SAFE_CALL_PTR(neigh_iter, (struct rtnl_neigh*)nl_cache_get_first(nl_ctx->addr_cache), error_out); + SRPC_SAFE_CALL_PTR(neigh_iter, (struct rtnl_neigh*)nl_cache_get_first(nl_ctx->neigh_cache), error_out); // iterate links while (neigh_iter) { diff --git a/src/interfaces/src/plugin/startup/load.c b/src/interfaces/src/plugin/startup/load.c index 0be82f13..b571a19b 100644 --- a/src/interfaces/src/plugin/startup/load.c +++ b/src/interfaces/src/plugin/startup/load.c @@ -85,50 +85,50 @@ static int interfaces_startup_load_interface(void* priv, sr_session_ctx_t* sessi int error = 0; interfaces_ctx_t* ctx = (interfaces_ctx_t*)priv; interfaces_interface_hash_element_t* interface_head = NULL; - // interfaces_interface_hash_element_t *iter = NULL, *tmp = NULL; + interfaces_interface_hash_element_t *iter = NULL, *tmp = NULL; - // interfaces_interface_ipv4_address_element_t* v4_addr_iter = NULL; - // interfaces_interface_ipv6_address_element_t* v6_addr_iter = NULL; + interfaces_interface_ipv4_address_element_t* v4_addr_iter = NULL; + interfaces_interface_ipv6_address_element_t* v6_addr_iter = NULL; - // interfaces_interface_ipv4_neighbor_element_t* v4_neigh_iter = NULL; - // interfaces_interface_ipv6_neighbor_element_t* v6_neigh_iter = NULL; + interfaces_interface_ipv4_neighbor_element_t* v4_neigh_iter = NULL; + interfaces_interface_ipv6_neighbor_element_t* v6_neigh_iter = NULL; SRPC_SAFE_CALL_ERR(error, interfaces_load_interface(ctx, &interface_head), error_out); - // HASH_ITER(hh, interface_head, iter, tmp) - // { - // SRPLG_LOG_INF(PLUGIN_NAME, "Name: %s", iter->interface.name); - // SRPLG_LOG_INF(PLUGIN_NAME, "Type: %s", iter->interface.type); - // SRPLG_LOG_INF(PLUGIN_NAME, "Enabled: %d", iter->interface.enabled); - - // // v4 - // SRPLG_LOG_INF(PLUGIN_NAME, "v4 MTU: %d", iter->interface.ipv4.mtu); - // SRPLG_LOG_INF(PLUGIN_NAME, "v4 Enabled: %d", iter->interface.ipv4.enabled); - // SRPLG_LOG_INF(PLUGIN_NAME, "v4 Forwarding: %d", iter->interface.ipv4.forwarding); - - // LL_FOREACH(iter->interface.ipv4.address, v4_addr_iter) - // { - // SRPLG_LOG_INF(PLUGIN_NAME, "v4 Address : %s/%d", v4_addr_iter->address.ip, v4_addr_iter->address.subnet.prefix_length); - // } - // LL_FOREACH(iter->interface.ipv4.neighbor, v4_neigh_iter) - // { - // SRPLG_LOG_INF(PLUGIN_NAME, "v4 Neighbor : %s : %s", v4_neigh_iter->neighbor.ip, v4_neigh_iter->neighbor.link_layer_address); - // } - - // // v6 - // SRPLG_LOG_INF(PLUGIN_NAME, "v6 MTU: %d", iter->interface.ipv6.mtu); - // SRPLG_LOG_INF(PLUGIN_NAME, "v6 Enabled: %d", iter->interface.ipv6.enabled); - // SRPLG_LOG_INF(PLUGIN_NAME, "v6 Forwarding: %d", iter->interface.ipv6.forwarding); - - // LL_FOREACH(iter->interface.ipv6.address, v6_addr_iter) - // { - // SRPLG_LOG_INF(PLUGIN_NAME, "v6 Address : %s/%d", v6_addr_iter->address.ip, v6_addr_iter->address.prefix_length); - // } - // LL_FOREACH(iter->interface.ipv6.neighbor, v6_neigh_iter) - // { - // SRPLG_LOG_INF(PLUGIN_NAME, "v6 Neighbor : %s : %s", v6_neigh_iter->neighbor.ip, v6_neigh_iter->neighbor.link_layer_address); - // } - // } + HASH_ITER(hh, interface_head, iter, tmp) + { + SRPLG_LOG_INF(PLUGIN_NAME, "Name: %s", iter->interface.name); + SRPLG_LOG_INF(PLUGIN_NAME, "Type: %s", iter->interface.type); + SRPLG_LOG_INF(PLUGIN_NAME, "Enabled: %d", iter->interface.enabled); + + // v4 + SRPLG_LOG_INF(PLUGIN_NAME, "v4 MTU: %d", iter->interface.ipv4.mtu); + SRPLG_LOG_INF(PLUGIN_NAME, "v4 Enabled: %d", iter->interface.ipv4.enabled); + SRPLG_LOG_INF(PLUGIN_NAME, "v4 Forwarding: %d", iter->interface.ipv4.forwarding); + + LL_FOREACH(iter->interface.ipv4.address, v4_addr_iter) + { + SRPLG_LOG_INF(PLUGIN_NAME, "v4 Address : %s/%d", v4_addr_iter->address.ip, v4_addr_iter->address.subnet.prefix_length); + } + LL_FOREACH(iter->interface.ipv4.neighbor, v4_neigh_iter) + { + SRPLG_LOG_INF(PLUGIN_NAME, "v4 Neighbor : %s : %s", v4_neigh_iter->neighbor.ip, v4_neigh_iter->neighbor.link_layer_address); + } + + // v6 + SRPLG_LOG_INF(PLUGIN_NAME, "v6 MTU: %d", iter->interface.ipv6.mtu); + SRPLG_LOG_INF(PLUGIN_NAME, "v6 Enabled: %d", iter->interface.ipv6.enabled); + SRPLG_LOG_INF(PLUGIN_NAME, "v6 Forwarding: %d", iter->interface.ipv6.forwarding); + + LL_FOREACH(iter->interface.ipv6.address, v6_addr_iter) + { + SRPLG_LOG_INF(PLUGIN_NAME, "v6 Address : %s/%d", v6_addr_iter->address.ip, v6_addr_iter->address.prefix_length); + } + LL_FOREACH(iter->interface.ipv6.neighbor, v6_neigh_iter) + { + SRPLG_LOG_INF(PLUGIN_NAME, "v6 Neighbor : %s : %s", v6_neigh_iter->neighbor.ip, v6_neigh_iter->neighbor.link_layer_address); + } + } goto out; From 42b7dd8f4bd3fbdd46067b12f03375839457efda Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Mon, 31 Oct 2022 21:28:13 +0000 Subject: [PATCH 227/247] interfaces-plugin: setup code for hash to libyang conversion on load --- .../src/plugin/data/interfaces/interface.c | 28 +++++++--- .../src/plugin/data/interfaces/interface.h | 1 + src/interfaces/src/plugin/startup/load.c | 51 +++---------------- 3 files changed, 30 insertions(+), 50 deletions(-) diff --git a/src/interfaces/src/plugin/data/interfaces/interface.c b/src/interfaces/src/plugin/data/interfaces/interface.c index 8689497e..5e64ce4f 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface.c +++ b/src/interfaces/src/plugin/data/interfaces/interface.c @@ -86,6 +86,8 @@ void interfaces_interface_hash_print_debug(const interfaces_interface_hash_eleme const interfaces_interface_hash_element_t *iter = NULL, *tmp = NULL; interfaces_interface_ipv4_address_element_t* v4addr_iter = NULL; interfaces_interface_ipv6_address_element_t* v6addr_iter = NULL; + interfaces_interface_ipv4_neighbor_element_t* v4neigh_iter = NULL; + interfaces_interface_ipv6_neighbor_element_t* v6neigh_iter = NULL; HASH_ITER(hh, if_hash, iter, tmp) { @@ -97,20 +99,25 @@ void interfaces_interface_hash_print_debug(const interfaces_interface_hash_eleme SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv4:Enabled = %d", iter->interface.ipv4.enabled); SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv4:Forwarding = %d", iter->interface.ipv4.forwarding); SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv4:MTU = %hu", iter->interface.ipv4.mtu); - SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv4:Address List:"); LL_FOREACH(iter->interface.ipv4.address, v4addr_iter) { - SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv4:Address %s:", v4addr_iter->address.ip); - SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv4:Address IP = %s", v4addr_iter->address.ip); - SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv4:Address Prefix Length = %d", v4addr_iter->address.subnet.prefix_length); + SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv4:Address = %s/%d", v4addr_iter->address.ip, v4addr_iter->address.subnet.prefix_length); + } + + LL_FOREACH(iter->interface.ipv4.neighbor, v4neigh_iter) + { + SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv4:Neighbor = %s : %s", v4neigh_iter->neighbor.ip, v4neigh_iter->neighbor.link_layer_address); } LL_FOREACH(iter->interface.ipv6.address, v6addr_iter) { - SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv6:Address %s:", v6addr_iter->address.ip); - SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv6:Address IP = %s", v6addr_iter->address.ip); - SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv6:Address Prefix Length = %d", v6addr_iter->address.prefix_length); + SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv6:Address = %s/%d", v6addr_iter->address.ip, v6addr_iter->address.prefix_length); + } + + LL_FOREACH(iter->interface.ipv6.neighbor, v6neigh_iter) + { + SRPLG_LOG_INF(PLUGIN_NAME, "\t IPv6:Neighbor = %s : %s", v6neigh_iter->neighbor.ip, v6neigh_iter->neighbor.link_layer_address); } } } @@ -308,6 +315,13 @@ int interfaces_interface_hash_from_ly(interfaces_interface_hash_element_t** if_h return error; } +int interfaces_interface_hash_to_ly(interfaces_interface_hash_element_t* if_hash, struct lyd_node** interfaces_container_node) +{ + int error = 0; + + return error; +} + int interfaces_interface_hash_add_element(interfaces_interface_hash_element_t** hash, interfaces_interface_hash_element_t* new_element) { interfaces_interface_hash_element_t* found_element = NULL; diff --git a/src/interfaces/src/plugin/data/interfaces/interface.h b/src/interfaces/src/plugin/data/interfaces/interface.h index 2c62cff7..09df7f55 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface.h +++ b/src/interfaces/src/plugin/data/interfaces/interface.h @@ -11,6 +11,7 @@ interfaces_interface_hash_element_t* interfaces_interface_hash_new(void); void interfaces_interface_hash_print_debug(const interfaces_interface_hash_element_t* if_hash); int interfaces_interface_hash_from_ly(interfaces_interface_hash_element_t** if_hash, const struct lyd_node* interface_list_node); +int interfaces_interface_hash_to_ly(interfaces_interface_hash_element_t* if_hash, struct lyd_node** interfaces_container_node); int interfaces_interface_hash_add_element(interfaces_interface_hash_element_t** hash, interfaces_interface_hash_element_t* new_element); interfaces_interface_hash_element_t* interfaces_interface_hash_get_element(interfaces_interface_hash_element_t** hash, const char* name); void interfaces_interface_hash_free(interfaces_interface_hash_element_t** hash); diff --git a/src/interfaces/src/plugin/startup/load.c b/src/interfaces/src/plugin/startup/load.c index b571a19b..c30065f8 100644 --- a/src/interfaces/src/plugin/startup/load.c +++ b/src/interfaces/src/plugin/startup/load.c @@ -84,58 +84,23 @@ static int interfaces_startup_load_interface(void* priv, sr_session_ctx_t* sessi { int error = 0; interfaces_ctx_t* ctx = (interfaces_ctx_t*)priv; - interfaces_interface_hash_element_t* interface_head = NULL; - interfaces_interface_hash_element_t *iter = NULL, *tmp = NULL; + interfaces_interface_hash_element_t* interface_hash = NULL; - interfaces_interface_ipv4_address_element_t* v4_addr_iter = NULL; - interfaces_interface_ipv6_address_element_t* v6_addr_iter = NULL; + // load interfaces data + SRPC_SAFE_CALL_ERR(error, interfaces_load_interface(ctx, &interface_hash), error_out); - interfaces_interface_ipv4_neighbor_element_t* v4_neigh_iter = NULL; - interfaces_interface_ipv6_neighbor_element_t* v6_neigh_iter = NULL; + // print debug info for now + // interfaces_interface_hash_print_debug(interface_hash); - SRPC_SAFE_CALL_ERR(error, interfaces_load_interface(ctx, &interface_head), error_out); - - HASH_ITER(hh, interface_head, iter, tmp) - { - SRPLG_LOG_INF(PLUGIN_NAME, "Name: %s", iter->interface.name); - SRPLG_LOG_INF(PLUGIN_NAME, "Type: %s", iter->interface.type); - SRPLG_LOG_INF(PLUGIN_NAME, "Enabled: %d", iter->interface.enabled); - - // v4 - SRPLG_LOG_INF(PLUGIN_NAME, "v4 MTU: %d", iter->interface.ipv4.mtu); - SRPLG_LOG_INF(PLUGIN_NAME, "v4 Enabled: %d", iter->interface.ipv4.enabled); - SRPLG_LOG_INF(PLUGIN_NAME, "v4 Forwarding: %d", iter->interface.ipv4.forwarding); - - LL_FOREACH(iter->interface.ipv4.address, v4_addr_iter) - { - SRPLG_LOG_INF(PLUGIN_NAME, "v4 Address : %s/%d", v4_addr_iter->address.ip, v4_addr_iter->address.subnet.prefix_length); - } - LL_FOREACH(iter->interface.ipv4.neighbor, v4_neigh_iter) - { - SRPLG_LOG_INF(PLUGIN_NAME, "v4 Neighbor : %s : %s", v4_neigh_iter->neighbor.ip, v4_neigh_iter->neighbor.link_layer_address); - } - - // v6 - SRPLG_LOG_INF(PLUGIN_NAME, "v6 MTU: %d", iter->interface.ipv6.mtu); - SRPLG_LOG_INF(PLUGIN_NAME, "v6 Enabled: %d", iter->interface.ipv6.enabled); - SRPLG_LOG_INF(PLUGIN_NAME, "v6 Forwarding: %d", iter->interface.ipv6.forwarding); - - LL_FOREACH(iter->interface.ipv6.address, v6_addr_iter) - { - SRPLG_LOG_INF(PLUGIN_NAME, "v6 Address : %s/%d", v6_addr_iter->address.ip, v6_addr_iter->address.prefix_length); - } - LL_FOREACH(iter->interface.ipv6.neighbor, v6_neigh_iter) - { - SRPLG_LOG_INF(PLUGIN_NAME, "v6 Neighbor : %s : %s", v6_neigh_iter->neighbor.ip, v6_neigh_iter->neighbor.link_layer_address); - } - } + // convert to libyang + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_to_ly(interface_hash, &parent_node), error_out); goto out; error_out: error = -1; out: - interfaces_interface_hash_free(&interface_head); + interfaces_interface_hash_free(&interface_hash); return error; } From 18f02facfe4e4965b4b7b212d5c9521e6e744d21 Mon Sep 17 00:00:00 2001 From: andrej Date: Wed, 2 Nov 2022 11:39:24 +0100 Subject: [PATCH 228/247] unit-tests: remove interfaces from Tests.cmake --- tests/Tests.cmake | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Tests.cmake b/tests/Tests.cmake index cdeac767..14082338 100644 --- a/tests/Tests.cmake +++ b/tests/Tests.cmake @@ -1,2 +1 @@ -add_subdirectory(${CMAKE_SOURCE_DIR}/tests/interfaces) add_subdirectory(${CMAKE_SOURCE_DIR}/tests/routing) From 2862c388d8277e4a460f6a316becafc8b70afb22 Mon Sep 17 00:00:00 2001 From: andrej Date: Wed, 2 Nov 2022 12:07:22 +0100 Subject: [PATCH 229/247] unit-tests: add target linker options for wrap --- src/interfaces/tests/CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/interfaces/tests/CMakeLists.txt b/src/interfaces/tests/CMakeLists.txt index c0d717b5..c7e9f3e0 100644 --- a/src/interfaces/tests/CMakeLists.txt +++ b/src/interfaces/tests/CMakeLists.txt @@ -1,5 +1,9 @@ set(INTERFACES_UTEST_NAME "interfaces_utest") set(UTILS_MEMORY_LIBRARY_NAME "utils_memory") +set( + INTERFACES_UTEST_LINKER_OPTIONS + #"-Wl,--wrap=foo" +) add_executable( ${INTERFACES_UTEST_NAME} @@ -15,6 +19,10 @@ add_library( STATIC ${CMAKE_SOURCE_DIR}/src/utils/memory.c ) +target_link_options( + ${INTERFACES_UTEST_NAME} + PRIVATE ${INTERFACES_UTEST_LINKER_OPTIONS} +) target_link_libraries( ${INTERFACES_UTEST_NAME} From d55c8cae6773e263311ab64fd3a13319fb4a470d Mon Sep 17 00:00:00 2001 From: andrej Date: Wed, 2 Nov 2022 17:26:12 +0100 Subject: [PATCH 230/247] interfaces-plugin: change state name set return for NULL name --- src/interfaces/src/plugin/data/interfaces/interface_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin/data/interfaces/interface_state.c b/src/interfaces/src/plugin/data/interfaces/interface_state.c index 426dff94..850875a3 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface_state.c +++ b/src/interfaces/src/plugin/data/interfaces/interface_state.c @@ -71,7 +71,7 @@ int interfaces_interface_state_hash_element_set_name(interfaces_interface_state_ return (*el)->state.name == NULL; } - return 0; + return -1; } void interfaces_interface_state_hash_element_set_state(interfaces_interface_state_hash_element_t** el, const uint8_t state) From 74aa7fa975ca2968c4f65ed2f87dfd81bec314a6 Mon Sep 17 00:00:00 2001 From: andrej Date: Wed, 2 Nov 2022 17:48:51 +0100 Subject: [PATCH 231/247] unit-tests: add remaining interfaces hash state unit tests --- src/interfaces/tests/interfaces_utest.c | 167 ++++++++++++++++++++++-- 1 file changed, 159 insertions(+), 8 deletions(-) diff --git a/src/interfaces/tests/interfaces_utest.c b/src/interfaces/tests/interfaces_utest.c index 93aee787..4496dac9 100644 --- a/src/interfaces/tests/interfaces_utest.c +++ b/src/interfaces/tests/interfaces_utest.c @@ -25,7 +25,14 @@ static int teardown(void **state); /* tests */ /** interface hash table state **/ -static void test_hash_new_correct(void **state); +static void test_state_hash_new_correct(void **state); +static void test_state_hash_element_new_correct(void **state); +static void test_state_hash_add_correct(void **state); +static void test_state_hash_add_incorrect(void **state); +static void test_state_hash_get_correct(void **state); +static void test_state_hash_get_incorrect(void **state); +static void test_state_hash_set_name_correct(void **state); +static void test_state_hash_set_name_incorrect(void **state); /* load */ static void test_correct_load_interface(void **state); @@ -34,7 +41,14 @@ int main(void) { const struct CMUnitTest tests[] = { cmocka_unit_test(test_correct_load_interface), - cmocka_unit_test(test_hash_new_correct), + cmocka_unit_test(test_state_hash_new_correct), + cmocka_unit_test(test_state_hash_element_new_correct), + cmocka_unit_test(test_state_hash_add_correct), + cmocka_unit_test(test_state_hash_add_incorrect), + cmocka_unit_test(test_state_hash_get_correct), + cmocka_unit_test(test_state_hash_get_incorrect), + cmocka_unit_test(test_state_hash_set_name_correct), + cmocka_unit_test(test_state_hash_set_name_incorrect), }; return cmocka_run_group_tests(tests, setup, teardown); @@ -64,23 +78,160 @@ static int teardown(void **state) static void test_correct_load_interface(void **state) { - interfaces_ctx_t *ctx = *state; + (void) state; + + int rc = 0; + + assert_int_equal(rc, 0); +} + +static void test_state_hash_new_correct(void **state) +{ + (void) state; + + interfaces_interface_state_hash_element_t *state_hash; + + state_hash = interfaces_interface_state_hash_new(); + assert_null(state_hash); +} + +static void test_state_hash_element_new_correct(void **state) +{ + (void) state; + + interfaces_interface_state_hash_element_t *new_elem; + + new_elem = interfaces_interface_state_hash_element_new(); + assert_non_null(new_elem); + + interfaces_interface_state_hash_element_free(&new_elem); + assert_null(new_elem); +} + +static void test_state_hash_add_correct(void **state) +{ + (void) state; + + int rc = 0; + + interfaces_interface_state_hash_element_t *state_hash, *new_elem; + + state_hash = interfaces_interface_state_hash_new(); + assert_null(state_hash); + + new_elem = interfaces_interface_state_hash_element_new(); + + interfaces_interface_state_hash_element_set_name(&new_elem, "FOO"); + assert_int_equal(rc, 0); + + rc = interfaces_interface_state_hash_add(&state_hash, new_elem); + assert_int_equal(rc, 0); + + interfaces_interface_state_hash_free(&state_hash); +} + +static void test_state_hash_add_incorrect(void **state) +{ + (void) state; + + int rc = 0; + + interfaces_interface_state_hash_element_t *state_hash, *new_elem; + + state_hash = interfaces_interface_state_hash_new(); + assert_null(state_hash); + + new_elem = interfaces_interface_state_hash_element_new(); + + interfaces_interface_state_hash_element_set_name(&new_elem, "FOO"); + assert_int_equal(rc, 0); + + rc = interfaces_interface_state_hash_add(&state_hash, new_elem); + assert_int_equal(rc, 0); + + /* try adding the same element */ + rc = interfaces_interface_state_hash_add(&state_hash, new_elem); + assert_int_not_equal(rc, 0); + + interfaces_interface_state_hash_free(&state_hash); +} + +static void test_state_hash_get_correct(void **state) +{ + (void) state; + int rc = 0; + const char *name = "FOO"; + + interfaces_interface_state_hash_element_t *state_hash, *new_elem, *found; + state_hash = interfaces_interface_state_hash_new(); + assert_null(state_hash); + + new_elem = interfaces_interface_state_hash_element_new(); + + interfaces_interface_state_hash_element_set_name(&new_elem, name); assert_int_equal(rc, 0); + + rc = interfaces_interface_state_hash_add(&state_hash, new_elem); + assert_int_equal(rc, 0); + + found = interfaces_interface_state_hash_get(state_hash, name); + assert_non_null(found); + + interfaces_interface_state_hash_free(&state_hash); } -static void test_hash_new_correct(void **state) +static void test_state_hash_get_incorrect(void **state) { - interfaces_ctx_t *ctx = *state; + (void) state; + int rc = 0; + const char *names[] = { "FOO", "BAR" }; - interfaces_interface_state_hash_element_t *if_root; + interfaces_interface_state_hash_element_t *state_hash, *new_elem, *found; - if_root = interfaces_interface_state_hash_new(); + state_hash = interfaces_interface_state_hash_new(); + assert_null(state_hash); - assert_null(if_root); + new_elem = interfaces_interface_state_hash_element_new(); + + interfaces_interface_state_hash_element_set_name(&new_elem, names[0]); + assert_int_equal(rc, 0); + rc = interfaces_interface_state_hash_add(&state_hash, new_elem); + assert_int_equal(rc, 0); + + found = interfaces_interface_state_hash_get(state_hash, names[1]); + assert_null(found); + + interfaces_interface_state_hash_free(&state_hash); +} + +static void test_state_hash_set_name_correct(void **state) +{ + (void) state; + + int rc = 0; + + interfaces_interface_state_hash_element_t *new_elem; + + new_elem = interfaces_interface_state_hash_element_new(); + + rc = interfaces_interface_state_hash_element_set_name(&new_elem, "FOO"); assert_int_equal(rc, 0); } +static void test_state_hash_set_name_incorrect(void **state) +{ + (void) state; + + int rc = 0; + + interfaces_interface_state_hash_element_t *new_elem; + + new_elem = interfaces_interface_state_hash_element_new(); + + rc = interfaces_interface_state_hash_element_set_name(&new_elem, NULL); + assert_int_not_equal(rc, 0); +} From 48b4d58a18ef45b16373473de1a909d71cd5be01 Mon Sep 17 00:00:00 2001 From: andrej Date: Wed, 2 Nov 2022 17:51:11 +0100 Subject: [PATCH 232/247] unit-tests: clarify target linker wrap options --- src/interfaces/tests/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/interfaces/tests/CMakeLists.txt b/src/interfaces/tests/CMakeLists.txt index c7e9f3e0..26fa9f7f 100644 --- a/src/interfaces/tests/CMakeLists.txt +++ b/src/interfaces/tests/CMakeLists.txt @@ -1,8 +1,9 @@ set(INTERFACES_UTEST_NAME "interfaces_utest") set(UTILS_MEMORY_LIBRARY_NAME "utils_memory") +# for wrapping cmocka mock functions set( INTERFACES_UTEST_LINKER_OPTIONS - #"-Wl,--wrap=foo" + #"-Wl,--wrap=function_foo" ) add_executable( From 53d01fda81adb4438015dd82728c2756e818d8ed Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Tue, 8 Nov 2022 20:30:51 +0000 Subject: [PATCH 233/247] interfaces-plugin: use SRPC_SAFE_CALL --- src/interfaces/src/plugin/startup/load.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/interfaces/src/plugin/startup/load.c b/src/interfaces/src/plugin/startup/load.c index c30065f8..874d5085 100644 --- a/src/interfaces/src/plugin/startup/load.c +++ b/src/interfaces/src/plugin/startup/load.c @@ -30,12 +30,8 @@ int interfaces_startup_load(interfaces_ctx_t* ctx, sr_session_ctx_t* session) }, }; - conn_ctx = sr_session_get_connection(session); - ly_ctx = sr_acquire_context(conn_ctx); - if (ly_ctx == NULL) { - SRPLG_LOG_ERR(PLUGIN_NAME, "Unable to get ly_ctx variable"); - goto error_out; - } + SRPC_SAFE_CALL_PTR(conn_ctx, sr_session_get_connection(session), error_out); + SRPC_SAFE_CALL_PTR(ly_ctx, sr_acquire_context(conn_ctx), error_out); SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces(ly_ctx, &root_node), error_out); From 2b2e02cd429bbcc49d8d7dc21669a2508e6736dd Mon Sep 17 00:00:00 2001 From: andrej Date: Thu, 8 Dec 2022 12:30:20 +0100 Subject: [PATCH 234/247] interfaces-plugin: add interface list api unit tests --- src/interfaces/tests/interfaces_utest.c | 251 +++++++++++++++++++++++- 1 file changed, 250 insertions(+), 1 deletion(-) diff --git a/src/interfaces/tests/interfaces_utest.c b/src/interfaces/tests/interfaces_utest.c index 4496dac9..f1f53801 100644 --- a/src/interfaces/tests/interfaces_utest.c +++ b/src/interfaces/tests/interfaces_utest.c @@ -34,12 +34,31 @@ static void test_state_hash_get_incorrect(void **state); static void test_state_hash_set_name_correct(void **state); static void test_state_hash_set_name_incorrect(void **state); -/* load */ + +/** interface list state **/ +static void test_interface_list_new_correct(void **state); +static void test_interface_list_add_element_correct(void **state); +/*** ipv4 ***/ +static void test_interface_list_new_ipv4_address_correct(void **state); +static void test_interface_list_new_ipv4_neighbor_correct(void **state); +static void test_interface_list_element_new_ipv4_address_correct(void **state); +static void test_interface_list_element_new_ipv4_neighbor_correct(void **state); +static void test_interface_ipv4_address_netmask2prefix_correct(void **state); +static void test_interface_ipv4_address_netmask2prefix_incorrect(void **state); + +/*** ipv6 ***/ +static void test_interface_list_new_ipv6_address_correct(void **state); +static void test_interface_list_new_ipv6_neighbor_correct(void **state); +static void test_interface_list_element_new_ipv6_address_correct(void **state); +static void test_interface_list_element_new_ipv6_neighbor_correct(void **state); + +/** load **/ static void test_correct_load_interface(void **state); int main(void) { const struct CMUnitTest tests[] = { + /** interface hash table state **/ cmocka_unit_test(test_correct_load_interface), cmocka_unit_test(test_state_hash_new_correct), cmocka_unit_test(test_state_hash_element_new_correct), @@ -49,6 +68,21 @@ int main(void) cmocka_unit_test(test_state_hash_get_incorrect), cmocka_unit_test(test_state_hash_set_name_correct), cmocka_unit_test(test_state_hash_set_name_incorrect), + /** interface list state **/ + cmocka_unit_test(test_interface_list_new_correct), + cmocka_unit_test(test_interface_list_add_element_correct), + /*** ipv4 ***/ + cmocka_unit_test(test_interface_list_new_ipv4_address_correct), + cmocka_unit_test(test_interface_list_new_ipv4_neighbor_correct), + cmocka_unit_test(test_interface_list_element_new_ipv4_address_correct), + cmocka_unit_test(test_interface_list_element_new_ipv4_neighbor_correct), + cmocka_unit_test(test_interface_ipv4_address_netmask2prefix_correct), + cmocka_unit_test(test_interface_ipv4_address_netmask2prefix_incorrect), + /*** ipv6 ***/ + cmocka_unit_test(test_interface_list_new_ipv6_address_correct), + cmocka_unit_test(test_interface_list_new_ipv6_neighbor_correct), + cmocka_unit_test(test_interface_list_element_new_ipv6_address_correct), + cmocka_unit_test(test_interface_list_element_new_ipv6_neighbor_correct), }; return cmocka_run_group_tests(tests, setup, teardown); @@ -235,3 +269,218 @@ static void test_state_hash_set_name_incorrect(void **state) rc = interfaces_interface_state_hash_element_set_name(&new_elem, NULL); assert_int_not_equal(rc, 0); } + +static void test_interface_list_new_correct(void **state) +{ + (void) state; + interfaces_interface_ipv4_address_element_t *address_ipv4; + interfaces_interface_ipv4_neighbor_element_t *neighbor_ipv4; + + interfaces_interface_ipv6_address_element_t *address_ipv6; + interfaces_interface_ipv6_neighbor_element_t *neighbor_ipv6; + + INTERFACES_INTERFACE_LIST_NEW(address_ipv4); + assert_null(address_ipv4); + + INTERFACES_INTERFACE_LIST_NEW(neighbor_ipv4); + assert_null(neighbor_ipv4); + + INTERFACES_INTERFACE_LIST_NEW(address_ipv6); + assert_null(address_ipv6); + + INTERFACES_INTERFACE_LIST_NEW(neighbor_ipv6); + assert_null(neighbor_ipv6); +} + +static void test_interface_list_add_element_correct(void **state) +{ + (void) state; + interfaces_interface_ipv4_address_element_t *address_ipv4; + interfaces_interface_ipv4_address_element_t *address_elem_ipv4; + + interfaces_interface_ipv4_neighbor_element_t *neighbor_ipv4; + interfaces_interface_ipv4_neighbor_element_t *neighbor_elem_ipv4; + + interfaces_interface_ipv6_address_element_t *address_ipv6; + interfaces_interface_ipv6_address_element_t *address_elem_ipv6; + + interfaces_interface_ipv6_neighbor_element_t *neighbor_ipv6; + interfaces_interface_ipv6_neighbor_element_t *neighbor_elem_ipv6; + + INTERFACES_INTERFACE_LIST_NEW(address_ipv4); + assert_null(address_ipv4); + + INTERFACES_INTERFACE_LIST_NEW(neighbor_ipv4); + assert_null(neighbor_ipv4); + + INTERFACES_INTERFACE_LIST_NEW(address_ipv6); + assert_null(address_ipv6); + + INTERFACES_INTERFACE_LIST_NEW(neighbor_ipv6); + assert_null(neighbor_ipv6); + + address_elem_ipv4 = interfaces_interface_ipv4_address_new(); + assert_null(address_elem_ipv4); + address_elem_ipv4 = interfaces_interface_ipv4_address_element_new(); + assert_non_null(address_elem_ipv4); + INTERFACES_INTERFACE_LIST_ADD_ELEMENT(address_ipv4, address_elem_ipv4); + assert_non_null(address_ipv4); + INTERFACES_INTERFACE_LIST_FREE(address_ipv4); + assert_null(address_ipv4); + + neighbor_elem_ipv4 = interfaces_interface_ipv4_neighbor_new(); + assert_null(neighbor_elem_ipv4); + neighbor_elem_ipv4 = interfaces_interface_ipv4_neighbor_element_new(); + assert_non_null(neighbor_elem_ipv4); + INTERFACES_INTERFACE_LIST_ADD_ELEMENT(neighbor_ipv4, neighbor_elem_ipv4); + assert_non_null(neighbor_ipv4); + INTERFACES_INTERFACE_LIST_FREE(neighbor_ipv4); + assert_null(neighbor_ipv4); + + address_elem_ipv6 = interfaces_interface_ipv6_address_new(); + assert_null(address_elem_ipv6); + address_elem_ipv6 = interfaces_interface_ipv6_address_element_new(); + assert_non_null(address_elem_ipv6); + INTERFACES_INTERFACE_LIST_ADD_ELEMENT(address_ipv6, address_elem_ipv6); + assert_non_null(address_ipv6); + INTERFACES_INTERFACE_LIST_FREE(address_ipv6); + assert_null(address_ipv6); + + neighbor_elem_ipv6 = interfaces_interface_ipv6_neighbor_new(); + assert_null(neighbor_elem_ipv6); + neighbor_elem_ipv6 = interfaces_interface_ipv6_neighbor_element_new(); + assert_non_null(neighbor_elem_ipv6); + INTERFACES_INTERFACE_LIST_ADD_ELEMENT(neighbor_ipv6, neighbor_elem_ipv6); + assert_non_null(neighbor_ipv6); + INTERFACES_INTERFACE_LIST_FREE(neighbor_ipv6); + assert_null(neighbor_ipv6); +} + +static void test_interface_list_new_ipv4_address_correct(void **state) +{ + (void) state; + + interfaces_interface_ipv4_address_element_t *address; + + address = interfaces_interface_ipv4_address_new(); + assert_null(address); +} + +static void test_interface_list_new_ipv4_neighbor_correct(void **state) +{ + (void) state; + + interfaces_interface_ipv4_neighbor_element_t *neighbor; + + neighbor = interfaces_interface_ipv4_neighbor_new(); + assert_null(neighbor); +} + +static void test_interface_list_element_new_ipv4_address_correct(void **state) +{ + (void) state; + + interfaces_interface_ipv4_address_element_t *address; + + address = interfaces_interface_ipv4_address_new(); + assert_null(address); + + address = interfaces_interface_ipv4_address_element_new(); + assert_non_null(address); + + interfaces_interface_ipv4_address_element_free(&address); + assert_null(address); +} + +static void test_interface_list_element_new_ipv4_neighbor_correct(void **state) +{ + (void) state; + + interfaces_interface_ipv4_neighbor_element_t *neighbor; + + neighbor = interfaces_interface_ipv4_neighbor_new(); + assert_null(neighbor); + + neighbor = interfaces_interface_ipv4_neighbor_element_new(); + assert_non_null(neighbor); + + interfaces_interface_ipv4_neighbor_element_free(&neighbor); + assert_null(neighbor); +} + +static void test_interface_ipv4_address_netmask2prefix_correct(void **state) +{ + (void) state; + + int rc = -1; + uint8_t prefix_length = 0; + const char *netmask = "255.255.255.0"; + + rc = interfaces_interface_ipv4_address_netmask2prefix(netmask, &prefix_length); + assert_int_equal(rc, 0); + assert_int_equal(prefix_length, 24); +} + +static void test_interface_ipv4_address_netmask2prefix_incorrect(void **state) +{ + (void) state; + + int rc = 0; + uint8_t prefix_length = 0; + const char *netmask = "FOOBAR"; + + rc = interfaces_interface_ipv4_address_netmask2prefix(netmask, &prefix_length); + assert_int_not_equal(rc, 0); +} + +static void test_interface_list_new_ipv6_address_correct(void **state) +{ + (void) state; + + interfaces_interface_ipv6_address_element_t *address; + + address = interfaces_interface_ipv6_address_new(); + assert_null(address); +} + +static void test_interface_list_new_ipv6_neighbor_correct(void **state) +{ + (void) state; + + interfaces_interface_ipv6_neighbor_element_t *neighbor; + + neighbor = interfaces_interface_ipv6_neighbor_new(); + assert_null(neighbor); +} + +static void test_interface_list_element_new_ipv6_address_correct(void **state) +{ + (void) state; + + interfaces_interface_ipv6_address_element_t *address; + + address = interfaces_interface_ipv6_address_new(); + assert_null(address); + + address = interfaces_interface_ipv6_address_element_new(); + assert_non_null(address); + + interfaces_interface_ipv6_address_element_free(&address); + assert_null(address); +} + +static void test_interface_list_element_new_ipv6_neighbor_correct(void **state) +{ + (void) state; + + interfaces_interface_ipv6_neighbor_element_t *neighbor; + + neighbor = interfaces_interface_ipv6_neighbor_new(); + assert_null(neighbor); + + neighbor = interfaces_interface_ipv6_neighbor_element_new(); + assert_non_null(neighbor); + + interfaces_interface_ipv6_neighbor_element_free(&neighbor); + assert_null(neighbor); +} From 9f1759a9bc932f44c8eec735dfc082a185be5e27 Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Thu, 8 Dec 2022 17:35:18 +0000 Subject: [PATCH 235/247] interfaces-plugin: add IPv4 address list libyang conversion --- .../src/plugin/data/interfaces/interface.c | 79 ++++++++++++++++++- .../src/plugin/data/interfaces/interface.h | 2 +- src/interfaces/src/plugin/startup/load.c | 12 +-- 3 files changed, 86 insertions(+), 7 deletions(-) diff --git a/src/interfaces/src/plugin/data/interfaces/interface.c b/src/interfaces/src/plugin/data/interfaces/interface.c index 5e64ce4f..6f62019f 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface.c +++ b/src/interfaces/src/plugin/data/interfaces/interface.c @@ -1,7 +1,10 @@ #include "interface.h" #include "interface/ipv4.h" +#include "libyang/log.h" #include "libyang/tree_data.h" #include "plugin/common.h" +#include "plugin/ly_tree.h" +#include "plugin/types.h" #include "srpc/ly_tree.h" #include "sysrepo.h" #include "uthash.h" @@ -315,10 +318,84 @@ int interfaces_interface_hash_from_ly(interfaces_interface_hash_element_t** if_h return error; } -int interfaces_interface_hash_to_ly(interfaces_interface_hash_element_t* if_hash, struct lyd_node** interfaces_container_node) +int interfaces_interface_hash_to_ly(const struct ly_ctx* ly_ctx, interfaces_interface_hash_element_t* if_hash, struct lyd_node** interfaces_container_node) { int error = 0; + // interface iterator + interfaces_interface_hash_element_t *if_iter = NULL, *tmp = NULL; + + // address iterators + interfaces_interface_ipv4_address_element_t* v4_addr_iter = NULL; + interfaces_interface_ipv6_address_element_t* v6_addr_iter = NULL; + + // neighbor iterators + interfaces_interface_ipv4_neighbor_element_t* v4_neigh_iter = NULL; + interfaces_interface_ipv6_neighbor_element_t* v6_neigh_iter = NULL; + + // libyang data + struct lyd_node* interface_list_node = NULL; + struct lyd_node *ipv4_container_node = NULL, *ipv6_container_node = NULL; + struct lyd_node *ipv4_address_node = NULL, *ipv6_address_node = NULL; + struct lyd_node *ipv4_neighbor_node = NULL, *ipv6_neighbor_node = NULL; + + // buffers + char mtu_buffer[20] = { 0 }; + char prefix_length_buffer[20] = { 0 }; + + HASH_ITER(hh, if_hash, if_iter, tmp) + { + // alloc new interface list node and fill that node with info + // name added via list creation + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface(ly_ctx, *interfaces_container_node, &interface_list_node, if_iter->interface.name), error_out); + + // enabled + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_enabled(ly_ctx, interface_list_node, if_iter->interface.enabled ? "true" : "false"), error_out); + + // type + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_type(ly_ctx, interface_list_node, if_iter->interface.type), error_out); + + // IPv4 + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4(ly_ctx, interface_list_node, &ipv4_container_node), error_out); + + // IPv4 properties + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_enabled(ly_ctx, ipv4_container_node, if_iter->interface.ipv4.enabled ? "enabled" : "disabled"), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_forwarding(ly_ctx, ipv4_container_node, if_iter->interface.ipv4.forwarding ? "enabled" : "disabled"), error_out); + + // write MTU to the buffer + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(mtu_buffer, sizeof(mtu_buffer), "%d", if_iter->interface.ipv4.mtu), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_mtu(ly_ctx, ipv4_container_node, mtu_buffer), error_out); + + // address list + LL_FOREACH(if_iter->interface.ipv4.address, v4_addr_iter) + { + // create list element + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_address(ly_ctx, ipv4_container_node, &ipv4_address_node, v4_addr_iter->address.ip), error_out); + + // add properties to the list element + switch (v4_addr_iter->address.subnet_type) { + case interfaces_interface_ipv4_address_subnet_none: + break; + case interfaces_interface_ipv4_address_subnet_prefix_length: + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(prefix_length_buffer, sizeof(prefix_length_buffer), "%d", v4_addr_iter->address.subnet.prefix_length), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_address_prefix_length(ly_ctx, ipv4_address_node, prefix_length_buffer), error_out); + break; + case interfaces_interface_ipv4_address_subnet_netmask: + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_address_netmask(ly_ctx, ipv4_address_node, v4_addr_iter->address.subnet.netmask), error_out); + break; + } + } + + // IPv6 + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv6(ly_ctx, interface_list_node, &ipv6_container_node), error_out); + } + + goto out; + +error_out: + error = -1; + +out: return error; } diff --git a/src/interfaces/src/plugin/data/interfaces/interface.h b/src/interfaces/src/plugin/data/interfaces/interface.h index 09df7f55..eda09843 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface.h +++ b/src/interfaces/src/plugin/data/interfaces/interface.h @@ -11,7 +11,7 @@ interfaces_interface_hash_element_t* interfaces_interface_hash_new(void); void interfaces_interface_hash_print_debug(const interfaces_interface_hash_element_t* if_hash); int interfaces_interface_hash_from_ly(interfaces_interface_hash_element_t** if_hash, const struct lyd_node* interface_list_node); -int interfaces_interface_hash_to_ly(interfaces_interface_hash_element_t* if_hash, struct lyd_node** interfaces_container_node); +int interfaces_interface_hash_to_ly(const struct ly_ctx* ly_ctx, interfaces_interface_hash_element_t* if_hash, struct lyd_node** interfaces_container_node); int interfaces_interface_hash_add_element(interfaces_interface_hash_element_t** hash, interfaces_interface_hash_element_t* new_element); interfaces_interface_hash_element_t* interfaces_interface_hash_get_element(interfaces_interface_hash_element_t** hash, const char* name); void interfaces_interface_hash_free(interfaces_interface_hash_element_t** hash); diff --git a/src/interfaces/src/plugin/startup/load.c b/src/interfaces/src/plugin/startup/load.c index 874d5085..e848a2b1 100644 --- a/src/interfaces/src/plugin/startup/load.c +++ b/src/interfaces/src/plugin/startup/load.c @@ -1,4 +1,5 @@ #include "load.h" +#include "libyang/printer_data.h" #include "plugin/common.h" #include "plugin/data/interfaces/interface.h" #include "plugin/ly_tree.h" @@ -25,7 +26,7 @@ int interfaces_startup_load(interfaces_ctx_t* ctx, sr_session_ctx_t* session) srpc_startup_load_t load_values[] = { { - "/ietf-interfaces:interfaces/interface[name='%s']", + "/ietf-interfaces:interfaces/interface", interfaces_startup_load_interface, }, }; @@ -73,6 +74,7 @@ int interfaces_startup_load(interfaces_ctx_t* ctx, sr_session_ctx_t* session) lyd_free_tree(root_node); } sr_release_context(conn_ctx); + return error; } @@ -85,11 +87,11 @@ static int interfaces_startup_load_interface(void* priv, sr_session_ctx_t* sessi // load interfaces data SRPC_SAFE_CALL_ERR(error, interfaces_load_interface(ctx, &interface_hash), error_out); - // print debug info for now - // interfaces_interface_hash_print_debug(interface_hash); - // convert to libyang - SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_to_ly(interface_hash, &parent_node), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_to_ly(ly_ctx, interface_hash, &parent_node), error_out); + + // print created tree + lyd_print_file(stdout, parent_node, LYD_XML, 0); goto out; From d6d75ba556d39e30dde5d5b96e358e858eec89fb Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Thu, 8 Dec 2022 17:52:16 +0000 Subject: [PATCH 236/247] interfaces-plugin: fix MTU conversion to libyang --- src/interfaces/src/plugin/data/interfaces/interface.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/interfaces/src/plugin/data/interfaces/interface.c b/src/interfaces/src/plugin/data/interfaces/interface.c index 6f62019f..d49cd943 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface.c +++ b/src/interfaces/src/plugin/data/interfaces/interface.c @@ -359,12 +359,14 @@ int interfaces_interface_hash_to_ly(const struct ly_ctx* ly_ctx, interfaces_inte SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4(ly_ctx, interface_list_node, &ipv4_container_node), error_out); // IPv4 properties - SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_enabled(ly_ctx, ipv4_container_node, if_iter->interface.ipv4.enabled ? "enabled" : "disabled"), error_out); - SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_forwarding(ly_ctx, ipv4_container_node, if_iter->interface.ipv4.forwarding ? "enabled" : "disabled"), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_enabled(ly_ctx, ipv4_container_node, if_iter->interface.ipv4.enabled ? "true" : "false"), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_forwarding(ly_ctx, ipv4_container_node, if_iter->interface.ipv4.forwarding ? "true" : "false"), error_out); // write MTU to the buffer - SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(mtu_buffer, sizeof(mtu_buffer), "%d", if_iter->interface.ipv4.mtu), error_out); - SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_mtu(ly_ctx, ipv4_container_node, mtu_buffer), error_out); + if (if_iter->interface.ipv4.mtu != 0) { + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(mtu_buffer, sizeof(mtu_buffer), "%u", if_iter->interface.ipv4.mtu), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_mtu(ly_ctx, ipv4_container_node, mtu_buffer), error_out); + } // address list LL_FOREACH(if_iter->interface.ipv4.address, v4_addr_iter) From 9fde13ce04abe30614451c84ee897accaca2dff0 Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Thu, 8 Dec 2022 17:55:21 +0000 Subject: [PATCH 237/247] interfaces-plugin: add IPv4 neighbor list libyang conversion --- src/interfaces/src/plugin/data/interfaces/interface.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/interfaces/src/plugin/data/interfaces/interface.c b/src/interfaces/src/plugin/data/interfaces/interface.c index d49cd943..51437b15 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface.c +++ b/src/interfaces/src/plugin/data/interfaces/interface.c @@ -388,6 +388,15 @@ int interfaces_interface_hash_to_ly(const struct ly_ctx* ly_ctx, interfaces_inte } } + LL_FOREACH(if_iter->interface.ipv4.neighbor, v4_neigh_iter) + { + // create list element + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_neighbor(ly_ctx, ipv4_container_node, &ipv4_neighbor_node, v4_neigh_iter->neighbor.ip), error_out); + + // add properties to the list element + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_neighbor_link_layer_address(ly_ctx, ipv4_neighbor_node, v4_neigh_iter->neighbor.link_layer_address), error_out); + } + // IPv6 SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv6(ly_ctx, interface_list_node, &ipv6_container_node), error_out); } From c7c0f12d88f4fcd12c2dec04d217418dbd8cb4cc Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Thu, 8 Dec 2022 18:00:12 +0000 Subject: [PATCH 238/247] interfaces-plugin: add IPv6 data libyang conversion --- .../src/plugin/data/interfaces/interface.c | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/src/interfaces/src/plugin/data/interfaces/interface.c b/src/interfaces/src/plugin/data/interfaces/interface.c index 51437b15..125376f1 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface.c +++ b/src/interfaces/src/plugin/data/interfaces/interface.c @@ -340,8 +340,8 @@ int interfaces_interface_hash_to_ly(const struct ly_ctx* ly_ctx, interfaces_inte struct lyd_node *ipv4_neighbor_node = NULL, *ipv6_neighbor_node = NULL; // buffers - char mtu_buffer[20] = { 0 }; - char prefix_length_buffer[20] = { 0 }; + char mtu_buffer[100] = { 0 }; + char prefix_length_buffer[100] = { 0 }; HASH_ITER(hh, if_hash, if_iter, tmp) { @@ -362,13 +362,13 @@ int interfaces_interface_hash_to_ly(const struct ly_ctx* ly_ctx, interfaces_inte SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_enabled(ly_ctx, ipv4_container_node, if_iter->interface.ipv4.enabled ? "true" : "false"), error_out); SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_forwarding(ly_ctx, ipv4_container_node, if_iter->interface.ipv4.forwarding ? "true" : "false"), error_out); - // write MTU to the buffer + // write IPv4 MTU to the buffer if (if_iter->interface.ipv4.mtu != 0) { SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(mtu_buffer, sizeof(mtu_buffer), "%u", if_iter->interface.ipv4.mtu), error_out); SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv4_mtu(ly_ctx, ipv4_container_node, mtu_buffer), error_out); } - // address list + // IPv4 address list LL_FOREACH(if_iter->interface.ipv4.address, v4_addr_iter) { // create list element @@ -388,6 +388,7 @@ int interfaces_interface_hash_to_ly(const struct ly_ctx* ly_ctx, interfaces_inte } } + // IPv4 neighbor list LL_FOREACH(if_iter->interface.ipv4.neighbor, v4_neigh_iter) { // create list element @@ -399,6 +400,37 @@ int interfaces_interface_hash_to_ly(const struct ly_ctx* ly_ctx, interfaces_inte // IPv6 SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv6(ly_ctx, interface_list_node, &ipv6_container_node), error_out); + + // IPv6 properties + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv6_enabled(ly_ctx, ipv6_container_node, if_iter->interface.ipv6.enabled ? "true" : "false"), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv6_forwarding(ly_ctx, ipv6_container_node, if_iter->interface.ipv6.forwarding ? "true" : "false"), error_out); + + // write IPv6 MTU to the buffer + if (if_iter->interface.ipv6.mtu != 0) { + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(mtu_buffer, sizeof(mtu_buffer), "%u", if_iter->interface.ipv6.mtu), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv6_mtu(ly_ctx, ipv6_container_node, mtu_buffer), error_out); + } + + // IPv6 address list + LL_FOREACH(if_iter->interface.ipv6.address, v6_addr_iter) + { + // create list element + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv6_address(ly_ctx, ipv6_container_node, &ipv6_address_node, v6_addr_iter->address.ip), error_out); + + // element properties + SRPC_SAFE_CALL_ERR_COND(error, error < 0, snprintf(prefix_length_buffer, sizeof(prefix_length_buffer), "%d", v6_addr_iter->address.prefix_length), error_out); + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv6_address_prefix_length(ly_ctx, ipv6_address_node, prefix_length_buffer), error_out); + } + + // IPv4 neighbor list + LL_FOREACH(if_iter->interface.ipv6.neighbor, v6_neigh_iter) + { + // create list element + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv6_neighbor(ly_ctx, ipv6_container_node, &ipv6_neighbor_node, v6_neigh_iter->neighbor.ip), error_out); + + // add properties to the list element + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces_interface_ipv6_neighbor_link_layer_address(ly_ctx, ipv6_neighbor_node, v6_neigh_iter->neighbor.link_layer_address), error_out); + } } goto out; From 8b276b19d6954fbb0e28a8bab3c0dee8b30debfa Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Thu, 8 Dec 2022 18:10:21 +0000 Subject: [PATCH 239/247] interfaces-plugin: use libyang conversion API to load data into the running datastore --- src/interfaces/src/plugin/startup/load.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/interfaces/src/plugin/startup/load.c b/src/interfaces/src/plugin/startup/load.c index e848a2b1..ede59c6c 100644 --- a/src/interfaces/src/plugin/startup/load.c +++ b/src/interfaces/src/plugin/startup/load.c @@ -49,7 +49,7 @@ int interfaces_startup_load(interfaces_ctx_t* ctx, sr_session_ctx_t* session) /* enable or disable storing into startup, use for testing */ #define INTERFACES_PLUGIN_LOAD_STARTUP /* disable for now */ -#undef INTERFACES_PLUGIN_LOAD_STARTUP +// #undef INTERFACES_PLUGIN_LOAD_STARTUP #ifdef INTERFACES_PLUGIN_LOAD_STARTUP error = sr_edit_batch(session, root_node, "merge"); if (error != SR_ERR_OK) { @@ -91,7 +91,7 @@ static int interfaces_startup_load_interface(void* priv, sr_session_ctx_t* sessi SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_to_ly(ly_ctx, interface_hash, &parent_node), error_out); // print created tree - lyd_print_file(stdout, parent_node, LYD_XML, 0); + // lyd_print_file(stdout, parent_node, LYD_XML, 0); goto out; From ca194f0c8888bd0af02fd4091bcce5d0cfb76684 Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Thu, 8 Dec 2022 18:12:24 +0000 Subject: [PATCH 240/247] interfaces-plugin: fix log message --- src/interfaces/src/plugin/startup/store.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin/startup/store.c b/src/interfaces/src/plugin/startup/store.c index 0d12d885..a7243aa5 100644 --- a/src/interfaces/src/plugin/startup/store.c +++ b/src/interfaces/src/plugin/startup/store.c @@ -77,7 +77,7 @@ static int interfaces_startup_store_interface(void* priv, const struct lyd_node* SRPLG_LOG_ERR(PLUGIN_NAME, "Error loading current interface list"); goto error_out; case srpc_check_status_error: - SRPLG_LOG_ERR(PLUGIN_NAME, "Error loading current interface array"); + SRPLG_LOG_ERR(PLUGIN_NAME, "Error loading current interface list"); goto error_out; case srpc_check_status_non_existant: SRPLG_LOG_INF(PLUGIN_NAME, "Storing interface array"); From 95a94666e28863945351c2390ba618b49f3a2dca Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Thu, 8 Dec 2022 18:13:21 +0000 Subject: [PATCH 241/247] interfaces-plugin: fix log messages --- src/interfaces/src/plugin/startup/store.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/interfaces/src/plugin/startup/store.c b/src/interfaces/src/plugin/startup/store.c index a7243aa5..4dc91851 100644 --- a/src/interfaces/src/plugin/startup/store.c +++ b/src/interfaces/src/plugin/startup/store.c @@ -80,15 +80,14 @@ static int interfaces_startup_store_interface(void* priv, const struct lyd_node* SRPLG_LOG_ERR(PLUGIN_NAME, "Error loading current interface list"); goto error_out; case srpc_check_status_non_existant: - SRPLG_LOG_INF(PLUGIN_NAME, "Storing interface array"); - + SRPLG_LOG_INF(PLUGIN_NAME, "Storing interface list"); SRPC_SAFE_CALL_ERR(error, interfaces_store_interface(ctx, if_hash), error_out); break; case srpc_check_status_equal: - SRPLG_LOG_ERR(PLUGIN_NAME, "Startup interface array is already applied on the system"); + SRPLG_LOG_ERR(PLUGIN_NAME, "Startup interface list is already applied on the system"); break; case srpc_check_status_partial: - SRPLG_LOG_ERR(PLUGIN_NAME, "Error loading current interface array"); + SRPLG_LOG_ERR(PLUGIN_NAME, "Error loading current interface list"); goto error_out; } From b0e0394cb22d3ea10816e3fa110012eafbf9844c Mon Sep 17 00:00:00 2001 From: andrej Date: Fri, 9 Dec 2022 12:10:56 +0100 Subject: [PATCH 242/247] interfaces-plugin: remove utils/memory from unit tests --- src/interfaces/tests/interfaces_utest.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/interfaces/tests/interfaces_utest.c b/src/interfaces/tests/interfaces_utest.c index f1f53801..4bf70593 100644 --- a/src/interfaces/tests/interfaces_utest.c +++ b/src/interfaces/tests/interfaces_utest.c @@ -6,9 +6,6 @@ #include #include -/* xmalloc, FREE_SAFE */ -#include "utils/memory.h" - /* load api */ #include "plugin/api/interfaces/load.h" @@ -90,7 +87,7 @@ int main(void) static int setup(void **state) { - interfaces_ctx_t *ctx = xmalloc(sizeof(interfaces_ctx_t)); + interfaces_ctx_t *ctx = malloc(sizeof(interfaces_ctx_t)); if (!ctx) { return -1; } @@ -104,7 +101,7 @@ static int setup(void **state) static int teardown(void **state) { if (*state) { - FREE_SAFE(*state); + free(*state); } return 0; From c5685ecfe8d6617ab969b69d033edcb653c51d59 Mon Sep 17 00:00:00 2001 From: andrej Date: Fri, 9 Dec 2022 12:14:52 +0100 Subject: [PATCH 243/247] interfaces-plugin: don't link against utils/memory --- src/interfaces/tests/CMakeLists.txt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/interfaces/tests/CMakeLists.txt b/src/interfaces/tests/CMakeLists.txt index 26fa9f7f..1fbb933b 100644 --- a/src/interfaces/tests/CMakeLists.txt +++ b/src/interfaces/tests/CMakeLists.txt @@ -15,11 +15,6 @@ target_include_directories( ${INTERFACES_UTEST_NAME} PUBLIC ${CMAKE_SOURCE_DIR}/src/interfaces/src ) -add_library( - ${UTILS_MEMORY_LIBRARY_NAME} - STATIC - ${CMAKE_SOURCE_DIR}/src/utils/memory.c -) target_link_options( ${INTERFACES_UTEST_NAME} PRIVATE ${INTERFACES_UTEST_LINKER_OPTIONS} @@ -31,7 +26,6 @@ target_link_libraries( ${PLUGIN_LIBRARY_NAME} ${SYSREPO_LIBRARIES} ${LIBYANG_LIBRARIES} - ${UTILS_MEMORY_LIBRARY_NAME} ) add_test( NAME ${INTERFACES_UTEST_NAME} From 85310bd7a586097969edee42b72586a43b061c01 Mon Sep 17 00:00:00 2001 From: andrej Date: Fri, 9 Dec 2022 12:15:55 +0100 Subject: [PATCH 244/247] Revert "interfaces-plugin: change state name set return for NULL name" This reverts commit d55c8cae6773e263311ab64fd3a13319fb4a470d. --- src/interfaces/src/plugin/data/interfaces/interface_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin/data/interfaces/interface_state.c b/src/interfaces/src/plugin/data/interfaces/interface_state.c index 850875a3..426dff94 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface_state.c +++ b/src/interfaces/src/plugin/data/interfaces/interface_state.c @@ -71,7 +71,7 @@ int interfaces_interface_state_hash_element_set_name(interfaces_interface_state_ return (*el)->state.name == NULL; } - return -1; + return 0; } void interfaces_interface_state_hash_element_set_state(interfaces_interface_state_hash_element_t** el, const uint8_t state) From 652bf8563d3a823855f4904da01ad5a85b8bf3d6 Mon Sep 17 00:00:00 2001 From: andrej Date: Fri, 9 Dec 2022 12:24:16 +0100 Subject: [PATCH 245/247] interfaces-plugin: fix memory leak, check name null/non-null --- src/interfaces/tests/interfaces_utest.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/interfaces/tests/interfaces_utest.c b/src/interfaces/tests/interfaces_utest.c index 4bf70593..a884d612 100644 --- a/src/interfaces/tests/interfaces_utest.c +++ b/src/interfaces/tests/interfaces_utest.c @@ -251,6 +251,9 @@ static void test_state_hash_set_name_correct(void **state) rc = interfaces_interface_state_hash_element_set_name(&new_elem, "FOO"); assert_int_equal(rc, 0); + assert_non_null(new_elem->state.name); + + interfaces_interface_state_hash_element_free(&new_elem); } static void test_state_hash_set_name_incorrect(void **state) @@ -264,7 +267,10 @@ static void test_state_hash_set_name_incorrect(void **state) new_elem = interfaces_interface_state_hash_element_new(); rc = interfaces_interface_state_hash_element_set_name(&new_elem, NULL); - assert_int_not_equal(rc, 0); + assert_int_equal(rc, 0); + assert_null(new_elem->state.name); + + interfaces_interface_state_hash_element_free(&new_elem); } static void test_interface_list_new_correct(void **state) From 7b92de775416c134f0669c80f4dc4aba8af4de5b Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Tue, 13 Dec 2022 22:48:31 +0000 Subject: [PATCH 246/247] interfaces-plugin: switch startup DS loading to running DS loading --- src/interfaces/CMakeLists.txt | 4 + src/interfaces/src/plugin.c | 24 ++-- .../src/plugin/data/interfaces/interface.c | 4 +- src/interfaces/src/plugin/running/load.c | 104 ++++++++++++++++++ src/interfaces/src/plugin/running/load.h | 8 ++ src/interfaces/src/plugin/running/store.c | 103 +++++++++++++++++ src/interfaces/src/plugin/running/store.h | 8 ++ 7 files changed, 244 insertions(+), 11 deletions(-) create mode 100644 src/interfaces/src/plugin/running/load.c create mode 100644 src/interfaces/src/plugin/running/load.h create mode 100644 src/interfaces/src/plugin/running/store.c create mode 100644 src/interfaces/src/plugin/running/store.h diff --git a/src/interfaces/CMakeLists.txt b/src/interfaces/CMakeLists.txt index 2710ed23..8ac11d4c 100644 --- a/src/interfaces/CMakeLists.txt +++ b/src/interfaces/CMakeLists.txt @@ -18,6 +18,10 @@ set( src/plugin/startup/load.c src/plugin/startup/store.c + # running + src/plugin/running/load.c + src/plugin/running/store.c + # subscription src/plugin/subscription/change.c src/plugin/subscription/operational.c diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index 3e776bf4..2e608709 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -4,12 +4,16 @@ #include "netlink/socket.h" #include "plugin/common.h" #include "plugin/context.h" - -// startup #include "plugin/data/interfaces/interface_state.h" + +// startup DS #include "plugin/startup/load.h" #include "plugin/startup/store.h" +// running DS +#include "plugin/running/load.h" +#include "plugin/running/store.h" + // subscription #include "plugin/subscription/change.h" #include "plugin/subscription/operational.h" @@ -284,21 +288,21 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) ctx->startup_ctx.startup_session = startup_session; - SRPC_SAFE_CALL_ERR(error, srpc_check_empty_datastore(startup_session, INTERFACES_INTERFACES_INTERFACE_YANG_PATH, &empty_startup), error_out); + SRPC_SAFE_CALL_ERR(error, srpc_check_empty_datastore(running_session, INTERFACES_INTERFACES_INTERFACE_YANG_PATH, &empty_startup), error_out); if (empty_startup) { - SRPLG_LOG_INF(PLUGIN_NAME, "Startup datastore is empty"); + SRPLG_LOG_INF(PLUGIN_NAME, "Running datastore is empty"); SRPLG_LOG_INF(PLUGIN_NAME, "Loading initial system data"); - // load initial data on the system - SRPC_SAFE_CALL_ERR(error, interfaces_startup_load(ctx, running_session), error_out); + // load initial running DS data on the system + SRPC_SAFE_CALL_ERR(error, interfaces_running_load(ctx, running_session), error_out); } else { // make sure the data from startup DS is stored in the interfaces - SRPLG_LOG_INF(PLUGIN_NAME, "Startup datastore contains data"); - SRPLG_LOG_INF(PLUGIN_NAME, "Storing startup datastore data in the system"); + SRPLG_LOG_INF(PLUGIN_NAME, "Running datastore contains data"); + SRPLG_LOG_INF(PLUGIN_NAME, "Checking running datastore against system data"); - // check and store startup data on the system - SRPC_SAFE_CALL_ERR(error, interfaces_startup_store(ctx, startup_session), error_out); + // check and store running DS data on the system + SRPC_SAFE_CALL_ERR(error, interfaces_running_store(ctx, running_session), error_out); } // subscribe every module change diff --git a/src/interfaces/src/plugin/data/interfaces/interface.c b/src/interfaces/src/plugin/data/interfaces/interface.c index 125376f1..efb46763 100644 --- a/src/interfaces/src/plugin/data/interfaces/interface.c +++ b/src/interfaces/src/plugin/data/interfaces/interface.c @@ -611,7 +611,7 @@ int interfaces_interface_type_nl2ly(const char* nl_type, const char** ly_type) if (nl_type == NULL) { // fix for now - investigate more - lo interface has type == NULL - *ly_type = "iana-if-type:softwareLoopback"; + *ly_type = "iana-if-type:other"; return 0; } @@ -623,6 +623,8 @@ int interfaces_interface_type_nl2ly(const char* nl_type, const char** ly_type) *ly_type = "iana-if-type:l2vlan"; } else if (strcmp(nl_type, "dummy") == 0) { *ly_type = "iana-if-type:other"; + } else if (strcmp(nl_type, "bridge") == 0) { + *ly_type = "iana-if-type:bridge"; } else { error = -2; } diff --git a/src/interfaces/src/plugin/running/load.c b/src/interfaces/src/plugin/running/load.c new file mode 100644 index 00000000..986b1966 --- /dev/null +++ b/src/interfaces/src/plugin/running/load.c @@ -0,0 +1,104 @@ +#include "load.h" +#include "libyang/printer_data.h" +#include "plugin/common.h" +#include "plugin/data/interfaces/interface.h" +#include "plugin/ly_tree.h" + +#include "plugin/api/interfaces/load.h" +#include "plugin/types.h" +#include "src/uthash.h" +#include "src/utlist.h" +#include "srpc/common.h" + +#include +#include +#include + +static int interfaces_running_load_interface(void* priv, sr_session_ctx_t* session, const struct ly_ctx* ly_ctx, struct lyd_node* parent_node); + +int interfaces_running_load(interfaces_ctx_t* ctx, sr_session_ctx_t* session) +{ + int error = 0; + + const struct ly_ctx* ly_ctx = NULL; + struct lyd_node* root_node = NULL; + sr_conn_ctx_t* conn_ctx = NULL; + + srpc_startup_load_t load_values[] = { + { + "/ietf-interfaces:interfaces/interface", + interfaces_running_load_interface, + }, + }; + + SRPC_SAFE_CALL_PTR(conn_ctx, sr_session_get_connection(session), error_out); + SRPC_SAFE_CALL_PTR(ly_ctx, sr_acquire_context(conn_ctx), error_out); + + SRPC_SAFE_CALL_ERR(error, interfaces_ly_tree_create_interfaces(ly_ctx, &root_node), error_out); + + for (size_t i = 0; i < ARRAY_SIZE(load_values); i++) { + const srpc_startup_load_t* load = &load_values[i]; + + error = load->cb((void*)ctx, session, ly_ctx, root_node); + if (error) { + SRPLG_LOG_ERR(PLUGIN_NAME, "Node creation callback failed for value %s", load->name); + goto error_out; + } + } + +/* enable or disable storing into startup, use for testing */ +#define INTERFACES_PLUGIN_LOAD_STARTUP +/* disable for now */ +// #undef INTERFACES_PLUGIN_LOAD_STARTUP +#ifdef INTERFACES_PLUGIN_LOAD_STARTUP + error = sr_edit_batch(session, root_node, "merge"); + if (error != SR_ERR_OK) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_edit_batch() error (%d): %s", error, sr_strerror(error)); + goto error_out; + } + + error = sr_apply_changes(session, 0); + if (error != 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "sr_apply_changes() error (%d): %s", error, sr_strerror(error)); + goto error_out; + } +#endif + + goto out; + +error_out: + error = -1; + +out: + if (root_node) { + lyd_free_tree(root_node); + } + sr_release_context(conn_ctx); + + return error; +} + +static int interfaces_running_load_interface(void* priv, sr_session_ctx_t* session, const struct ly_ctx* ly_ctx, struct lyd_node* parent_node) +{ + int error = 0; + interfaces_ctx_t* ctx = (interfaces_ctx_t*)priv; + interfaces_interface_hash_element_t* interface_hash = NULL; + + // load interfaces data + SRPC_SAFE_CALL_ERR(error, interfaces_load_interface(ctx, &interface_hash), error_out); + + // convert to libyang + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_to_ly(ly_ctx, interface_hash, &parent_node), error_out); + + // print created tree + // lyd_print_file(stdout, parent_node, LYD_XML, 0); + + goto out; + +error_out: + error = -1; +out: + interfaces_interface_hash_free(&interface_hash); + + return error; +} diff --git a/src/interfaces/src/plugin/running/load.h b/src/interfaces/src/plugin/running/load.h new file mode 100644 index 00000000..b17d10aa --- /dev/null +++ b/src/interfaces/src/plugin/running/load.h @@ -0,0 +1,8 @@ +#ifndef INTERFACES_PLUGIN_RUNNING_LOAD_H +#define INTERFACES_PLUGIN_RUNNING_LOAD_H + +#include "plugin/context.h" + +int interfaces_running_load(interfaces_ctx_t* ctx, sr_session_ctx_t* session); + +#endif // INTERFACES_PLUGIN_RUNNING_LOAD_H \ No newline at end of file diff --git a/src/interfaces/src/plugin/running/store.c b/src/interfaces/src/plugin/running/store.c new file mode 100644 index 00000000..45e69cd0 --- /dev/null +++ b/src/interfaces/src/plugin/running/store.c @@ -0,0 +1,103 @@ +#include "store.h" +#include "plugin/common.h" + +#include "plugin/api/interfaces/check.h" +#include "plugin/api/interfaces/store.h" +#include "plugin/data/interfaces/interface.h" +#include "srpc/ly_tree.h" + +#include +#include +#include + +static int interfaces_running_store_interface(void* priv, const struct lyd_node* parent_container); + +int interfaces_running_store(interfaces_ctx_t* ctx, sr_session_ctx_t* session) +{ + int error = 0; + sr_data_t* subtree = NULL; + + SRPC_SAFE_CALL_ERR(error, sr_get_subtree(session, INTERFACES_INTERFACES_CONTAINER_YANG_PATH, 0, &subtree), error_out); + + srpc_startup_store_t store_values[] = { + { + "/ietf-interfaces:interfaces/interface[name='%s']", + interfaces_running_store_interface, + }, + }; + + for (size_t i = 0; i < ARRAY_SIZE(store_values); i++) { + const srpc_startup_store_t* store = &store_values[i]; + + error = store->cb(ctx, subtree->tree); + if (error != 0) { + SRPLG_LOG_ERR(PLUGIN_NAME, "Startup store callback failed for value %s", store->name); + goto error_out; + } + } + + goto out; + +error_out: + error = -1; + +out: + if (subtree) { + sr_release_data(subtree); + } + + return error; +} + +static int interfaces_running_store_interface(void* priv, const struct lyd_node* parent_container) +{ + int error = 0; + interfaces_ctx_t* ctx = (interfaces_ctx_t*)priv; + srpc_check_status_t check_status = srpc_check_status_none; + interfaces_interface_hash_element_t* if_hash = NULL; + struct lyd_node* interface_node = NULL; + + interface_node = srpc_ly_tree_get_child_list(parent_container, "interface"); + if (interface_node == NULL) { + SRPLG_LOG_ERR(PLUGIN_NAME, "srpc_ly_tree_get_child_leaf returned NULL for 'interfaces'"); + goto error_out; + } + + // map libyang data to the interface hash + SRPC_SAFE_CALL_ERR(error, interfaces_interface_hash_from_ly(&if_hash, interface_node), error_out); + + // check startup data + SRPLG_LOG_INF(PLUGIN_NAME, "Checking interface list data"); + check_status = interfaces_check_interface(ctx, if_hash); + + switch (check_status) { + case srpc_check_status_none: + SRPLG_LOG_ERR(PLUGIN_NAME, "Error loading current interface list"); + goto error_out; + case srpc_check_status_error: + SRPLG_LOG_ERR(PLUGIN_NAME, "Error loading current interface list"); + goto error_out; + case srpc_check_status_non_existant: + SRPLG_LOG_INF(PLUGIN_NAME, "Storing interface list"); + SRPC_SAFE_CALL_ERR(error, interfaces_store_interface(ctx, if_hash), error_out); + break; + case srpc_check_status_equal: + SRPLG_LOG_ERR(PLUGIN_NAME, "Startup interface list is already applied on the system"); + break; + case srpc_check_status_partial: + SRPLG_LOG_ERR(PLUGIN_NAME, "Error loading current interface list"); + goto error_out; + } + + goto out; + +error_out: + error = -1; + +out: + if (if_hash) { + interfaces_interface_hash_free(&if_hash); + } + + return error; +} diff --git a/src/interfaces/src/plugin/running/store.h b/src/interfaces/src/plugin/running/store.h new file mode 100644 index 00000000..a2a9cece --- /dev/null +++ b/src/interfaces/src/plugin/running/store.h @@ -0,0 +1,8 @@ +#ifndef INTERFACES_PLUGIN_RUNNING_STORE_H +#define INTERFACES_PLUGIN_RUNNING_STORE_H + +#include "plugin/context.h" + +int interfaces_running_store(interfaces_ctx_t* ctx, sr_session_ctx_t* session); + +#endif // INTERFACES_PLUGIN_RUNNING_STORE_H \ No newline at end of file From abd6f2fefc3864fbed10607f00392e881c385d79 Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Tue, 13 Dec 2022 22:51:22 +0000 Subject: [PATCH 247/247] interfaces-plugin: remove startup DS storing --- src/interfaces/src/plugin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interfaces/src/plugin.c b/src/interfaces/src/plugin.c index 2e608709..dc621716 100644 --- a/src/interfaces/src/plugin.c +++ b/src/interfaces/src/plugin.c @@ -302,7 +302,7 @@ int sr_plugin_init_cb(sr_session_ctx_t* running_session, void** private_data) SRPLG_LOG_INF(PLUGIN_NAME, "Checking running datastore against system data"); // check and store running DS data on the system - SRPC_SAFE_CALL_ERR(error, interfaces_running_store(ctx, running_session), error_out); + // SRPC_SAFE_CALL_ERR(error, interfaces_running_store(ctx, running_session), error_out); } // subscribe every module change