From: Felix Fietkau Date: Sun, 24 Jun 2012 22:55:17 +0000 (+0200) Subject: add netdev ifindex support X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fprocd.git;a=commitdiff_plain;h=9ec29d3648904002f92b7d2b0732a820e44c5f4b add netdev ifindex support --- diff --git a/instance.c b/instance.c index c70fff6..19454c7 100644 --- a/instance.c +++ b/instance.c @@ -1,3 +1,6 @@ +#include +#include +#include #include #include "procd.h" @@ -8,6 +11,7 @@ enum { INSTANCE_ATTR_COMMAND, INSTANCE_ATTR_ENV, INSTANCE_ATTR_DATA, + INSTANCE_ATTR_NETDEV, __INSTANCE_ATTR_MAX }; @@ -15,6 +19,12 @@ static const struct blobmsg_policy instance_attr[__INSTANCE_ATTR_MAX] = { [INSTANCE_ATTR_COMMAND] = { "command", BLOBMSG_TYPE_ARRAY }, [INSTANCE_ATTR_ENV] = { "env", BLOBMSG_TYPE_TABLE }, [INSTANCE_ATTR_DATA] = { "data", BLOBMSG_TYPE_TABLE }, + [INSTANCE_ATTR_NETDEV] = { "netdev", BLOBMSG_TYPE_ARRAY }, +}; + +struct instance_netdev { + struct blobmsg_list_node node; + int ifindex; }; static void @@ -116,10 +126,30 @@ instance_config_changed(struct service_instance *in, struct service_instance *in if (!blobmsg_list_equal(&in->data, &in_new->data)) return true; + if (!blobmsg_list_equal(&in->netdev, &in_new->netdev)) + return true; + return false; } static bool +instance_netdev_cmp(struct blobmsg_list_node *l1, struct blobmsg_list_node *l2) +{ + struct instance_netdev *n1 = container_of(l1, struct instance_netdev, node); + struct instance_netdev *n2 = container_of(l2, struct instance_netdev, node); + + return n1->ifindex == n2->ifindex; +} + +static void +instance_netdev_update(struct blobmsg_list_node *l) +{ + struct instance_netdev *n = container_of(l, struct instance_netdev, node); + + n->ifindex = if_nametoindex(n->node.avl.key); +} + +static bool instance_config_parse(struct service_instance *in) { struct blob_attr *tb[__INSTANCE_ATTR_MAX]; @@ -149,15 +179,28 @@ instance_config_parse(struct service_instance *in) if ((cur = tb[INSTANCE_ATTR_ENV])) { if (!blobmsg_check_attr_list(cur, BLOBMSG_TYPE_STRING)) return false; + blobmsg_list_fill(&in->env, blobmsg_data(cur), blobmsg_data_len(cur), false); } if ((cur = tb[INSTANCE_ATTR_DATA])) { if (!blobmsg_check_attr_list(cur, BLOBMSG_TYPE_STRING)) return false; + blobmsg_list_fill(&in->data, blobmsg_data(cur), blobmsg_data_len(cur), false); } + if ((cur = tb[INSTANCE_ATTR_NETDEV])) { + struct blobmsg_list_node *ndev; + + if (!blobmsg_check_attr_list(cur, BLOBMSG_TYPE_STRING)) + return false; + + blobmsg_list_fill(&in->netdev, blobmsg_data(cur), blobmsg_data_len(cur), true); + blobmsg_list_for_each(&in->netdev, ndev) + instance_netdev_update(ndev); + } + return true; } @@ -166,6 +209,7 @@ instance_config_cleanup(struct service_instance *in) { blobmsg_list_free(&in->env); blobmsg_list_free(&in->data); + blobmsg_list_free(&in->netdev); } static void @@ -174,8 +218,12 @@ instance_config_move(struct service_instance *in, struct service_instance *in_sr instance_config_cleanup(in); blobmsg_list_move(&in->env, &in_src->env); blobmsg_list_move(&in->data, &in_src->data); + blobmsg_list_move(&in->netdev, &in_src->netdev); in->command = in_src->command; in->name = in_src->name; + in->node.avl.key = in_src->node.avl.key; + in->config = in_src->config; + in_src->config = NULL; } bool @@ -183,7 +231,6 @@ instance_update(struct service_instance *in, struct service_instance *in_new) { bool changed = instance_config_changed(in, in_new); - in->config = in_new->config; if (!changed) return false; @@ -211,6 +258,7 @@ instance_init(struct service_instance *in, struct service *s, struct blob_attr * in->timeout.cb = instance_timeout; in->proc.cb = instance_exit; + blobmsg_list_init(&in->netdev, struct instance_netdev, node, instance_netdev_cmp); blobmsg_list_simple_init(&in->env); blobmsg_list_simple_init(&in->data); in->valid = instance_config_parse(in); diff --git a/instance.h b/instance.h index 011cd9c..59e887c 100644 --- a/instance.h +++ b/instance.h @@ -19,6 +19,7 @@ struct service_instance { struct blob_attr *command; struct blobmsg_list env; struct blobmsg_list data; + struct blobmsg_list netdev; }; void instance_start(struct service_instance *in); diff --git a/utils.c b/utils.c index 0f9ce74..628136f 100644 --- a/utils.c +++ b/utils.c @@ -3,11 +3,12 @@ #include "utils.h" void -__blobmsg_list_init(struct blobmsg_list *list, int offset, int len) +__blobmsg_list_init(struct blobmsg_list *list, int offset, int len, blobmsg_list_cmp cmp) { avl_init(&list->avl, avl_strcmp, false, NULL); list->node_offset = offset; list->node_len = len; + list->cmp = cmp; } int @@ -21,7 +22,7 @@ blobmsg_list_fill(struct blobmsg_list *list, void *data, int len, bool array) int rem = len; __blob_for_each_attr(cur, data, rem) { - if (!blobmsg_check_attr(cur, true)) + if (!blobmsg_check_attr(cur, !array)) continue; ptr = calloc(1, list->node_len); @@ -52,7 +53,7 @@ blobmsg_list_move(struct blobmsg_list *list, struct blobmsg_list *src) void *ptr; avl_remove_all_elements(&src->avl, node, avl, tmp) { - if (!avl_insert(&list->avl, &node->avl)) { + if (avl_insert(&list->avl, &node->avl)) { ptr = ((char *) node - list->node_offset); free(ptr); } @@ -93,6 +94,9 @@ blobmsg_list_equal(struct blobmsg_list *l1, struct blobmsg_list *l2) if (memcmp(n1->data, n2->data, len) != 0) return false; + if (l1->cmp && !l1->cmp(n1, n2)) + return false; + if (!count) break; diff --git a/utils.h b/utils.h index e20169a..360f9f1 100644 --- a/utils.h +++ b/utils.h @@ -5,27 +5,31 @@ #include #include +struct blobmsg_list_node { + struct avl_node avl; + struct blob_attr *data; +}; + +typedef bool (*blobmsg_list_cmp)(struct blobmsg_list_node *l1, struct blobmsg_list_node *l2); + struct blobmsg_list { struct avl_tree avl; int node_offset; int node_len; -}; -struct blobmsg_list_node { - struct avl_node avl; - struct blob_attr *data; + blobmsg_list_cmp cmp; }; #define blobmsg_list_simple_init(list) \ - __blobmsg_list_init(list, 0, sizeof(struct blobmsg_list_node)) + __blobmsg_list_init(list, 0, sizeof(struct blobmsg_list_node), NULL) -#define blobmsg_list_init(list, type, field) \ - __blobmsg_list_init(list, offsetof(type, field), sizeof(type)) +#define blobmsg_list_init(list, type, field, cmp) \ + __blobmsg_list_init(list, offsetof(type, field), sizeof(type), cmp) #define blobmsg_list_for_each(list, element) \ avl_for_each_element(&(list)->avl, element, avl) -void __blobmsg_list_init(struct blobmsg_list *list, int offset, int len); +void __blobmsg_list_init(struct blobmsg_list *list, int offset, int len, blobmsg_list_cmp cmp); int blobmsg_list_fill(struct blobmsg_list *list, void *data, int len, bool array); void blobmsg_list_free(struct blobmsg_list *list); bool blobmsg_list_equal(struct blobmsg_list *l1, struct blobmsg_list *l2);