diff options
author | Hans Dedecker <dedeckeh@gmail.com> | 2015-04-08 16:20:22 +0200 |
---|---|---|
committer | John Crispin <blogic@openwrt.org> | 2015-04-03 10:44:54 +0200 |
commit | 92d2aea918f650f309f753349457028032d53280 (patch) | |
tree | e221bfb22d1cfe3980b5881bd2c66810118b84ca /interface.c | |
parent | 3a0f953722698eab6f3f623a1d6ec5a1b7102b77 (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.c | 27 |
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: |