summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2014-07-09 17:08:01 +0400
committerDmitry Kozlov <xeb@mail.ru>2014-07-11 15:06:11 +0400
commit894cd3e7aa89ee0139dd1ba132391db802ffd55b (patch)
tree33112d775bb084c287fe9a0de1e5da90ce11735c
parent00981be8678f0bcd6bd4ac16cc0c06276af1f535 (diff)
downloadaccel-ppp-xebd-894cd3e7aa89ee0139dd1ba132391db802ffd55b.tar.gz
accel-ppp-xebd-894cd3e7aa89ee0139dd1ba132391db802ffd55b.zip
ipv6_nd: retry to start ND later if bind failed
There is some issue on binding raw ICMPv6 socket immediately after assigning address on 3.14 (and probably later) kernel. This causes ipv6_nd to fail to start. This patch makes ipv6_nd to try to bind later if bind fails.
-rw-r--r--accel-pppd/ipv6/nd.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/accel-pppd/ipv6/nd.c b/accel-pppd/ipv6/nd.c
index 1335338..181230c 100644
--- a/accel-pppd/ipv6/nd.c
+++ b/accel-pppd/ipv6/nd.c
@@ -5,6 +5,7 @@
#include <string.h>
#include <errno.h>
#include <pthread.h>
+#include <sched.h>
#include <netinet/in.h>
#include <netinet/icmp6.h>
#include <arpa/inet.h>
@@ -271,8 +272,8 @@ static int ipv6_nd_start(struct ppp_t *ppp)
addr.sin6_scope_id = ppp->ifindex;
if (bind(sock, (struct sockaddr *)&addr, sizeof(addr))) {
- log_ppp_error("ipv6_nd: bind: %s %i\n", strerror(errno), errno);
- goto out_err;
+ close(sock);
+ return 1;
}
val = 2;
@@ -352,12 +353,19 @@ static struct ipv6_nd_handler_t *find_pd(struct ppp_t *ppp)
return NULL;
}
+static void ipv6_nd_start_later(struct ppp_t *ppp)
+{
+ while (ipv6_nd_start(ppp) == 1)
+ sched_yield();
+}
+
static void ev_ppp_started(struct ppp_t *ppp)
{
if (!ppp->ipv6)
return;
- ipv6_nd_start(ppp);
+ if (ipv6_nd_start(ppp) == 1)
+ triton_context_call(triton_context_self(), (triton_event_func)ipv6_nd_start_later, ppp);
}
static void ev_ppp_finishing(struct ppp_t *ppp)