From 32f95476a8d60508ca9d24fe20b09899b72de9d7 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Thu, 6 Oct 2011 22:48:49 +0200 Subject: Signal problems with route installation to kernel tables. --- nest/route.h | 4 ++++ nest/rt-table.c | 3 ++- proto/ospf/packet.c | 2 +- sysdep/bsd/krt-sock.c | 27 ++++++++++++++++----------- sysdep/linux/netlink/netlink.c | 19 +++++++++++++------ sysdep/unix/krt.h | 5 +---- 6 files changed, 37 insertions(+), 23 deletions(-) diff --git a/nest/route.h b/nest/route.h index 641b924..a4c0154 100644 --- a/nest/route.h +++ b/nest/route.h @@ -321,6 +321,10 @@ typedef struct rta { #define RTD_MULTIPATH 5 /* Multipath route (nexthops != NULL) */ #define RTD_NONE 6 /* Invalid RTD */ + /* Flags for net->n.flags, used by kernel syncer */ +#define KRF_INSTALLED 0x80 /* This route should be installed in the kernel */ +#define KRF_SYNC_ERROR 0x40 /* Error during kernel table synchronization */ + #define RTAF_CACHED 1 /* This is a cached rta */ #define IGP_METRIC_UNKNOWN 0x80000000 /* Default igp_metric used when no other diff --git a/nest/rt-table.c b/nest/rt-table.c index 3ff53ff..e20d2f6 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -1645,6 +1645,7 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, ea_list *tm byte tm[TM_DATETIME_BUFFER_SIZE], info[256]; rta *a = e->attrs; int primary = (e->net->routes == e); + int sync_error = (e->net->n.flags & KRF_SYNC_ERROR); struct mpnh *nh; rt_format_via(e, via); @@ -1667,7 +1668,7 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, ea_list *tm else bsprintf(info, " (%d)", e->pref); cli_printf(c, -1007, "%-18s %s [%s %s%s]%s%s", ia, via, a->proto->name, - tm, from, primary ? " *" : "", info); + tm, from, primary ? (sync_error ? " !" : " *") : "", info); for (nh = a->nexthops; nh; nh = nh->next) cli_printf(c, -1007, "\tvia %I on %s weight %d", nh->gw, nh->iface->name, nh->weight + 1); if (d->verbose) diff --git a/proto/ospf/packet.c b/proto/ospf/packet.c index 3076297..df67d5a 100644 --- a/proto/ospf/packet.c +++ b/proto/ospf/packet.c @@ -499,7 +499,7 @@ ospf_err_hook(sock * sk, int err) { // struct ospf_iface *ifa= (struct ospf_iface *) (sk->data); // struct proto *p = (struct proto *) (ifa->oa->po); - log(L_ERR "OSPF: Socket error: %m", err); + log(L_ERR "OSPF: Socket error: %M", err); } void diff --git a/sysdep/bsd/krt-sock.c b/sysdep/bsd/krt-sock.c index f6bc4a2..7229590 100644 --- a/sysdep/bsd/krt-sock.c +++ b/sysdep/bsd/krt-sock.c @@ -68,7 +68,7 @@ krt_capable(rte *e) memcpy(p, body, (l > sizeof(*p) ? sizeof(*p) : l));\ body += l;} -static void +static int krt_sock_send(int cmd, rte *e) { net *net = e->net; @@ -160,7 +160,7 @@ krt_sock_send(int cmd, rte *e) if(!i->addr) { log(L_ERR "KRT: interface %s has no IP addess", i->name); - return; + return -1; } fill_in_sockaddr(&gate, i->addr->ip, 0); @@ -182,22 +182,27 @@ krt_sock_send(int cmd, rte *e) if ((l = write(rt_sock, (char *)&msg, l)) < 0) { log(L_ERR "KRT: Error sending route %I/%d to kernel", net->n.prefix, net->n.pxlen); + return -1; } + + return 0; } void -krt_set_notify(struct krt_proto *p UNUSED, net *net, rte *new, rte *old) +krt_set_notify(struct krt_proto *p UNUSED, net *n, rte *new, rte *old) { + int err = 0; + if (old) - { - DBG("krt_remove_route(%I/%d)\n", net->n.prefix, net->n.pxlen); - krt_sock_send(RTM_DELETE, old); - } + krt_sock_send(RTM_DELETE, old); + if (new) - { - DBG("krt_add_route(%I/%d)\n", net->n.prefix, net->n.pxlen); - krt_sock_send(RTM_ADD, new); - } + err = krt_sock_send(RTM_ADD, new); + + if (err < 0) + n->n.flags |= KRF_SYNC_ERROR; + else + n->n.flags &= ~KRF_SYNC_ERROR; } static int diff --git a/sysdep/linux/netlink/netlink.c b/sysdep/linux/netlink/netlink.c index 0830097..f8a5d63 100644 --- a/sysdep/linux/netlink/netlink.c +++ b/sysdep/linux/netlink/netlink.c @@ -198,7 +198,7 @@ nl_exchange(struct nlmsghdr *pkt) break; log(L_WARN "nl_exchange: Unexpected reply received"); } - return nl_error(h); + return nl_error(h) ? -1 : 0; } /* @@ -616,7 +616,7 @@ nh_bufsize(struct mpnh *nh) return rv; } -static void +static int nl_send_route(struct krt_proto *p, rte *e, int new) { eattr *ea; @@ -663,7 +663,7 @@ nl_send_route(struct krt_proto *p, rte *e, int new) break; case RTD_DEVICE: if (!a->iface) - return; + return -1; r.r.rtm_type = RTN_UNICAST; nl_add_attr_u32(&r.h, sizeof(r), RTA_OIF, a->iface->index); break; @@ -684,17 +684,24 @@ nl_send_route(struct krt_proto *p, rte *e, int new) bug("krt_capable inconsistent with nl_send_route"); } - nl_exchange(&r.h); + return nl_exchange(&r.h); } void -krt_set_notify(struct krt_proto *p, net *n UNUSED, rte *new, rte *old) +krt_set_notify(struct krt_proto *p, net *n, rte *new, rte *old) { + int err = 0; + if (old) nl_send_route(p, old, 0); if (new) - nl_send_route(p, new, 1); + err = nl_send_route(p, new, 1); + + if (err < 0) + n->n.flags |= KRF_SYNC_ERROR; + else + n->n.flags &= ~KRF_SYNC_ERROR; } diff --git a/sysdep/unix/krt.h b/sysdep/unix/krt.h index c88bc48..f83e6ee 100644 --- a/sysdep/unix/krt.h +++ b/sysdep/unix/krt.h @@ -19,7 +19,7 @@ struct kif_proto; #include "lib/krt-set.h" #include "lib/krt-iface.h" -/* Flags stored in net->n.flags */ +/* Flags stored in net->n.flags, rest are in nest/route.h */ #define KRF_VERDICT_MASK 0x0f #define KRF_CREATE 0 /* Not seen in kernel table */ @@ -28,9 +28,6 @@ struct kif_proto; #define KRF_DELETE 3 /* Should be deleted */ #define KRF_IGNORE 4 /* To be ignored */ -#define KRF_INSTALLED 0x80 /* This route should be installed in the kernel */ - - #define EA_KRT_PREFSRC EA_CODE(EAP_KRT, 0) #define EA_KRT_REALM EA_CODE(EAP_KRT, 1) -- cgit v1.2.3