summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2015-05-20 02:58:13 +0200
committerDonald Sharp <sharpd@cumulusnetworks.com>2015-05-20 02:58:13 +0200
commitc8a1cb5c9db0490cd6d426999f3d1cb2df143e45 (patch)
tree3dc701e31028f4be1716b3f6df7f3c57076b1fef /lib
parentSupport for 'clear ip ospf interface [IFNAME]' (diff)
downloadfrr-c8a1cb5c9db0490cd6d426999f3d1cb2df143e45.tar.xz
frr-c8a1cb5c9db0490cd6d426999f3d1cb2df143e45.zip
onlink commit from Quagga-RE branch
Diffstat (limited to 'lib')
-rw-r--r--lib/zclient.c34
-rw-r--r--lib/zclient.h3
-rw-r--r--lib/zebra.h1
3 files changed, 36 insertions, 2 deletions
diff --git a/lib/zclient.c b/lib/zclient.c
index ac418addf..d8ef0e853 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -450,6 +450,21 @@ zclient_connect (struct thread *t)
* nexthop information is provided, and the message describes a prefix
* to blackhole or reject route.
*
+ * The original struct zapi_ipv4, zapi_ipv4_route() and zread_ipv4_*()
+ * infrastructure was built around the traditional (32-bit "gate OR
+ * ifindex") nexthop data unit. A special encoding can be used to feed
+ * onlink (64-bit "gate AND ifindex") nexthops into zapi_ipv4_route()
+ * using the same zapi_ipv4 structure. This is done by setting zapi_ipv4
+ * fields as follows:
+ * - .message |= ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_ONLINK
+ * - .nexthop_num == .ifindex_num
+ * - .nexthop and .ifindex are filled with gate and ifindex parts of
+ * each compound nexthop, both in the same order
+ *
+ * zapi_ipv4_route() will produce two nexthop data units for each such
+ * interleaved 64-bit nexthop. On the zserv side of the socket it will be
+ * mapped to a singlle NEXTHOP_TYPE_IPV4_IFINDEX_OL RIB nexthop structure.
+ *
* If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1
* byte value.
*
@@ -486,8 +501,25 @@ zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
stream_write (s, (u_char *) & p->prefix, psize);
/* Nexthop, ifindex, distance and metric information. */
- if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
+ /* ZAPI_MESSAGE_ONLINK implies interleaving */
+ if (CHECK_FLAG (api->message, ZAPI_MESSAGE_ONLINK))
{
+ /* ZAPI_MESSAGE_NEXTHOP is required for proper receiving */
+ assert (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP));
+ /* 64-bit data units, interleaved between nexthop[] and ifindex[] */
+ assert (api->nexthop_num == api->ifindex_num);
+ stream_putc (s, api->nexthop_num * 2);
+ for (i = 0; i < api->nexthop_num; i++)
+ {
+ stream_putc (s, ZEBRA_NEXTHOP_IPV4_ONLINK);
+ stream_put_in_addr (s, api->nexthop[i]);
+ stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
+ stream_putl (s, api->ifindex[i]);
+ }
+ }
+ else if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
+ {
+ /* traditional 32-bit data units */
if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))
{
stream_putc (s, 1);
diff --git a/lib/zclient.h b/lib/zclient.h
index 9b359893e..e1bb2000c 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -93,7 +93,8 @@ struct zclient
#define ZAPI_MESSAGE_IFINDEX 0x02
#define ZAPI_MESSAGE_DISTANCE 0x04
#define ZAPI_MESSAGE_METRIC 0x08
-#define ZAPI_MESSAGE_TAG 0x20
+#define ZAPI_MESSAGE_TAG 0x10
+#define ZAPI_MESSAGE_ONLINK 0x20
/* Zserv protocol message header */
struct zserv_header
diff --git a/lib/zebra.h b/lib/zebra.h
index 794a457ea..4e976eb10 100644
--- a/lib/zebra.h
+++ b/lib/zebra.h
@@ -493,6 +493,7 @@ extern const char *zserv_command_string (unsigned int command);
#define ZEBRA_NEXTHOP_IPV6_IFINDEX 7
#define ZEBRA_NEXTHOP_IPV6_IFNAME 8
#define ZEBRA_NEXTHOP_BLACKHOLE 9
+#define ZEBRA_NEXTHOP_IPV4_ONLINK 10
#ifndef INADDR_LOOPBACK
#define INADDR_LOOPBACK 0x7f000001 /* Internet address 127.0.0.1. */