diff options
author | Felix Fietkau <nbd@openwrt.org> | 2011-03-28 00:17:51 +0200 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2011-03-28 00:17:51 +0200 |
commit | 308f0a4a364cfb9df6f6991eac00aa306846d2f6 (patch) | |
tree | c7476893bc8f931f01eea577326b9c7df50b540d /interface.c | |
parent | 856b9f1c3794b96738e89b4d7655b3acdb16d9a9 (diff) |
add error reporting support
Diffstat (limited to 'interface.c')
-rw-r--r-- | interface.c | 61 |
1 files changed, 56 insertions, 5 deletions
diff --git a/interface.c b/interface.c index d45f2d5..52d30fc 100644 --- a/interface.c +++ b/interface.c @@ -7,7 +7,53 @@ LIST_HEAD(interfaces); -static int interface_event(struct interface *iface, enum interface_event ev) +static void +clear_interface_errors(struct interface *iface) +{ + struct interface_error *error, *tmp; + + list_for_each_entry_safe(error, tmp, &iface->errors, list) { + list_del(&error->list); + free(error); + } +} + +void interface_add_error(struct interface *iface, const char *subsystem, + const char *code, const char **data, int n_data) +{ + struct interface_error *error; + int i, len = 0; + int *datalen; + char *dest; + + if (n_data) { + len = n_data * sizeof(char *); + datalen = alloca(len); + for (i = 0; i < n_data; i++) { + datalen[i] = strlen(data[i]) + 1; + len += datalen[i]; + } + } + + error = calloc(1, sizeof(*error) + sizeof(char *) + len); + if (!error) + return; + + list_add_tail(&error->list, &iface->errors); + error->subsystem = subsystem; + error->code = code; + + dest = (char *) &error->data[n_data + 1]; + for (i = 0; i < n_data; i++) { + error->data[i] = dest; + memcpy(dest, data[i], datalen[i]); + dest += datalen[i]; + } + error->data[n_data] = NULL; +} + +static int +interface_event(struct interface *iface, enum interface_event ev) { if (!iface->state || !iface->state->event) return 0; @@ -35,6 +81,8 @@ __set_interface_up(struct interface *iface) static void __set_interface_down(struct interface *iface) { + clear_interface_errors(iface); + if (!iface->up) return; @@ -87,6 +135,8 @@ alloc_interface(const char *name) iface->l3_iface = &iface->main_dev; strncpy(iface->name, name, sizeof(iface->name) - 1); list_add(&iface->list, &interfaces); + INIT_LIST_HEAD(&iface->errors); + netifd_ubus_add_interface(iface); return iface; @@ -148,6 +198,11 @@ set_interface_up(struct interface *iface) { iface->autostart = true; + if (!iface->active) { + interface_add_error(iface, "interface", "NO_DEVICE", NULL, 0); + return -1; + } + if (iface->up || !iface->active) return -1; @@ -159,10 +214,6 @@ int set_interface_down(struct interface *iface) { iface->autostart = false; - - if (!iface->up) - return -1; - __set_interface_down(iface); return 0; |