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