This is needed for L2TP with xl2tpd daemon.

Signed-off-by: Yousong Zhou <[email protected]>
---
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 <[email protected]>
+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 <[email protected]>
+---
+ 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
[email protected]
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

Reply via email to