summaryrefslogtreecommitdiffstats
path: root/src/socket.c
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2014-01-26 09:23:00 +0100
committerMatthias Schiffer <mschiffer@universe-factory.net>2014-01-26 09:23:00 +0100
commit534ae7240bc5cad6edb9fd160cdb0ff0eb4778de (patch)
tree9d77fdd80b3fb5da130de1c55b5f96406814447a /src/socket.c
parentb78d55b69ed9d9c88d12f0159e78973ad0d70b49 (diff)
downloadfastd-534ae7240bc5cad6edb9fd160cdb0ff0eb4778de.tar
fastd-534ae7240bc5cad6edb9fd160cdb0ff0eb4778de.zip
Add support for link-local bind addresses
Diffstat (limited to 'src/socket.c')
-rw-r--r--src/socket.c16
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);