[OpenWrt-Devel] [PATCH 2/2] proto-shell: add checkup timeout to restart interface.

Yousong Zhou yszhou4tech at gmail.com
Wed Aug 12 09:08:16 EDT 2015


This is mainly for protocols with no_proto_task set.  L2TP with xl2tpd
is such a case and the issue this commit tries to address is that xl2tpd
could fail redialing the connection (segfault or abort) without the
notice of netifd causing the concerned interface being left down.

This patch solves it by allowing users to configure an timeout value
instructing netifd to check if the interface is in up state after its
last attempt to setup it and try again if that is not the case.

Signed-off-by: Yousong Zhou <yszhou4tech at gmail.com>
---
 proto-shell.c |   53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/proto-shell.c b/proto-shell.c
index e2e765f..dfb14a9 100644
--- a/proto-shell.c
+++ b/proto-shell.c
@@ -69,6 +69,15 @@ struct proto_shell_state {
 
 	struct uloop_timeout teardown_timeout;
 
+	/*
+	 * Teardown and setup interface again if it is still not up (IFS_UP)
+	 * after checkup_interval seconds since previous attempt.  This check
+	 * will be disabled when the config option "checkup_interval" is
+	 * missing or has a negative value
+	 */
+	int checkup_interval;
+	struct uloop_timeout checkup_timeout;
+
 	struct netifd_process script_task;
 	struct netifd_process proto_task;
 
@@ -303,6 +312,10 @@ proto_shell_task_finish(struct proto_shell_state *state,
 				proto_shell_handler(&state->proto,
 						    PROTO_CMD_TEARDOWN,
 						    false);
+			if (state->checkup_interval > 0) {
+				uloop_timeout_set(&state->checkup_timeout,
+						  state->checkup_interval * 1000);
+			}
 		}
 		break;
 
@@ -768,6 +781,45 @@ proto_shell_notify(struct interface_proto_state *proto, struct blob_attr *attr)
 	}
 }
 
+static void
+proto_shell_checkup_timeout_cb(struct uloop_timeout *timeout)
+{
+	struct proto_shell_state *state = container_of(timeout, struct
+			proto_shell_state, checkup_timeout);
+	struct interface_proto_state *proto = &state->proto;
+	struct interface *iface = proto->iface;
+
+	if (!iface->autostart)
+		return;
+
+	if (iface->state == IFS_UP)
+		return;
+
+	D(INTERFACE, "Interface '%s' is not up after %d sec\n",
+			iface->name, state->checkup_interval);
+	proto_shell_handler(proto, PROTO_CMD_TEARDOWN, false);
+}
+
+static void
+proto_shell_checkup_attach(struct proto_shell_state *state,
+		const struct blob_attr *attr)
+{
+	struct blob_attr *tb;
+	struct blobmsg_policy checkup_policy = {
+		.name = "checkup_interval",
+		.type = BLOBMSG_TYPE_INT32
+	};
+
+	blobmsg_parse(&checkup_policy, 1, &tb, blob_data(attr), blob_len(attr));
+	if (!tb) {
+		state->checkup_interval = -1;
+		state->checkup_timeout.cb = NULL;
+	} else {
+		state->checkup_interval = blobmsg_get_u32(tb);
+		state->checkup_timeout.cb = proto_shell_checkup_timeout_cb;
+	}
+}
+
 static struct interface_proto_state *
 proto_shell_attach(const struct proto_handler *h, struct interface *iface,
 		   struct blob_attr *attr)
@@ -782,6 +834,7 @@ proto_shell_attach(const struct proto_handler *h, struct interface *iface,
 		goto error;
 
 	memcpy(state->config, attr, blob_pad_len(attr));
+	proto_shell_checkup_attach(state, state->config);
 	state->proto.free = proto_shell_free;
 	state->proto.notify = proto_shell_notify;
 	state->proto.cb = proto_shell_handler;
-- 
1.7.10.4
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list