From patchwork Wed Apr 8 14:20:22 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Dedecker X-Patchwork-Id: 459290 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from arrakis.dune.hu (arrakis.dune.hu [78.24.191.176]) (using TLSv1.1 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id AD2F414011D for ; Thu, 9 Apr 2015 00:21:50 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="verification failed; unprotected key" header.d=gmail.com header.i=@gmail.com header.b=s12qDsCR; dkim-adsp=none (unprotected policy); dkim-atps=neutral Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id 8176728C6DB; Wed, 8 Apr 2015 16:20:03 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on arrakis.dune.hu X-Spam-Level: X-Spam-Status: No, score=-1.5 required=5.0 tests=BAYES_00,FREEMAIL_FROM, T_DKIM_INVALID autolearn=unavailable version=3.3.2 Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id 589AC28C68C for ; Wed, 8 Apr 2015 16:19:52 +0200 (CEST) X-policyd-weight: using cached result; rate: -8.5 Received: from mail-wi0-f180.google.com (mail-wi0-f180.google.com [209.85.212.180]) by arrakis.dune.hu (Postfix) with ESMTPS for ; Wed, 8 Apr 2015 16:19:51 +0200 (CEST) Received: by wiaa2 with SMTP id a2so60621393wia.0 for ; Wed, 08 Apr 2015 07:20:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=kHnNME+1yydgHqXkmAhMAPuhJAIffScwa9WQDpCAAzU=; b=s12qDsCRzZ7WmgI0eI6J89plpX2iMNfU2EXK5sOvtqZOLOKXpa2M+dfHg175XtQIJI OrTQd7t2UhD8/elcLN1jJW8uIeq7V1zoalgG8NnCSdaK8mFp9Ig/uuzGFLCvn3A9u796 XSxp88CSA9QPkPcc9yLzpvriahZK/WjcLZuCBaLW2sU7moTYwmRjHPZHFeBOrsTKJw44 2l2P0xF06+xIb7Av5P7B7UkaQqeSXSJyk1IQunDP92tEs7NJySYYR0J7HRoorwYCRWgw wgW4Kgf9OPFxYSCVulrD6DLGSTs3jTSnNJK4CagebR2ROB+W2lhD+FCfl2/l/gqPsjTH QmYg== X-Received: by 10.194.185.68 with SMTP id fa4mr49511702wjc.111.1428502838042; Wed, 08 Apr 2015 07:20:38 -0700 (PDT) Received: from cplx43.eu.thmulti.com ([141.11.62.7]) by mx.google.com with ESMTPSA id ff4sm15903097wib.9.2015.04.08.07.20.36 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 08 Apr 2015 07:20:37 -0700 (PDT) From: Hans Dedecker To: openwrt-devel@lists.openwrt.org Date: Wed, 8 Apr 2015 16:20:22 +0200 Message-Id: <1428502822-23703-2-git-send-email-dedeckeh@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1428502822-23703-1-git-send-email-dedeckeh@gmail.com> References: <1428502822-23703-1-git-send-email-dedeckeh@gmail.com> Cc: Johan Peeters , Hans Dedecker , cyrus@openwrt.org Subject: [OpenWrt-Devel] [PATCH] netifd: Interface last error support X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: openwrt-devel-bounces@lists.openwrt.org Sender: "openwrt-devel" 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 Signed-off-by: Hans Dedecker --- interface.c | 27 ++++++++++++++++++++++++++- proto-shell.c | 4 ++++ proto.c | 6 +++++- proto.h | 1 + scripts/netifd-proto.sh | 1 + 5 files changed, 37 insertions(+), 2 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: diff --git a/proto-shell.c b/proto-shell.c index 977cdbc..7a1896b 100644 --- a/proto-shell.c +++ b/proto-shell.c @@ -819,6 +819,10 @@ proto_shell_add_handler(const char *script, const char *name, json_object *obj) if (tmp && json_object_get_boolean(tmp)) handler->proto.flags |= PROTO_FLAG_RENEW_AVAILABLE; + tmp = json_get_field(obj, "lasterror", json_type_boolean); + if (tmp && json_object_get_boolean(tmp)) + handler->proto.flags |= PROTO_FLAG_LASTERROR; + config = json_get_field(obj, "config", json_type_array); if (config) handler->config_buf = netifd_handler_parse_config(&handler->config, config); diff --git a/proto.c b/proto.c index 0ba2fbe..eaec913 100644 --- a/proto.c +++ b/proto.c @@ -586,16 +586,20 @@ void proto_attach_interface(struct interface *iface, const char *proto_name) { const struct proto_handler *proto = &no_proto; + const char *error = NULL; if (proto_name) { proto = get_proto_handler(proto_name); if (!proto) { - interface_add_error(iface, "proto", "INVALID_PROTO", NULL, 0); + error = "INVALID_PROTO"; proto = &no_proto; } } iface->proto_handler = proto; + + if (error) + interface_add_error(iface, "proto", error, NULL, 0); } int diff --git a/proto.h b/proto.h index 7210f48..87dec4e 100644 --- a/proto.h +++ b/proto.h @@ -37,6 +37,7 @@ enum { PROTO_FLAG_INIT_AVAILABLE = (1 << 2), PROTO_FLAG_RENEW_AVAILABLE = (1 << 3), PROTO_FLAG_FORCE_LINK_DEFAULT = (1 << 4), + PROTO_FLAG_LASTERROR = (1 << 5), }; struct interface_proto_state { diff --git a/scripts/netifd-proto.sh b/scripts/netifd-proto.sh index ce60cd0..95c1bb3 100644 --- a/scripts/netifd-proto.sh +++ b/scripts/netifd-proto.sh @@ -375,6 +375,7 @@ init_proto() { json_add_boolean no-device "$no_device" json_add_boolean available "$available" json_add_boolean renew-handler "$renew_handler" + json_add_boolean lasterror "$lasterror" json_dump } ;;