summaryrefslogtreecommitdiffhomepage
path: root/interface.c
diff options
context:
space:
mode:
authorHans Dedecker <dedeckeh@gmail.com>2015-04-08 16:20:22 +0200
committerJohn Crispin <blogic@openwrt.org>2015-04-03 10:44:54 +0200
commit92d2aea918f650f309f753349457028032d53280 (patch)
treee221bfb22d1cfe3980b5881bd2c66810118b84ca /interface.c
parent3a0f953722698eab6f3f623a1d6ec5a1b7102b77 (diff)
netifd: Interface last error support
Adds interface last error support which preserves the last reported error reported by the protocol handler till the interface is up; e.g. survives network reload and interface restarts. This is mainly usefull for tracking down why an interface fails to establish; eg auth failure/traffic limit for PPP interfaces Protocol handlers register last error support by setting lasterror=1 in the proto_init function Signed-off-by: Johan Peeters <johan.peeters111@gmail.com> Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
Diffstat (limited to 'interface.c')
-rw-r--r--interface.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/interface.c b/interface.c
index 444f3ac..8239eac 100644
--- a/interface.c
+++ b/interface.c
@@ -80,7 +80,7 @@ const struct uci_blob_param_list interface_attr_list = {
};
static void
-interface_clear_errors(struct interface *iface)
+interface_error_flush(struct interface *iface)
{
struct interface_error *error, *tmp;
@@ -90,6 +90,17 @@ interface_clear_errors(struct interface *iface)
}
}
+static void
+interface_clear_errors(struct interface *iface)
+{
+ /* don't flush the errors in case the configured protocol handler matches the
+ running protocol handler and is having the last error capability */
+ if (!(iface->proto &&
+ (iface->proto->handler->flags & PROTO_FLAG_LASTERROR) &&
+ (iface->proto->handler->name == iface->proto_handler->name)))
+ interface_error_flush(iface);
+}
+
void interface_add_error(struct interface *iface, const char *subsystem,
const char *code, const char **data, int n_data)
{
@@ -98,6 +109,14 @@ void interface_add_error(struct interface *iface, const char *subsystem,
int *datalen = NULL;
char *dest, *d_subsys, *d_code;
+ /* if the configured protocol handler has the last error support capability,
+ errors should only be added if the running protocol handler matches the
+ configured one */
+ if (iface->proto &&
+ (iface->proto->handler->flags & PROTO_FLAG_LASTERROR) &&
+ (iface->proto->handler->name != iface->proto_handler->name))
+ return;
+
if (n_data) {
len = n_data * sizeof(char *);
datalen = alloca(len);
@@ -113,6 +132,11 @@ void interface_add_error(struct interface *iface, const char *subsystem,
if (!error)
return;
+ /* Only keep the last flagged error, prevent this list grows unlimitted in case the
+ protocol can't be established (e.g auth failure) */
+ if (iface->proto_handler->flags & PROTO_FLAG_LASTERROR)
+ interface_error_flush(iface);
+
list_add_tail(&error->list, &iface->errors);
dest = (char *) &error->data[n_data + 1];
@@ -188,6 +212,7 @@ interface_event(struct interface *iface, enum interface_event ev)
switch (ev) {
case IFEV_UP:
+ interface_error_flush(iface);
adev = iface->l3_dev.dev;
/* fall through */
case IFEV_DOWN: