From: Ondrej Zajicek Date: Tue, 29 Apr 2014 13:31:46 +0000 (+0200) Subject: Merge commit '64534ea2f4361c247d7a0d1b6b14a02e8e3d6d33' into integrated X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=054bc43a5c60398865b37cd75aae2f0a965b87d3;p=thirdparty%2Fbird.git Merge commit '64534ea2f4361c247d7a0d1b6b14a02e8e3d6d33' into integrated Conflicts: sysdep/bsd/krt-sock.c --- 054bc43a5c60398865b37cd75aae2f0a965b87d3 diff --cc sysdep/bsd/krt-sock.c index 550032c7f,0bc29458c..9f955d489 --- a/sysdep/bsd/krt-sock.c +++ b/sysdep/bsd/krt-sock.c @@@ -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) @@@ -752,32 -682,27 +753,28 @@@ } 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