summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/command.c8
-rw-r--r--lib/command_match.c10
-rw-r--r--lib/ferr.c2
-rw-r--r--lib/frr_pthread.c2
-rw-r--r--lib/grammar_sandbox.c6
-rw-r--r--lib/hash.c2
-rw-r--r--lib/if.c4
-rw-r--r--lib/keychain.c2
-rw-r--r--lib/libfrr.c22
-rw-r--r--lib/linklist.c7
-rw-r--r--lib/linklist.h32
-rw-r--r--lib/lua.c130
-rw-r--r--lib/lua.h79
-rw-r--r--lib/nexthop_group.c2
-rw-r--r--lib/openbsd-tree.c2
-rw-r--r--lib/routemap.c139
-rw-r--r--lib/routemap.h16
-rw-r--r--lib/subdir.am19
-rw-r--r--lib/thread.c4
-rw-r--r--lib/wheel.c2
-rw-r--r--lib/zclient.c2
21 files changed, 427 insertions, 65 deletions
diff --git a/lib/command.c b/lib/command.c
index e4e3d786ac..60c5f4e75b 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -695,7 +695,7 @@ static vector cmd_complete_command_real(vector vline, struct vty *vty,
}
vector comps = completions_to_vec(completions);
- list_delete_and_null(&completions);
+ list_delete(&completions);
// set status code appropriately
switch (vector_active(comps)) {
@@ -1020,7 +1020,7 @@ static int cmd_execute_command_real(vector vline, enum filter_type filter,
// if matcher error, return corresponding CMD_ERR
if (MATCHER_ERROR(status)) {
if (argv_list)
- list_delete_and_null(&argv_list);
+ list_delete(&argv_list);
switch (status) {
case MATCHER_INCOMPLETE:
return CMD_ERR_INCOMPLETE;
@@ -1049,7 +1049,7 @@ static int cmd_execute_command_real(vector vline, enum filter_type filter,
ret = matched_element->func(matched_element, vty, argc, argv);
// delete list and cmd_token's in it
- list_delete_and_null(&argv_list);
+ list_delete(&argv_list);
XFREE(MTYPE_TMP, argv);
return ret;
@@ -2949,6 +2949,6 @@ void cmd_terminate()
if (host.config)
XFREE(MTYPE_HOST, host.config);
- list_delete_and_null(&varhandlers);
+ list_delete(&varhandlers);
qobj_finish();
}
diff --git a/lib/command_match.c b/lib/command_match.c
index a1ae3ac6b9..8b34d1e3eb 100644
--- a/lib/command_match.c
+++ b/lib/command_match.c
@@ -334,7 +334,7 @@ static enum matcher_rv command_match_r(struct graph_node *start, vector vline,
status = MATCHER_INCOMPLETE;
// cleanup
- list_delete_and_null(&next);
+ list_delete(&next);
return status;
}
@@ -367,7 +367,7 @@ enum matcher_rv command_complete(struct graph *graph, vector vline,
unsigned int idx;
for (idx = 0; idx < vector_active(vline) && next->count > 0; idx++) {
- list_delete_and_null(&current);
+ list_delete(&current);
current = next;
next = list_new();
next->del = stack_del;
@@ -458,8 +458,8 @@ enum matcher_rv command_complete(struct graph *graph, vector vline,
}
}
- list_delete_and_null(&current);
- list_delete_and_null(&next);
+ list_delete(&current);
+ list_delete(&next);
return mrv;
}
@@ -652,7 +652,7 @@ static void del_arglist(struct list *list)
list_delete_node(list, tail);
// delete the rest of the list as usual
- list_delete_and_null(&list);
+ list_delete(&list);
}
/*---------- token level matching functions ----------*/
diff --git a/lib/ferr.c b/lib/ferr.c
index afef196cec..bf89cc7f46 100644
--- a/lib/ferr.c
+++ b/lib/ferr.c
@@ -167,7 +167,7 @@ void log_ref_display(struct vty *vty, uint32_t code, bool json)
json_object_free(top);
}
- list_delete_and_null(&errlist);
+ list_delete(&errlist);
}
DEFUN_NOSH(show_error_code,
diff --git a/lib/frr_pthread.c b/lib/frr_pthread.c
index c1ce57e24e..a0223730b8 100644
--- a/lib/frr_pthread.c
+++ b/lib/frr_pthread.c
@@ -61,7 +61,7 @@ void frr_pthread_finish()
{
pthread_mutex_lock(&frr_pthread_list_mtx);
{
- list_delete_and_null(&frr_pthread_list);
+ list_delete(&frr_pthread_list);
}
pthread_mutex_unlock(&frr_pthread_list_mtx);
}
diff --git a/lib/grammar_sandbox.c b/lib/grammar_sandbox.c
index 0d6200b006..20d5879c67 100644
--- a/lib/grammar_sandbox.c
+++ b/lib/grammar_sandbox.c
@@ -140,7 +140,7 @@ DEFUN (grammar_test_complete,
vty_out(vty, "%% No match\n");
// free resources
- list_delete_and_null(&completions);
+ list_delete(&completions);
cmd_free_strvec(command);
XFREE(MTYPE_TMP, cmdstr);
@@ -184,7 +184,7 @@ DEFUN (grammar_test_match,
vty_out(vty, "func: %p\n", element->func);
- list_delete_and_null(&argvv);
+ list_delete(&argvv);
} else {
assert(MATCHER_ERROR(result));
switch (result) {
@@ -421,7 +421,7 @@ DEFUN (grammar_findambig,
}
prev = cur;
}
- list_delete_and_null(&commands);
+ list_delete(&commands);
vty_out(vty, "\n");
} while (scan && scannode < LINK_PARAMS_NODE);
diff --git a/lib/hash.c b/lib/hash.c
index ee5401b236..114522a75a 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -318,7 +318,7 @@ void hash_free(struct hash *hash)
if (_hashes) {
listnode_delete(_hashes, hash);
if (_hashes->count == 0) {
- list_delete_and_null(&_hashes);
+ list_delete(&_hashes);
}
}
}
diff --git a/lib/if.c b/lib/if.c
index 67e2d366cd..e952313e8e 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -206,8 +206,8 @@ void if_delete(struct interface *ifp)
if_delete_retain(ifp);
- list_delete_and_null(&ifp->connected);
- list_delete_and_null(&ifp->nbr_connected);
+ list_delete(&ifp->connected);
+ list_delete(&ifp->nbr_connected);
if_link_params_free(ifp);
diff --git a/lib/keychain.c b/lib/keychain.c
index 494f6f6430..601b44a4f1 100644
--- a/lib/keychain.c
+++ b/lib/keychain.c
@@ -119,7 +119,7 @@ static void keychain_delete(struct keychain *keychain)
if (keychain->name)
XFREE(MTYPE_KEYCHAIN, keychain->name);
- list_delete_and_null(&keychain->key);
+ list_delete(&keychain->key);
listnode_delete(keychain_list, keychain);
keychain_free(keychain);
}
diff --git a/lib/libfrr.c b/lib/libfrr.c
index 2bce4766d3..94cd0ab623 100644
--- a/lib/libfrr.c
+++ b/lib/libfrr.c
@@ -973,3 +973,25 @@ void frr_fini(void)
fclose(fp);
}
}
+
+#ifdef INTERP
+static const char interp[]
+ __attribute__((section(".interp"), used)) = INTERP;
+#endif
+/*
+ * executable entry point for libfrr.so
+ *
+ * note that libc initialization is skipped for this so the set of functions
+ * that can be called is rather limited
+ */
+extern void _libfrr_version(void)
+ __attribute__((visibility("hidden"), noreturn));
+void _libfrr_version(void)
+{
+ const char banner[] =
+ FRR_FULL_NAME " " FRR_VERSION ".\n"
+ FRR_COPYRIGHT GIT_INFO "\n"
+ "configured with:\n " FRR_CONFIG_ARGS "\n";
+ write(1, banner, sizeof(banner) - 1);
+ _exit(0);
+}
diff --git a/lib/linklist.c b/lib/linklist.c
index bee9d05a2c..3aa7cae8b7 100644
--- a/lib/linklist.c
+++ b/lib/linklist.c
@@ -240,7 +240,7 @@ void list_delete_all_node(struct list *list)
list->count = 0;
}
-void list_delete_and_null(struct list **list)
+void list_delete(struct list **list)
{
assert(*list);
list_delete_all_node(*list);
@@ -248,11 +248,6 @@ void list_delete_and_null(struct list **list)
*list = NULL;
}
-void list_delete_original(struct list *list)
-{
- list_delete_and_null(&list);
-}
-
struct listnode *listnode_lookup(struct list *list, void *data)
{
struct listnode *node;
diff --git a/lib/linklist.h b/lib/linklist.h
index f5cd44efb0..0475391e9f 100644
--- a/lib/linklist.h
+++ b/lib/linklist.h
@@ -236,20 +236,6 @@ extern void list_sort(struct list *list,
int (*cmp)(const void **, const void **));
/*
- * The usage of list_delete is being transitioned to pass in
- * the double pointer to remove use after free's.
- * list_free usage is deprecated, it leads to memory leaks
- * of the linklist nodes. Please use list_delete_and_null
- *
- * In Oct of 2018, rename list_delete_and_null to list_delete
- * and remove list_delete_original and the list_delete #define
- * Additionally remove list_free entirely
- */
-#if CONFDATE > 20181001
-CPP_NOTICE("list_delete without double pointer is deprecated, please fixup")
-#endif
-
-/*
* Delete a list and NULL its pointer.
*
* If non-null, list->del is called with each data element.
@@ -258,23 +244,7 @@ CPP_NOTICE("list_delete without double pointer is deprecated, please fixup")
* pointer to list pointer; this will be set to NULL after the list has been
* deleted
*/
-extern void list_delete_and_null(struct list **plist);
-
-/*
- * Delete a list.
- *
- * If non-null, list->del is called with each data element.
- *
- * plist
- * pointer to list pointer
- */
-extern void list_delete_original(struct list *list);
-#define list_delete(X) \
- list_delete_original((X)) \
- CPP_WARN("Please transition to using list_delete_and_null")
-#define list_free(X) \
- list_delete_original((X)) \
- CPP_WARN("Please transition tousing list_delete_and_null")
+extern void list_delete(struct list **plist);
/*
* Delete all nodes from a list without deleting the list itself.
diff --git a/lib/lua.c b/lib/lua.c
new file mode 100644
index 0000000000..3d701a9364
--- /dev/null
+++ b/lib/lua.c
@@ -0,0 +1,130 @@
+/*
+ * This file defines the lua interface into
+ * FRRouting.
+ *
+ * Copyright (C) 2016 Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * This file is part of FreeRangeRouting (FRR).
+ *
+ * FRR 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.
+ *
+ * FRR 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 FRR; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <stdio.h>
+
+#include <zebra.h>
+
+#if defined(HAVE_LUA)
+#include "prefix.h"
+#include "lua.h"
+#include "log.h"
+
+static int lua_zlog_debug(lua_State *L)
+{
+ int debug_lua = 1;
+ const char *string = lua_tostring(L, 1);
+
+ if (debug_lua)
+ zlog_debug("%s", string);
+
+ return 0;
+}
+
+const char *get_string(lua_State *L, const char *key)
+{
+ const char *str;
+
+ lua_pushstring(L, key);
+ lua_gettable(L, -2);
+
+ str = (const char *)lua_tostring(L, -1);
+ lua_pop(L, 1);
+
+ return str;
+}
+
+int get_integer(lua_State *L, const char *key)
+{
+ int result;
+
+ lua_pushstring(L, key);
+ lua_gettable(L, -2);
+
+ result = lua_tointeger(L, -1);
+ lua_pop(L, 1);
+
+ return result;
+}
+
+static void *lua_alloc(void *ud, void *ptr, size_t osize,
+ size_t nsize)
+{
+ (void)ud; (void)osize; /* not used */
+ if (nsize == 0) {
+ free(ptr);
+ return NULL;
+ } else
+ return realloc(ptr, nsize);
+}
+
+lua_State *lua_initialize(const char *file)
+{
+ int status;
+ lua_State *L = lua_newstate(lua_alloc, NULL);
+
+ zlog_debug("Newstate: %p", L);
+ luaL_openlibs(L);
+ zlog_debug("Opened lib");
+ status = luaL_loadfile(L, file);
+ if (status) {
+ zlog_debug("Failure to open %s %d", file, status);
+ lua_close(L);
+ return NULL;
+ }
+
+ lua_pcall(L, 0, LUA_MULTRET, 0);
+ zlog_debug("Setting global function");
+ lua_pushcfunction(L, lua_zlog_debug);
+ lua_setglobal(L, "zlog_debug");
+
+ return L;
+}
+
+void lua_setup_prefix_table(lua_State *L, const struct prefix *prefix)
+{
+ char buffer[100];
+
+ lua_newtable(L);
+ lua_pushstring(L, prefix2str(prefix, buffer, 100));
+ lua_setfield(L, -2, "route");
+ lua_pushinteger(L, prefix->family);
+ lua_setfield(L, -2, "family");
+ lua_setglobal(L, "prefix");
+}
+
+enum lua_rm_status lua_run_rm_rule(lua_State *L, const char *rule)
+{
+ int status;
+
+ lua_getglobal(L, rule);
+ status = lua_pcall(L, 0, 1, 0);
+ if (status) {
+ zlog_debug("Executing Failure with function: %s: %d",
+ rule, status);
+ return LUA_RM_FAILURE;
+ }
+
+ status = lua_tonumber(L, -1);
+ return status;
+}
+#endif
diff --git a/lib/lua.h b/lib/lua.h
new file mode 100644
index 0000000000..8020a22711
--- /dev/null
+++ b/lib/lua.h
@@ -0,0 +1,79 @@
+/*
+ * This file defines the lua interface into
+ * FRRouting.
+ *
+ * Copyright (C) 2016 Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * This file is part of FreeRangeRouting (FRR).
+ *
+ * FRR 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.
+ *
+ * FRR 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 FRR; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef __LUA_H__
+#define __LUA_H__
+
+#if defined(HAVE_LUA)
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+/*
+ * These functions are helper functions that
+ * try to glom some of the lua_XXX functionality
+ * into what we actually need, instead of having
+ * to make multiple calls to set up what
+ * we want
+ */
+enum lua_rm_status {
+ /*
+ * Script function run failure. This will translate into a
+ * deny
+ */
+ LUA_RM_FAILURE = 0,
+ /*
+ * No Match was found for the route map function
+ */
+ LUA_RM_NOMATCH,
+ /*
+ * Match was found but no changes were made to the
+ * incoming data.
+ */
+ LUA_RM_MATCH,
+ /*
+ * Match was found and data was modified, so
+ * figure out what changed
+ */
+ LUA_RM_MATCH_AND_CHANGE,
+};
+
+/*
+ * Open up the lua.scr file and parse
+ * initial global values, if any.
+ */
+lua_State *lua_initialize(const char *file);
+
+void lua_setup_prefix_table(lua_State *L, const struct prefix *prefix);
+
+enum lua_rm_status lua_run_rm_rule(lua_State *L, const char *rule);
+
+/*
+ * Get particular string/integer information
+ * from a table. It is *assumed* that
+ * the table has already been selected
+ */
+const char *get_string(lua_State *L, const char *key);
+int get_integer(lua_State *L, const char *key);
+#endif
+#endif
diff --git a/lib/nexthop_group.c b/lib/nexthop_group.c
index 937b84bddd..23ea96f75c 100644
--- a/lib/nexthop_group.c
+++ b/lib/nexthop_group.c
@@ -246,7 +246,7 @@ static void nhgc_delete(struct nexthop_group_cmd *nhgc)
RB_REMOVE(nhgc_entry_head, &nhgc_entries, nhgc);
- list_delete_and_null(&nhgc->nhg_list);
+ list_delete(&nhgc->nhg_list);
XFREE(MTYPE_TMP, nhgc);
}
diff --git a/lib/openbsd-tree.c b/lib/openbsd-tree.c
index e8d13339b6..eadef9902b 100644
--- a/lib/openbsd-tree.c
+++ b/lib/openbsd-tree.c
@@ -345,7 +345,7 @@ rbe_remove(const struct rb_type *t, struct rbt_tree *rbt, struct rb_entry *rbe)
else
RBE_RIGHT(tmp) = rbe;
- rbe_if_augment(t, parent);
+ rbe_if_augment(t, tmp);
} else
RBH_ROOT(rbt) = rbe;
diff --git a/lib/routemap.c b/lib/routemap.c
index 028351f6c6..bc45cd51d0 100644
--- a/lib/routemap.c
+++ b/lib/routemap.c
@@ -111,6 +111,20 @@ struct route_map_match_set_hooks {
const char *arg,
route_map_event_t type);
+ /* match ip next hop type */
+ int (*match_ip_next_hop_type)(struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* no match ip next hop type */
+ int (*no_match_ip_next_hop_type)(struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
/* match ipv6 address */
int (*match_ipv6_address)(struct vty *vty,
struct route_map_index *index,
@@ -138,6 +152,19 @@ struct route_map_match_set_hooks {
const char *arg,
route_map_event_t type);
+ /* match ipv6 next-hop type */
+ int (*match_ipv6_next_hop_type)(struct vty *vty,
+ struct route_map_index *index,
+ const char *command,
+ const char *arg,
+ route_map_event_t type);
+
+ /* no match ipv6next-hop type */
+ int (*no_match_ipv6_next_hop_type)(struct vty *vty,
+ struct route_map_index *index,
+ const char *command, const char *arg,
+ route_map_event_t type);
+
/* match metric */
int (*match_metric)(struct vty *vty, struct route_map_index *index,
const char *command, const char *arg,
@@ -275,6 +302,22 @@ void route_map_no_match_ip_next_hop_prefix_list_hook(int (*func)(
rmap_match_set_hook.no_match_ip_next_hop_prefix_list = func;
}
+/* match ip next hop type */
+void route_map_match_ip_next_hop_type_hook(int (*func)(
+ struct vty *vty, struct route_map_index *index, const char *command,
+ const char *arg, route_map_event_t type))
+{
+ rmap_match_set_hook.match_ip_next_hop_type = func;
+}
+
+/* no match ip next hop type */
+void route_map_no_match_ip_next_hop_type_hook(int (*func)(
+ struct vty *vty, struct route_map_index *index, const char *command,
+ const char *arg, route_map_event_t type))
+{
+ rmap_match_set_hook.no_match_ip_next_hop_type = func;
+}
+
/* match ipv6 address */
void route_map_match_ipv6_address_hook(int (*func)(
struct vty *vty, struct route_map_index *index, const char *command,
@@ -308,6 +351,22 @@ void route_map_no_match_ipv6_address_prefix_list_hook(int (*func)(
rmap_match_set_hook.no_match_ipv6_address_prefix_list = func;
}
+/* match ipv6 next-hop type */
+void route_map_match_ipv6_next_hop_type_hook(int (*func)(
+ struct vty *vty, struct route_map_index *index, const char *command,
+ const char *arg, route_map_event_t type))
+{
+ rmap_match_set_hook.match_ipv6_next_hop_type = func;
+}
+
+/* no match ipv6 next-hop type */
+void route_map_no_match_ipv6_next_hop_type_hook(int (*func)(
+ struct vty *vty, struct route_map_index *index, const char *command,
+ const char *arg, route_map_event_t type))
+{
+ rmap_match_set_hook.no_match_ipv6_next_hop_type = func;
+}
+
/* match metric */
void route_map_match_metric_hook(int (*func)(
struct vty *vty, struct route_map_index *index, const char *command,
@@ -932,7 +991,7 @@ static int vty_show_route_map(struct vty *vty, const char *name)
for (ALL_LIST_ELEMENTS_RO(maplist, ln, map))
vty_show_route_map_entry(vty, map);
- list_delete_and_null(&maplist);
+ list_delete(&maplist);
}
return CMD_SUCCESS;
}
@@ -2034,6 +2093,45 @@ DEFUN (no_match_ip_next_hop_prefix_list,
return CMD_SUCCESS;
}
+DEFUN(match_ip_next_hop_type, match_ip_next_hop_type_cmd,
+ "match ip next-hop type <blackhole>",
+ MATCH_STR IP_STR
+ "Match next-hop address of route\n"
+ "Match entries by type\n"
+ "Blackhole\n")
+{
+ int idx_word = 4;
+ VTY_DECLVAR_CONTEXT(route_map_index, index);
+
+ if (rmap_match_set_hook.match_ip_next_hop_type)
+ return rmap_match_set_hook.match_ip_next_hop_type(
+ vty, index, "ip next-hop type", argv[idx_word]->arg,
+ RMAP_EVENT_MATCH_ADDED);
+ return CMD_SUCCESS;
+}
+
+DEFUN(no_match_ip_next_hop_type, no_match_ip_next_hop_type_cmd,
+ "no match ip next-hop type [<blackhole>]",
+ NO_STR MATCH_STR IP_STR
+ "Match next-hop address of route\n"
+ "Match entries by type\n"
+ "Blackhole\n")
+{
+ int idx_word = 5;
+ VTY_DECLVAR_CONTEXT(route_map_index, index);
+
+ if (rmap_match_set_hook.no_match_ip_next_hop) {
+ if (argc <= idx_word)
+ return rmap_match_set_hook.no_match_ip_next_hop(
+ vty, index, "ip next-hop type", NULL,
+ RMAP_EVENT_MATCH_DELETED);
+ return rmap_match_set_hook.no_match_ip_next_hop(
+ vty, index, "ip next-hop type", argv[idx_word]->arg,
+ RMAP_EVENT_MATCH_DELETED);
+ }
+ return CMD_SUCCESS;
+}
+
DEFUN (match_ipv6_address,
match_ipv6_address_cmd,
@@ -2112,6 +2210,39 @@ DEFUN (no_match_ipv6_address_prefix_list,
return CMD_SUCCESS;
}
+DEFUN(match_ipv6_next_hop_type, match_ipv6_next_hop_type_cmd,
+ "match ipv6 next-hop type <blackhole>",
+ MATCH_STR IPV6_STR
+ "Match address of route\n"
+ "Match entries by type\n"
+ "Blackhole\n")
+{
+ int idx_word = 4;
+ VTY_DECLVAR_CONTEXT(route_map_index, index);
+
+ if (rmap_match_set_hook.match_ipv6_next_hop_type)
+ return rmap_match_set_hook.match_ipv6_next_hop_type(
+ vty, index, "ipv6 next-hop type", argv[idx_word]->arg,
+ RMAP_EVENT_MATCH_ADDED);
+ return CMD_SUCCESS;
+}
+
+DEFUN(no_match_ipv6_next_hop_type, no_match_ipv6_next_hop_type_cmd,
+ "no match ipv6 next-hop type [<blackhole>]",
+ NO_STR MATCH_STR IPV6_STR
+ "Match address of route\n"
+ "Match entries by type\n"
+ "Blackhole\n")
+{
+ int idx_word = 5;
+ VTY_DECLVAR_CONTEXT(route_map_index, index);
+
+ if (rmap_match_set_hook.no_match_ipv6_next_hop_type)
+ return rmap_match_set_hook.no_match_ipv6_next_hop_type(
+ vty, index, "ipv6 next-hop type", argv[idx_word]->arg,
+ RMAP_EVENT_MATCH_DELETED);
+ return CMD_SUCCESS;
+}
DEFUN (match_metric,
match_metric_cmd,
@@ -2879,12 +3010,18 @@ void route_map_init(void)
install_element(RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
install_element(RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
+ install_element(RMAP_NODE, &match_ip_next_hop_type_cmd);
+ install_element(RMAP_NODE, &no_match_ip_next_hop_type_cmd);
+
install_element(RMAP_NODE, &match_ipv6_address_cmd);
install_element(RMAP_NODE, &no_match_ipv6_address_cmd);
install_element(RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
install_element(RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
+ install_element(RMAP_NODE, &match_ipv6_next_hop_type_cmd);
+ install_element(RMAP_NODE, &no_match_ipv6_next_hop_type_cmd);
+
install_element(RMAP_NODE, &match_metric_cmd);
install_element(RMAP_NODE, &no_match_metric_cmd);
diff --git a/lib/routemap.h b/lib/routemap.h
index 1914563687..481b8c4a9a 100644
--- a/lib/routemap.h
+++ b/lib/routemap.h
@@ -289,6 +289,14 @@ extern void route_map_match_ip_next_hop_prefix_list_hook(int (*func)(
extern void route_map_no_match_ip_next_hop_prefix_list_hook(int (*func)(
struct vty *vty, struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type));
+/* match ip next hop type */
+extern void route_map_match_ip_next_hop_type_hook(int (*func)(
+ struct vty *vty, struct route_map_index *index, const char *command,
+ const char *arg, route_map_event_t type));
+/* no match ip next hop type */
+extern void route_map_no_match_ip_next_hop_type_hook(int (*func)(
+ struct vty *vty, struct route_map_index *index, const char *command,
+ const char *arg, route_map_event_t type));
/* match ipv6 address */
extern void route_map_match_ipv6_address_hook(int (*func)(
struct vty *vty, struct route_map_index *index, const char *command,
@@ -305,6 +313,14 @@ extern void route_map_match_ipv6_address_prefix_list_hook(int (*func)(
extern void route_map_no_match_ipv6_address_prefix_list_hook(int (*func)(
struct vty *vty, struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type));
+/* match ipv6 next-hop type */
+extern void route_map_match_ipv6_next_hop_type_hook(int (*func)(
+ struct vty *vty, struct route_map_index *index, const char *command,
+ const char *arg, route_map_event_t type));
+/* no match ipv6 next-hop type */
+extern void route_map_no_match_ipv6_next_hop_type_hook(int (*func)(
+ struct vty *vty, struct route_map_index *index, const char *command,
+ const char *arg, route_map_event_t type));
/* match metric */
extern void route_map_match_metric_hook(int (*func)(
struct vty *vty, struct route_map_index *index, const char *command,
diff --git a/lib/subdir.am b/lib/subdir.am
index 499bb94920..dd2731f74c 100644
--- a/lib/subdir.am
+++ b/lib/subdir.am
@@ -2,7 +2,7 @@
# libfrr
#
lib_LTLIBRARIES += lib/libfrr.la
-lib_libfrr_la_LDFLAGS = -version-info 0:0:0
+lib_libfrr_la_LDFLAGS = -version-info 0:0:0 -Xlinker -e_libfrr_version
lib_libfrr_la_LIBADD = @LIBCAP@
lib_libfrr_la_SOURCES = \
@@ -82,6 +82,7 @@ lib_libfrr_la_SOURCES = \
lib/workqueue.c \
lib/zclient.c \
lib/logicalrouter.c \
+ lib/lua.c \
# end
vtysh_scan += \
@@ -190,6 +191,7 @@ pkginclude_HEADERS += \
lib/zclient.h \
lib/zebra.h \
lib/logicalrouter.h \
+ lib/lua.h \
lib/pbr.h \
# end
@@ -205,6 +207,17 @@ noinst_HEADERS += \
lib/plist_int.h \
#end
+# General note about module and module helper library (libfrrsnmp, libfrrzmq)
+# linking: If we're linking libfrr statically into daemons, we *must* remove
+# libfrr from modules because modules will always link it in dynamically and
+# thus 2 copies of libfrr will be loaded... hilarity ensues.
+#
+# Not linking libfrr into modules should generally work fine because the
+# executable refers to libfrr either way and the dynamic linker should make
+# libfrr available to modules. If some OS platform has a dynamic linker that
+# doesn't do that, libfrr needs to be readded to modules, but _only_ _if_
+# it's not linked into daemons statically.
+
#
# SNMP support
#
@@ -214,7 +227,7 @@ endif
lib_libfrrsnmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99
lib_libfrrsnmp_la_LDFLAGS = -version-info 0:0:0
-lib_libfrrsnmp_la_LIBADD = lib/libfrr.la $(SNMP_LIBS)
+lib_libfrrsnmp_la_LIBADD = $(SNMP_LIBS)
lib_libfrrsnmp_la_SOURCES = \
lib/agentx.c \
lib/snmp.c \
@@ -230,7 +243,7 @@ endif
lib_libfrrzmq_la_CFLAGS = $(WERROR) $(ZEROMQ_CFLAGS)
lib_libfrrzmq_la_LDFLAGS = -version-info 0:0:0
-lib_libfrrzmq_la_LIBADD = lib/libfrr.la $(ZEROMQ_LIBS)
+lib_libfrrzmq_la_LIBADD = $(ZEROMQ_LIBS)
lib_libfrrzmq_la_SOURCES = \
lib/frr_zmq.c \
#end
diff --git a/lib/thread.c b/lib/thread.c
index 2c3db27c7b..a81faae796 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -622,7 +622,7 @@ void thread_master_free(struct thread_master *m)
{
listnode_delete(masters, m);
if (masters->count == 0) {
- list_delete_and_null(&masters);
+ list_delete(&masters);
}
}
pthread_mutex_unlock(&masters_mtx);
@@ -637,7 +637,7 @@ void thread_master_free(struct thread_master *m)
pthread_cond_destroy(&m->cancel_cond);
close(m->io_pipe[0]);
close(m->io_pipe[1]);
- list_delete_and_null(&m->cancel_req);
+ list_delete(&m->cancel_req);
m->cancel_req = NULL;
hash_clean(m->cpu_record, cpu_record_hash_free);
diff --git a/lib/wheel.c b/lib/wheel.c
index 722b02424a..69d2fa48dc 100644
--- a/lib/wheel.c
+++ b/lib/wheel.c
@@ -115,7 +115,7 @@ void wheel_delete(struct timer_wheel *wheel)
int i;
for (i = 0; i < wheel->slots; i++) {
- list_delete_and_null(&wheel->wheel_slot_lists[i]);
+ list_delete(&wheel->wheel_slot_lists[i]);
}
THREAD_OFF(wheel->timer);
diff --git a/lib/zclient.c b/lib/zclient.c
index e6626a178b..8b1069b827 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -133,7 +133,7 @@ void redist_del_instance(struct redist_proto *red, unsigned short instance)
XFREE(MTYPE_REDIST_INST, id);
if (!red->instances->count) {
red->enabled = 0;
- list_delete_and_null(&red->instances);
+ list_delete(&red->instances);
}
}