summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_evpn.c4
-rw-r--r--bgpd/bgp_route.c3
-rw-r--r--bgpd/bgp_routemap.c128
-rwxr-xr-xconfigure.ac12
-rw-r--r--debianpkg/backports/ubuntu17.10/debian/control4
-rw-r--r--debianpkg/backports/ubuntu18.04/debian/control4
-rw-r--r--doc/developer/building-frr-for-ubuntu1604.rst4
-rw-r--r--doc/developer/building-frr-for-ubuntu1804.rst4
-rw-r--r--lib/lua.c130
-rw-r--r--lib/lua.h79
-rw-r--r--lib/openbsd-tree.c2
-rw-r--r--lib/subdir.am2
-rw-r--r--redhat/frr.spec.in2
-rw-r--r--tools/.gitignore1
-rwxr-xr-xtools/frr-reload.py102
-rw-r--r--tools/lua.scr29
16 files changed, 467 insertions, 43 deletions
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index 41aceae9f7..8002ebe1c7 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -2428,6 +2428,8 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
ri->uptime = bgp_clock();
}
+ bgp_aggregate_increment(bgp_vrf, &rn->p, ri, afi, safi);
+
/* Perform route selection and update zebra, if required. */
bgp_process(bgp_vrf, rn, afi, safi);
@@ -2597,6 +2599,8 @@ static int uninstall_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
if (!ri)
return 0;
+ bgp_aggregate_decrement(bgp_vrf, &rn->p, ri, afi, safi);
+
/* Mark entry for deletion */
bgp_info_delete(rn, ri);
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index a04ed8eef5..c508758204 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -5478,6 +5478,9 @@ static int bgp_aggregate_info_same(struct bgp_info *ri, uint8_t origin,
if (!community_cmp(ri->attr->community, comm))
return 0;
+ if (!CHECK_FLAG(ri->flags, BGP_INFO_VALID))
+ return 0;
+
return 1;
}
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index 0b4355805c..8e7c0a69dd 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -28,6 +28,7 @@
#include "plist.h"
#include "memory.h"
#include "log.h"
+#include "lua.h"
#ifdef HAVE_LIBPCREPOSIX
#include <pcreposix.h>
#else
@@ -330,6 +331,102 @@ struct route_map_rule_cmd route_match_peer_cmd = {"peer", route_match_peer,
route_match_peer_compile,
route_match_peer_free};
+#if defined(HAVE_LUA)
+static route_map_result_t route_match_command(void *rule,
+ const struct prefix *prefix,
+ route_map_object_t type,
+ void *object)
+{
+ int status = RMAP_NOMATCH;
+ u_int32_t locpref = 0;
+ u_int32_t newlocpref = 0;
+ enum lua_rm_status lrm_status;
+ struct bgp_info *info = (struct bgp_info *)object;
+ lua_State *L = lua_initialize("/etc/frr/lua.scr");
+
+ if (L == NULL)
+ return status;
+
+ /*
+ * Setup the prefix information to pass in
+ */
+ lua_setup_prefix_table(L, prefix);
+
+ zlog_debug("Set up prefix table");
+ /*
+ * Setup the bgp_info information
+ */
+ lua_newtable(L);
+ lua_pushinteger(L, info->attr->med);
+ lua_setfield(L, -2, "metric");
+ lua_pushinteger(L, info->attr->nh_ifindex);
+ lua_setfield(L, -2, "ifindex");
+ lua_pushstring(L, info->attr->aspath->str);
+ lua_setfield(L, -2, "aspath");
+ lua_pushinteger(L, info->attr->local_pref);
+ lua_setfield(L, -2, "localpref");
+ zlog_debug("%s %d", info->attr->aspath->str, info->attr->nh_ifindex);
+ lua_setglobal(L, "nexthop");
+
+ zlog_debug("Set up nexthop information");
+ /*
+ * Run the rule
+ */
+ lrm_status = lua_run_rm_rule(L, rule);
+ switch (lrm_status) {
+ case LUA_RM_FAILURE:
+ zlog_debug("RM_FAILURE");
+ break;
+ case LUA_RM_NOMATCH:
+ zlog_debug("RM_NOMATCH");
+ break;
+ case LUA_RM_MATCH_AND_CHANGE:
+ zlog_debug("MATCH AND CHANGE");
+ lua_getglobal(L, "nexthop");
+ info->attr->med = get_integer(L, "metric");
+ /*
+ * This needs to be abstraced with the set function
+ */
+ if (info->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
+ locpref = info->attr->local_pref;
+ newlocpref = get_integer(L, "localpref");
+ if (newlocpref != locpref) {
+ info->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
+ info->attr->local_pref = newlocpref;
+ }
+ status = RMAP_MATCH;
+ break;
+ case LUA_RM_MATCH:
+ zlog_debug("MATCH ONLY");
+ status = RMAP_MATCH;
+ break;
+ }
+ lua_close(L);
+ return status;
+}
+
+static void *route_match_command_compile(const char *arg)
+{
+ char *command;
+
+ command = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
+ return command;
+}
+
+static void
+route_match_command_free(void *rule)
+{
+ XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+struct route_map_rule_cmd route_match_command_cmd = {
+ "command",
+ route_match_command,
+ route_match_command_compile,
+ route_match_command_free
+};
+#endif
+
/* `match ip address IP_ACCESS_LIST' */
/* Match function should return 1 if match is success else return
@@ -3356,6 +3453,30 @@ DEFUN (no_match_peer,
RMAP_EVENT_MATCH_DELETED);
}
+#if defined(HAVE_LUA)
+DEFUN (match_command,
+ match_command_cmd,
+ "match command WORD",
+ MATCH_STR
+ "Run a command to match\n"
+ "The command to run\n")
+{
+ return bgp_route_match_add(vty, "command", argv[2]->arg,
+ RMAP_EVENT_FILTER_ADDED);
+}
+
+DEFUN (no_match_command,
+ no_match_command_cmd,
+ "no match command WORD",
+ NO_STR
+ MATCH_STR
+ "Run a command to match\n"
+ "The command to run\n")
+{
+ return bgp_route_match_delete(vty, "command", argv[3]->arg,
+ RMAP_EVENT_FILTER_DELETED);
+}
+#endif
/* match probability */
DEFUN (match_probability,
@@ -4671,6 +4792,9 @@ void bgp_route_map_init(void)
route_map_install_match(&route_match_peer_cmd);
route_map_install_match(&route_match_local_pref_cmd);
+#if defined(HAVE_LUA)
+ route_map_install_match(&route_match_command_cmd);
+#endif
route_map_install_match(&route_match_ip_address_cmd);
route_map_install_match(&route_match_ip_next_hop_cmd);
route_map_install_match(&route_match_ip_route_source_cmd);
@@ -4804,6 +4928,10 @@ void bgp_route_map_init(void)
install_element(RMAP_NODE, &no_set_ipv6_nexthop_prefer_global_cmd);
install_element(RMAP_NODE, &set_ipv6_nexthop_peer_cmd);
install_element(RMAP_NODE, &no_set_ipv6_nexthop_peer_cmd);
+#if defined(HAVE_LUA)
+ install_element(RMAP_NODE, &match_command_cmd);
+ install_element(RMAP_NODE, &no_match_command_cmd);
+#endif
}
void bgp_route_map_terminate(void)
diff --git a/configure.ac b/configure.ac
index 3d17293a94..4d18c7997a 100755
--- a/configure.ac
+++ b/configure.ac
@@ -203,7 +203,15 @@ elif test "x${enable_dev_build}" = "xyes"; then
AC_C_FLAG([-g3])
AC_C_FLAG([-O0])
fi
+ if test "x${enable_lua}" = "xyes"; then
+ AC_CHECK_LIB([lua], [lua_newstate],
+ [LIBS="$LIBS -llua"])
+ AC_DEFINE(HAVE_LUA,,Lua enabled for development)
+ fi
else
+ if test "x${enable_lua}" = "xyes"; then
+ AC_MSG_ERROR([Lua is not meant to be built/used outside of development at this time])
+ fi
if test "z$orig_cflags" = "z"; then
AC_C_FLAG([-g])
AC_C_FLAG([-Os], [
@@ -454,6 +462,9 @@ fi
AC_ARG_ENABLE([dev_build],
AS_HELP_STRING([--enable-dev-build], [build for development]))
+AC_ARG_ENABLE([lua],
+ AS_HELP_STRING([--enable-lua], [Build Lua scripting]))
+
if test x"${enable_time_check}" != x"no" ; then
if test x"${enable_time_check}" = x"yes" -o x"${enable_time_check}" = x ; then
AC_DEFINE(CONSUMED_TIME_CHECK,5000000,Consumed Time Check)
@@ -1126,6 +1137,7 @@ if test x"$LIBM" = x ; then
AC_MSG_WARN([Unable to find working pow function - bgpd may not link])
fi
LIBS="$TMPLIBS"
+
AC_SUBST(LIBM)
AC_CHECK_FUNCS([ppoll], [
diff --git a/debianpkg/backports/ubuntu17.10/debian/control b/debianpkg/backports/ubuntu17.10/debian/control
index 1bc3c4e4b5..ce73f9d1b0 100644
--- a/debianpkg/backports/ubuntu17.10/debian/control
+++ b/debianpkg/backports/ubuntu17.10/debian/control
@@ -4,7 +4,7 @@ Priority: optional
Maintainer: Nobody <nobody@frrouting.org>
Uploaders: Nobody <nobody@frrouting.org>
XSBC-Original-Maintainer: <maintainers@frrouting.org>
-Build-Depends: debhelper (>= 7.0.50~), libncurses5-dev, libreadline-dev, texlive-latex-base, texlive-generic-recommended, libpam0g-dev | libpam-dev, libcap-dev, texinfo (>= 4.7), imagemagick, ghostscript, groff, autotools-dev, libpcre3-dev, gawk, chrpath, libsnmp-dev, git, dh-autoreconf, libjson-c-dev, libjson-c2 | libjson-c3, dh-systemd, libsystemd-dev, bison, flex, libc-ares-dev, pkg-config, python (>= 2.7), python-ipaddr, libpython-dev
+Build-Depends: debhelper (>= 7.0.50~), libncurses5-dev, libreadline-dev, texlive-latex-base, texlive-generic-recommended, libpam0g-dev | libpam-dev, libcap-dev, texinfo (>= 4.7), imagemagick, ghostscript, groff, autotools-dev, libpcre3-dev, gawk, chrpath, libsnmp-dev, git, dh-autoreconf, libjson-c-dev, libjson-c2 | libjson-c3, dh-systemd, libsystemd-dev, bison, flex, libc-ares-dev, pkg-config, python (>= 2.7), python-ipaddress, libpython-dev
Standards-Version: 3.9.6
Homepage: http://www.frrouting.org/
@@ -47,7 +47,7 @@ Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon (documentation)
Package: frr-pythontools
Section: net
Architecture: all
-Depends: ${misc:Depends}, frr (= ${binary:Version}), python (>= 2.7), python-ipaddr
+Depends: ${misc:Depends}, frr (= ${binary:Version}), python (>= 2.7), python-ipaddress
Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon (Python Tools)
This package includes info files for frr, a free software which manages
TCP/IP based routing protocols. It supports BGP4, BGP4+, OSPFv2, OSPFv3,
diff --git a/debianpkg/backports/ubuntu18.04/debian/control b/debianpkg/backports/ubuntu18.04/debian/control
index 1e31ad6d51..3fccb46b7a 100644
--- a/debianpkg/backports/ubuntu18.04/debian/control
+++ b/debianpkg/backports/ubuntu18.04/debian/control
@@ -4,7 +4,7 @@ Priority: optional
Maintainer: Nobody <nobody@frrouting.org>
Uploaders: Nobody <nobody@frrouting.org>
XSBC-Original-Maintainer: <maintainers@frrouting.org>
-Build-Depends: debhelper (>= 7.0.50~), libncurses5-dev, libreadline-dev, texlive-latex-base, texlive-generic-recommended, libpam0g-dev | libpam-dev, libcap-dev, texinfo (>= 4.7), imagemagick, ghostscript, groff, autotools-dev, libpcre3-dev, gawk, chrpath, libsnmp-dev, git, dh-autoreconf, libjson-c-dev, libjson-c2 | libjson-c3, dh-systemd, libsystemd-dev, bison, flex, libc-ares-dev, pkg-config, python (>= 2.7), python-ipaddr, python-sphinx, libpython-dev
+Build-Depends: debhelper (>= 7.0.50~), libncurses5-dev, libreadline-dev, texlive-latex-base, texlive-generic-recommended, libpam0g-dev | libpam-dev, libcap-dev, texinfo (>= 4.7), imagemagick, ghostscript, groff, autotools-dev, libpcre3-dev, gawk, chrpath, libsnmp-dev, git, dh-autoreconf, libjson-c-dev, libjson-c2 | libjson-c3, dh-systemd, libsystemd-dev, bison, flex, libc-ares-dev, pkg-config, python (>= 2.7), python-ipaddress, python-sphinx, libpython-dev
Standards-Version: 3.9.6
Homepage: http://www.frrouting.org/
@@ -47,7 +47,7 @@ Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon (documentation)
Package: frr-pythontools
Section: net
Architecture: all
-Depends: ${misc:Depends}, frr (= ${binary:Version}), python (>= 2.7), python-ipaddr
+Depends: ${misc:Depends}, frr (= ${binary:Version}), python (>= 2.7), python-ipaddress
Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon (Python Tools)
This package includes info files for frr, a free software which manages
TCP/IP based routing protocols. It supports BGP4, BGP4+, OSPFv2, OSPFv3,
diff --git a/doc/developer/building-frr-for-ubuntu1604.rst b/doc/developer/building-frr-for-ubuntu1604.rst
index 69c4e44d98..1fa0ede201 100644
--- a/doc/developer/building-frr-for-ubuntu1604.rst
+++ b/doc/developer/building-frr-for-ubuntu1604.rst
@@ -16,8 +16,8 @@ Add packages:
apt-get install \
git autoconf automake libtool make gawk libreadline-dev texinfo dejagnu \
pkg-config libpam0g-dev libjson-c-dev bison flex python-pytest \
- libc-ares-dev python3-dev libsystemd-dev python-ipaddr python3-sphinx \
- install-info
+ libc-ares-dev python3-dev libsystemd-dev python-ipaddress \
+ python3-sphinx install-info
Get FRR, compile it and install it (from Git)
---------------------------------------------
diff --git a/doc/developer/building-frr-for-ubuntu1804.rst b/doc/developer/building-frr-for-ubuntu1804.rst
index 50e90fc7ea..75b31a41f9 100644
--- a/doc/developer/building-frr-for-ubuntu1804.rst
+++ b/doc/developer/building-frr-for-ubuntu1804.rst
@@ -12,8 +12,8 @@ Required packages
sudo apt-get install \
git autoconf automake libtool make gawk libreadline-dev texinfo \
pkg-config libpam0g-dev libjson-c-dev bison flex python-pytest \
- libc-ares-dev python3-dev libsystemd-dev python-ipaddr python3-sphinx \
- install-info
+ libc-ares-dev python3-dev libsystemd-dev python-ipaddress \
+ python3-sphinx install-info
Optional packages
^^^^^^^^^^^^^^^^^
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/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/subdir.am b/lib/subdir.am
index 499bb94920..6dc2fc529e 100644
--- a/lib/subdir.am
+++ b/lib/subdir.am
@@ -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
diff --git a/redhat/frr.spec.in b/redhat/frr.spec.in
index bff0b40515..1395af5dfb 100644
--- a/redhat/frr.spec.in
+++ b/redhat/frr.spec.in
@@ -216,7 +216,7 @@ Contributed/3rd party tools which may be of use with frr.
%package pythontools
Summary: python tools for frr
BuildRequires: python
-Requires: python-ipaddr
+Requires: python-ipaddress
Group: System Environment/Daemons
%description pythontools
diff --git a/tools/.gitignore b/tools/.gitignore
index d400dfe8fa..a8d01d680e 100644
--- a/tools/.gitignore
+++ b/tools/.gitignore
@@ -1,2 +1,3 @@
+/frr
/permutations
/ssd
diff --git a/tools/frr-reload.py b/tools/frr-reload.py
index 9d1af27d6c..3b41b57d68 100755
--- a/tools/frr-reload.py
+++ b/tools/frr-reload.py
@@ -28,6 +28,7 @@ This program
text file
"""
+from __future__ import print_function, unicode_literals
import argparse
import copy
import logging
@@ -38,9 +39,22 @@ import string
import subprocess
import sys
from collections import OrderedDict
-from ipaddr import IPv6Address, IPNetwork
+try:
+ from ipaddress import IPv6Address, ip_network
+except ImportError:
+ from ipaddr import IPv6Address, IPNetwork
from pprint import pformat
+try:
+ dict.iteritems
+except AttributeError:
+ # Python 3
+ def iteritems(d):
+ return iter(d.items())
+else:
+ # Python 2
+ def iteritems(d):
+ return d.iteritems()
log = logging.getLogger(__name__)
@@ -116,7 +130,7 @@ class Config(object):
ve.output = e.output
raise ve
- for line in file_output.split('\n'):
+ for line in file_output.decode('utf-8').split('\n'):
line = line.strip()
# Compress duplicate whitespaces
@@ -147,7 +161,7 @@ class Config(object):
ve.output = e.output
raise ve
- for line in config_text.split('\n'):
+ for line in config_text.decode('utf-8').split('\n'):
line = line.strip()
if (line == 'Building configuration...' or
@@ -171,8 +185,8 @@ class Config(object):
Return the parsed context as strings for display, log etc.
"""
- for (_, ctx) in sorted(self.contexts.iteritems()):
- print str(ctx) + '\n'
+ for (_, ctx) in sorted(iteritems(self.contexts)):
+ print(str(ctx) + '\n')
def save_contexts(self, key, lines):
"""
@@ -195,11 +209,18 @@ class Config(object):
addr = re_key_rt.group(2)
if '/' in addr:
try:
- newaddr = IPNetwork(addr)
- key[0] = '%s route %s/%s%s' % (re_key_rt.group(1),
- newaddr.network,
- newaddr.prefixlen,
- re_key_rt.group(3))
+ if 'ipaddress' not in sys.modules:
+ newaddr = IPNetwork(addr)
+ key[0] = '%s route %s/%s%s' % (re_key_rt.group(1),
+ newaddr.network,
+ newaddr.prefixlen,
+ re_key_rt.group(3))
+ else:
+ newaddr = ip_network(addr, strict=False)
+ key[0] = '%s route %s/%s%s' % (re_key_rt.group(1),
+ str(newaddr.network_address),
+ newaddr.prefixlen,
+ re_key_rt.group(3))
except ValueError:
pass
@@ -211,8 +232,13 @@ class Config(object):
addr = re_key_rt.group(4)
if '/' in addr:
try:
- newaddr = '%s/%s' % (IPNetwork(addr).network,
- IPNetwork(addr).prefixlen)
+ if 'ipaddress' not in sys.modules:
+ newaddr = '%s/%s' % (IPNetwork(addr).network,
+ IPNetwork(addr).prefixlen)
+ else:
+ network_addr = ip_network(addr, strict=False)
+ newaddr = '%s/%s' % (str(network_addr.network_address),
+ network_addr.prefixlen)
except ValueError:
newaddr = addr
else:
@@ -253,10 +279,16 @@ class Config(object):
addr = addr + '/8'
try:
- newaddr = IPNetwork(addr)
- line = 'network %s/%s %s' % (newaddr.network,
- newaddr.prefixlen,
- re_net.group(2))
+ if 'ipaddress' not in sys.modules:
+ newaddr = IPNetwork(addr)
+ line = 'network %s/%s %s' % (newaddr.network,
+ newaddr.prefixlen,
+ re_net.group(2))
+ else:
+ network_addr = ip_network(addr, strict=False)
+ line = 'network %s/%s %s' % (str(network_addr.network_address),
+ network_addr.prefixlen,
+ re_net.group(2))
newlines.append(line)
except ValueError:
# Really this should be an error. Whats a network
@@ -598,8 +630,12 @@ def get_normalized_ipv6_line(line):
norm_word = None
if "/" in word:
try:
- v6word = IPNetwork(word)
- norm_word = '%s/%s' % (v6word.network, v6word.prefixlen)
+ if 'ipaddress' not in sys.modules:
+ v6word = IPNetwork(word)
+ norm_word = '%s/%s' % (v6word.network, v6word.prefixlen)
+ else:
+ v6word = ip_network(word, strict=False)
+ norm_word = '%s/%s' % (str(v6word.network_address), v6word.prefixlen)
except ValueError:
pass
if not norm_word:
@@ -926,7 +962,7 @@ def compare_context_objects(newconf, running):
# Find contexts that are in newconf but not in running
# Find contexts that are in running but not in newconf
- for (running_ctx_keys, running_ctx) in running.contexts.iteritems():
+ for (running_ctx_keys, running_ctx) in iteritems(running.contexts):
if running_ctx_keys not in newconf.contexts:
@@ -977,7 +1013,7 @@ def compare_context_objects(newconf, running):
# Find the lines within each context to add
# Find the lines within each context to del
- for (newconf_ctx_keys, newconf_ctx) in newconf.contexts.iteritems():
+ for (newconf_ctx_keys, newconf_ctx) in iteritems(newconf.contexts):
if newconf_ctx_keys in running.contexts:
running_ctx = running.contexts[newconf_ctx_keys]
@@ -990,7 +1026,7 @@ def compare_context_objects(newconf, running):
if line not in newconf_ctx.dlines:
lines_to_del.append((newconf_ctx_keys, line))
- for (newconf_ctx_keys, newconf_ctx) in newconf.contexts.iteritems():
+ for (newconf_ctx_keys, newconf_ctx) in iteritems(newconf.contexts):
if newconf_ctx_keys not in running.contexts:
lines_to_add.append((newconf_ctx_keys, None))
@@ -1016,14 +1052,14 @@ def vtysh_config_available():
cmd = ['/usr/bin/vtysh', '-c', 'conf t']
output = subprocess.check_output(cmd, stderr=subprocess.STDOUT).strip()
- if 'VTY configuration is locked by other VTY' in output:
- print output
+ if 'VTY configuration is locked by other VTY' in output.decode('utf-8'):
+ print(output)
log.error("'%s' returned\n%s\n" % (' '.join(cmd), output))
return False
except subprocess.CalledProcessError as e:
msg = "vtysh could not connect with any frr daemons"
- print msg
+ print(msg)
log.error(msg)
return False
@@ -1070,13 +1106,13 @@ if __name__ == '__main__':
# Verify the new config file is valid
if not os.path.isfile(args.filename):
msg = "Filename %s does not exist" % args.filename
- print msg
+ print(msg)
log.error(msg)
sys.exit(1)
if not os.path.getsize(args.filename):
msg = "Filename %s is an empty file" % args.filename
- print msg
+ print(msg)
log.error(msg)
sys.exit(1)
@@ -1095,7 +1131,7 @@ if __name__ == '__main__':
if not service_integrated_vtysh_config:
msg = "'service integrated-vtysh-config' is not configured, this is required for 'service frr reload'"
- print msg
+ print(msg)
log.error(msg)
sys.exit(1)
@@ -1123,8 +1159,8 @@ if __name__ == '__main__':
lines_to_configure = []
if lines_to_del:
- print "\nLines To Delete"
- print "==============="
+ print("\nLines To Delete")
+ print("===============")
for (ctx_keys, line) in lines_to_del:
@@ -1133,11 +1169,11 @@ if __name__ == '__main__':
cmd = line_for_vtysh_file(ctx_keys, line, True)
lines_to_configure.append(cmd)
- print cmd
+ print(cmd)
if lines_to_add:
- print "\nLines To Add"
- print "============"
+ print("\nLines To Add")
+ print("============")
for (ctx_keys, line) in lines_to_add:
@@ -1146,7 +1182,7 @@ if __name__ == '__main__':
cmd = line_for_vtysh_file(ctx_keys, line, False)
lines_to_configure.append(cmd)
- print cmd
+ print(cmd)
elif args.reload:
diff --git a/tools/lua.scr b/tools/lua.scr
new file mode 100644
index 0000000000..db6bf7d36b
--- /dev/null
+++ b/tools/lua.scr
@@ -0,0 +1,29 @@
+-- Route map functionality
+--
+-- There are no parameters passed in.
+-- Currently we set two global tables
+-- prefix
+-- .family = The v4 or v6 family we are working in
+-- .route = the A.B.C.D/X or Z:A:B::D/X string
+-- nexthop
+-- .metric = The metric we are going to use
+-- .ifindex = The outgoing interface
+-- .aspath = The aspath of the route
+-- .localpref = The localpref value
+--
+-- Valid Return Codes:
+-- 0 - Some sort of processing failure
+-- This turns into a implicit DENY
+-- 1 - No match was found, turns into a DENY
+-- 2 - Match found, turns into a PERMIT
+-- 3 - Match found and data structures changed, turns into a PERMIT
+-- and a reread of the prefix and nexthop tables
+function mooey ()
+ zlog_debug(string.format("Family: %d: %s %d ifindex: %d aspath: %s localpref: %d",
+ prefix.family, prefix.route,
+ nexthop.metric, nexthop.ifindex, nexthop.aspath, nexthop.localpref))
+
+ nexthop.metric = 33
+ nexthop.localpref = 13
+ return 3
+end