diff options
-rw-r--r-- | configure.in | 3 | ||||
-rw-r--r-- | proto/static/static.c | 25 | ||||
-rw-r--r-- | proto/static/static.h | 2 | ||||
-rw-r--r-- | sysdep/bsd/krt-sock.c | 16 | ||||
-rw-r--r-- | sysdep/linux/netlink.c | 16 |
5 files changed, 41 insertions, 21 deletions
diff --git a/configure.in b/configure.in index 09e29dc2..c81709e6 100644 --- a/configure.in +++ b/configure.in @@ -69,7 +69,8 @@ fi AC_SUBST(CONFIG_FILE) AC_SUBST(CONTROL_SOCKET) -AC_SEARCH_LIBS(clock_gettime,[c rt posix4]) +AC_SEARCH_LIBS(clock_gettime, [c rt posix4], , + AC_MSG_ERROR([[Function clock_gettime not available.]])) AC_CANONICAL_HOST diff --git a/proto/static/static.c b/proto/static/static.c index 9b115acd..d3a595d3 100644 --- a/proto/static/static.c +++ b/proto/static/static.c @@ -62,7 +62,7 @@ static_install(struct proto *p, struct static_route *r, struct iface *ifa) rta a, *aa; rte *e; - if (r->installed) + if (r->installed > 0) return; DBG("Installing static route %I/%d, rtd=%d\n", r->net, r->masklen, r->dest); @@ -125,7 +125,7 @@ static_remove(struct proto *p, struct static_route *r) if (!r->installed) return; - DBG("Removing static route %I/%d\n", r->net, r->masklen); + DBG("Removing static route %I/%d via %I\n", r->net, r->masklen, r->via); n = net_find(p->table, r->net, r->masklen); rte_update(p, n, NULL); r->installed = 0; @@ -420,19 +420,24 @@ static_match(struct proto *p, struct static_route *r, struct static_config *n) if (r->neigh) r->neigh->data = NULL; + WALK_LIST(t, n->iface_routes) if (static_same_net(r, t)) - { - t->installed = r->installed && static_same_dest(r, t); - return; - } + goto found; + WALK_LIST(t, n->other_routes) if (static_same_net(r, t)) - { - t->installed = r->installed && static_same_dest(r, t); - return; - } + goto found; + static_remove(p, r); + return; + + found: + /* If destination is different, force reinstall */ + if ((r->installed > 0) && !static_same_dest(r, t)) + t->installed = -1; + else + t->installed = r->installed; } static inline rtable * diff --git a/proto/static/static.h b/proto/static/static.h index eb87ddec..99a0e68b 100644 --- a/proto/static/static.h +++ b/proto/static/static.h @@ -31,7 +31,7 @@ struct static_route { struct neighbor *neigh; byte *if_name; /* Name for RTD_DEVICE routes */ struct static_route *mp_next; /* Nexthops for RTD_MULTIPATH routes */ - int installed; /* Installed in master table */ + int installed; /* Installed in rt table, -1 for reinstall */ }; /* Dummy nodes (parts of multipath route) abuses masklen field for weight diff --git a/sysdep/bsd/krt-sock.c b/sysdep/bsd/krt-sock.c index 176e11ed..aaeb7d90 100644 --- a/sysdep/bsd/krt-sock.c +++ b/sysdep/bsd/krt-sock.c @@ -535,7 +535,7 @@ krt_read_ifannounce(struct ks_msg *msg) } 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; void *body = (void *)(ifm + 1); @@ -608,11 +608,14 @@ krt_read_ifinfo(struct ks_msg *msg) else f.flags |= IF_MULTIACCESS; /* NBMA */ - if_update(&f); + iface = if_update(&f); + + if (!scan) + if_end_partial_update(iface); } 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; void *body = (void *)(ifam + 1); @@ -715,6 +718,9 @@ krt_read_addr(struct ks_msg *msg) ifa_update(&ifa); else ifa_delete(&ifa); + + if (!scan) + if_end_partial_update(iface); } static void @@ -734,11 +740,11 @@ krt_read_msg(struct proto *p, struct ks_msg *msg, int scan) krt_read_ifannounce(msg); break; case RTM_IFINFO: - krt_read_ifinfo(msg); + krt_read_ifinfo(msg, scan); break; case RTM_NEWADDR: case RTM_DELADDR: - krt_read_addr(msg); + krt_read_addr(msg, scan); break; default: break; diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c index ed8769b7..7063e2ca 100644 --- a/sysdep/linux/netlink.c +++ b/sysdep/linux/netlink.c @@ -437,12 +437,16 @@ nl_parse_link(struct nlmsghdr *h, int scan) f.flags |= IF_MULTIACCESS | IF_BROADCAST | IF_MULTICAST; else f.flags |= IF_MULTIACCESS; /* NBMA */ - if_update(&f); + + ifi = if_update(&f); + + if (!scan) + if_end_partial_update(ifi); } } static void -nl_parse_addr(struct nlmsghdr *h) +nl_parse_addr(struct nlmsghdr *h, int scan) { struct ifaddrmsg *i; struct rtattr *a[IFA_ANYCAST+1]; @@ -542,10 +546,14 @@ nl_parse_addr(struct nlmsghdr *h) ifi->index, ifi->name, new ? "added" : "removed", ifa.ip, ifa.flags, ifa.prefix, ifa.pxlen, ifa.brd, ifa.opposite); + if (new) ifa_update(&ifa); else ifa_delete(&ifa); + + if (!scan) + if_end_partial_update(ifi); } void @@ -565,7 +573,7 @@ kif_do_scan(struct kif_proto *p UNUSED) nl_request_dump(RTM_GETADDR); while (h = nl_get_scan()) if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR) - nl_parse_addr(h); + nl_parse_addr(h, 1); else 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_DELADDR: DBG("KRT: Received async address notification (%d)\n", h->nlmsg_type); - nl_parse_addr(h); + nl_parse_addr(h, 0); break; default: DBG("KRT: Received unknown async notification (%d)\n", h->nlmsg_type); |