summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Franke <chris@opensourcerouting.org>2013-07-05 15:35:39 +0000
committerDavid Lamparter <equinox@opensourcerouting.org>2013-09-19 18:04:40 +0200
commite8d3d2991f72613edb76dea244a8c8e4684873dd (patch)
treed02f768800ebaac51439368ff3d851e63ed6359e
parent48a53dc71cb422e619859b79d5069e02fcd867d0 (diff)
zebra: implement NEXTHOP_FLAG_ONLINK
On Linux, the kernel will only allow for a route to be installed when its gateway is directly attached according the kernel fib. There are cases when this restriction by the kernel is too strong, in those cases, we deploy the RTNH_F_ONLINK netlink flag. Signed-off-by: Christian Franke <chris@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
-rw-r--r--zebra/rib.h1
-rw-r--r--zebra/rt_netlink.c9
-rw-r--r--zebra/zebra_vty.c9
3 files changed, 18 insertions, 1 deletions
diff --git a/zebra/rib.h b/zebra/rib.h
index 4d98e059..1c548795 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -253,6 +253,7 @@ struct nexthop
#define NEXTHOP_FLAG_ACTIVE (1 << 0) /* This nexthop is alive. */
#define NEXTHOP_FLAG_FIB (1 << 1) /* FIB nexthop. */
#define NEXTHOP_FLAG_RECURSIVE (1 << 2) /* Recursive nexthop. */
+#define NEXTHOP_FLAG_ONLINK (1 << 3) /* Nexthop should be installed onlink. */
/* Nexthop address */
union g_addr gate;
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index b0ade058..7a820bfd 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -1443,8 +1443,11 @@ _netlink_route_build_singlepath(
int bytelen,
struct nexthop *nexthop,
struct nlmsghdr *nlmsg,
+ struct rtmsg *rtmsg,
size_t req_size)
{
+ if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
+ rtmsg->rtm_flags |= RTNH_F_ONLINK;
if (nexthop->type == NEXTHOP_TYPE_IPV4
|| nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
{
@@ -1534,6 +1537,9 @@ _netlink_route_build_multipath(
rtnh->rtnh_hops = 0;
rta->rta_len += rtnh->rtnh_len;
+ if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
+ rtnh->rtnh_flags |= RTNH_F_ONLINK;
+
if (nexthop->type == NEXTHOP_TYPE_IPV4
|| nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
{
@@ -1733,7 +1739,8 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
_netlink_route_debug(cmd, p, nexthop, routedesc, family);
_netlink_route_build_singlepath(routedesc, bytelen,
- nexthop, &req.n, sizeof req);
+ nexthop, &req.n, &req.r,
+ sizeof req);
if (cmd == RTM_NEWROUTE)
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index e1da7df8..45928e93 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -615,6 +615,9 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn)
if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
vty_out (vty, " inactive");
+ if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
+ vty_out (vty, " onlink");
+
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
vty_out (vty, " (recursive)");
@@ -710,6 +713,9 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib)
if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
vty_out (vty, " inactive");
+ if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
+ vty_out (vty, " onlink");
+
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
vty_out (vty, " (recursive)");
@@ -1600,6 +1606,9 @@ vty_show_ipv6_route_detail (struct vty *vty, struct route_node *rn)
if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
vty_out (vty, " inactive");
+ if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
+ vty_out (vty, " onlink");
+
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
vty_out (vty, " (recursive)");