[OpenWrt-Devel] [RFC] netifd: backport support of checkup_interval option

Yousong Zhou yszhou4tech at gmail.com
Thu Sep 17 21:58:42 EDT 2015


This is needed for L2TP with xl2tpd daemon.

Signed-off-by: Yousong Zhou <yszhou4tech at gmail.com>
---
Another option would be bump the netifd version to the lastest, but I am a bit
conservative now.  That said, I plan to backport xl2tpd from trunk to
packages;for-15.05 after this checkup_interval option will be available in CC
as the current version there does not work at all [1]

[1] please update xl2tpd package in 15.05 branch,
	https://github.com/openwrt/packages/issues/1478

 ...-add-checkup-timeout-to-restart-interface.patch |  137 ++++++++++++++++++++
 1 file changed, 137 insertions(+)
 create mode 100644 package/network/config/netifd/patches/0001-proto-shell-add-checkup-timeout-to-restart-interface.patch

diff --git a/package/network/config/netifd/patches/0001-proto-shell-add-checkup-timeout-to-restart-interface.patch b/package/network/config/netifd/patches/0001-proto-shell-add-checkup-timeout-to-restart-interface.patch
new file mode 100644
index 0000000..784ae7f
--- /dev/null
+++ b/package/network/config/netifd/patches/0001-proto-shell-add-checkup-timeout-to-restart-interface.patch
@@ -0,0 +1,137 @@
+From 6ed631e55686b909e6db25838e6e591316933c97 Mon Sep 17 00:00:00 2001
+From: Yousong Zhou <yszhou4tech at gmail.com>
+Date: Fri, 21 Aug 2015 10:11:57 +0800
+Subject: [PATCH] proto-shell: add checkup timeout to restart interface.
+
+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 |   60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 60 insertions(+)
+
+diff --git a/proto-shell.c b/proto-shell.c
+index e2e765f..8a3ff69 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,12 @@ proto_shell_task_finish(struct proto_shell_state *state,
+ 				proto_shell_handler(&state->proto,
+ 						    PROTO_CMD_TEARDOWN,
+ 						    false);
++
++			/* check up status after setup attempt by this script_task */
++			if (state->sm == S_SETUP && state->checkup_interval > 0) {
++				uloop_timeout_set(&state->checkup_timeout,
++						  state->checkup_interval * 1000);
++			}
+ 		}
+ 		break;
+ 
+@@ -311,7 +326,9 @@ proto_shell_task_finish(struct proto_shell_state *state,
+ 		    state->proto_task.uloop.pending)
+ 			break;
+ 
++		/* completed aborting all tasks, now idle */
+ 		uloop_timeout_cancel(&state->teardown_timeout);
++		uloop_timeout_cancel(&state->checkup_timeout);
+ 		state->sm = S_IDLE;
+ 		proto_shell_handler(&state->proto, PROTO_CMD_TEARDOWN, false);
+ 		break;
+@@ -326,7 +343,9 @@ proto_shell_task_finish(struct proto_shell_state *state,
+ 			break;
+ 		}
+ 
++		/* completed tearing down all tasks, now idle */
+ 		uloop_timeout_cancel(&state->teardown_timeout);
++		uloop_timeout_cancel(&state->checkup_timeout);
+ 		state->sm = S_IDLE;
+ 		state->proto.proto_event(&state->proto, IFPEV_DOWN);
+ 		break;
+@@ -374,6 +393,7 @@ proto_shell_free(struct interface_proto_state *proto)
+ 
+ 	state = container_of(proto, struct proto_shell_state, proto);
+ 	uloop_timeout_cancel(&state->teardown_timeout);
++	uloop_timeout_cancel(&state->checkup_timeout);
+ 	proto_shell_clear_host_dep(state);
+ 	netifd_kill_process(&state->script_task);
+ 	netifd_kill_process(&state->proto_task);
+@@ -768,6 +788,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 +841,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
+
-- 
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