diff --git a/include/wicked/netinfo.h b/include/wicked/netinfo.h index 4c7506382..c12696901 100644 --- a/include/wicked/netinfo.h +++ b/include/wicked/netinfo.h @@ -257,6 +257,17 @@ extern ni_netdev_t * ni_netdev_ref_bind_ifindex(ni_netdev_ref_t *, ni_netconfig_ extern ni_netdev_t * ni_netdev_ref_bind_ifname (ni_netdev_ref_t *, ni_netconfig_t *); extern void ni_netdev_ref_destroy(ni_netdev_ref_t *); +extern ni_bool_t ni_netdev_ref_array_init(ni_netdev_ref_array_t *); +extern const ni_netdev_ref_t * + ni_netdev_ref_array_at(const ni_netdev_ref_array_t *, unsigned int); +extern const ni_netdev_ref_t * + ni_netdev_ref_array_find_name(const ni_netdev_ref_array_t *, const char *); +extern const ni_netdev_ref_t * + ni_netdev_ref_array_find_index(const ni_netdev_ref_array_t *, unsigned int); +extern const ni_netdev_ref_t * + ni_netdev_ref_array_append(ni_netdev_ref_array_t *, const char *, unsigned int); +extern void ni_netdev_ref_array_destroy(ni_netdev_ref_array_t *); + extern ni_netdev_req_t *ni_netdev_req_new(void); extern void ni_netdev_req_free(ni_netdev_req_t *req); diff --git a/include/wicked/types.h b/include/wicked/types.h index 1189ce4e6..ccbb18930 100644 --- a/include/wicked/types.h +++ b/include/wicked/types.h @@ -76,6 +76,13 @@ typedef struct ni_netdev_ref { char * name; /* by ifname */ } ni_netdev_ref_t; +#define NI_NETDEV_REF_ARRAY_INIT { .count = 0, .data = NULL } + +typedef struct ni_netdev_ref_array { + unsigned int count; + ni_netdev_ref_t * data; +} ni_netdev_ref_array_t; + typedef struct ni_dbus_server ni_dbus_server_t; typedef struct ni_dbus_client ni_dbus_client_t; diff --git a/src/netinfo.c b/src/netinfo.c index 9598155d6..c802b8e8a 100644 --- a/src/netinfo.c +++ b/src/netinfo.c @@ -35,6 +35,9 @@ #include "dhcp.h" #include + +#define NI_NETDEV_REF_ARRAY_CHUNK 16 + extern void ni_addrconf_updater_free(ni_addrconf_updater_t **); typedef struct ni_netconfig_filter { @@ -1008,6 +1011,114 @@ ni_netdev_ref_destroy(ni_netdev_ref_t *ref) } } +ni_bool_t +ni_netdev_ref_array_init(ni_netdev_ref_array_t *array) +{ + if (array) { + memset(array, 0, sizeof(*array)); + return TRUE; + } + return FALSE; +} + +const ni_netdev_ref_t * +ni_netdev_ref_array_at(const ni_netdev_ref_array_t *array, unsigned int i) +{ + if (!array || i >= array->count) + return NULL; + return &array->data[i]; +} + +const ni_netdev_ref_t * +ni_netdev_ref_array_find_index(const ni_netdev_ref_array_t *array, unsigned int index) +{ + const ni_netdev_ref_t *ref; + unsigned int i; + + if (!array) + return NULL; + + for (i = 0; i < array->count; ++i) { + ref = &array->data[i]; + if (ref->index == index) + return ref; + } + return NULL; +} + +const ni_netdev_ref_t * +ni_netdev_ref_array_find_name(const ni_netdev_ref_array_t *array, const char *name) +{ + const ni_netdev_ref_t *ref; + unsigned int i; + + if (!array) + return NULL; + + for (i = 0; i < array->count; ++i) { + ref = &array->data[i]; + if (ni_string_eq(ref->name, name)) + return ref; + } + return NULL; +} + +static ni_bool_t +ni_netdev_ref_array_realloc(ni_netdev_ref_array_t *array, unsigned int count) +{ + ni_netdev_ref_t *newdata; + size_t newsize; + unsigned int i; + + if ((UINT_MAX - array->count) <= count) + return FALSE; + + newsize = array->count + count; + if ((SIZE_MAX / sizeof(*newdata)) < newsize) + return FALSE; + + newdata = realloc(array->data, newsize * sizeof(*newdata)); + if (!newdata) + return FALSE; + + array->data = newdata; + for (i = array->count; i < newsize; ++i) { + array->data[i].index = 0; + array->data[i].name = NULL; + } + return TRUE; +} + +const ni_netdev_ref_t * +ni_netdev_ref_array_append(ni_netdev_ref_array_t *array, const char *name, unsigned int index) +{ + ni_netdev_ref_t *item; + + if (!array || ((array->count % NI_NETDEV_REF_ARRAY_CHUNK) == 0 && + !ni_netdev_ref_array_realloc(array, NI_NETDEV_REF_ARRAY_CHUNK))) + return NULL; + + item = &array->data[array->count++]; + ni_netdev_ref_set(item, name, index); + return item; +} + +void +ni_netdev_ref_array_destroy(ni_netdev_ref_array_t *array) +{ + ni_netdev_ref_t *item; + + if (array) { + while (array->count) { + array->count--; + item = &array->data[array->count]; + ni_netdev_ref_destroy(item); + } + free(array->data); + array->data = NULL; + } +} + /* * Handle netdev request port config */