diff options
author | Dmitry Kozlov <xeb@mail.ru> | 2014-07-09 17:08:01 +0400 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2014-07-09 17:08:01 +0400 |
commit | 1df4a4e757e1356d1bd558f0fca1c6169d97fa90 (patch) | |
tree | a6272f9377d50c4c1cd00bb6635d83706a02dbb6 /accel-pppd | |
parent | 6f54f26ccdd8750b44da63a5e6a3724cc4b219b7 (diff) | |
download | accel-ppp-1df4a4e757e1356d1bd558f0fca1c6169d97fa90.tar.gz accel-ppp-1df4a4e757e1356d1bd558f0fca1c6169d97fa90.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.
Diffstat (limited to 'accel-pppd')
-rw-r--r-- | accel-pppd/ipv6/nd.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/accel-pppd/ipv6/nd.c b/accel-pppd/ipv6/nd.c index d10d4b89..02e372c0 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> @@ -276,8 +277,8 @@ static int ipv6_nd_start(struct ap_session *ses) addr.sin6_scope_id = ses->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; @@ -357,12 +358,19 @@ static struct ipv6_nd_handler_t *find_pd(struct ap_session *ses) return NULL; } +static void ipv6_nd_start_later(struct ap_session *ses) +{ + while (ipv6_nd_start(ses) == 1) + sched_yield(); +} + static void ev_ses_started(struct ap_session *ses) { if (!ses->ipv6) return; - ipv6_nd_start(ses); + if (ipv6_nd_start(ses) == 1) + triton_context_call(triton_context_self(), (triton_event_func)ipv6_nd_start_later, ses); } static void ev_ses_finishing(struct ap_session *ses) |