diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2010-04-02 16:11:46 +0200 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2010-04-02 16:11:46 +0200 |
commit | e7b09e4ab99fc850480480bbb577ffa36a6c5cd7 (patch) | |
tree | 878afa02cdb11fc78664ea8ce5ac542e897d91d2 | |
parent | 97ab4c34986139b2419c563a3de7ddfe41727d07 (diff) |
Use SO_BINDTODEVICE also in Linux/IPv6.
-rw-r--r-- | proto/ospf/iface.c | 10 | ||||
-rw-r--r-- | sysdep/bsd/sysio.h | 8 | ||||
-rw-r--r-- | sysdep/linux/sysio.h | 15 | ||||
-rw-r--r-- | sysdep/unix/io.c | 3 |
4 files changed, 24 insertions, 12 deletions
diff --git a/proto/ospf/iface.c b/proto/ospf/iface.c index 04163553..6931619b 100644 --- a/proto/ospf/iface.c +++ b/proto/ospf/iface.c @@ -66,17 +66,7 @@ ospf_sk_open(struct ospf_iface *ifa) sk = sk_new(p->pool); sk->type = SK_IP; sk->dport = OSPF_PROTO; - -#ifdef OSPFv2 - /* - * In Linux IPv4, binding a raw socket to an IP address of an iface causes - * that the socket does not receive multicast packets, as they have - * different (multicast) destination IP address. - */ sk->saddr = IPA_NONE; -#else /* OSPFv3 */ - sk->saddr = ifa->addr->ip; /* link-local addr */ -#endif sk->tos = IP_PREC_INTERNET_CONTROL; sk->rx_hook = ospf_rx_hook; diff --git a/sysdep/bsd/sysio.h b/sysdep/bsd/sysio.h index 87c78fb3..ff821a77 100644 --- a/sysdep/bsd/sysio.h +++ b/sysdep/bsd/sysio.h @@ -22,6 +22,14 @@ get_inaddr(ip_addr *a, struct in6_addr *ia) ipa_ntoh(*a); } +static inline char * +sysio_bind_to_iface(sock *s) +{ + /* Unfortunately not available */ + return NULL; +} + + #else #include <net/if.h> diff --git a/sysdep/linux/sysio.h b/sysdep/linux/sysio.h index 1cfbcc4b..795d0b36 100644 --- a/sysdep/linux/sysio.h +++ b/sysdep/linux/sysio.h @@ -6,6 +6,8 @@ * Can be freely distributed and used under the terms of the GNU GPL. */ +#include <net/if.h> + #ifdef IPV6 #ifndef IPV6_UNICAST_HOPS @@ -28,9 +30,18 @@ get_inaddr(ip_addr *a, struct in6_addr *ia) ipa_ntoh(*a); } -#else +static inline char * +sysio_bind_to_iface(sock *s) +{ + struct ifreq ifr; + strcpy(ifr.ifr_name, s->iface->name); + if (setsockopt(s->fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) < 0) + return "SO_BINDTODEVICE"; -#include <net/if.h> + return NULL; +} + +#else static inline void set_inaddr(struct in_addr *ia, ip_addr a) diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c index abfa5c26..a0dbb418 100644 --- a/sysdep/unix/io.c +++ b/sysdep/unix/io.c @@ -876,6 +876,9 @@ sk_setup_multicast(sock *s) if (setsockopt(s->fd, SOL_IPV6, IPV6_MULTICAST_IF, &index, sizeof(index)) < 0) ERR("IPV6_MULTICAST_IF"); + if (err = sysio_bind_to_iface(s)) + goto bad; + return 0; bad: |