diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2015-05-20 02:40:34 +0200 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2015-05-20 02:40:34 +0200 |
commit | fb018d251e5fc2fee0814a63c4e0a44274c98bb9 (patch) | |
tree | 59351ede3cd497fbb05c2b6906de549f17686f55 /lib | |
parent | bgpd: bgpd-update-delay.patch (diff) | |
download | frr-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.am | 4 | ||||
-rw-r--r-- | lib/log.c | 3 | ||||
-rw-r--r-- | lib/memtypes.c | 1 | ||||
-rw-r--r-- | lib/nexthop.c | 100 | ||||
-rw-r--r-- | lib/nexthop.h | 89 | ||||
-rw-r--r-- | lib/zclient.c | 6 | ||||
-rw-r--r-- | lib/zclient.h | 1 | ||||
-rw-r--r-- | lib/zebra.h | 6 |
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 \ @@ -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; |