diff options
-rw-r--r-- | src/device-common.c | 121 | ||||
-rw-r--r-- | src/device-common.h | 31 | ||||
-rw-r--r-- | src/device-interface.c | 170 | ||||
-rw-r--r-- | src/meson.build | 1 |
4 files changed, 162 insertions, 161 deletions
diff --git a/src/device-common.c b/src/device-common.c new file mode 100644 index 0000000..4a10bf5 --- /dev/null +++ b/src/device-common.c @@ -0,0 +1,121 @@ +#include "device-common.h" +#include "util.h" + +#include <assert.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <arpa/inet.h> + +static unsigned long strtoul_safe(const char *str) { + char *endptr; + + errno = 0; + unsigned long val = strtoul(str, &endptr, 10); + if (endptr == str || *endptr) + errno = EINVAL; + + return val; +} + +static bool parse_address(ipaddr_t *addr, const char *str) { + if (inet_pton(AF_INET, str, &addr->addr4)) { + addr->af = AF_INET; + return true; + } + + if (inet_pton(AF_INET6, str, &addr->addr6)) { + addr->af = AF_INET6; + return true; + } + + return false; +} + +static bool parse_prefix(ipaddr_prefix_t *prefix, const char *str, bool allow_host) { + const char *slash = strrchr(str, '/'); + if (!slash) + return false; + + size_t len = slash - str; + char buf[len+1]; + memcpy(buf, str, len); + buf[len] = 0; + + if (!parse_address(&prefix->addr, buf)) + return false; + + long plen = strtoul_safe(slash + 1); + if (errno) + return false; + + switch (prefix->addr.af) { + case AF_INET: + if (plen > 32) + return false; + break; + + case AF_INET6: + if (plen > 128) + return false; + break; + + default: + assert(false); + __builtin_unreachable(); + } + + prefix->plen = plen; + + // TODO: Implement allow_host + + return true; +} + +static bool process_section_device(device_common_t *device, struct json_object *section) { + return true; +} + +static bool process_section_static(device_common_t *device, struct json_object *section) { + struct json_object *addresses = neco_json_get_value(section, "addresses", json_type_array); + if (addresses) { + for (size_t i = 0; i < json_object_array_length(addresses); i++) { + struct json_object *address = json_object_array_get_idx(addresses, i); + if (!json_object_is_type(address, json_type_string)) { + fprintf(stderr, "interface: static: invalid address entry of type %s\n", json_type_to_name(json_object_get_type(address))); + continue; + } + + ipaddr_prefix_t p; + if (!parse_prefix(&p, json_object_get_string(address), true)) { + fprintf(stderr, "interface: static: unable to parse Address %s\n", json_object_get_string(address)); + break; + } + + if (!VECTOR_ADD(device->addrs, p)) { + fprintf(stderr, "interface: static: adding address failed\n"); + return false; + } + } + } + + return true; +} + +bool device_common_process_config(device_common_t *device, struct json_object *config) { + struct json_object *sec_device = neco_json_get_value(config, "device", json_type_object); + if (sec_device) { + if (!process_section_device(device, sec_device)) + return false; + } + + struct json_object *sec_static = neco_json_get_value(config, "static", json_type_object); + if (sec_static) { + if (!process_section_static(device, sec_static)) + return false; + } + + return true; +} diff --git a/src/device-common.h b/src/device-common.h new file mode 100644 index 0000000..ff27961 --- /dev/null +++ b/src/device-common.h @@ -0,0 +1,31 @@ +#pragma once + +#include "device.h" +#include "vector.h" + +#include <netinet/ether.h> +#include <netinet/in.h> + +typedef struct _ipaddr { + int af; + union { + struct in_addr addr4; + struct in6_addr addr6; + }; +} ipaddr_t; + +typedef struct _ipprefix { + ipaddr_t addr; + uint8_t plen; +} ipaddr_prefix_t; + +typedef VECTOR(ipaddr_prefix_t) ipaddr_prefix_vector_t; + +typedef struct _device_common { + struct ether_addr macaddr; + uint16_t mtu; + + ipaddr_prefix_vector_t addrs; +} device_common_t; + +bool device_common_process_config(device_common_t *device, struct json_object *config); diff --git a/src/device-interface.c b/src/device-interface.c index ef85089..aa37940 100644 --- a/src/device-interface.c +++ b/src/device-interface.c @@ -1,17 +1,13 @@ -#include "device.h" +#include "device-common.h" #include "netlink.h" #include "util.h" #include "vector.h" -#include <assert.h> #include <errno.h> #include <stdlib.h> #include <string.h> -#include <arpa/inet.h> #include <net/if.h> -#include <netinet/ether.h> -#include <netinet/in.h> #include <linux/if.h> #include <linux/if_link.h> @@ -19,158 +15,19 @@ static device_type_t device_type_interface; -typedef struct _ipaddr { - int af; - union { - struct in_addr addr4; - struct in6_addr addr6; - }; -} ipaddr_t; - -typedef struct _ipprefix { - ipaddr_t addr; - uint8_t plen; -} ipaddr_prefix_t; - -typedef VECTOR(ipaddr_prefix_t) ipaddr_prefix_vector_t; - typedef struct _device_interface { device_t device; - - struct ether_addr macaddr; - uint16_t mtu; - - ipaddr_prefix_vector_t addrs; + device_common_t common; } device_interface_t; -static unsigned long strtoul_safe(const char *str) { - char *endptr; - - errno = 0; - unsigned long val = strtoul(str, &endptr, 10); - if (endptr == str || *endptr) - errno = EINVAL; - - return val; -} - -static bool parse_address(ipaddr_t *addr, const char *str) { - if (inet_pton(AF_INET, str, &addr->addr4)) { - addr->af = AF_INET; - return true; - } - - if (inet_pton(AF_INET6, str, &addr->addr6)) { - addr->af = AF_INET6; - return true; - } - - return false; -} - -static bool parse_prefix(ipaddr_prefix_t *prefix, const char *str, bool allow_host) { - const char *slash = strrchr(str, '/'); - if (!slash) - return false; - - size_t len = slash - str; - char buf[len+1]; - memcpy(buf, str, len); - buf[len] = 0; - - if (!parse_address(&prefix->addr, buf)) - return false; - - long plen = strtoul_safe(slash + 1); - if (errno) - return false; - - switch (prefix->addr.af) { - case AF_INET: - if (plen > 32) - return false; - break; - - case AF_INET6: - if (plen > 128) - return false; - break; - - default: - assert(false); - __builtin_unreachable(); - } - - prefix->plen = plen; - - // TODO: Implement allow_host - - return true; -} - static void interface_free(device_t *dev) { device_interface_t *iface = container_of(dev, device_interface_t, device); - VECTOR_FREE(iface->addrs); + VECTOR_FREE(iface->common.addrs); free(NODE_NAME(dev)); free(iface); } -static bool process_section_device(device_interface_t *iface, struct json_object *section) { - return true; -} - -static bool process_section_static(device_interface_t *iface, struct json_object *section) { - struct json_object *addresses = neco_json_get_value(section, "addresses", json_type_array); - if (addresses) { - for (size_t i = 0; i < json_object_array_length(addresses); i++) { - struct json_object *address = json_object_array_get_idx(addresses, i); - if (!json_object_is_type(address, json_type_string)) { - fprintf(stderr, "interface: static: invalid address entry of type %s\n", json_type_to_name(json_object_get_type(address))); - continue; - } - - ipaddr_prefix_t p; - if (!parse_prefix(&p, json_object_get_string(address), true)) { - fprintf(stderr, "interface: static: unable to parse Address %s\n", json_object_get_string(address)); - break; - } - - if (!VECTOR_ADD(iface->addrs, p)) { - fprintf(stderr, "interface: static: adding address failed\n"); - return false; - } - } - } - - - /* - list_for_each_entry(field, §ion->fields, node) { - switch (lookup_keyword(field->key)) { - case KW_Address: { - ipaddr_prefix_t p; - if (!parse_prefix(&p, field->value, true)) { - fprintf(stderr, "interface: [Static]: unable to parse Address %s\n", field->value); - break; - } - - if (!VECTOR_ADD(iface->addrs, p)) { - fprintf(stderr, "interface: [Static]: adding address failed\n"); - return false; - } - - break; - } - - default: - fprintf(stderr, "interface: [Static]: unknown field %s\n", field->key); - } - } - */ - - return true; -} - static device_t * interface_process_config(const char *name, struct json_object *config) { device_interface_t *iface = calloc(1, sizeof(*iface)); if (!iface) @@ -185,17 +42,8 @@ static device_t * interface_process_config(const char *name, struct json_object return NULL; } - struct json_object *sec_device = neco_json_get_value(config, "device", json_type_object); - if (sec_device) { - if (!process_section_device(iface, sec_device)) - goto err; - } - - struct json_object *sec_static = neco_json_get_value(config, "static", json_type_object); - if (sec_static) { - if (!process_section_static(iface, sec_static)) - goto err; - } + if (!device_common_process_config(&iface->common, config)) + goto err; return dev; @@ -307,8 +155,8 @@ static void interface_init(device_t *dev) { interface_set_link_state(index, true); - for (size_t i = 0; i < VECTOR_LEN(iface->addrs); i++) - interface_set_ipaddr(index, &VECTOR_INDEX(iface->addrs, i), true); + for (size_t i = 0; i < VECTOR_LEN(iface->common.addrs); i++) + interface_set_ipaddr(index, &VECTOR_INDEX(iface->common.addrs, i), true); } static void interface_update(device_t *dev) { @@ -321,8 +169,8 @@ static void interface_release(device_t *dev) { if (!index) return; - for (size_t i = 0; i < VECTOR_LEN(iface->addrs); i++) - interface_set_ipaddr(index, &VECTOR_INDEX(iface->addrs, i), false); + for (size_t i = 0; i < VECTOR_LEN(iface->common.addrs); i++) + interface_set_ipaddr(index, &VECTOR_INDEX(iface->common.addrs, i), false); interface_set_link_state(index, false); } diff --git a/src/meson.build b/src/meson.build index b359ab4..3cc830c 100644 --- a/src/meson.build +++ b/src/meson.build @@ -4,6 +4,7 @@ src = [ 'config-process.c', 'device.c', 'device-bridge.c', + 'device-common.c', 'device-interface.c', 'netlink.c', 'vector.c', |