summaryrefslogtreecommitdiff
path: root/sysdep/linux/netlink
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2012-03-25 19:44:14 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2012-03-25 19:44:14 +0200
commitc9df01d3215379c0463dd2a3b0c9b1700d6e2ac3 (patch)
treea8f1f24a99e6ee9747f19e20cd43f33bf6f19ef4 /sysdep/linux/netlink
parent9ba2798c65c02254ec000ab03a76fbbaae1ddc97 (diff)
Fixes several minor bugs in kernel syncer.
Diffstat (limited to 'sysdep/linux/netlink')
-rw-r--r--sysdep/linux/netlink/netlink.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/sysdep/linux/netlink/netlink.c b/sysdep/linux/netlink/netlink.c
index a0743da7..c8eed0f3 100644
--- a/sysdep/linux/netlink/netlink.c
+++ b/sysdep/linux/netlink/netlink.c
@@ -612,7 +612,7 @@ nh_bufsize(struct mpnh *nh)
}
static int
-nl_send_route(struct krt_proto *p, rte *e, int new)
+nl_send_route(struct krt_proto *p, rte *e, struct ea_list *eattrs, int new)
{
eattr *ea;
net *net = e->net;
@@ -639,13 +639,18 @@ nl_send_route(struct krt_proto *p, rte *e, int new)
r.r.rtm_scope = RT_SCOPE_UNIVERSE;
nl_add_attr_ipa(&r.h, sizeof(r), RTA_DST, net->n.prefix);
- if (ea = ea_find(a->eattrs, EA_KRT_METRIC))
- nl_add_attr_u32(&r.h, sizeof(r), RTA_PRIORITY, ea->u.data);
+ u32 metric = 0;
+ if (new && e->attrs->source == RTS_INHERIT)
+ metric = e->u.krt.metric;
+ if (ea = ea_find(eattrs, EA_KRT_METRIC))
+ metric = ea->u.data;
+ if (metric != 0)
+ nl_add_attr_u32(&r.h, sizeof(r), RTA_PRIORITY, metric);
- if (ea = ea_find(a->eattrs, EA_KRT_PREFSRC))
+ if (ea = ea_find(eattrs, EA_KRT_PREFSRC))
nl_add_attr_ipa(&r.h, sizeof(r), RTA_PREFSRC, *(ip_addr *)ea->u.ptr->data);
- if (ea = ea_find(a->eattrs, EA_KRT_REALM))
+ if (ea = ea_find(eattrs, EA_KRT_REALM))
nl_add_attr_u32(&r.h, sizeof(r), RTA_FLOW, ea->u.data);
switch (a->dest)
@@ -686,15 +691,22 @@ nl_send_route(struct krt_proto *p, rte *e, int new)
}
void
-krt_set_notify(struct krt_proto *p, net *n, rte *new, rte *old)
+krt_set_notify(struct krt_proto *p, net *n, rte *new, rte *old, struct ea_list *eattrs)
{
int err = 0;
+ /*
+ * NULL for eattr of the old route is a little hack, but we don't
+ * get proper eattrs for old in rt_notify() anyway. NULL means no
+ * extended route attributes and therefore matches if the kernel
+ * route has any of them.
+ */
+
if (old)
- nl_send_route(p, old, 0);
+ nl_send_route(p, old, NULL, 0);
if (new)
- err = nl_send_route(p, new, 1);
+ err = nl_send_route(p, new, eattrs, 1);
if (err < 0)
n->n.flags |= KRF_SYNC_ERROR;