Fixes longstanding issue with interfaces staying in IF_TMP_DOWN.

Thanks to Pierluigi Rolando and others for the bugreport.
This commit is contained in:
Ondrej Zajicek 2014-02-26 12:52:00 +01:00
parent d776540811
commit 3216eb03dd
2 changed files with 23 additions and 9 deletions

View file

@ -535,7 +535,7 @@ krt_read_ifannounce(struct ks_msg *msg)
} }
static void static void
krt_read_ifinfo(struct ks_msg *msg) krt_read_ifinfo(struct ks_msg *msg, int scan)
{ {
struct if_msghdr *ifm = (struct if_msghdr *)&msg->rtm; struct if_msghdr *ifm = (struct if_msghdr *)&msg->rtm;
void *body = (void *)(ifm + 1); void *body = (void *)(ifm + 1);
@ -608,11 +608,14 @@ krt_read_ifinfo(struct ks_msg *msg)
else else
f.flags |= IF_MULTIACCESS; /* NBMA */ f.flags |= IF_MULTIACCESS; /* NBMA */
if_update(&f); iface = if_update(&f);
if (!scan)
if_end_partial_update(iface);
} }
static void static void
krt_read_addr(struct ks_msg *msg) krt_read_addr(struct ks_msg *msg, int scan)
{ {
struct ifa_msghdr *ifam = (struct ifa_msghdr *)&msg->rtm; struct ifa_msghdr *ifam = (struct ifa_msghdr *)&msg->rtm;
void *body = (void *)(ifam + 1); void *body = (void *)(ifam + 1);
@ -715,6 +718,9 @@ krt_read_addr(struct ks_msg *msg)
ifa_update(&ifa); ifa_update(&ifa);
else else
ifa_delete(&ifa); ifa_delete(&ifa);
if (!scan)
if_end_partial_update(iface);
} }
static void static void
@ -734,11 +740,11 @@ krt_read_msg(struct proto *p, struct ks_msg *msg, int scan)
krt_read_ifannounce(msg); krt_read_ifannounce(msg);
break; break;
case RTM_IFINFO: case RTM_IFINFO:
krt_read_ifinfo(msg); krt_read_ifinfo(msg, scan);
break; break;
case RTM_NEWADDR: case RTM_NEWADDR:
case RTM_DELADDR: case RTM_DELADDR:
krt_read_addr(msg); krt_read_addr(msg, scan);
break; break;
default: default:
break; break;

View file

@ -437,12 +437,16 @@ nl_parse_link(struct nlmsghdr *h, int scan)
f.flags |= IF_MULTIACCESS | IF_BROADCAST | IF_MULTICAST; f.flags |= IF_MULTIACCESS | IF_BROADCAST | IF_MULTICAST;
else else
f.flags |= IF_MULTIACCESS; /* NBMA */ f.flags |= IF_MULTIACCESS; /* NBMA */
if_update(&f);
ifi = if_update(&f);
if (!scan)
if_end_partial_update(ifi);
} }
} }
static void static void
nl_parse_addr(struct nlmsghdr *h) nl_parse_addr(struct nlmsghdr *h, int scan)
{ {
struct ifaddrmsg *i; struct ifaddrmsg *i;
struct rtattr *a[IFA_ANYCAST+1]; struct rtattr *a[IFA_ANYCAST+1];
@ -542,10 +546,14 @@ nl_parse_addr(struct nlmsghdr *h)
ifi->index, ifi->name, ifi->index, ifi->name,
new ? "added" : "removed", new ? "added" : "removed",
ifa.ip, ifa.flags, ifa.prefix, ifa.pxlen, ifa.brd, ifa.opposite); ifa.ip, ifa.flags, ifa.prefix, ifa.pxlen, ifa.brd, ifa.opposite);
if (new) if (new)
ifa_update(&ifa); ifa_update(&ifa);
else else
ifa_delete(&ifa); ifa_delete(&ifa);
if (!scan)
if_end_partial_update(ifi);
} }
void void
@ -565,7 +573,7 @@ kif_do_scan(struct kif_proto *p UNUSED)
nl_request_dump(RTM_GETADDR); nl_request_dump(RTM_GETADDR);
while (h = nl_get_scan()) while (h = nl_get_scan())
if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR) if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR)
nl_parse_addr(h); nl_parse_addr(h, 1);
else else
log(L_DEBUG "nl_scan_ifaces: Unknown packet received (type=%d)", h->nlmsg_type); log(L_DEBUG "nl_scan_ifaces: Unknown packet received (type=%d)", h->nlmsg_type);
@ -967,7 +975,7 @@ nl_async_msg(struct nlmsghdr *h)
case RTM_NEWADDR: case RTM_NEWADDR:
case RTM_DELADDR: case RTM_DELADDR:
DBG("KRT: Received async address notification (%d)\n", h->nlmsg_type); DBG("KRT: Received async address notification (%d)\n", h->nlmsg_type);
nl_parse_addr(h); nl_parse_addr(h, 0);
break; break;
default: default:
DBG("KRT: Received unknown async notification (%d)\n", h->nlmsg_type); DBG("KRT: Received unknown async notification (%d)\n", h->nlmsg_type);