Fixes an issue when opposite address is mistaken for broadcast on ptp ifaces on BSDs.

Thanks to Lex van Roon for the bugreport and to Alexander V. Chernikov
for examining it and locating the problem.
This commit is contained in:
Ondrej Zajicek 2013-11-21 13:17:42 +01:00
parent f8f2419d4c
commit 64534ea2f4

View file

@ -654,17 +654,25 @@ krt_read_addr(struct ks_msg *msg)
if ((masklen = ipa_mklen(imask)) < 0) if ((masklen = ipa_mklen(imask)) < 0)
{ {
log("Invalid masklen"); log(L_ERR "KIF: Invalid masklen %I for %s", imask, iface->name);
return; return;
} }
#ifdef IPV6
/* Clean up embedded interface ID returned in link-local address */
if (ipa_has_link_scope(iaddr))
_I0(iaddr) = 0xfe800000;
if (ipa_has_link_scope(ibrd))
_I0(ibrd) = 0xfe800000;
#endif
bzero(&ifa, sizeof(ifa)); bzero(&ifa, sizeof(ifa));
ifa.iface = iface; ifa.iface = iface;
ifa.ip = iaddr;
memcpy(&ifa.ip, &iaddr, sizeof(ip_addr));
ifa.pxlen = masklen; ifa.pxlen = masklen;
memcpy(&ifa.brd, &ibrd, sizeof(ip_addr));
scope = ipa_classify(ifa.ip); scope = ipa_classify(ifa.ip);
if (scope < 0) if (scope < 0)
@ -674,16 +682,6 @@ krt_read_addr(struct ks_msg *msg)
} }
ifa.scope = scope & IADDR_SCOPE_MASK; ifa.scope = scope & IADDR_SCOPE_MASK;
#ifdef IPV6
/* Clean up embedded interface ID returned in link-local address */
if (ipa_has_link_scope(ifa.ip))
_I0(ifa.ip) = 0xfe800000;
if (ipa_has_link_scope(ifa.brd))
_I0(ifa.brd) = 0xfe800000;
#endif
if (masklen < BITS_PER_IP_ADDRESS) if (masklen < BITS_PER_IP_ADDRESS)
{ {
ifa.prefix = ipa_and(ifa.ip, ipa_mkmask(masklen)); ifa.prefix = ipa_and(ifa.ip, ipa_mkmask(masklen));
@ -696,12 +694,15 @@ krt_read_addr(struct ks_msg *msg)
ifa.opposite = ipa_opposite_m2(ifa.ip); ifa.opposite = ipa_opposite_m2(ifa.ip);
#endif #endif
if (iface->flags & IF_BROADCAST)
ifa.brd = ibrd;
if (!(iface->flags & IF_MULTIACCESS)) 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; ifa.flags |= IA_PEER;
} }
else else