Use SO_BINDTODEVICE also in Linux/IPv6.
This commit is contained in:
parent
97ab4c3498
commit
e7b09e4ab9
4 changed files with 24 additions and 12 deletions
|
@ -66,17 +66,7 @@ ospf_sk_open(struct ospf_iface *ifa)
|
||||||
sk = sk_new(p->pool);
|
sk = sk_new(p->pool);
|
||||||
sk->type = SK_IP;
|
sk->type = SK_IP;
|
||||||
sk->dport = OSPF_PROTO;
|
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;
|
sk->saddr = IPA_NONE;
|
||||||
#else /* OSPFv3 */
|
|
||||||
sk->saddr = ifa->addr->ip; /* link-local addr */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sk->tos = IP_PREC_INTERNET_CONTROL;
|
sk->tos = IP_PREC_INTERNET_CONTROL;
|
||||||
sk->rx_hook = ospf_rx_hook;
|
sk->rx_hook = ospf_rx_hook;
|
||||||
|
|
|
@ -22,6 +22,14 @@ get_inaddr(ip_addr *a, struct in6_addr *ia)
|
||||||
ipa_ntoh(*a);
|
ipa_ntoh(*a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline char *
|
||||||
|
sysio_bind_to_iface(sock *s)
|
||||||
|
{
|
||||||
|
/* Unfortunately not available */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
* Can be freely distributed and used under the terms of the GNU GPL.
|
* Can be freely distributed and used under the terms of the GNU GPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <net/if.h>
|
||||||
|
|
||||||
#ifdef IPV6
|
#ifdef IPV6
|
||||||
|
|
||||||
#ifndef IPV6_UNICAST_HOPS
|
#ifndef IPV6_UNICAST_HOPS
|
||||||
|
@ -28,9 +30,18 @@ get_inaddr(ip_addr *a, struct in6_addr *ia)
|
||||||
ipa_ntoh(*a);
|
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
|
static inline void
|
||||||
set_inaddr(struct in_addr *ia, ip_addr a)
|
set_inaddr(struct in_addr *ia, ip_addr a)
|
||||||
|
|
|
@ -876,6 +876,9 @@ sk_setup_multicast(sock *s)
|
||||||
if (setsockopt(s->fd, SOL_IPV6, IPV6_MULTICAST_IF, &index, sizeof(index)) < 0)
|
if (setsockopt(s->fd, SOL_IPV6, IPV6_MULTICAST_IF, &index, sizeof(index)) < 0)
|
||||||
ERR("IPV6_MULTICAST_IF");
|
ERR("IPV6_MULTICAST_IF");
|
||||||
|
|
||||||
|
if (err = sysio_bind_to_iface(s))
|
||||||
|
goto bad;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
bad:
|
bad:
|
||||||
|
|
Loading…
Reference in a new issue