summaryrefslogtreecommitdiff
path: root/proto/bfd
diff options
context:
space:
mode:
Diffstat (limited to 'proto/bfd')
-rw-r--r--proto/bfd/Makefile9
-rw-r--r--proto/bfd/bfd.c67
-rw-r--r--proto/bfd/bfd.h14
-rw-r--r--proto/bfd/io.c281
-rw-r--r--proto/bfd/io.h67
-rw-r--r--proto/bfd/packets.c13
6 files changed, 74 insertions, 377 deletions
diff --git a/proto/bfd/Makefile b/proto/bfd/Makefile
index c28cedec..402122fc 100644
--- a/proto/bfd/Makefile
+++ b/proto/bfd/Makefile
@@ -1,5 +1,6 @@
-source=bfd.c packets.c io.c
-root-rel=../../
-dir-name=proto/bfd
+src := bfd.c io.c packets.c
+obj := $(src-o-files)
+$(all-daemon)
+$(cf-local)
-include ../../Rules
+tests_objs := $(tests_objs) $(src-o-files) \ No newline at end of file
diff --git a/proto/bfd/bfd.c b/proto/bfd/bfd.c
index 79135fae..67ec2270 100644
--- a/proto/bfd/bfd.c
+++ b/proto/bfd/bfd.c
@@ -64,16 +64,15 @@
* ready, the protocol just creates a BFD request like any other protocol.
*
* The protocol uses a new generic event loop (structure &birdloop) from |io.c|,
- * which supports sockets, timers and events like the main loop. Timers
- * (structure &timer2) are new microsecond based timers, while sockets and
- * events are the same. A birdloop is associated with a thread (field @thread)
- * in which event hooks are executed. Most functions for setting event sources
- * (like sk_start() or tm2_start()) must be called from the context of that
- * thread. Birdloop allows to temporarily acquire the context of that thread for
- * the main thread by calling birdloop_enter() and then birdloop_leave(), which
- * also ensures mutual exclusion with all event hooks. Note that resources
- * associated with a birdloop (like timers) should be attached to the
- * independent resource pool, detached from the main resource tree.
+ * which supports sockets, timers and events like the main loop. A birdloop is
+ * associated with a thread (field @thread) in which event hooks are executed.
+ * Most functions for setting event sources (like sk_start() or tm_start()) must
+ * be called from the context of that thread. Birdloop allows to temporarily
+ * acquire the context of that thread for the main thread by calling
+ * birdloop_enter() and then birdloop_leave(), which also ensures mutual
+ * exclusion with all event hooks. Note that resources associated with a
+ * birdloop (like timers) should be attached to the independent resource pool,
+ * detached from the main resource tree.
*
* There are two kinds of interaction between the BFD core (running in the BFD
* thread) and the rest of BFD (running in the main thread). The first kind are
@@ -112,7 +111,7 @@
#define HASH_IP_KEY(n) n->addr
#define HASH_IP_NEXT(n) n->next_ip
#define HASH_IP_EQ(a,b) ipa_equal(a,b)
-#define HASH_IP_FN(k) ipa_hash32(k)
+#define HASH_IP_FN(k) ipa_hash(k)
static list bfd_proto_list;
static list bfd_wait_list;
@@ -145,6 +144,7 @@ bfd_session_update_state(struct bfd_session *s, uint state, uint diag)
bfd_lock_sessions(p);
s->loc_state = state;
s->loc_diag = diag;
+ s->last_state_change = current_time();
notify = !NODE_VALID(&s->n);
if (notify)
@@ -176,7 +176,7 @@ bfd_session_update_tx_interval(struct bfd_session *s)
return;
/* Set timer relative to last tx_timer event */
- tm2_set(s->tx_timer, s->last_tx + tx_int_l);
+ tm_set(s->tx_timer, s->last_tx + tx_int_l);
}
static void
@@ -190,7 +190,7 @@ bfd_session_update_detection_time(struct bfd_session *s, int kick)
if (!s->last_rx)
return;
- tm2_set(s->hold_timer, s->last_rx + timeout);
+ tm_set(s->hold_timer, s->last_rx + timeout);
}
static void
@@ -211,16 +211,16 @@ bfd_session_control_tx_timer(struct bfd_session *s, int reset)
goto stop;
/* So TX timer should run */
- if (reset || !tm2_active(s->tx_timer))
+ if (reset || !tm_active(s->tx_timer))
{
s->last_tx = 0;
- tm2_start(s->tx_timer, 0);
+ tm_start(s->tx_timer, 0);
}
return;
stop:
- tm2_stop(s->tx_timer);
+ tm_stop(s->tx_timer);
s->last_tx = 0;
}
@@ -379,7 +379,7 @@ bfd_find_session_by_addr(struct bfd_proto *p, ip_addr addr)
}
static void
-bfd_tx_timer_hook(timer2 *t)
+bfd_tx_timer_hook(timer *t)
{
struct bfd_session *s = t->data;
@@ -388,7 +388,7 @@ bfd_tx_timer_hook(timer2 *t)
}
static void
-bfd_hold_timer_hook(timer2 *t)
+bfd_hold_timer_hook(timer *t)
{
bfd_session_timeout(t->data);
}
@@ -432,13 +432,13 @@ bfd_add_session(struct bfd_proto *p, ip_addr addr, ip_addr local, struct iface *
s->passive = ifa->cf->passive;
s->tx_csn = random_u32();
- s->tx_timer = tm2_new_init(p->tpool, bfd_tx_timer_hook, s, 0, 0);
- s->hold_timer = tm2_new_init(p->tpool, bfd_hold_timer_hook, s, 0, 0);
+ s->tx_timer = tm_new_init(p->tpool, bfd_tx_timer_hook, s, 0, 0);
+ s->hold_timer = tm_new_init(p->tpool, bfd_hold_timer_hook, s, 0, 0);
bfd_session_update_tx_interval(s);
bfd_session_control_tx_timer(s, 1);
init_list(&s->request_list);
- s->last_state_change = now;
+ s->last_state_change = current_time();
TRACE(D_EVENTS, "Session to %I added", s->addr);
@@ -879,9 +879,6 @@ bfd_notify_hook(sock *sk, uint len UNUSED)
diag = s->loc_diag;
bfd_unlock_sessions(p);
- /* FIXME: convert to btime and move to bfd_session_update_state() */
- s->last_state_change = now;
-
s->notify_running = 1;
WALK_LIST_DELSAFE(n, nn, s->request_list)
bfd_request_notify(SKIP_BACK(struct bfd_request, n, n), state, diag);
@@ -954,7 +951,7 @@ bfd_init_all(void)
static struct proto *
bfd_init(struct proto_config *c)
{
- struct proto *p = proto_new(c, sizeof(struct bfd_proto));
+ struct proto *p = proto_new(c);
p->neigh_notify = bfd_neigh_notify;
@@ -983,8 +980,10 @@ bfd_start(struct proto *P)
add_tail(&bfd_proto_list, &p->bfd_node);
birdloop_enter(p->loop);
- p->rx_1 = bfd_open_rx_sk(p, 0);
- p->rx_m = bfd_open_rx_sk(p, 1);
+ p->rx4_1 = bfd_open_rx_sk(p, 0, SK_IPV4);
+ p->rx4_m = bfd_open_rx_sk(p, 1, SK_IPV4);
+ p->rx6_1 = bfd_open_rx_sk(p, 0, SK_IPV6);
+ p->rx6_m = bfd_open_rx_sk(p, 1, SK_IPV6);
birdloop_leave(p->loop);
bfd_take_requests(p);
@@ -1078,7 +1077,7 @@ bfd_show_sessions(struct proto *P)
byte tbuf[TM_DATETIME_BUFFER_SIZE];
struct bfd_proto *p = (struct bfd_proto *) P;
uint state, diag UNUSED;
- u32 tx_int, timeout;
+ btime tx_int, timeout;
const char *ifname;
if (p->p.proto_state != PS_UP)
@@ -1099,15 +1098,14 @@ bfd_show_sessions(struct proto *P)
state = s->loc_state;
diag = s->loc_diag;
ifname = (s->ifa && s->ifa->iface) ? s->ifa->iface->name : "---";
- tx_int = s->last_tx ? (MAX(s->des_min_tx_int, s->rem_min_rx_int) TO_MS) : 0;
- timeout = (MAX(s->req_min_rx_int, s->rem_min_tx_int) TO_MS) * s->rem_detect_mult;
+ tx_int = s->last_tx ? MAX(s->des_min_tx_int, s->rem_min_rx_int) : 0;
+ timeout = (btime) MAX(s->req_min_rx_int, s->rem_min_tx_int) * s->rem_detect_mult;
state = (state < 4) ? state : 0;
- tm_format_datetime(tbuf, &config->tf_proto, s->last_state_change);
+ tm_format_time(tbuf, &config->tf_proto, s->last_state_change);
- cli_msg(-1020, "%-25I %-10s %-10s %-10s %3u.%03u %3u.%03u",
- s->addr, ifname, bfd_state_names[state], tbuf,
- tx_int / 1000, tx_int % 1000, timeout / 1000, timeout % 1000);
+ cli_msg(-1020, "%-25I %-10s %-10s %-10s %7t %7t",
+ s->addr, ifname, bfd_state_names[state], tbuf, tx_int, timeout);
}
HASH_WALK_END;
@@ -1118,6 +1116,7 @@ bfd_show_sessions(struct proto *P)
struct protocol proto_bfd = {
.name = "BFD",
.template = "bfd%d",
+ .proto_size = sizeof(struct bfd_proto),
.config_size = sizeof(struct bfd_config),
.init = bfd_init,
.start = bfd_start,
diff --git a/proto/bfd/bfd.h b/proto/bfd/bfd.h
index 46e09879..bc4fe969 100644
--- a/proto/bfd/bfd.h
+++ b/proto/bfd/bfd.h
@@ -87,8 +87,10 @@ struct bfd_proto
sock *notify_ws;
list notify_list;
- sock *rx_1;
- sock *rx_m;
+ sock *rx4_1;
+ sock *rx6_1;
+ sock *rx4_m;
+ sock *rx6_m;
list iface_list;
};
@@ -138,11 +140,11 @@ struct bfd_session
btime last_tx; /* Time of last sent periodic control packet */
btime last_rx; /* Time of last received valid control packet */
- timer2 *tx_timer; /* Periodic control packet timer */
- timer2 *hold_timer; /* Timer for session down detection time */
+ timer *tx_timer; /* Periodic control packet timer */
+ timer *hold_timer; /* Timer for session down detection time */
list request_list; /* List of client requests (struct bfd_request) */
- bird_clock_t last_state_change; /* Time of last state change */
+ btime last_state_change; /* Time of last state change */
u8 notify_running; /* 1 if notify hooks are running */
u8 rx_csn_known; /* Received crypto sequence number is known */
@@ -201,7 +203,7 @@ void bfd_show_sessions(struct proto *P);
/* packets.c */
void bfd_send_ctl(struct bfd_proto *p, struct bfd_session *s, int final);
-sock * bfd_open_rx_sk(struct bfd_proto *p, int multihop);
+sock * bfd_open_rx_sk(struct bfd_proto *p, int multihop, int inet_version);
sock * bfd_open_tx_sk(struct bfd_proto *p, ip_addr local, struct iface *ifa);
diff --git a/proto/bfd/io.c b/proto/bfd/io.c
index 8f4f5007..b01cbfce 100644
--- a/proto/bfd/io.c
+++ b/proto/bfd/io.c
@@ -18,10 +18,10 @@
#include "proto/bfd/io.h"
#include "lib/buffer.h"
-#include "lib/heap.h"
#include "lib/lists.h"
#include "lib/resource.h"
#include "lib/event.h"
+#include "lib/timer.h"
#include "lib/socket.h"
@@ -31,16 +31,12 @@ struct birdloop
pthread_t thread;
pthread_mutex_t mutex;
- btime last_time;
- btime real_time;
- u8 use_monotonic_clock;
-
u8 stop_called;
u8 poll_active;
u8 wakeup_masked;
int wakeup_fds[2];
- BUFFER(timer2 *) timers;
+ struct timeloop time;
list event_list;
list sock_list;
uint sock_num;
@@ -57,6 +53,7 @@ struct birdloop
*/
static pthread_key_t current_loop_key;
+extern pthread_key_t current_time_key;
static inline struct birdloop *
birdloop_current(void)
@@ -68,6 +65,7 @@ static inline void
birdloop_set_current(struct birdloop *loop)
{
pthread_setspecific(current_loop_key, loop);
+ pthread_setspecific(current_time_key, loop ? &loop->time : &main_timeloop);
}
static inline void
@@ -78,98 +76,6 @@ birdloop_init_current(void)
/*
- * Time clock
- */
-
-static void times_update_alt(struct birdloop *loop);
-
-static void
-times_init(struct birdloop *loop)
-{
- struct timespec ts;
- int rv;
-
- rv = clock_gettime(CLOCK_MONOTONIC, &ts);
- if (rv < 0)
- {
- log(L_WARN "Monotonic clock is missing");
-
- loop->use_monotonic_clock = 0;
- loop->last_time = 0;
- loop->real_time = 0;
- times_update_alt(loop);
- return;
- }
-
- if ((ts.tv_sec < 0) || (((s64) ts.tv_sec) > ((s64) 1 << 40)))
- log(L_WARN "Monotonic clock is crazy");
-
- loop->use_monotonic_clock = 1;
- loop->last_time = ((s64) ts.tv_sec S) + (ts.tv_nsec / 1000);
- loop->real_time = 0;
-}
-
-static void
-times_update_pri(struct birdloop *loop)
-{
- struct timespec ts;
- int rv;
-
- rv = clock_gettime(CLOCK_MONOTONIC, &ts);
- if (rv < 0)
- die("clock_gettime: %m");
-
- btime new_time = ((s64) ts.tv_sec S) + (ts.tv_nsec / 1000);
-
- if (new_time < loop->last_time)
- log(L_ERR "Monotonic clock is broken");
-
- loop->last_time = new_time;
- loop->real_time = 0;
-}
-
-static void
-times_update_alt(struct birdloop *loop)
-{
- struct timeval tv;
- int rv;
-
- rv = gettimeofday(&tv, NULL);
- if (rv < 0)
- die("gettimeofday: %m");
-
- btime new_time = ((s64) tv.tv_sec S) + tv.tv_usec;
- btime delta = new_time - loop->real_time;
-
- if ((delta < 0) || (delta > (60 S)))
- {
- if (loop->real_time)
- log(L_WARN "Time jump, delta %d us", (int) delta);
-
- delta = 100 MS;
- }
-
- loop->last_time += delta;
- loop->real_time = new_time;
-}
-
-static void
-times_update(struct birdloop *loop)
-{
- if (loop->use_monotonic_clock)
- times_update_pri(loop);
- else
- times_update_alt(loop);
-}
-
-btime
-current_time(void)
-{
- return birdloop_current()->last_time;
-}
-
-
-/*
* Wakeup code for birdloop
*/
@@ -238,7 +144,7 @@ wakeup_drain(struct birdloop *loop)
}
static inline void
-wakeup_do_kick(struct birdloop *loop)
+wakeup_do_kick(struct birdloop *loop)
{
pipe_kick(loop->wakeup_fds[1]);
}
@@ -252,6 +158,16 @@ wakeup_kick(struct birdloop *loop)
loop->wakeup_masked = 2;
}
+/* For notifications from outside */
+void
+wakeup_kick_current(void)
+{
+ struct birdloop *loop = birdloop_current();
+
+ if (loop && loop->poll_active)
+ wakeup_kick(loop);
+}
+
/*
* Events
@@ -272,7 +188,7 @@ events_init(struct birdloop *loop)
static void
events_fire(struct birdloop *loop)
{
- times_update(loop);
+ times_update(&loop->time);
ev_run_list(&loop->event_list);
}
@@ -292,154 +208,6 @@ ev2_schedule(event *e)
/*
- * Timers
- */
-
-#define TIMER_LESS(a,b) ((a)->expires < (b)->expires)
-#define TIMER_SWAP(heap,a,b,t) (t = heap[a], heap[a] = heap[b], heap[b] = t, \
- heap[a]->index = (a), heap[b]->index = (b))
-
-static inline uint timers_count(struct birdloop *loop)
-{ return loop->timers.used - 1; }
-
-static inline timer2 *timers_first(struct birdloop *loop)
-{ return (loop->timers.used > 1) ? loop->timers.data[1] : NULL; }
-
-
-static void
-tm2_free(resource *r)
-{
- timer2 *t = (timer2 *) r;
-
- tm2_stop(t);
-}
-
-static void
-tm2_dump(resource *r)
-{
- timer2 *t = (timer2 *) r;
-
- debug("(code %p, data %p, ", t->hook, t->data);
- if (t->randomize)
- debug("rand %d, ", t->randomize);
- if (t->recurrent)
- debug("recur %d, ", t->recurrent);
- if (t->expires)
- debug("expires in %d ms)\n", (t->expires - current_time()) TO_MS);
- else
- debug("inactive)\n");
-}
-
-
-static struct resclass tm2_class = {
- "Timer",
- sizeof(timer2),
- tm2_free,
- tm2_dump,
- NULL,
- NULL
-};
-
-timer2 *
-tm2_new(pool *p)
-{
- timer2 *t = ralloc(p, &tm2_class);
- t->index = -1;
- return t;
-}
-
-void
-tm2_set(timer2 *t, btime when)
-{
- struct birdloop *loop = birdloop_current();
- uint tc = timers_count(loop);
-
- if (!t->expires)
- {
- t->index = ++tc;
- t->expires = when;
- BUFFER_PUSH(loop->timers) = t;
- HEAP_INSERT(loop->timers.data, tc, timer2 *, TIMER_LESS, TIMER_SWAP);
- }
- else if (t->expires < when)
- {
- t->expires = when;
- HEAP_INCREASE(loop->timers.data, tc, timer2 *, TIMER_LESS, TIMER_SWAP, t->index);
- }
- else if (t->expires > when)
- {
- t->expires = when;
- HEAP_DECREASE(loop->timers.data, tc, timer2 *, TIMER_LESS, TIMER_SWAP, t->index);
- }
-
- if (loop->poll_active && (t->index == 1))
- wakeup_kick(loop);
-}
-
-void
-tm2_start(timer2 *t, btime after)
-{
- tm2_set(t, current_time() + MAX(after, 0));
-}
-
-void
-tm2_stop(timer2 *t)
-{
- if (!t->expires)
- return;
-
- struct birdloop *loop = birdloop_current();
- uint tc = timers_count(loop);
-
- HEAP_DELETE(loop->timers.data, tc, timer2 *, TIMER_LESS, TIMER_SWAP, t->index);
- BUFFER_POP(loop->timers);
-
- t->index = -1;
- t->expires = 0;
-}
-
-static void
-timers_init(struct birdloop *loop)
-{
- BUFFER_INIT(loop->timers, loop->pool, 4);
- BUFFER_PUSH(loop->timers) = NULL;
-}
-
-static void
-timers_fire(struct birdloop *loop)
-{
- btime base_time;
- timer2 *t;
-
- times_update(loop);
- base_time = loop->last_time;
-
- while (t = timers_first(loop))
- {
- if (t->expires > base_time)
- return;
-
- if (t->recurrent)
- {
- btime when = t->expires + t->recurrent;
-
- if (when <= loop->last_time)
- when = loop->last_time + t->recurrent;
-
- if (t->randomize)
- when += random() % (t->randomize + 1);
-
- tm2_set(t, when);
- }
- else
- tm2_stop(t);
-
- t->hook(t);
- }
-}
-
-
-/*
* Sockets
*/
@@ -586,7 +354,7 @@ sockets_fire(struct birdloop *loop)
sock **psk = loop->poll_sk.data;
int poll_num = loop->poll_fd.used - 1;
- times_update(loop);
+ times_update(&loop->time);
/* Last fd is internal wakeup fd */
if (pfd[poll_num].revents & POLLIN)
@@ -634,11 +402,10 @@ birdloop_new(void)
loop->pool = p;
pthread_mutex_init(&loop->mutex, NULL);
- times_init(loop);
wakeup_init(loop);
events_init(loop);
- timers_init(loop);
+ timers_init(&loop->time, p);
sockets_init(loop);
return loop;
@@ -710,7 +477,7 @@ static void *
birdloop_main(void *arg)
{
struct birdloop *loop = arg;
- timer2 *t;
+ timer *t;
int rv, timeout;
birdloop_set_current(loop);
@@ -719,13 +486,13 @@ birdloop_main(void *arg)
while (1)
{
events_fire(loop);
- timers_fire(loop);
+ timers_fire(&loop->time);
- times_update(loop);
+ times_update(&loop->time);
if (events_waiting(loop))
timeout = 0;
- else if (t = timers_first(loop))
- timeout = (tm2_remains(t) TO_MS) + 1;
+ else if (t = timers_first(&loop->time))
+ timeout = (tm_remains(t) TO_MS) + 1;
else
timeout = -1;
@@ -756,7 +523,7 @@ birdloop_main(void *arg)
if (rv)
sockets_fire(loop);
- timers_fire(loop);
+ timers_fire(&loop->time);
}
loop->stop_called = 0;
diff --git a/proto/bfd/io.h b/proto/bfd/io.h
index 641ee054..ec706e9a 100644
--- a/proto/bfd/io.h
+++ b/proto/bfd/io.h
@@ -11,80 +11,15 @@
#include "lib/lists.h"
#include "lib/resource.h"
#include "lib/event.h"
+#include "lib/timer.h"
#include "lib/socket.h"
-// #include "lib/timer.h"
-typedef struct timer2
-{
- resource r;
- void (*hook)(struct timer2 *);
- void *data;
-
- btime expires; /* 0=inactive */
- uint randomize; /* Amount of randomization */
- uint recurrent; /* Timer recurrence */
-
- int index;
-} timer2;
-
-
-btime current_time(void);
-
void ev2_schedule(event *e);
-
-timer2 *tm2_new(pool *p);
-void tm2_set(timer2 *t, btime when);
-void tm2_start(timer2 *t, btime after);
-void tm2_stop(timer2 *t);
-
-static inline int
-tm2_active(timer2 *t)
-{
- return t->expires != 0;
-}
-
-static inline btime
-tm2_remains(timer2 *t)
-{
- btime now = current_time();
- return (t->expires > now) ? (t->expires - now) : 0;
-}
-
-static inline timer2 *
-tm2_new_init(pool *p, void (*hook)(struct timer2 *), void *data, uint rec, uint rand)
-{
- timer2 *t = tm2_new(p);
- t->hook = hook;
- t->data = data;
- t->recurrent = rec;
- t->randomize = rand;
- return t;
-}
-
-static inline void
-tm2_set_max(timer2 *t, btime when)
-{
- if (when > t->expires)
- tm2_set(t, when);
-}
-
-/*
-static inline void
-tm2_start_max(timer2 *t, btime after)
-{
- btime rem = tm2_remains(t);
- tm2_start(t, MAX_(rem, after));
-}
-*/
-
-
void sk_start(sock *s);
void sk_stop(sock *s);
-
-
struct birdloop *birdloop_new(void);
void birdloop_start(struct birdloop *loop);
void birdloop_stop(struct birdloop *loop);
diff --git a/proto/bfd/packets.c b/proto/bfd/packets.c
index 129db72f..b76efda6 100644
--- a/proto/bfd/packets.c
+++ b/proto/bfd/packets.c
@@ -248,7 +248,7 @@ bfd_check_authentication(struct bfd_proto *p, struct bfd_session *s, struct bfd_
/* BFD CSNs are in 32-bit circular number space */
u32 csn = ntohl(auth->csn);
if (s->rx_csn_known &&
- (((csn - s->rx_csn) > (3 * s->detect_mult)) ||
+ (((csn - s->rx_csn) > (3 * (uint) s->detect_mult)) ||
(meticulous && (csn == s->rx_csn))))
{
/* We want to report both new and old CSN */
@@ -405,10 +405,11 @@ bfd_err_hook(sock *sk, int err)
}
sock *
-bfd_open_rx_sk(struct bfd_proto *p, int multihop)
+bfd_open_rx_sk(struct bfd_proto *p, int multihop, int af)
{
sock *sk = sk_new(p->tpool);
sk->type = SK_UDP;
+ sk->subtype = af;
sk->sport = !multihop ? BFD_CONTROL_PORT : BFD_MULTI_CTL_PORT;
sk->data = p;
@@ -421,10 +422,6 @@ bfd_open_rx_sk(struct bfd_proto *p, int multihop)
sk->priority = sk_priority_control;
sk->flags = SKF_THREAD | SKF_LADDR_RX | (!multihop ? SKF_TTL_RX : 0);
-#ifdef IPV6
- sk->flags |= SKF_V6ONLY;
-#endif
-
if (sk_open(sk) < 0)
goto err;
@@ -456,10 +453,6 @@ bfd_open_tx_sk(struct bfd_proto *p, ip_addr local, struct iface *ifa)
sk->ttl = ifa ? 255 : -1;
sk->flags = SKF_THREAD | SKF_BIND | SKF_HIGH_PORT;
-#ifdef IPV6
- sk->flags |= SKF_V6ONLY;
-#endif
-
if (sk_open(sk) < 0)
goto err;