diff options
Diffstat (limited to 'src/socket.c')
-rw-r--r-- | src/socket.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/src/socket.c b/src/socket.c index af99894..25f50e7 100644 --- a/src/socket.c +++ b/src/socket.c @@ -77,7 +77,7 @@ static int bind_socket(fastd_context_t *ctx, const fastd_bind_address_t *addr, b } #ifdef USE_BINDTODEVICE - if (addr->bindtodev) { + if (addr->bindtodev && !fastd_peer_address_is_v6_ll(&addr->addr)) { if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, addr->bindtodev, strlen(addr->bindtodev))) { if (warn) pr_warn_errno(ctx, "setsockopt: unable to bind to device"); @@ -107,6 +107,18 @@ static int bind_socket(fastd_context_t *ctx, const fastd_bind_address_t *addr, b fastd_peer_address_t bind_address = addr->addr; + if (fastd_peer_address_is_v6_ll(&addr->addr) && addr->bindtodev) { + bind_address.in6.sin6_scope_id = atoi(addr->bindtodev); + + if (!bind_address.in6.sin6_scope_id) + bind_address.in6.sin6_scope_id = if_nametoindex(addr->bindtodev); + + if (!bind_address.in6.sin6_scope_id) { + pr_warn_errno(ctx, "if_nametoindex"); + goto error; + } + } + if (bind_address.sa.sa_family == AF_UNSPEC) { memset(&bind_address, 0, sizeof(bind_address)); bind_address.sa.sa_family = af; @@ -180,7 +192,7 @@ bool fastd_socket_handle_binds(fastd_context_t *ctx) { if (!ctx->socks[i].addr->addr.sa.sa_family) bound_addr.sa.sa_family = AF_UNSPEC; - if (ctx->socks[i].addr->bindtodev) + if (ctx->socks[i].addr->bindtodev && !fastd_peer_address_is_v6_ll(&bound_addr)) pr_info(ctx, "successfully bound to %B on `%s'", &bound_addr, ctx->socks[i].addr->bindtodev); else pr_info(ctx, "successfully bound to %B", &bound_addr); |