]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Merge commit '64534ea2f4361c247d7a0d1b6b14a02e8e3d6d33' into integrated
authorOndrej Zajicek <santiago@crfreenet.org>
Tue, 29 Apr 2014 13:31:46 +0000 (15:31 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Tue, 29 Apr 2014 13:31:46 +0000 (15:31 +0200)
Conflicts:

sysdep/bsd/krt-sock.c

1  2 
sysdep/bsd/krt-sock.c

index 550032c7f55f9aec3d107739dfbe6f0556ec5afd,0bc29458cc083e90d5bf584d40d3f1129576568e..9f955d4895d73f50bb7a51d900a16ccb2e210a83
@@@ -709,40 -644,35 +709,41 @@@ krt_read_addr(struct ks_msg *msg
    GETADDR (&null, RTA_AUTHOR);
    GETADDR (&brd, RTA_BRD);
  
 -  /* Some other family address */
 -  if (!sa_family_check(&addr))
 +  /* Basic family check */
 +  if (addr.sin6_family != AF_INET && addr.sin6_family != AF_INET6)
      return;
  
 -  get_sockaddr(&addr, &iaddr, NULL, NULL, 0);
 -  get_sockaddr(&mask, &imask, NULL, NULL, 0);
 -  get_sockaddr(&brd, &ibrd, NULL, NULL, 0);
 +  ipv4 = (addr.sin6_family == AF_INET) ? 1 : 0;
 +
 +  /*
 +   * Work around (Free?)BSD bug with netmask
 +   * family not being filled in IPv6 case.
 +   * FreeBSD fix: r250815.
 +   */
 +  if (addr.sin6_family == AF_INET6 && mask.sin6_family == 0)
 +        mask.sin6_family = AF_INET6;
 +
 +  sockaddr_read((struct sockaddr *)&addr, &iaddr, NULL, NULL, 0);
 +  sockaddr_read((struct sockaddr *)&mask, &imask, NULL, NULL, 0);
 +  sockaddr_read((struct sockaddr *)&brd, &ibrd, NULL, NULL, 0);
  
 -  if ((masklen = ipa_mklen(imask)) < 0)
 +  masklen = ipv4 ? (ip4_masklen(ipa_to_ip4(imask)) + 96) : ip6_masklen(&imask);  // XXXX: Hack
 +  if (masklen < 0)
    {
-     log("Invalid masklen");
+     log(L_ERR "KIF: Invalid masklen %I for %s", imask, iface->name);
      return;
    }
  
-   // log("got %I/%I (%d)", iaddr, imask, masklen);
 -#ifdef IPV6
+   /* Clean up embedded interface ID returned in link-local address */
 -
 -  if (ipa_has_link_scope(iaddr))
++  if (ipa_is_link_local(ifa.ip))
+     _I0(iaddr) = 0xfe800000;
 -
 -  if (ipa_has_link_scope(ibrd))
++  if (ipa_is_link_local(ifa.brd))
+     _I0(ibrd) = 0xfe800000;
 -#endif
 -
  
    bzero(&ifa, sizeof(ifa));
    ifa.iface = iface;
-   memcpy(&ifa.ip, &iaddr, sizeof(ip_addr));
+   ifa.ip = iaddr;
    ifa.pxlen = masklen;
-   memcpy(&ifa.brd, &ibrd, sizeof(ip_addr));
  
    scope = ipa_classify(ifa.ip);
    if (scope < 0)
    }
    ifa.scope = scope & IADDR_SCOPE_MASK;
  
-   /* Clean up embedded interface ID returned in link-local address */
-   if (ipa_is_link_local(ifa.ip))
-     _I0(ifa.ip) = 0xfe800000;
-   if (ipa_is_link_local(ifa.brd))
-     _I0(ifa.brd) = 0xfe800000;
 -  if (masklen < BITS_PER_IP_ADDRESS)
 +  // maxlen = ipv4 ? BITS_PER_IP_ADDRESS4 : BITS_PER_IP_ADDRESS6;
 +  maxlen = BITS_PER_IP_ADDRESS; // XXXX: Hack
 +
 +  if (masklen < maxlen)
    {
      ifa.prefix = ipa_and(ifa.ip, ipa_mkmask(masklen));
  
 -    if (masklen == (BITS_PER_IP_ADDRESS - 1))
 +    if (masklen == (maxlen - 1))
        ifa.opposite = ipa_opposite_m1(ifa.ip);
  
 -#ifndef IPV6
 -    if (masklen == (BITS_PER_IP_ADDRESS - 2))
 +    if (ipv4 && masklen == (maxlen - 2))
        ifa.opposite = ipa_opposite_m2(ifa.ip);
 -#endif
  
+     if (iface->flags & IF_BROADCAST)
+       ifa.brd = ibrd;
      if (!(iface->flags & IF_MULTIACCESS))
-       ifa.opposite = ifa.brd;
+       ifa.opposite = ibrd;
    }
-   else if (!(iface->flags & IF_MULTIACCESS) && ipa_nonzero(ifa.brd))
+   else if (!(iface->flags & IF_MULTIACCESS) && ipa_nonzero(ibrd))
    {
-     ifa.prefix = ifa.opposite = ifa.brd;
+     ifa.prefix = ifa.opposite = ibrd;
      ifa.flags |= IA_PEER;
    }
    else