Commit e237b28a authored by Ondrej Zajicek's avatar Ondrej Zajicek
Browse files

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

Thanks to Alexander V. Chernikov for the original patch.
parent 5ebc9293
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -1058,3 +1058,36 @@ kif_sys_shutdown(struct kif_proto *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;
}
+2 −0
Original line number Diff line number Diff line
@@ -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_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 */

+3 −0
Original line number Diff line number Diff line
@@ -159,6 +159,9 @@ kif_choose_primary(struct iface *i)
	  return a;
    }

  if (a = kif_get_primary_ip(i))
    return a;

  return find_preferred_ifa(i, IPA_NONE, IPA_NONE);
}

+1 −0
Original line number Diff line number Diff line
@@ -142,5 +142,6 @@ void kif_sys_copy_config(struct kif_config *, struct kif_config *);

void kif_do_scan(struct kif_proto *);

struct ifa *kif_get_primary_ip(struct iface *i);

#endif