[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