Netlink support for secondary interface addresses.
This commit is contained in:
parent
9a158361da
commit
a2697f02ac
3 changed files with 34 additions and 35 deletions
1
TODO
1
TODO
|
@ -26,6 +26,7 @@ Core
|
||||||
- iface: when seen an invalid broadcast, fix it up or at least report
|
- iface: when seen an invalid broadcast, fix it up or at least report
|
||||||
- iface: we always need ifindex at least for PtP links (OSPF)
|
- iface: we always need ifindex at least for PtP links (OSPF)
|
||||||
- iface: interface filters should support filtering by IP address as well
|
- iface: interface filters should support filtering by IP address as well
|
||||||
|
- iface: SIOCGIFINDEX exists on glibc systems, but it doesn't work on 2.0.x kernels!
|
||||||
|
|
||||||
- socket: Use IP_RECVERR for BGP TCP sockets?
|
- socket: Use IP_RECVERR for BGP TCP sockets?
|
||||||
|
|
||||||
|
|
|
@ -361,8 +361,9 @@ if_update(struct iface *new)
|
||||||
DBG("Interface %s changed too much -- forcing down/up transition\n", i->name);
|
DBG("Interface %s changed too much -- forcing down/up transition\n", i->name);
|
||||||
if_change_flags(i, i->flags | IF_TMP_DOWN);
|
if_change_flags(i, i->flags | IF_TMP_DOWN);
|
||||||
rem_node(&i->n);
|
rem_node(&i->n);
|
||||||
WALK_LIST_DELSAFE(a, b, i->addrs)
|
new->addr = i->addr;
|
||||||
ifa_delete(a);
|
memcpy(&new->addrs, &i->addrs, sizeof(i->addrs));
|
||||||
|
memcpy(i, new, sizeof(*i));
|
||||||
goto newif;
|
goto newif;
|
||||||
}
|
}
|
||||||
else if (c)
|
else if (c)
|
||||||
|
@ -374,9 +375,9 @@ if_update(struct iface *new)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
i = mb_alloc(if_pool, sizeof(struct iface));
|
i = mb_alloc(if_pool, sizeof(struct iface));
|
||||||
newif:
|
|
||||||
memcpy(i, new, sizeof(*i));
|
memcpy(i, new, sizeof(*i));
|
||||||
init_list(&i->addrs);
|
init_list(&i->addrs);
|
||||||
|
newif:
|
||||||
i->flags |= IF_UPDATED | IF_TMP_DOWN; /* Tmp down as we don't have addresses yet */
|
i->flags |= IF_UPDATED | IF_TMP_DOWN; /* Tmp down as we don't have addresses yet */
|
||||||
add_tail(&iface_list, &i->n);
|
add_tail(&iface_list, &i->n);
|
||||||
return i;
|
return i;
|
||||||
|
@ -543,6 +544,7 @@ ifa_delete(struct ifa *a)
|
||||||
ifa_recalc_primary(i);
|
ifa_recalc_primary(i);
|
||||||
}
|
}
|
||||||
mb_free(b);
|
mb_free(b);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -316,7 +316,7 @@ nl_parse_addr(struct nlmsghdr *h)
|
||||||
struct ifaddrmsg *i;
|
struct ifaddrmsg *i;
|
||||||
struct rtattr *a[IFA_ANYCAST+1];
|
struct rtattr *a[IFA_ANYCAST+1];
|
||||||
int new = h->nlmsg_type == RTM_NEWADDR;
|
int new = h->nlmsg_type == RTM_NEWADDR;
|
||||||
struct iface f;
|
struct ifa ifa;
|
||||||
struct iface *ifi;
|
struct iface *ifi;
|
||||||
|
|
||||||
if (!(i = nl_checkin(h, sizeof(*i))) || !nl_parse_attrs(IFA_RTA(i), a, sizeof(a)))
|
if (!(i = nl_checkin(h, sizeof(*i))) || !nl_parse_attrs(IFA_RTA(i), a, sizeof(a)))
|
||||||
|
@ -330,11 +330,6 @@ nl_parse_addr(struct nlmsghdr *h)
|
||||||
log(L_ERR "nl_parse_addr: Malformed message received");
|
log(L_ERR "nl_parse_addr: Malformed message received");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (i->ifa_flags & IFA_F_SECONDARY)
|
|
||||||
{
|
|
||||||
DBG("KIF: Received address message for secondary address which is not supported.\n"); /* FIXME */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ifi = if_find_by_index(i->ifa_index);
|
ifi = if_find_by_index(i->ifa_index);
|
||||||
if (!ifi)
|
if (!ifi)
|
||||||
|
@ -342,41 +337,42 @@ nl_parse_addr(struct nlmsghdr *h)
|
||||||
log(L_ERR "KIF: Received address message for unknown interface %d\n", i->ifa_index);
|
log(L_ERR "KIF: Received address message for unknown interface %d\n", i->ifa_index);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy(&f, ifi, sizeof(f));
|
|
||||||
|
|
||||||
if (i->ifa_prefixlen > 32 || i->ifa_prefixlen == 31 ||
|
if (i->ifa_prefixlen > 32 || i->ifa_prefixlen == 31 ||
|
||||||
(f.flags & IF_UNNUMBERED) && i->ifa_prefixlen != 32)
|
(ifi->flags & IF_UNNUMBERED) && i->ifa_prefixlen != 32)
|
||||||
{
|
{
|
||||||
log(L_ERR "KIF: Invalid prefix length for interface %s: %d\n", f.name, i->ifa_prefixlen);
|
log(L_ERR "KIF: Invalid prefix length for interface %s: %d\n", ifi->name, i->ifa_prefixlen);
|
||||||
new = 0;
|
new = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
f.ip = f.brd = f.opposite = IPA_NONE;
|
bzero(&ifa, sizeof(ifa));
|
||||||
if (!new)
|
ifa.iface = ifi;
|
||||||
|
if (i->ifa_flags & IFA_F_SECONDARY)
|
||||||
|
ifa.flags |= IA_SECONDARY;
|
||||||
|
memcpy(&ifa.ip, RTA_DATA(a[IFA_LOCAL]), sizeof(ifa.ip));
|
||||||
|
ifa.ip = ipa_ntoh(ifa.ip);
|
||||||
|
ifa.pxlen = i->ifa_prefixlen;
|
||||||
|
if (ifi->flags & IF_UNNUMBERED)
|
||||||
{
|
{
|
||||||
DBG("KIF: IF%d IP address deleted\n");
|
memcpy(&ifa.opposite, RTA_DATA(a[IFA_ADDRESS]), sizeof(ifa.opposite));
|
||||||
f.pxlen = 0;
|
ifa.opposite = ifa.brd = ipa_ntoh(ifa.opposite);
|
||||||
}
|
}
|
||||||
|
else if ((ifi->flags & IF_BROADCAST) && a[IFA_BROADCAST])
|
||||||
|
{
|
||||||
|
memcpy(&ifa.brd, RTA_DATA(a[IFA_BROADCAST]), sizeof(ifa.brd));
|
||||||
|
ifa.brd = ipa_ntoh(ifa.brd);
|
||||||
|
}
|
||||||
|
/* else a NBMA link */
|
||||||
|
ifa.prefix = ipa_and(ifa.ip, ipa_mkmask(ifa.pxlen));
|
||||||
|
|
||||||
|
DBG("KIF: IF%d(%s): %s IPA %I, net %I/%d, brd %I, opp %I\n",
|
||||||
|
ifi->index, ifi->name,
|
||||||
|
new ? "added" : "removed",
|
||||||
|
ifa.ip, ifa.prefix, ifa.pxlen, ifa.brd, ifa.opposite);
|
||||||
|
if (new)
|
||||||
|
ifa_update(&ifa);
|
||||||
else
|
else
|
||||||
{
|
ifa_delete(&ifa);
|
||||||
memcpy(&f.ip, RTA_DATA(a[IFA_LOCAL]), sizeof(f.ip));
|
|
||||||
f.ip = ipa_ntoh(f.ip);
|
|
||||||
f.pxlen = i->ifa_prefixlen;
|
|
||||||
if (f.flags & IF_UNNUMBERED)
|
|
||||||
{
|
|
||||||
memcpy(&f.opposite, RTA_DATA(a[IFA_ADDRESS]), sizeof(f.opposite));
|
|
||||||
f.opposite = f.brd = ipa_ntoh(f.opposite);
|
|
||||||
}
|
|
||||||
else if ((f.flags & IF_BROADCAST) && a[IFA_BROADCAST])
|
|
||||||
{
|
|
||||||
memcpy(&f.brd, RTA_DATA(a[IFA_BROADCAST]), sizeof(f.brd));
|
|
||||||
f.brd = ipa_ntoh(f.brd);
|
|
||||||
}
|
|
||||||
/* else a NBMA link */
|
|
||||||
f.prefix = ipa_and(f.ip, ipa_mkmask(f.pxlen));
|
|
||||||
DBG("KIF: IF%d IP address set to %I, net %I/%d, brd %I, opp %I\n", f.index, f.ip, f.prefix, f.pxlen, f.brd, f.opposite);
|
|
||||||
}
|
|
||||||
if_update(&f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in a new issue