Changes primary addr selection on BSD to respect SIOCGIFADDR ioctl() result.

Thanks to Alexander V. Chernikov for the original patch.
This commit is contained in:
Ondrej Zajicek 2013-11-25 01:21:39 +01:00
parent 5ebc92935c
commit e237b28a4d
4 changed files with 39 additions and 0 deletions

View file

@ -1058,3 +1058,36 @@ kif_sys_shutdown(struct kif_proto *p)
krt_buffer_release(&p->p); krt_buffer_release(&p->p);
} }
struct ifa *
kif_get_primary_ip(struct iface *i)
{
#ifndef IPV6
static int fd = -1;
if (fd < 0)
fd = socket(AF_INET, SOCK_DGRAM, 0);
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, i->name, IFNAMSIZ);
int rv = ioctl(fd, SIOCGIFADDR, (char *) &ifr);
if (rv < 0)
return NULL;
ip_addr addr;
struct sockaddr_in *sin = (struct sockaddr_in *) &ifr.ifr_addr;
memcpy(&addr, &sin->sin_addr.s_addr, sizeof(ip_addr));
ipa_ntoh(addr);
struct ifa *a;
WALK_LIST(a, i->addrs)
{
if (ipa_equal(a->ip, addr))
return a;
}
#endif
return NULL;
}

View file

@ -27,6 +27,8 @@ static inline void kif_sys_postconfig(struct kif_config *c UNUSED) { }
static inline void kif_sys_init_config(struct kif_config *c UNUSED) { } static inline void kif_sys_init_config(struct kif_config *c UNUSED) { }
static inline void kif_sys_copy_config(struct kif_config *d UNUSED, struct kif_config *s UNUSED) { } static inline void kif_sys_copy_config(struct kif_config *d UNUSED, struct kif_config *s UNUSED) { }
static inline struct ifa * kif_get_primary_ip(struct iface *i) { return NULL; }
/* Kernel routes */ /* Kernel routes */

View file

@ -159,6 +159,9 @@ kif_choose_primary(struct iface *i)
return a; return a;
} }
if (a = kif_get_primary_ip(i))
return a;
return find_preferred_ifa(i, IPA_NONE, IPA_NONE); return find_preferred_ifa(i, IPA_NONE, IPA_NONE);
} }

View file

@ -142,5 +142,6 @@ void kif_sys_copy_config(struct kif_config *, struct kif_config *);
void kif_do_scan(struct kif_proto *); void kif_do_scan(struct kif_proto *);
struct ifa *kif_get_primary_ip(struct iface *i);
#endif #endif