summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.in3
-rw-r--r--proto/static/static.c25
-rw-r--r--proto/static/static.h2
-rw-r--r--sysdep/bsd/krt-sock.c16
-rw-r--r--sysdep/linux/netlink.c16
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);