Skip to content

Commit

Permalink
interfaces-plugin: add IPv4 and IPv6 address and neighbor load API
Browse files Browse the repository at this point in the history
  • Loading branch information
zinccyy committed Oct 31, 2022
1 parent 7f8be4d commit 43f3ce7
Show file tree
Hide file tree
Showing 13 changed files with 377 additions and 46 deletions.
4 changes: 4 additions & 0 deletions src/interfaces/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -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
105 changes: 105 additions & 0 deletions src/interfaces/src/plugin/api/interfaces/interface/ipv4/load.c
Original file line number Diff line number Diff line change
@@ -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)
{
Expand Down Expand Up @@ -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;
}
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit 43f3ce7

Please sign in to comment.