isisd: add support to import routes from other protocols
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c
index 1201627..8c4eef0 100644
--- a/isisd/isis_zebra.c
+++ b/isisd/isis_zebra.c
@@ -4,6 +4,7 @@
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
+ * Copyright (C) 2013-2015 Christian Franke <chris@opensourcerouting.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
@@ -525,11 +526,14 @@
struct stream *stream;
struct zapi_ipv4 api;
struct prefix_ipv4 p;
+ struct prefix *p_generic = (struct prefix*)&p;
unsigned long ifindex __attribute__ ((unused));
struct in_addr nexthop __attribute__ ((unused));
stream = zclient->ibuf;
+ memset(&api, 0, sizeof(api));
memset (&p, 0, sizeof (struct prefix_ipv4));
+ memset(&nexthop, 0, sizeof(nexthop));
ifindex = 0;
api.type = stream_getc (stream);
@@ -554,31 +558,80 @@
api.distance = stream_getc (stream);
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
api.metric = stream_getl (stream);
- else
- api.metric = 0;
+
+ /*
+ * Avoid advertising a false default reachability. (A default
+ * route installed by IS-IS gets redistributed from zebra back
+ * into IS-IS causing us to start advertising default reachabity
+ * without this check)
+ */
+ if (p.prefixlen == 0 && api.type == ZEBRA_ROUTE_ISIS)
+ command = ZEBRA_IPV4_ROUTE_DELETE;
if (command == ZEBRA_IPV4_ROUTE_ADD)
- {
- if (isis->debugs & DEBUG_ZEBRA)
- zlog_debug ("IPv4 Route add from Z");
- }
+ isis_redist_add(api.type, p_generic, api.distance, api.metric);
+ else
+ isis_redist_delete(api.type, p_generic);
return 0;
}
-#ifdef HAVE_IPV6
static int
isis_zebra_read_ipv6 (int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
+ struct stream *stream;
+ struct zapi_ipv6 api;
+ struct prefix_ipv6 p;
+ struct prefix *p_generic = (struct prefix*)&p;
+ struct in6_addr nexthop;
+ unsigned long ifindex __attribute__((unused));
+
+ stream = zclient->ibuf;
+ memset(&api, 0, sizeof(api));
+ memset(&p, 0, sizeof(struct prefix_ipv6));
+ memset(&nexthop, 0, sizeof(nexthop));
+ ifindex = 0;
+
+ api.type = stream_getc(stream);
+ api.flags = stream_getc(stream);
+ api.message = stream_getc(stream);
+
+ p.family = AF_INET6;
+ p.prefixlen = stream_getc(stream);
+ stream_get(&p.prefix, stream, PSIZE(p.prefixlen));
+
+ if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP))
+ {
+ api.nexthop_num = stream_getc(stream); /* this is always 1 */
+ stream_get(&nexthop, stream, sizeof(nexthop));
+ }
+ if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX))
+ {
+ api.ifindex_num = stream_getc(stream);
+ ifindex = stream_getl(stream);
+ }
+ if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE))
+ api.distance = stream_getc(stream);
+ if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC))
+ api.metric = stream_getl(stream);
+
+ /*
+ * Avoid advertising a false default reachability. (A default
+ * route installed by IS-IS gets redistributed from zebra back
+ * into IS-IS causing us to start advertising default reachabity
+ * without this check)
+ */
+ if (p.prefixlen == 0 && api.type == ZEBRA_ROUTE_ISIS)
+ command = ZEBRA_IPV6_ROUTE_DELETE;
+
+ if (command == ZEBRA_IPV6_ROUTE_ADD)
+ isis_redist_add(api.type, p_generic, api.distance, api.metric);
+ else
+ isis_redist_delete(api.type, p_generic);
+
return 0;
}
-#endif
-
-#define ISIS_TYPE_IS_REDISTRIBUTED(T) \
-T == ZEBRA_ROUTE_MAX ? \
- vrf_bitmap_check (zclient->default_information, VRF_DEFAULT) : \
- vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT)
int
isis_distribute_list_update (int routetype)
@@ -586,14 +639,23 @@
return 0;
}
-#if 0 /* Not yet. */
-static int
-isis_redistribute_default_set (int routetype, int metric_type,
- int metric_value)
+void
+isis_zebra_redistribute_set(int type)
{
- return 0;
+ if (type == DEFAULT_ROUTE)
+ zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient, VRF_DEFAULT);
+ else
+ zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, type, VRF_DEFAULT);
}
-#endif /* 0 */
+
+void
+isis_zebra_redistribute_unset(int type)
+{
+ if (type == DEFAULT_ROUTE)
+ zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient, VRF_DEFAULT);
+ else
+ zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, type, VRF_DEFAULT);
+}
static void
isis_zebra_connected (struct zclient *zclient)