summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2015-05-20 02:40:34 +0200
committerDonald Sharp <sharpd@cumulusnetworks.com>2015-05-20 02:40:34 +0200
commitfb018d251e5fc2fee0814a63c4e0a44274c98bb9 (patch)
tree59351ede3cd497fbb05c2b6906de549f17686f55 /lib
parentbgpd: bgpd-update-delay.patch (diff)
downloadfrr-fb018d251e5fc2fee0814a63c4e0a44274c98bb9.tar.xz
frr-fb018d251e5fc2fee0814a63c4e0a44274c98bb9.zip
nexthop-tracking.patch
quagga: nexthop-tracking.patch Add next hop tracking support to Quagga. Complete documentation in doc/next-hop-tracking.txt. Signed-off-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com> Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com> Signed-off-by: Dinesh Dutt <ddutt@cumulusnetworks.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.am4
-rw-r--r--lib/log.c3
-rw-r--r--lib/memtypes.c1
-rw-r--r--lib/nexthop.c100
-rw-r--r--lib/nexthop.h89
-rw-r--r--lib/zclient.c6
-rw-r--r--lib/zclient.h1
-rw-r--r--lib/zebra.h6
8 files changed, 207 insertions, 3 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index bd2109292..f64972dd0 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -12,7 +12,7 @@ libzebra_la_SOURCES = \
sockunion.c prefix.c thread.c if.c memory.c buffer.c table.c hash.c \
filter.c routemap.c distribute.c stream.c str.c log.c plist.c \
zclient.c sockopt.c smux.c agentx.c snmp.c md5.c if_rmap.c keychain.c privs.c \
- sigevent.c pqueue.c jhash.c memtypes.c workqueue.c
+ sigevent.c pqueue.c jhash.c memtypes.c workqueue.c nexthop.c
BUILT_SOURCES = memtypes.h route_types.h gitversion.h
@@ -27,7 +27,7 @@ pkginclude_HEADERS = \
str.h stream.h table.h thread.h vector.h version.h vty.h zebra.h \
plist.h zclient.h sockopt.h smux.h md5.h if_rmap.h keychain.h \
privs.h sigevent.h pqueue.h jhash.h zassert.h memtypes.h \
- workqueue.h route_types.h libospf.h
+ workqueue.h route_types.h libospf.h nexthop.h
EXTRA_DIST = \
regex.c regex-gnu.h \
diff --git a/lib/log.c b/lib/log.c
index 1058844b7..7e03aa9af 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -845,6 +845,9 @@ static const struct zebra_desc_table command_types[] = {
DESC_ENTRY (ZEBRA_ROUTER_ID_DELETE),
DESC_ENTRY (ZEBRA_ROUTER_ID_UPDATE),
DESC_ENTRY (ZEBRA_HELLO),
+ DESC_ENTRY (ZEBRA_NEXTHOP_REGISTER),
+ DESC_ENTRY (ZEBRA_NEXTHOP_UNREGISTER),
+ DESC_ENTRY (ZEBRA_NEXTHOP_UPDATE),
};
#undef DESC_ENTRY
diff --git a/lib/memtypes.c b/lib/memtypes.c
index 47a343873..5af2642be 100644
--- a/lib/memtypes.c
+++ b/lib/memtypes.c
@@ -84,6 +84,7 @@ struct memory_list memory_list_zebra[] =
{ MTYPE_STATIC_IPV6, "Static IPv6 route" },
{ MTYPE_RIB_DEST, "RIB destination" },
{ MTYPE_RIB_TABLE_INFO, "RIB table info" },
+ { MTYPE_RNH, "Nexthop tracking object" },
{ -1, NULL },
};
diff --git a/lib/nexthop.c b/lib/nexthop.c
new file mode 100644
index 000000000..2478dca7a
--- /dev/null
+++ b/lib/nexthop.c
@@ -0,0 +1,100 @@
+/* A generic nexthop structure
+ * Copyright (C) 2013 Cumulus Networks, Inc.
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Zebra; see the file COPYING. If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#include <zebra.h>
+
+#include "prefix.h"
+#include "table.h"
+#include "memory.h"
+#include "str.h"
+#include "command.h"
+#include "if.h"
+#include "log.h"
+#include "sockunion.h"
+#include "linklist.h"
+#include "thread.h"
+#include "prefix.h"
+#include "nexthop.h"
+
+/* check if nexthops are same, non-recursive */
+int
+nexthop_same_no_recurse (struct nexthop *next1, struct nexthop *next2)
+{
+ if (next1->type != next2->type)
+ return 0;
+
+ switch (next1->type)
+ {
+ case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ if (! IPV4_ADDR_SAME (&next1->gate.ipv4, &next2->gate.ipv4))
+ return 0;
+ if (next1->ifindex && (next1->ifindex != next2->ifindex))
+ return 0;
+ break;
+ case NEXTHOP_TYPE_IFINDEX:
+ case NEXTHOP_TYPE_IFNAME:
+ if (next1->ifindex != next2->ifindex)
+ return 0;
+ break;
+#ifdef HAVE_IPV6
+ case NEXTHOP_TYPE_IPV6:
+ if (! IPV6_ADDR_SAME (&next1->gate.ipv6, &next2->gate.ipv6))
+ return 0;
+ break;
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ case NEXTHOP_TYPE_IPV6_IFNAME:
+ if (! IPV6_ADDR_SAME (&next1->gate.ipv6, &next2->gate.ipv6))
+ return 0;
+ if (next1->ifindex != next2->ifindex)
+ return 0;
+ break;
+#endif /* HAVE_IPV6 */
+ default:
+ /* do nothing */
+ break;
+ }
+ return 1;
+}
+
+/*
+ * nexthop_type_to_str
+ */
+const char *
+nexthop_type_to_str (enum nexthop_types_t nh_type)
+{
+ static const char *desc[] = {
+ "none",
+ "Directly connected",
+ "Interface route",
+ "IPv4 nexthop",
+ "IPv4 nexthop with ifindex",
+ "IPv4 nexthop with ifname",
+ "IPv6 nexthop",
+ "IPv6 nexthop with ifindex",
+ "IPv6 nexthop with ifname",
+ "Null0 nexthop",
+ };
+
+ if (nh_type >= ZEBRA_NUM_OF (desc))
+ return "<Invalid nh type>";
+
+ return desc[nh_type];
+}
diff --git a/lib/nexthop.h b/lib/nexthop.h
new file mode 100644
index 000000000..bddac6554
--- /dev/null
+++ b/lib/nexthop.h
@@ -0,0 +1,89 @@
+/*
+ * Nexthop structure definition.
+ * Copyright (C) 2013 Cumulus Networks, Inc.
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Zebra; see the file COPYING. If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef _LIB_NEXTHOP_H
+#define _LIB_NEXTHOP_H
+
+#include "prefix.h"
+
+union g_addr {
+ struct in_addr ipv4;
+#ifdef HAVE_IPV6
+ struct in6_addr ipv6;
+#endif /* HAVE_IPV6 */
+};
+
+enum nexthop_types_t
+{
+ NEXTHOP_TYPE_IFINDEX = 1, /* Directly connected. */
+ NEXTHOP_TYPE_IFNAME, /* Interface route. */
+ NEXTHOP_TYPE_IPV4, /* IPv4 nexthop. */
+ NEXTHOP_TYPE_IPV4_IFINDEX, /* IPv4 nexthop with ifindex. */
+ NEXTHOP_TYPE_IPV4_IFNAME, /* IPv4 nexthop with ifname. */
+ NEXTHOP_TYPE_IPV6, /* IPv6 nexthop. */
+ NEXTHOP_TYPE_IPV6_IFINDEX, /* IPv6 nexthop with ifindex. */
+ NEXTHOP_TYPE_IPV6_IFNAME, /* IPv6 nexthop with ifname. */
+ NEXTHOP_TYPE_BLACKHOLE, /* Null0 nexthop. */
+};
+
+/* Nexthop structure. */
+struct nexthop
+{
+ struct nexthop *next;
+ struct nexthop *prev;
+
+ /* Interface index. */
+ char *ifname;
+ unsigned int ifindex;
+
+ enum nexthop_types_t type;
+
+ u_char flags;
+#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. */
+#define NEXTHOP_FLAG_MATCHED (1 << 4) /* Already matched vs a nexthop */
+
+ /* Nexthop address */
+ union g_addr gate;
+ union g_addr src;
+
+ /* Nexthops obtained by recursive resolution.
+ *
+ * If the nexthop struct needs to be resolved recursively,
+ * NEXTHOP_FLAG_RECURSIVE will be set in flags and the nexthops
+ * obtained by recursive resolution will be added to `resolved'.
+ * Only one level of recursive resolution is currently supported. */
+ struct nexthop *resolved;
+};
+
+#define nexthop_new() \
+({ \
+ struct nexthop *n = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop)); \
+ n; \
+})
+
+extern const char *nexthop_type_to_str (enum nexthop_types_t nh_type);
+extern int nexthop_same_no_recurse (struct nexthop *next1, struct nexthop *next2);
+
+#endif /*_LIB_NEXTHOP_H */
diff --git a/lib/zclient.c b/lib/zclient.c
index 3b5477e90..b77fd3432 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -967,6 +967,12 @@ zclient_read (struct thread *thread)
if (zclient->ipv6_route_delete)
(*zclient->ipv6_route_delete) (command, zclient, length);
break;
+ case ZEBRA_NEXTHOP_UPDATE:
+ if (zclient_debug)
+ zlog_debug("zclient rcvd nexthop update\n");
+ if (zclient->nexthop_update)
+ (*zclient->nexthop_update) (command, zclient, length);
+ break;
default:
break;
}
diff --git a/lib/zclient.h b/lib/zclient.h
index a660bbf19..2ece81ebc 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -82,6 +82,7 @@ struct zclient
int (*ipv4_route_delete) (int, struct zclient *, uint16_t);
int (*ipv6_route_add) (int, struct zclient *, uint16_t);
int (*ipv6_route_delete) (int, struct zclient *, uint16_t);
+ int (*nexthop_update) (int, struct zclient *, uint16_t);
};
/* Zebra API message flag. */
diff --git a/lib/zebra.h b/lib/zebra.h
index 3715b342e..124431a85 100644
--- a/lib/zebra.h
+++ b/lib/zebra.h
@@ -424,7 +424,10 @@ struct in_pktinfo
#define ZEBRA_ROUTER_ID_DELETE 21
#define ZEBRA_ROUTER_ID_UPDATE 22
#define ZEBRA_HELLO 23
-#define ZEBRA_MESSAGE_MAX 24
+#define ZEBRA_NEXTHOP_REGISTER 24
+#define ZEBRA_NEXTHOP_UNREGISTER 25
+#define ZEBRA_NEXTHOP_UPDATE 26
+#define ZEBRA_MESSAGE_MAX 27
/* Marker value used in new Zserv, in the byte location corresponding
* the command value in the old zserv header. To allow old and new
@@ -525,6 +528,7 @@ extern const char *zserv_command_string (unsigned int command);
#define CHECK_FLAG(V,F) ((V) & (F))
#define SET_FLAG(V,F) (V) |= (F)
#define UNSET_FLAG(V,F) (V) &= ~(F)
+#define RESET_FLAG(V) (V) = 0
/* AFI and SAFI type. */
typedef u_int16_t afi_t;