summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--COMMUNITY.md1
-rw-r--r--Makefile.am1
-rw-r--r--README4
-rwxr-xr-xREADME.NetBSD46
-rw-r--r--REPORTING-BUGS35
-rw-r--r--bgpd/bgp_evpn.c6
-rw-r--r--bgpd/bgp_evpn_vty.c53
-rw-r--r--bgpd/bgp_fsm.c21
-rw-r--r--bgpd/bgp_io.c2
-rw-r--r--bgpd/bgp_main.c2
-rw-r--r--bgpd/bgp_route.c42
-rw-r--r--bgpd/bgp_snmp.c42
-rw-r--r--bgpd/bgp_updgrp_packet.c3
-rw-r--r--bgpd/bgp_vty.c26
-rw-r--r--bgpd/bgp_zebra.c24
-rw-r--r--bgpd/bgpd.c39
-rw-r--r--bgpd/bgpd.h1
-rwxr-xr-xconfigure.ac9
-rw-r--r--debianpkg/README.deb_build.md127
-rw-r--r--debianpkg/backports/ubuntu14.04/debian/frr.postinst2
-rw-r--r--debianpkg/frr-doc.docs1
-rw-r--r--debianpkg/frr.postinst2
-rw-r--r--doc/Makefile.am2
-rw-r--r--doc/developer/.gitignore2
-rw-r--r--doc/developer/Makefile1
-rw-r--r--doc/developer/Makefile.in8
-rw-r--r--doc/developer/building.rst2
-rw-r--r--doc/developer/conf.py10
-rw-r--r--doc/developer/index.rst1
-rw-r--r--doc/developer/packaging-debian.rst173
-rw-r--r--doc/developer/packaging.rst8
-rw-r--r--doc/frr-sphinx.mk9
-rw-r--r--doc/manpages/.gitignore2
-rw-r--r--doc/manpages/Makefile.in (renamed from doc/manpages/Makefile)9
-rw-r--r--doc/user/.gitignore2
-rw-r--r--doc/user/Makefile.in (renamed from doc/user/Makefile)9
-rw-r--r--doc/user/basic.rst19
-rw-r--r--doc/user/bugs.rst67
-rw-r--r--doc/user/conf.py10
-rw-r--r--doc/user/index.rst1
-rw-r--r--doc/user/pbr.rst2
-rw-r--r--lib/command.c228
-rw-r--r--lib/command.h2
-rw-r--r--lib/ipaddr.h10
-rw-r--r--lib/zclient.c14
-rw-r--r--lib/zclient.h4
-rw-r--r--ospfd/ospf_interface.c12
-rw-r--r--pbrd/pbr_vty.c4
-rw-r--r--pimd/COMMANDS1
-rw-r--r--pimd/pim_cmd.c98
-rw-r--r--pimd/pim_igmp.c23
-rw-r--r--pimd/pim_igmp.h3
-rw-r--r--pimd/pim_igmp_mtrace.c6
-rw-r--r--pimd/pim_igmp_stats.c42
-rw-r--r--pimd/pim_igmp_stats.h41
-rw-r--r--pimd/pim_igmpv2.c6
-rw-r--r--pimd/pim_igmpv3.c3
-rw-r--r--pimd/subdir.am2
-rw-r--r--redhat/frr.spec.in2
-rw-r--r--vtysh/vtysh.c14
-rw-r--r--zebra/connected.c4
-rw-r--r--zebra/if_netlink.c41
-rw-r--r--zebra/interface.c13
-rw-r--r--zebra/kernel_netlink.c2
-rw-r--r--zebra/kernel_netlink.h1
-rw-r--r--zebra/kernel_socket.c8
-rw-r--r--zebra/redistribute.c2
-rw-r--r--zebra/rib.h3
-rw-r--r--zebra/rt_netlink.c12
-rw-r--r--zebra/zapi_msg.c11
-rw-r--r--zebra/zebra_ptm.c6
-rw-r--r--zebra/zebra_rib.c5
-rw-r--r--zebra/zebra_vty.c12
-rw-r--r--zebra/zebra_vxlan.c79
-rw-r--r--zebra/zebra_vxlan.h1
75 files changed, 1044 insertions, 497 deletions
diff --git a/COMMUNITY.md b/COMMUNITY.md
deleted file mode 100644
index fa00310851..0000000000
--- a/COMMUNITY.md
+++ /dev/null
@@ -1 +0,0 @@
-Moved to doc/developer/workflow.rst
diff --git a/Makefile.am b/Makefile.am
index 6cac1a7ba3..3b8deb5884 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -83,7 +83,6 @@ rc_SCRIPTS = \
endif
EXTRA_DIST += \
- REPORTING-BUGS \
SERVICES \
aclocal.m4 \
update-autotools \
diff --git a/README b/README
index af14795a6a..95ed0d3fc2 100644
--- a/README
+++ b/README
@@ -5,9 +5,9 @@ Currently FRRouting supports BGP4, BGP4+, OSPFv2, OSPFv3, RIPv1, RIPv2, RIPng,
IS-IS, PIM-SM/MSDP, LDP and Babel as well as very early support for EIGRP and
NHRP.
-See the file REPORTING-BUGS to report bugs.
+See doc/user/bugs.rst for information on how to report bugs.
-See COMMUNITY.md for information on contributing.
+See doc/developer/workflow.rst for information on contributing.
Free RRRouting is free software. See the file COPYING for copying conditions.
diff --git a/README.NetBSD b/README.NetBSD
deleted file mode 100755
index c97e3bcb38..0000000000
--- a/README.NetBSD
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/sh
-
-# This file is helpful for building FRR from cvs on NetBSD, and
-# probably on any system using pkgsrc.
-# One should have readline installed already (pkgsrc/devel/readline).
-
-MAKE=make
-# FRR is currently documented not to require GNU make, but sometimes
-# BSD make fails. Enable this if statement as a workaround.
-if false; then
- MAKE=gmake
- echo "WARNING: using gmake to work around nonportable makefiles"
-fi
-
-# Use /usr/frr to be independent, and /usr/pkg to overwrite pkgsrc.
-PREFIX=/usr/pkg
-
-case $1 in
-
- build)
- # Omitted because it is now default:
- # --enable-opaque-lsa
- ./bootstrap.sh
- LDFLAGS="-L/usr/pkg/lib -R/usr/pkg/lib" CPPFLAGS="-I/usr/pkg/include" \
- ./configure --prefix=${PREFIX} \
- --sysconfdir=/etc/zebra --localstatedir=/var/run/zebra \
- --enable-exampledir=${PREFIX}/share/examples/zebra \
- --enable-pkgsrcrcdir=${PREFIX}/etc/rc.d \
- --enable-vtysh
- ${MAKE}
- ;;
-
- install)
- ${MAKE} install
- ;;
-
- clean)
- ${MAKE} clean
- ;;
-
- *)
- echo "Usage: README.NetBSD (build|install|clean)"
- exit 1
- ;;
-
-esac
diff --git a/REPORTING-BUGS b/REPORTING-BUGS
deleted file mode 100644
index 339ebc24d5..0000000000
--- a/REPORTING-BUGS
+++ /dev/null
@@ -1,35 +0,0 @@
-This file describes the procedure for reporting FRRouting bugs. You are not
-obliged to follow this format, but it would be great help for FRRouting developers
-if you report a bug as described below.
-
-Bugs submitted with woefully incomplete information may be summarily
-closed. Submitters of bugs against old versions may be asked to
-retest against the latest release. Submitters may be asked for
-additional information. Bugs may be closed after 30 days of
-non-response to requests to reconfirm or supply additional
-information.
-
-Report bugs on Github Issue Tracker at
- https://github.com/frrouting/frr/issues
-
-Please supply the following information:
-1. Your FRRouting version or if it is from git then the commit reference.
- Please try to report bugs against git master or the latest release.
-2. FRR daemons you run e.g. bgpd or ripd and full name of your OS. Any
- specific options you compiled FRR with.
-3. Problem description. Copy and paste relative commands and their output to
- describe your network setup e.g. "zebra>show ip route".
- Please, also give your simple network layout and output of relative OS
- commands (e.g., ifconfig (BSD) or ip (Linux)).
-4. All FRR configuration files you use. If you don't want to publish your
- network numbers change 2 middle bytes in IPv4 address to be XXX (e.g.
- 192.XXX.XXX.32/24). Similar could be done with IPv6.
-5. If any FRR daemon core dumped, please, supply stack trace using the
- following commands: host> gdb exec_file core_file , (gdb) bt .
-6. Run all FRR daemons with full debugging on (see documentation on
- debugging) and send _only_ part of logs which are relative to your problem.
-7. If the problem is difficult to reproduce please send a shell script to
- reproduce it.
-8. Patches, workarounds, fixes are always welcome.
-
-Thank You.
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index a0cd9edb0e..ee53beb191 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -4428,8 +4428,10 @@ int bgp_evpn_local_vni_del(struct bgp *bgp, vni_t vni)
/* Locate VNI hash */
vpn = bgp_evpn_lookup_vni(bgp, vni);
if (!vpn) {
- zlog_warn("%u: VNI hash entry for VNI %u not found at DEL",
- bgp->vrf_id, vni);
+ if (bgp_debug_zebra(NULL))
+ zlog_warn(
+ "%u: VNI hash entry for VNI %u not found at DEL",
+ bgp->vrf_id, vni);
return 0;
}
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index c74a1bfb7c..fd3c229472 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -311,7 +311,7 @@ static void bgp_evpn_show_route_rd_header(struct vty *vty,
}
static void bgp_evpn_show_route_header(struct vty *vty, struct bgp *bgp,
- json_object *json)
+ uint64_t tbl_ver, json_object *json)
{
char ri_header[] =
" Network Next Hop Metric LocPrf Weight Path\n";
@@ -319,9 +319,8 @@ static void bgp_evpn_show_route_header(struct vty *vty, struct bgp *bgp,
if (json)
return;
-
- vty_out(vty, "BGP table version is 0, local router ID is %s\n",
- inet_ntoa(bgp->router_id));
+ vty_out(vty, "BGP table version is %" PRIu64 ", local router ID is %s\n",
+ tbl_ver, inet_ntoa(bgp->router_id));
vty_out(vty,
"Status codes: s suppressed, d damped, h history, "
"* valid, > best, i - internal\n");
@@ -494,12 +493,16 @@ static void show_vni_routes(struct bgp *bgp, struct bgpevpn *vpn, int type,
{
struct bgp_node *rn;
struct bgp_info *ri;
+ struct bgp_table *table;
int header = 1;
+ uint64_t tbl_ver;
uint32_t prefix_cnt, path_cnt;
prefix_cnt = path_cnt = 0;
- for (rn = bgp_table_top(vpn->route_table); rn;
+ table = vpn->route_table;
+ tbl_ver = table->version;
+ for (rn = bgp_table_top(table); rn;
rn = bgp_route_next(rn)) {
struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
int add_prefix_to_json = 0;
@@ -519,7 +522,8 @@ static void show_vni_routes(struct bgp *bgp, struct bgpevpn *vpn, int type,
if (rn->info) {
/* Overall header/legend displayed once. */
if (header) {
- bgp_evpn_show_route_header(vty, bgp, json);
+ bgp_evpn_show_route_header(vty, bgp,
+ tbl_ver, json);
header = 0;
}
@@ -603,9 +607,9 @@ static void show_vni_routes_hash(struct hash_backet *backet, void *arg)
static void show_l3vni_entry(struct vty *vty, struct bgp *bgp,
json_object *json)
{
- json_object *json_vni;
- json_object *json_import_rtl;
- json_object *json_export_rtl;
+ json_object *json_vni = NULL;
+ json_object *json_import_rtl = NULL;
+ json_object *json_export_rtl = NULL;
char buf1[10];
char buf2[INET6_ADDRSTRLEN];
char rt_buf[25];
@@ -862,6 +866,8 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
for (rn = bgp_table_top(bgp->rib[afi][SAFI_EVPN]); rn;
rn = bgp_route_next(rn)) {
+ uint64_t tbl_ver;
+
if (use_json)
continue; /* XXX json TODO */
@@ -872,6 +878,7 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
continue;
rd_header = 1;
+ tbl_ver = table->version;
for (rm = bgp_table_top(table); rm; rm = bgp_route_next(rm))
for (ri = rm->info; ri; ri = ri->next) {
@@ -891,7 +898,7 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
json_object_int_add(
json,
"bgpTableVersion",
- 0);
+ tbl_ver);
json_object_string_add(
json,
"bgpLocalRouterId",
@@ -917,7 +924,8 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
V4_HEADER_OVERLAY);
else {
vty_out(vty,
- "BGP table version is 0, local router ID is %s\n",
+ "BGP table version is %" PRIu64 ", local router ID is %s\n",
+ tbl_ver,
inet_ntoa(
bgp->router_id));
vty_out(vty,
@@ -2201,11 +2209,13 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
char rd_str[RD_ADDRSTRLEN];
json_object *json_rd = NULL; /* contains routes for an RD */
int add_rd_to_json = 0;
+ uint64_t tbl_ver;
table = (struct bgp_table *)rd_rn->info;
if (table == NULL)
continue;
+ tbl_ver = table->version;
prefix_rd2str((struct prefix_rd *)&rd_rn->p, rd_str,
sizeof(rd_str));
@@ -2236,6 +2246,7 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
/* Overall header/legend displayed once. */
if (header) {
bgp_evpn_show_route_header(vty, bgp,
+ tbl_ver,
json);
header = 0;
}
@@ -2873,7 +2884,7 @@ DEFUN (no_bgp_evpn_advertise_type5,
if (CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST)) {
bgp_evpn_withdraw_type5_routes(bgp_vrf, afi, safi);
- UNSET_FLAG(bgp_vrf->vrf_flags,
+ UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST);
}
}
@@ -4382,12 +4393,22 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,
vty_out(vty, " advertise-default-gw\n");
if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
- BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST))
- vty_out(vty, " advertise ipv4 unicast\n");
+ BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST)) {
+ if (bgp->adv_cmd_rmap[AFI_IP][SAFI_UNICAST].name)
+ vty_out(vty, " advertise ipv4 unicast route-map %s\n",
+ bgp->adv_cmd_rmap[AFI_IP][SAFI_UNICAST].name);
+ else
+ vty_out(vty, " advertise ipv4 unicast\n");
+ }
if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
- BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST))
- vty_out(vty, " advertise ipv6 unicast\n");
+ BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST)) {
+ if (bgp->adv_cmd_rmap[AFI_IP6][SAFI_UNICAST].name)
+ vty_out(vty, " advertise ipv6 unicast route-map %s\n",
+ bgp->adv_cmd_rmap[AFI_IP6][SAFI_UNICAST].name);
+ else
+ vty_out(vty, " advertise ipv6 unicast\n");
+ }
if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4))
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index a11a4f78f7..3f5ff12cbc 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -52,6 +52,7 @@
#include "bgpd/bgp_memory.h"
#include "bgpd/bgp_keepalives.h"
#include "bgpd/bgp_io.h"
+#include "bgpd/bgp_zebra.h"
DEFINE_HOOK(peer_backward_transition, (struct peer * peer), (peer))
DEFINE_HOOK(peer_established, (struct peer * peer), (peer))
@@ -1256,7 +1257,8 @@ static int bgp_connect_check(struct thread *thread)
/* If getsockopt is fail, this is fatal error. */
if (ret < 0) {
- zlog_info("can't get sockopt for nonblocking connect");
+ zlog_info("can't get sockopt for nonblocking connect: %d(%s)",
+ errno, safe_strerror(errno));
BGP_EVENT_ADD(peer, TCP_fatal_error);
return -1;
}
@@ -1267,8 +1269,8 @@ static int bgp_connect_check(struct thread *thread)
return 1;
} else {
if (bgp_debug_neighbor_events(peer))
- zlog_debug("%s [Event] Connect failed (%s)", peer->host,
- safe_strerror(errno));
+ zlog_debug("%s [Event] Connect failed %d(%s)",
+ peer->host, status, safe_strerror(status));
BGP_EVENT_ADD(peer, TCP_connection_open_failed);
return 0;
}
@@ -1397,13 +1399,14 @@ int bgp_start(struct peer *peer)
if (!bgp_find_or_add_nexthop(peer->bgp, peer->bgp,
family2afi(peer->su.sa.sa_family), NULL,
peer, connected)) {
-#if defined(HAVE_CUMULUS)
- if (bgp_debug_neighbor_events(peer))
- zlog_debug("%s [FSM] Waiting for NHT", peer->host);
+ if (bgp_zebra_num_connects()) {
+ if (bgp_debug_neighbor_events(peer))
+ zlog_debug("%s [FSM] Waiting for NHT",
+ peer->host);
- BGP_EVENT_ADD(peer, TCP_connection_open_failed);
- return 0;
-#endif
+ BGP_EVENT_ADD(peer, TCP_connection_open_failed);
+ return 0;
+ }
}
assert(!peer->t_write);
diff --git a/bgpd/bgp_io.c b/bgpd/bgp_io.c
index 3882ff8b56..69c92e829c 100644
--- a/bgpd/bgp_io.c
+++ b/bgpd/bgp_io.c
@@ -179,7 +179,7 @@ static int bgp_process_reads(struct thread *thread)
peer = THREAD_ARG(thread);
- if (peer->fd < 0)
+ if (peer->fd < 0 || bm->terminating)
return -1;
struct frr_pthread *fpt = frr_pthread_get(PTHREAD_IO);
diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index 5158717b5d..004bdd90a2 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -143,6 +143,8 @@ void sighup(void)
__attribute__((__noreturn__)) void sigint(void)
{
zlog_notice("Terminating on signal");
+ assert(bm->terminating == false);
+ bm->terminating = true; /* global flag that shutting down */
if (!retain_mode)
bgp_terminate();
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 424fc4bc03..997d708baf 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -1341,6 +1341,8 @@ static void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
}
if (family == AF_INET6)
memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
+ if (family == AF_EVPN)
+ memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
}
int subgroup_announce_check(struct bgp_node *rn, struct bgp_info *ri,
@@ -2341,10 +2343,18 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,
if (new_select && new_select->type == ZEBRA_ROUTE_BGP
&& (new_select->sub_type == BGP_ROUTE_NORMAL
|| new_select->sub_type == BGP_ROUTE_AGGREGATE
- || new_select->sub_type == BGP_ROUTE_IMPORTED))
+ || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
+
+ /* if this is an evpn imported type-5 prefix,
+ * we need to withdraw the route first to clear
+ * the nh neigh and the RMAC entry.
+ */
+ if (old_select &&
+ is_route_parent_evpn(old_select))
+ bgp_zebra_withdraw(p, old_select, bgp, safi);
bgp_zebra_announce(rn, p, new_select, bgp, afi, safi);
- else {
+ } else {
/* Withdraw the route from the kernel. */
if (old_select && old_select->type == ZEBRA_ROUTE_BGP
&& (old_select->sub_type == BGP_ROUTE_NORMAL
@@ -2358,12 +2368,28 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,
/* advertise/withdraw type-5 routes */
if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
if (advertise_type5_routes(bgp, afi) && new_select &&
- (!new_select->extra || !new_select->extra->parent))
- bgp_evpn_advertise_type5_route(bgp, &rn->p,
- new_select->attr,
- afi, safi);
- else if (advertise_type5_routes(bgp, afi) && old_select &&
- (!old_select->extra || !old_select->extra->parent))
+ (!new_select->extra || !new_select->extra->parent)) {
+
+ /* apply the route-map */
+ if (bgp->adv_cmd_rmap[afi][safi].map) {
+ int ret = 0;
+
+ ret = route_map_apply(
+ bgp->adv_cmd_rmap[afi][safi].map,
+ &rn->p, RMAP_BGP, new_select);
+ if (ret == RMAP_MATCH)
+ bgp_evpn_advertise_type5_route(
+ bgp, &rn->p, new_select->attr,
+ afi, safi);
+ } else {
+ bgp_evpn_advertise_type5_route(bgp,
+ &rn->p,
+ new_select->attr,
+ afi, safi);
+
+ }
+ } else if (advertise_type5_routes(bgp, afi) && old_select &&
+ (!old_select->extra || !old_select->extra->parent))
bgp_evpn_withdraw_type5_route(bgp, &rn->p, afi, safi);
}
diff --git a/bgpd/bgp_snmp.c b/bgpd/bgp_snmp.c
index 2c7e4e0435..241b23a62d 100644
--- a/bgpd/bgp_snmp.c
+++ b/bgpd/bgp_snmp.c
@@ -356,20 +356,19 @@ static struct peer *peer_lookup_addr_ipv4(struct in_addr *src)
struct bgp *bgp;
struct peer *peer;
struct listnode *node;
- struct in_addr addr;
- int ret;
bgp = bgp_get_default();
if (!bgp)
return NULL;
for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) {
- ret = inet_pton(AF_INET, peer->host, &addr);
- if (ret > 0) {
- if (IPV4_ADDR_SAME(&addr, src))
- return peer;
- }
+ if (sockunion_family(&peer->su) != AF_INET)
+ continue;
+
+ if (sockunion2ip(&peer->su) == src->s_addr)
+ return peer;
}
+
return NULL;
}
@@ -377,28 +376,31 @@ static struct peer *bgp_peer_lookup_next(struct in_addr *src)
{
struct bgp *bgp;
struct peer *peer;
+ struct peer *next_peer = NULL;
struct listnode *node;
- struct in_addr *p;
- union sockunion su;
- int ret;
-
- sockunion_init(&su);
bgp = bgp_get_default();
if (!bgp)
return NULL;
for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) {
- ret = inet_pton(AF_INET, peer->host, &su.sin.sin_addr);
- if (ret > 0) {
- p = &su.sin.sin_addr;
-
- if (ntohl(p->s_addr) > ntohl(src->s_addr)) {
- src->s_addr = p->s_addr;
- return peer;
- }
+ if (sockunion_family(&peer->su) != AF_INET)
+ continue;
+ if (ntohl(sockunion2ip(&peer->su)) <= ntohl(src->s_addr))
+ continue;
+
+ if (!next_peer
+ || ntohl(sockunion2ip(&next_peer->su))
+ > ntohl(sockunion2ip(&peer->su))) {
+ next_peer = peer;
}
}
+
+ if (next_peer) {
+ src->s_addr = sockunion2ip(&next_peer->su);
+ return next_peer;
+ }
+
return NULL;
}
diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c
index 8ba7902a5f..cabd5b5cbd 100644
--- a/bgpd/bgp_updgrp_packet.c
+++ b/bgpd/bgp_updgrp_packet.c
@@ -467,13 +467,12 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt,
nh_modified = 1;
} else if (
peer->sort == BGP_PEER_EBGP
- && paf->safi != SAFI_EVPN
&& (bgp_multiaccess_check_v4(v4nh, peer) == 0)
&& !CHECK_FLAG(
vec->flags,
BPKT_ATTRVEC_FLAGS_RMAP_NH_UNCHANGED)
&& !peer_af_flag_check(
- peer, nhafi, paf->safi,
+ peer, paf->afi, paf->safi,
PEER_FLAG_NEXTHOP_UNCHANGED)) {
/* NOTE: not handling case where NH has new AFI
*/
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index e1b050bf59..b8c81232bb 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -12153,7 +12153,6 @@ static void bgp_ac_neighbor(vector comps, struct cmd_token *token)
{
struct bgp *bgp;
struct peer *peer;
- struct peer_group *group;
struct listnode *lnbgp, *lnpeer;
for (ALL_LIST_ELEMENTS_RO(bm->bgp, lnbgp, bgp)) {
@@ -12177,11 +12176,6 @@ static void bgp_ac_neighbor(vector comps, struct cmd_token *token)
vector_set(comps, XSTRDUP(MTYPE_COMPLETION, name));
}
-
- if (token->type == VARIABLE_TKN)
- for (ALL_LIST_ELEMENTS_RO(bgp->group, lnpeer, group))
- vector_set(comps, XSTRDUP(MTYPE_COMPLETION,
- group->name));
}
}
@@ -12191,9 +12185,27 @@ static const struct cmd_variable_handler bgp_var_neighbor[] = {
{.varname = "peer", .completions = bgp_ac_neighbor},
{.completions = NULL}};
+static void bgp_ac_peergroup(vector comps, struct cmd_token *token)
+{
+ struct bgp *bgp;
+ struct peer_group *group;
+ struct listnode *lnbgp, *lnpeer;
+
+ for (ALL_LIST_ELEMENTS_RO(bm->bgp, lnbgp, bgp)) {
+ for (ALL_LIST_ELEMENTS_RO(bgp->group, lnpeer, group))
+ vector_set(comps, XSTRDUP(MTYPE_COMPLETION,
+ group->name));
+ }
+}
+
+static const struct cmd_variable_handler bgp_var_peergroup[] = {
+ {.tokenname = "PGNAME", .completions = bgp_ac_peergroup},
+ {.completions = NULL} };
+
void bgp_vty_init(void)
{
cmd_variable_handler_register(bgp_var_neighbor);
+ cmd_variable_handler_register(bgp_var_peergroup);
/* Install bgp top node. */
install_node(&bgp_node, bgp_config_write);
@@ -12575,6 +12587,8 @@ void bgp_vty_init(void)
install_element(BGP_VPNV4_NODE, &no_neighbor_nexthop_self_cmd);
install_element(BGP_VPNV6_NODE, &neighbor_nexthop_self_cmd);
install_element(BGP_VPNV6_NODE, &no_neighbor_nexthop_self_cmd);
+ install_element(BGP_EVPN_NODE, &neighbor_nexthop_self_cmd);
+ install_element(BGP_EVPN_NODE, &no_neighbor_nexthop_self_cmd);
/* "neighbor next-hop-self force" commands. */
install_element(BGP_NODE, &neighbor_nexthop_self_force_hidden_cmd);
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 93a509c219..52a246387e 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -1207,7 +1207,6 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
/* Make Zebra API structure. */
memset(&api, 0, sizeof(api));
- memcpy(&api.rmac, &(info->attr->rmac), sizeof(struct ethaddr));
api.vrf_id = bgp->vrf_id;
api.type = ZEBRA_ROUTE_BGP;
api.safi = safi;
@@ -1288,17 +1287,11 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
}
}
- if (bgp->table_map[afi][safi].name || nh_othervrf) {
+ if (bgp->table_map[afi][safi].name) {
/* Copy info and attributes, so the route-map
apply doesn't modify the BGP route info. */
local_attr = *mpinfo->attr;
mpinfo_cp->attr = &local_attr;
- if (nh_othervrf) {
- /* allow route-map to modify */
- local_attr.nexthop =
- info->extra->nexthop_orig.u
- .prefix4;
- }
}
if (bgp->table_map[afi][safi].name) {
@@ -1323,19 +1316,11 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
ifindex_t ifindex;
struct in6_addr *nexthop;
- if (bgp->table_map[afi][safi].name || nh_othervrf) {
+ if (bgp->table_map[afi][safi].name) {
/* Copy info and attributes, so the route-map
apply doesn't modify the BGP route info. */
local_attr = *mpinfo->attr;
mpinfo_cp->attr = &local_attr;
- if (nh_othervrf) {
- /* allow route-map to modify */
- local_attr.mp_nexthop_global =
- info->extra->nexthop_orig.u
- .prefix6;
- local_attr.mp_nexthop_len =
- BGP_ATTR_NHLEN_IPV6_GLOBAL;
- }
}
if (bgp->table_map[afi][safi].name) {
@@ -1376,6 +1361,8 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
api_nh->label_num = 1;
api_nh->labels[0] = label;
}
+ memcpy(&api_nh->rmac, &(mpinfo->attr->rmac),
+ sizeof(struct ethaddr));
valid_nh_count++;
}
@@ -1500,7 +1487,6 @@ void bgp_zebra_withdraw(struct prefix *p, struct bgp_info *info,
}
memset(&api, 0, sizeof(api));
- memcpy(&api.rmac, &(info->attr->rmac), sizeof(struct ethaddr));
api.vrf_id = bgp->vrf_id;
api.type = ZEBRA_ROUTE_BGP;
api.safi = safi;
@@ -1913,7 +1899,7 @@ int bgp_zebra_advertise_gw_macip(struct bgp *bgp, int advertise, vni_t vni)
zclient_create_header(s, ZEBRA_ADVERTISE_DEFAULT_GW, bgp->vrf_id);
stream_putc(s, advertise);
- stream_put3(s, vni);
+ stream_putl(s, vni);
stream_putw_at(s, 0, stream_get_endp(s));
return zclient_send_message(zclient);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 32a1ea5a5f..71707b6afa 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -1174,6 +1174,11 @@ struct peer *peer_new(struct bgp *bgp)
}
peer->orf_plist[afi][safi] = NULL;
}
+
+ /* set nexthop-unchanged for l2vpn evpn by default */
+ SET_FLAG(peer->af_flags[AFI_L2VPN][SAFI_EVPN],
+ PEER_FLAG_NEXTHOP_UNCHANGED);
+
SET_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
/* Create buffers. */
@@ -4072,6 +4077,35 @@ static int peer_af_flag_modify(struct peer *peer, afi_t afi, safi_t safi,
return 0;
}
+ /*
+ * For EVPN we implicitly set the NEXTHOP_UNCHANGED flag,
+ * if we are setting/unsetting flags which conflict with this flag
+ * handle accordingly
+ */
+ if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
+ if (set) {
+
+ /*
+ * if we are setting NEXTHOP_SELF, we need to unset the
+ * NEXTHOP_UNCHANGED flag
+ */
+ if (CHECK_FLAG(flag, PEER_FLAG_NEXTHOP_SELF) ||
+ CHECK_FLAG(flag, PEER_FLAG_FORCE_NEXTHOP_SELF))
+ UNSET_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_NEXTHOP_UNCHANGED);
+ } else {
+
+ /*
+ * if we are unsetting NEXTHOP_SELF, we need to set the
+ * NEXTHOP_UNCHANGED flag to reset the defaults for EVPN
+ */
+ if (CHECK_FLAG(flag, PEER_FLAG_NEXTHOP_SELF) ||
+ CHECK_FLAG(flag, PEER_FLAG_FORCE_NEXTHOP_SELF))
+ SET_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_NEXTHOP_UNCHANGED);
+ }
+ }
+
if (set)
SET_FLAG(peer->af_flags[afi][safi], flag);
else
@@ -7133,7 +7167,9 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
/* atribute-unchanged. */
if (peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_PATH_UNCHANGED)
- || peer_af_flag_check(peer, afi, safi, PEER_FLAG_NEXTHOP_UNCHANGED)
+ || (safi != SAFI_EVPN
+ && peer_af_flag_check(peer, afi, safi,
+ PEER_FLAG_NEXTHOP_UNCHANGED))
|| peer_af_flag_check(peer, afi, safi, PEER_FLAG_MED_UNCHANGED)) {
if (!peer_group_active(peer)
@@ -7583,6 +7619,7 @@ void bgp_master_init(struct thread_master *master)
bm->start_time = bgp_clock();
bm->t_rmap_update = NULL;
bm->rmap_update_timer = RMAP_DEFAULT_UPDATE_TIMER;
+ bm->terminating = false;
bgp_process_queue_init();
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index d9ce77a55a..1ad6a5c9c8 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -144,6 +144,7 @@ struct bgp_master {
/* dynamic mpls label allocation pool */
struct labelpool labelpool;
+ bool terminating; /* global flag that sigint terminate seen */
QOBJ_FIELDS
};
DECLARE_QOBJ_TYPE(bgp_master)
diff --git a/configure.ac b/configure.ac
index 7662f2a4e5..8b49295444 100755
--- a/configure.ac
+++ b/configure.ac
@@ -1913,8 +1913,13 @@ AC_MSG_RESULT($ac_cv_htonl_works)
AC_CONFIG_FILES([Makefile
bgpd/Makefile
vtysh/Makefile
- doc/Makefile tests/Makefile
- bgpd/rfp-example/rfptest/Makefile bgpd/rfp-example/librfp/Makefile
+ doc/Makefile
+ doc/user/Makefile
+ doc/manpages/Makefile
+ doc/developer/Makefile
+ tests/Makefile
+ bgpd/rfp-example/rfptest/Makefile
+ bgpd/rfp-example/librfp/Makefile
redhat/frr.spec
debianpkg/Makefile
debianpkg/changelog
diff --git a/debianpkg/README.deb_build.md b/debianpkg/README.deb_build.md
deleted file mode 100644
index c90ca13394..0000000000
--- a/debianpkg/README.deb_build.md
+++ /dev/null
@@ -1,127 +0,0 @@
-Building your own FRRouting Debian Package
-==========================================
-(Tested on Ubuntu 12.04, 14.04, 16.04, 17.10, 18.04, Debian 8 and 9)
-
-**Note:** If you try to build for a different distro, then it will most likely
-fail because of the missing backport. See debianpkg/backports/README about
-adding a new backport.
-
-1. Follow the package installation as outlined in doc/Building_on_XXXX.md
- (XXXX refers your OS Distribution) to install the required build packages
-
-2. Install the following additional packages:
-
- on Ubuntu 12.04, 14.04, 16.04, 17.10, Debian 8 and 9:
-
- apt-get install realpath equivs groff fakeroot debhelper devscripts
-
- on Ubuntu 18.04: (realpath is now part of preinstalled by coreutils)
-
- apt-get install equivs groff fakeroot debhelper devscripts
-
-3. Checkout FRR under a **unpriviledged** user account
-
- git clone https://github.com/frrouting/frr.git frr
- cd frr
- # git checkout <branch> - if different branch than master
-
-4. Run Bootstrap and make distribution tar.gz
-
- ./bootstrap.sh
- ./configure --with-pkg-extra-version=-MyDebPkgVersion
- make dist
-
- Note: configure parameters are not important for the Debian Package
- building - except the `with-pkg-extra-version` if you want to give the
- Debian Package a specific name to mark your own unoffical build
-
-5. Edit `debianpkg/rules` and set the configuration as needed
-
- Look for section `dh_auto_configure` to modify the configure
- options as needed. Options might be different between main `rules` and
- `backports/XXXX/debian/rules`. Please adjust as needed on all files
-
-6. Create backports debian sources
-
- Move the `debianpkg` to `debian` and create the backports
- (Debian requires to not ship a `debian` directory inside the source
- directory to avoid build conflicts with the reserved `debian` subdirectory
- name during the build)
-
- mv debianpkg debian
- make -f debian/rules backports
-
- This will create a `frr_*.orig.tar.gz` with the source (same as dist tar),
- and multiple `frr_*.debian.tar.xz` and `frr_*.dsc` for the debian package
- source on each backport supported distribution
-
-7. Create a new directory to build the package and populate with package src
-
- mkdir frrpkg
- cd frrpkg
- tar xf ~/frr/frr_*.orig.tar.gz
- cd frr*
- . /etc/os-release
- tar xf ~/frr/frr_*${ID}${VERSION_ID}*.debian.tar.xz
-
-8. Build Debian Package Dependencies and install them as needed
-
- sudo mk-build-deps --install debian/control
-
-9. Build Debian Package
-
- Building with standard options:
-
- debuild -b -uc -us
-
- Or change some options:
- (see `rules` file for available options)
-
- debuild --set-envvar=WANT_BGP_VNC=1 --set-envvar=WANT_CUMULUS_MODE=1 -b -uc -us
-
- To build with RPKI, download the librtr packages from
- https://ci1.netdef.org/browse/RPKI-RTRLIB/latestSuccessful/artifact
- install librtr-dev on the build server and build the packages as
- debuild --set-envvar=WANT_RPKI=1 -b -uc -us
- RPKI packages have an additonal dependency of librtr0 which can be
- found at the same URL
-
-DONE.
-
-If all works correctly, then you should end up with the Debian packages under
-`frrpkg`. If distributed, please make sure you distribute it together with
-the sources (`frr_*.orig.tar.gz`, `frr_*.debian.tar.xz` and `frr_*.dsc`)
-
-
-Enabling daemons after installation of the package:
----------------------------------------------------
-
-1. Edit `/etc/frr/daemons` and enable required routing daemons (Zebra is
-probably needed for most deployments, so make sure to enable it.)
-
-2. Check your firewall / IPtables to make sure the routing protocols are
-allowed.
-
-3. Enable FRR at startup
-
- - On `init.d` based systems (Ubuntu 12.04)
-
- sudo update-rc.d frr defaults
-
- - On `systemd` based systems (Debian 8 and later, Ubuntu 14.04 and later)
-
- sudo systemctl enable frr
-
-4. Start/Restart the daemons (or reboot)
-
- - On `init.d` based systems (Ubuntu 12.04)
-
- sudo invoke-rc.d frr start
-
- - on `systemd` based systems (Debian 8 and later, Ubuntu 14.04 and later)
-
- sudo systemctl start frr
-
-
-Configuration is stored in `/etc/frr/*.conf` files and daemon selection
-is stored in `/etc/frr/daemons`.
diff --git a/debianpkg/backports/ubuntu14.04/debian/frr.postinst b/debianpkg/backports/ubuntu14.04/debian/frr.postinst
index b1d463a33d..5a14e510cd 100644
--- a/debianpkg/backports/ubuntu14.04/debian/frr.postinst
+++ b/debianpkg/backports/ubuntu14.04/debian/frr.postinst
@@ -18,7 +18,7 @@ chgrp ${frrvtygid} /etc/frr/vtysh*
chmod 644 /etc/frr/*
ENVIRONMENTFILE=/etc/environment
-if ! grep --quiet VTYSH_PAGER=/bin/cat ${ENVIRONMENTFILE}; then
+if ! egrep --quiet '^VTYSH_PAGER=' ${ENVIRONMENTFILE}; then
echo "VTYSH_PAGER=/bin/cat" >> ${ENVIRONMENTFILE}
fi
##################################################
diff --git a/debianpkg/frr-doc.docs b/debianpkg/frr-doc.docs
index 4720a3b920..d2218d00f9 100644
--- a/debianpkg/frr-doc.docs
+++ b/debianpkg/frr-doc.docs
@@ -1,6 +1,5 @@
AUTHORS
NEWS
README
-REPORTING-BUGS
doc/user/*.rst
doc/figures/*.png
diff --git a/debianpkg/frr.postinst b/debianpkg/frr.postinst
index 972f8c0500..32af741c98 100644
--- a/debianpkg/frr.postinst
+++ b/debianpkg/frr.postinst
@@ -19,7 +19,7 @@ chgrp ${frrvtygid} /etc/frr/vtysh*
chmod 644 /etc/frr/*
ENVIRONMENTFILE=/etc/environment
-if ! grep --quiet VTYSH_PAGER=/bin/cat ${ENVIRONMENTFILE}; then
+if ! egrep --quiet '^VTYSH_PAGER=' ${ENVIRONMENTFILE}; then
echo "VTYSH_PAGER=/bin/cat" >> ${ENVIRONMENTFILE}
fi
##################################################
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 053842283e..8fa057424a 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -14,7 +14,7 @@
.NOTPARALLEL:
SUBDIRS = manpages user
-AM_MAKEFLAGS = DESTDIR=${DESTDIR} infodir=${infodir} doczdir=${abs_srcdir}
+AM_MAKEFLAGS = DESTDIR=${DESTDIR} infodir=${infodir}
MANPAGE_BUILDDIR = manpages/_build/man
diff --git a/doc/developer/.gitignore b/doc/developer/.gitignore
index 0505537159..2e7d8573f1 100644
--- a/doc/developer/.gitignore
+++ b/doc/developer/.gitignore
@@ -1,3 +1,3 @@
/_templates
/_build
-!/Makefile
+!/Makefile.in
diff --git a/doc/developer/Makefile b/doc/developer/Makefile
deleted file mode 100644
index 9807a750bf..0000000000
--- a/doc/developer/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-include ../frr-sphinx.mk
diff --git a/doc/developer/Makefile.in b/doc/developer/Makefile.in
new file mode 100644
index 0000000000..76758f9242
--- /dev/null
+++ b/doc/developer/Makefile.in
@@ -0,0 +1,8 @@
+# This is necessary to support VPATH builds.
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+# This variable is used as the documentation source location in frr-sphinx.mk
+SOURCESDIR = @srcdir@
+
+include @srcdir@/../frr-sphinx.mk
diff --git a/doc/developer/building.rst b/doc/developer/building.rst
index 92fd1bb63a..051611a65d 100644
--- a/doc/developer/building.rst
+++ b/doc/developer/building.rst
@@ -1,3 +1,5 @@
+.. _building:
+
************
Building FRR
************
diff --git a/doc/developer/conf.py b/doc/developer/conf.py
index a3968b60ff..61253c4b2f 100644
--- a/doc/developer/conf.py
+++ b/doc/developer/conf.py
@@ -342,6 +342,14 @@ texinfo_documents = [
# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False
+# contents of ../extra/frrlexer.py.
+# This is read here to support VPATH build. Since this section is execfile()'d
+# with the file location, we can safely use a relative path here to save the
+# contents of the lexer file for later use even if our relative path changes
+# due to VPATH.
+with open('../extra/frrlexer.py', 'rb') as lex:
+ frrlexerpy = lex.read()
+
# custom extensions here
def setup(app):
# object type for FRR CLI commands, can be extended to document parent CLI
@@ -357,5 +365,5 @@ def setup(app):
#
# frrlexer = pygments.lexers.load_lexer_from_file('../extra/frrlexer.py', lexername="FRRLexer")
custom_namespace = {}
- exec(open('../extra/frrlexer.py', 'rb').read(), custom_namespace)
+ exec(frrlexerpy, custom_namespace)
lexers['frr'] = custom_namespace['FRRLexer']()
diff --git a/doc/developer/index.rst b/doc/developer/index.rst
index 2c855ee880..42192db637 100644
--- a/doc/developer/index.rst
+++ b/doc/developer/index.rst
@@ -6,6 +6,7 @@ FRRouting Developer's Guide
workflow
building
+ packaging
process-architecture
library
bgpd
diff --git a/doc/developer/packaging-debian.rst b/doc/developer/packaging-debian.rst
new file mode 100644
index 0000000000..66339b6d1f
--- /dev/null
+++ b/doc/developer/packaging-debian.rst
@@ -0,0 +1,173 @@
+Debian
+======
+
+(Tested on Ubuntu 12.04, 14.04, 16.04, 17.10, 18.04, Debian 8 and 9)
+
+.. note::
+
+ If you try to build for a different distro, then it will most likely fail
+ because of the missing backport. See :ref:`deb-backports` about adding a new
+ backport.
+
+1. Install build dependencies for your platform as outlined in :ref:`building`.
+
+2. Install the following additional packages:
+
+ - on Ubuntu 12.04, 14.04, 16.04, 17.10, Debian 8 and 9:
+
+ .. code-block:: shell
+
+ apt-get install realpath equivs groff fakeroot debhelper devscripts
+
+ - on Ubuntu 18.04: (realpath is now part of preinstalled by coreutils)
+
+ .. code-block:: shell
+
+ apt-get install equivs groff fakeroot debhelper devscripts
+
+3. Checkout FRR under a **unprivileged** user account:
+
+ .. code-block:: shell
+
+ git clone https://github.com/frrouting/frr.git frr
+ cd frr
+
+ If you wish to build a package for a branch other than master:
+
+ .. code-block:: shell
+
+ git checkout <branch>
+
+4. Run ``bootstrap.sh`` and make a dist tarball:
+
+ .. code-block:: shell
+
+ ./bootstrap.sh
+ ./configure --with-pkg-extra-version=-MyDebPkgVersion
+ make dist
+
+ .. note::
+
+ Configure parameters are not important for the Debian Package building -
+ except the `with-pkg-extra-version` if you want to give the Debian
+ package a specific name to mark your own unoffical build.
+
+5. Edit :file:`debianpkg/rules` and set the configuration as needed.
+
+ Look for section ``dh_auto_configure`` to modify the configure options as
+ needed. Options might be different between the top-level ``rules``` and
+ :file:`backports/XXXX/debian/rules`. Please adjust as needed on all files.
+
+6. Create backports debian sources
+
+ Rename the :file:`debianpkg` directory to :file:`debian` and create the
+ backports (Debian requires to not ship a :file:`debian` directory inside the
+ source directory to avoid build conflicts with the reserved ``debian``
+ subdirectory name during the build):
+
+ .. code-block:: shell
+
+ mv debianpkg debian
+ make -f debian/rules backports
+
+ This will create a :file:`frr_*.orig.tar.gz` with the source (same as the
+ dist tarball), as well as multiple :file:`frr_*.debian.tar.xz` and
+ :file:`frr_*.dsc` corresponding to each distribution for which a backport is
+ available.
+
+7. Create a new directory to build the package and populate with package
+ source.
+
+ .. code-block:: shell
+
+ mkdir frrpkg
+ cd frrpkg
+ tar xf ~/frr/frr_*.orig.tar.gz
+ cd frr*
+ . /etc/os-release
+ tar xf ~/frr/frr_*${ID}${VERSION_ID}*.debian.tar.xz
+
+8. Build Debian package dependencies and install them as needed.
+
+ .. code-block:: shell
+
+ sudo mk-build-deps --install debian/control
+
+9. Build Debian Package
+
+ Building with standard options:
+
+ .. code-block:: shell
+
+ debuild -b -uc -us
+
+ Or change some options (see `rules` file for available options):
+
+ .. code-block:: shell
+
+ debuild --set-envvar=WANT_BGP_VNC=1 --set-envvar=WANT_CUMULUS_MODE=1 -b -uc -us
+
+ To build with RPKI:
+
+ - Download the librtr packages from
+ https://ci1.netdef.org/browse/RPKI-RTRLIB/latestSuccessful/artifact
+
+ - install librtr-dev on the build server
+
+ Then build with:
+
+ .. code-block:: shell
+
+ debuild --set-envvar=WANT_RPKI=1 -b -uc -us
+
+ RPKI packages have an additonal dependency of ``librtr0`` which can be found
+ at the same URL.
+
+10. Done!
+
+If all worked correctly, then you should end up with the Debian packages under
+:file:`frrpkg`. If distributed, please make sure you distribute it together
+with the sources (``frr_*.orig.tar.gz``, ``frr_*.debian.tar.xz`` and
+``frr_*.dsc``)
+
+.. _deb-backports:
+
+Debian Backports
+----------------
+
+The :file:`debianpkg/backports` directory contains the Debian directories for
+backports to other Debian platforms. These are built via the ``3.0 (custom)``
+source format, which allows one to build a source package directly out of
+tarballs (e.g. an orig.tar.gz tarball and a debian.tar.gz file), at which point
+the format can be changed to a real format (e.g. ``3.0 (quilt)``).
+
+Source packages are assembled via targets of the same name as the system to
+which the backport is done (e.g. ``precise``), included in :file:`debian/rules`.
+
+To create a new Debian backport:
+
+- Add its name to ``KNOWN_BACKPORTS``, defined in :file:`debian/rules`.
+- Create a directory of the same name in :file:`debian/backports`.
+- Add the files ``exclude``, ``versionext``, and ``debian/source/format`` under
+ this directory.
+
+For the last point, these files should contain the following:
+
+``exclude``
+ Contains whitespace-separated paths (relative to the root of the source dir)
+ that should be excluded from the source package (e.g.
+ :file:`debian/patches`).
+
+``versionext``
+ Contains the suffix added to the version number for this backport's build.
+ Distributions often have guidelines for what this should be. If left empty,
+ no new :file:`debian/changelog` entry is created.
+
+``debian/source/format``
+ Contains the source format of the resulting source package. As of of the
+ writing of this document the only supported format is ``3.0 (quilt)``.
+
+- Add appropriate files under the :file:`debian/` subdirectory. These will be
+ included in the source package, overriding any top-level :file:`debian/`
+ files with equivalent paths.
+
diff --git a/doc/developer/packaging.rst b/doc/developer/packaging.rst
new file mode 100644
index 0000000000..e9bb3a5409
--- /dev/null
+++ b/doc/developer/packaging.rst
@@ -0,0 +1,8 @@
+*********
+Packaging
+*********
+
+.. toctree::
+ :maxdepth: 2
+
+ packaging-debian
diff --git a/doc/frr-sphinx.mk b/doc/frr-sphinx.mk
index df4056760d..3e4c67d374 100644
--- a/doc/frr-sphinx.mk
+++ b/doc/frr-sphinx.mk
@@ -10,6 +10,11 @@ SPHINXBUILD ?= sphinx-build
PAPER ?=
BUILDDIR = _build
+# This is a custom FRR variable just for this docs subdirectory used to support
+# VPATH builds. Makefiles which include this file should override it to point
+# to the correct sources path.
+SOURCESDIR ?= .
+
# User-friendly check for sphinx-build
ifneq ($(MAKECMDGOALS), clean)
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
@@ -23,9 +28,9 @@ endif
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SOURCESDIR)
# the i18n builder cannot share the environment and doctrees with the others
-I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SOURCESDIR)
.PHONY: help
help:
diff --git a/doc/manpages/.gitignore b/doc/manpages/.gitignore
index 0505537159..2e7d8573f1 100644
--- a/doc/manpages/.gitignore
+++ b/doc/manpages/.gitignore
@@ -1,3 +1,3 @@
/_templates
/_build
-!/Makefile
+!/Makefile.in
diff --git a/doc/manpages/Makefile b/doc/manpages/Makefile.in
index ebbbc31009..f28746cee6 100644
--- a/doc/manpages/Makefile
+++ b/doc/manpages/Makefile.in
@@ -1,4 +1,11 @@
-include ../frr-sphinx.mk
+# This is necessary to support VPATH builds.
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+# This variable is used as the documentation source location in frr-sphinx.mk
+SOURCESDIR = @srcdir@
+
+include @srcdir@/../frr-sphinx.mk
# -----------------------------------------------------------------------------
# Automake requires that 3rd-party Makefiles recognize these targets.
diff --git a/doc/user/.gitignore b/doc/user/.gitignore
index 0505537159..2e7d8573f1 100644
--- a/doc/user/.gitignore
+++ b/doc/user/.gitignore
@@ -1,3 +1,3 @@
/_templates
/_build
-!/Makefile
+!/Makefile.in
diff --git a/doc/user/Makefile b/doc/user/Makefile.in
index 223f8a64a3..77c6abf917 100644
--- a/doc/user/Makefile
+++ b/doc/user/Makefile.in
@@ -1,4 +1,11 @@
-include ../frr-sphinx.mk
+# This is necessary to support VPATH builds.
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+# This variable is used as the documentation source location in frr-sphinx.mk
+SOURCESDIR = @srcdir@
+
+include @srcdir@/../frr-sphinx.mk
# -----------------------------------------------------------------------------
# Automake requires that 3rd-party Makefiles recognize these targets.
diff --git a/doc/user/basic.rst b/doc/user/basic.rst
index f134133da4..b861444e88 100644
--- a/doc/user/basic.rst
+++ b/doc/user/basic.rst
@@ -55,18 +55,23 @@ Basic Config Commands
Set hostname of the router.
-.. index:: password PASSWORD
+.. index::
+ single: no password PASSWORD
+ single: password PASSWORD
-.. clicmd:: password PASSWORD
+.. clicmd:: [no] password PASSWORD
- Set password for vty interface. If there is no password, a vty won't
- accept connections.
+ Set password for vty interface. The ``no`` form of the command deletes the
+ password. If there is no password, a vty won't accept connections.
-.. index:: enable password PASSWORD
+.. index::
+ single: no enable password PASSWORD
+ single: enable password PASSWORD
-.. clicmd:: enable password PASSWORD
+.. clicmd:: [no] enable password PASSWORD
- Set enable password.
+ Set enable password. The ``no`` form of the command deletes the enable
+ password.
.. index::
single: no log trap [LEVEL]
diff --git a/doc/user/bugs.rst b/doc/user/bugs.rst
new file mode 100644
index 0000000000..60ddf612db
--- /dev/null
+++ b/doc/user/bugs.rst
@@ -0,0 +1,67 @@
+.. _bugs:
+
+**************
+Reporting Bugs
+**************
+
+This file describes the procedure for reporting FRRouting bugs. You are asked
+to follow this format when submitting bug reports.
+
+Bugs submitted with woefully incomplete information will receive little
+attention and are likely to be closed. If you hit a suspected bug in an older
+version, you may be asked to test with a later version in your environment.
+
+Often you may be asked for additional information to help solve the bug. Bugs
+may be closed after 30 days of non-response to requests to reconfirm or supply
+additional information.
+
+Please report bugs on the project GitHub issue tracker at
+https://github.com/frrouting/frr/issues
+
+Report Format & Requested Information
+=====================================
+
+When reporting a bug, please provide the following information.
+
+#. Your FRR version if it is a release build, or the commit hash if you built
+ from source.
+
+#. If you compiled from source, please provide your ``./configure`` line,
+ including all option flags.
+
+#. A full list of the FRR daemons you run.
+
+#. Your platform name and version, e.g. ``Ubuntu 18.04``.
+
+#. Problem description.
+
+ - Provide as much information as possible.
+ - Copy and paste relevant commands and their output to describe your network
+ setup.
+ - Topology diagrams are helpful when reporting bugs involving more than one
+ box.
+ - Platform routing tables and interface configurations are useful if you are
+ reporting a routing issue.
+
+ *Please be sure to review the provided information and censor any sensitive
+ material.*
+
+#. All FRR configuration files you use. Again, please be sure to censor any
+ sensitive information. For sensitive v4 / v6 addresses, we ask that you
+ censor the inner octets; e.g., ``192.XXX.XXX.32/24``.
+
+#. If you are reporting a crash and have a core file, please supply a stack
+ trace using GDB:
+
+ ::
+
+ $ gdb exec_file core_file
+ (gdb) bt .
+
+#. Run all FRR daemons with full debugging on and send *only* the portion of
+ logs which are relevant to your problem.
+
+#. Patches, workarounds, and fixes are always welcome.
+
+.. seealso:: :ref:`basic-config-commands`
+
diff --git a/doc/user/conf.py b/doc/user/conf.py
index 886403b69d..3fced11024 100644
--- a/doc/user/conf.py
+++ b/doc/user/conf.py
@@ -342,6 +342,14 @@ texinfo_documents = [
# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False
+# contents of ../extra/frrlexer.py.
+# This is read here to support VPATH build. Since this section is execfile()'d
+# with the file location, we can safely use a relative path here to save the
+# contents of the lexer file for later use even if our relative path changes
+# due to VPATH.
+with open('../extra/frrlexer.py', 'rb') as lex:
+ frrlexerpy = lex.read()
+
# custom extensions here
def setup(app):
# object type for FRR CLI commands, can be extended to document parent CLI
@@ -357,5 +365,5 @@ def setup(app):
#
# frrlexer = pygments.lexers.load_lexer_from_file('../extra/frrlexer.py', lexername="FRRLexer")
custom_namespace = {}
- exec(open('../extra/frrlexer.py', 'rb').read(), custom_namespace)
+ exec(frrlexerpy, custom_namespace)
lexers['frr'] = custom_namespace['FRRLexer']()
diff --git a/doc/user/index.rst b/doc/user/index.rst
index 9b9189dc30..f20ff8ec2b 100644
--- a/doc/user/index.rst
+++ b/doc/user/index.rst
@@ -27,6 +27,7 @@ FRRouting User Guide
ripngd
sharp
vnc
+ bugs
glossary
appendix
diff --git a/doc/user/pbr.rst b/doc/user/pbr.rst
index eec575cf3f..aa48a3cd4f 100644
--- a/doc/user/pbr.rst
+++ b/doc/user/pbr.rst
@@ -57,7 +57,7 @@ against incoming packets. If matched the nexthop-group or nexthop
is used to forward the packets to the end destination
.. index:: pbr-map
-.. clicmd:: pbr-map NAME seq (1-1000)
+.. clicmd:: pbr-map NAME seq (1-700)
Create a pbr-map with NAME and sequence number specified. This command puts
you into a new submode for pbr-map specification. To exit this mode type
diff --git a/lib/command.c b/lib/command.c
index 2744061b5a..69e301fcfa 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -85,6 +85,7 @@ const char *node_names[] = {
"keychain", // KEYCHAIN_NODE,
"keychain key", // KEYCHAIN_KEY_NODE,
"logical-router", // LOGICALROUTER_NODE,
+ "static ip", // IP_NODE,
"vrf", // VRF_NODE,
"interface", // INTERFACE_NODE,
"nexthop-group", // NH_GROUP_NODE,
@@ -119,7 +120,6 @@ const char *node_names[] = {
"ldp l2vpn", // LDP_L2VPN_NODE,
"ldp", // LDP_PSEUDOWIRE_NODE,
"isis", // ISIS_NODE,
- "static ip", // IP_NODE,
"ipv4 access list", // ACCESS_NODE,
"ipv4 prefix list", // PREFIX_NODE,
"ipv6 access list", // ACCESS_IPV6_NODE,
@@ -529,87 +529,103 @@ static int config_write_host(struct vty *vty)
if (cmd_domainname_get())
vty_out(vty, "domainname %s\n", cmd_domainname_get());
- if (host.encrypt) {
- if (host.password_encrypt)
- vty_out(vty, "password 8 %s\n", host.password_encrypt);
- if (host.enable_encrypt)
- vty_out(vty, "enable password 8 %s\n",
- host.enable_encrypt);
- } else {
- if (host.password)
- vty_out(vty, "password %s\n", host.password);
- if (host.enable)
- vty_out(vty, "enable password %s\n", host.enable);
- }
+ /* The following are all configuration commands that are not sent to
+ * watchfrr. For instance watchfrr is hardcoded to log to syslog so
+ * we would always display 'log syslog informational' in the config
+ * which would cause other daemons to then switch to syslog when they
+ * parse frr.conf.
+ */
+ if (strcmp(zlog_default->protoname, "WATCHFRR")) {
+ if (host.encrypt) {
+ if (host.password_encrypt)
+ vty_out(vty, "password 8 %s\n",
+ host.password_encrypt);
+ if (host.enable_encrypt)
+ vty_out(vty, "enable password 8 %s\n",
+ host.enable_encrypt);
+ } else {
+ if (host.password)
+ vty_out(vty, "password %s\n", host.password);
+ if (host.enable)
+ vty_out(vty, "enable password %s\n",
+ host.enable);
+ }
- if (zlog_default->default_lvl != LOG_DEBUG) {
- vty_out(vty, "! N.B. The 'log trap' command is deprecated.\n");
- vty_out(vty, "log trap %s\n",
- zlog_priority[zlog_default->default_lvl]);
- }
+ if (zlog_default->default_lvl != LOG_DEBUG) {
+ vty_out(vty,
+ "! N.B. The 'log trap' command is deprecated.\n");
+ vty_out(vty, "log trap %s\n",
+ zlog_priority[zlog_default->default_lvl]);
+ }
- if (host.logfile
- && (zlog_default->maxlvl[ZLOG_DEST_FILE] != ZLOG_DISABLED)) {
- vty_out(vty, "log file %s", host.logfile);
- if (zlog_default->maxlvl[ZLOG_DEST_FILE]
- != zlog_default->default_lvl)
- vty_out(vty, " %s",
- zlog_priority
- [zlog_default->maxlvl[ZLOG_DEST_FILE]]);
- vty_out(vty, "\n");
- }
+ if (host.logfile
+ && (zlog_default->maxlvl[ZLOG_DEST_FILE]
+ != ZLOG_DISABLED)) {
+ vty_out(vty, "log file %s", host.logfile);
+ if (zlog_default->maxlvl[ZLOG_DEST_FILE]
+ != zlog_default->default_lvl)
+ vty_out(vty, " %s",
+ zlog_priority
+ [zlog_default->maxlvl
+ [ZLOG_DEST_FILE]]);
+ vty_out(vty, "\n");
+ }
- if (zlog_default->maxlvl[ZLOG_DEST_STDOUT] != ZLOG_DISABLED) {
- vty_out(vty, "log stdout");
- if (zlog_default->maxlvl[ZLOG_DEST_STDOUT]
- != zlog_default->default_lvl)
- vty_out(vty, " %s",
- zlog_priority[zlog_default->maxlvl
- [ZLOG_DEST_STDOUT]]);
- vty_out(vty, "\n");
- }
+ if (zlog_default->maxlvl[ZLOG_DEST_STDOUT] != ZLOG_DISABLED) {
+ vty_out(vty, "log stdout");
+ if (zlog_default->maxlvl[ZLOG_DEST_STDOUT]
+ != zlog_default->default_lvl)
+ vty_out(vty, " %s",
+ zlog_priority
+ [zlog_default->maxlvl
+ [ZLOG_DEST_STDOUT]]);
+ vty_out(vty, "\n");
+ }
- if (zlog_default->maxlvl[ZLOG_DEST_MONITOR] == ZLOG_DISABLED)
- vty_out(vty, "no log monitor\n");
- else if (zlog_default->maxlvl[ZLOG_DEST_MONITOR]
- != zlog_default->default_lvl)
- vty_out(vty, "log monitor %s\n",
- zlog_priority[zlog_default->maxlvl[ZLOG_DEST_MONITOR]]);
-
- if (zlog_default->maxlvl[ZLOG_DEST_SYSLOG] != ZLOG_DISABLED) {
- vty_out(vty, "log syslog");
- if (zlog_default->maxlvl[ZLOG_DEST_SYSLOG]
- != zlog_default->default_lvl)
- vty_out(vty, " %s",
+ if (zlog_default->maxlvl[ZLOG_DEST_MONITOR] == ZLOG_DISABLED)
+ vty_out(vty, "no log monitor\n");
+ else if (zlog_default->maxlvl[ZLOG_DEST_MONITOR]
+ != zlog_default->default_lvl)
+ vty_out(vty, "log monitor %s\n",
zlog_priority[zlog_default->maxlvl
- [ZLOG_DEST_SYSLOG]]);
- vty_out(vty, "\n");
- }
+ [ZLOG_DEST_MONITOR]]);
+
+ if (zlog_default->maxlvl[ZLOG_DEST_SYSLOG] != ZLOG_DISABLED) {
+ vty_out(vty, "log syslog");
+ if (zlog_default->maxlvl[ZLOG_DEST_SYSLOG]
+ != zlog_default->default_lvl)
+ vty_out(vty, " %s",
+ zlog_priority[zlog_default->maxlvl
+ [ZLOG_DEST_SYSLOG]]);
+ vty_out(vty, "\n");
+ }
- if (zlog_default->facility != LOG_DAEMON)
- vty_out(vty, "log facility %s\n",
- facility_name(zlog_default->facility));
+ if (zlog_default->facility != LOG_DAEMON)
+ vty_out(vty, "log facility %s\n",
+ facility_name(zlog_default->facility));
- if (zlog_default->record_priority == 1)
- vty_out(vty, "log record-priority\n");
+ if (zlog_default->record_priority == 1)
+ vty_out(vty, "log record-priority\n");
- if (zlog_default->timestamp_precision > 0)
- vty_out(vty, "log timestamp precision %d\n",
- zlog_default->timestamp_precision);
+ if (zlog_default->timestamp_precision > 0)
+ vty_out(vty, "log timestamp precision %d\n",
+ zlog_default->timestamp_precision);
- if (host.advanced)
- vty_out(vty, "service advanced-vty\n");
+ if (host.advanced)
+ vty_out(vty, "service advanced-vty\n");
- if (host.encrypt)
- vty_out(vty, "service password-encryption\n");
+ if (host.encrypt)
+ vty_out(vty, "service password-encryption\n");
- if (host.lines >= 0)
- vty_out(vty, "service terminal-length %d\n", host.lines);
+ if (host.lines >= 0)
+ vty_out(vty, "service terminal-length %d\n",
+ host.lines);
- if (host.motdfile)
- vty_out(vty, "banner motd file %s\n", host.motdfile);
- else if (!host.motd)
- vty_out(vty, "no banner motd\n");
+ if (host.motdfile)
+ vty_out(vty, "banner motd file %s\n", host.motdfile);
+ else if (!host.motd)
+ vty_out(vty, "no banner motd\n");
+ }
if (debug_memstats_at_exit)
vty_out(vty, "!\ndebug memstats-at-exit\n");
@@ -1895,7 +1911,7 @@ DEFUN (config_no_hostname,
DEFUN (config_password,
password_cmd,
"password [(8-8)] WORD",
- "Assign the terminal connection password\n"
+ "Modify the terminal connection password\n"
"Specifies a HIDDEN password will follow\n"
"The password string\n")
{
@@ -1934,6 +1950,36 @@ DEFUN (config_password,
return CMD_SUCCESS;
}
+/* VTY interface password delete. */
+DEFUN (no_config_password,
+ no_password_cmd,
+ "no password",
+ NO_STR
+ "Modify the terminal connection password\n")
+{
+ bool warned = false;
+
+ if (host.password) {
+ vty_out(vty,
+ "Please be aware that removing the password is a security risk and "
+ "you should think twice about this command\n");
+ warned = true;
+ XFREE(MTYPE_HOST, host.password);
+ }
+ host.password = NULL;
+
+ if (host.password_encrypt) {
+ if (!warned)
+ vty_out(vty,
+ "Please be aware that removing the password is a security risk "
+ "and you should think twice about this command\n");
+ XFREE(MTYPE_HOST, host.password_encrypt);
+ }
+ host.password_encrypt = NULL;
+
+ return CMD_SUCCESS;
+}
+
/* VTY enable password set. */
DEFUN (config_enable_password,
enable_password_cmd,
@@ -1995,12 +2041,24 @@ DEFUN (no_config_enable_password,
"Modify enable password parameters\n"
"Assign the privileged level password\n")
{
- if (host.enable)
+ bool warned = false;
+
+ if (host.enable) {
+ vty_out(vty,
+ "Please be aware that removing the password is a security risk and "
+ "you should think twice about this command\n");
+ warned = true;
XFREE(MTYPE_HOST, host.enable);
+ }
host.enable = NULL;
- if (host.enable_encrypt)
+ if (host.enable_encrypt) {
+ if (!warned)
+ vty_out(vty,
+ "Please be aware that removing the password is a security risk "
+ "and you should think twice about this command\n");
XFREE(MTYPE_HOST, host.enable_encrypt);
+ }
host.enable_encrypt = NULL;
return CMD_SUCCESS;
@@ -2304,7 +2362,7 @@ static int set_log_file(struct vty *vty, const char *fname, int loglevel)
#if defined(HAVE_CUMULUS)
if (zlog_default->maxlvl[ZLOG_DEST_SYSLOG] != ZLOG_DISABLED)
- zlog_default->maxlvl[ZLOG_DEST_SYSLOG] = ZLOG_DISABLED;
+ zlog_set_level(ZLOG_DEST_SYSLOG, ZLOG_DISABLED);
#endif
return CMD_SUCCESS;
}
@@ -2330,6 +2388,16 @@ DEFUN (config_log_file,
zlog_default->default_lvl);
}
+static void disable_log_file(void)
+{
+ zlog_reset_file();
+
+ if (host.logfile)
+ XFREE(MTYPE_HOST, host.logfile);
+
+ host.logfile = NULL;
+}
+
DEFUN (no_config_log_file,
no_config_log_file_cmd,
"no log file [FILENAME [LEVEL]]",
@@ -2339,13 +2407,7 @@ DEFUN (no_config_log_file,
"Logging file name\n"
"Logging level\n")
{
- zlog_reset_file();
-
- if (host.logfile)
- XFREE(MTYPE_HOST, host.logfile);
-
- host.logfile = NULL;
-
+ disable_log_file();
return CMD_SUCCESS;
}
@@ -2357,6 +2419,9 @@ DEFUN (config_log_syslog,
LOG_LEVEL_DESC)
{
int idx_log_levels = 2;
+
+ disable_log_file();
+
if (argc == 3) {
int level;
if ((level = level_match(argv[idx_log_levels]->arg))
@@ -2710,6 +2775,7 @@ void cmd_init(int terminal)
if (terminal > 0) {
install_element(CONFIG_NODE, &password_cmd);
+ install_element(CONFIG_NODE, &no_password_cmd);
install_element(CONFIG_NODE, &enable_password_cmd);
install_element(CONFIG_NODE, &no_enable_password_cmd);
diff --git a/lib/command.h b/lib/command.h
index f18de3417c..9ba53e0907 100644
--- a/lib/command.h
+++ b/lib/command.h
@@ -85,6 +85,7 @@ enum node_type {
KEYCHAIN_NODE, /* Key-chain node. */
KEYCHAIN_KEY_NODE, /* Key-chain key node. */
LOGICALROUTER_NODE, /* Logical-Router node. */
+ IP_NODE, /* Static ip route node. */
VRF_NODE, /* VRF mode node. */
INTERFACE_NODE, /* Interface mode node. */
NH_GROUP_NODE, /* Nexthop-Group mode node. */
@@ -119,7 +120,6 @@ enum node_type {
LDP_L2VPN_NODE, /* LDP L2VPN node */
LDP_PSEUDOWIRE_NODE, /* LDP Pseudowire node */
ISIS_NODE, /* ISIS protocol mode */
- IP_NODE, /* Static ip route node. */
ACCESS_NODE, /* Access list node. */
PREFIX_NODE, /* Prefix list node. */
ACCESS_IPV6_NODE, /* Access list node. */
diff --git a/lib/ipaddr.h b/lib/ipaddr.h
index 33591cb4e7..7f2d06548b 100644
--- a/lib/ipaddr.h
+++ b/lib/ipaddr.h
@@ -102,4 +102,14 @@ static inline void ipv4_to_ipv4_mapped_ipv6(struct in6_addr *in6,
memcpy((char *)in6 + 12, &in, sizeof(struct in_addr));
}
+/*
+ * convert an ipv4 mapped ipv6 address back to ipv4 address
+ */
+static inline void ipv4_mapped_ipv6_to_ipv4(struct in6_addr *in6,
+ struct in_addr *in)
+{
+ memset(in, 0, sizeof(struct in_addr));
+ memcpy(in, (char *)in6 + 12, sizeof(struct in_addr));
+}
+
#endif /* __IPADDR_H__ */
diff --git a/lib/zclient.c b/lib/zclient.c
index cb39099fc2..05bd907589 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -975,8 +975,6 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
stream_putl(s, api->flags);
stream_putc(s, api->message);
stream_putc(s, api->safi);
- if (CHECK_FLAG(api->flags, ZEBRA_FLAG_EVPN_ROUTE))
- stream_put(s, &(api->rmac), sizeof(struct ethaddr));
/* Put prefix information. */
stream_putc(s, api->prefix.family);
@@ -1061,6 +1059,11 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
api_nh->label_num
* sizeof(mpls_label_t));
}
+
+ /* Router MAC for EVPN routes. */
+ if (CHECK_FLAG(api->flags, ZEBRA_FLAG_EVPN_ROUTE))
+ stream_put(s, &(api_nh->rmac),
+ sizeof(struct ethaddr));
}
}
@@ -1101,8 +1104,6 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
STREAM_GETL(s, api->flags);
STREAM_GETC(s, api->message);
STREAM_GETC(s, api->safi);
- if (CHECK_FLAG(api->flags, ZEBRA_FLAG_EVPN_ROUTE))
- STREAM_GET(&(api->rmac), s, sizeof(struct ethaddr));
/* Prefix. */
STREAM_GETC(s, api->prefix.family);
@@ -1212,6 +1213,11 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
api_nh->label_num
* sizeof(mpls_label_t));
}
+
+ /* Router MAC for EVPN routes. */
+ if (CHECK_FLAG(api->flags, ZEBRA_FLAG_EVPN_ROUTE))
+ stream_get(&(api_nh->rmac), s,
+ sizeof(struct ethaddr));
}
}
diff --git a/lib/zclient.h b/lib/zclient.h
index 8d26b7fe59..c5eaf9c0fd 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -302,6 +302,8 @@ struct zapi_nexthop {
/* MPLS labels for BGP-LU or Segment Routing */
uint8_t label_num;
mpls_label_t labels[MPLS_MAX_LABELS];
+
+ struct ethaddr rmac;
};
/*
@@ -342,8 +344,6 @@ struct zapi_route {
vrf_id_t vrf_id;
uint32_t tableid;
-
- struct ethaddr rmac;
};
/* Zebra IPv4 route message API. */
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index 52b954d6a1..ea31d8c2ca 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -263,6 +263,9 @@ struct ospf_interface *ospf_if_new(struct ospf *ospf, struct interface *ifp,
ospf_opaque_type9_lsa_init(oi);
oi->ospf = ospf;
+
+ ospf_if_stream_set(oi);
+
QOBJ_REG(oi, ospf_interface);
if (IS_DEBUG_OSPF_EVENT)
@@ -322,6 +325,9 @@ void ospf_if_free(struct ospf_interface *oi)
{
ospf_if_down(oi);
+ if (oi->obuf)
+ ospf_fifo_free(oi->obuf);
+
assert(oi->state == ISM_Down);
ospf_opaque_type9_lsa_term(oi);
@@ -496,9 +502,8 @@ void ospf_if_stream_unset(struct ospf_interface *oi)
struct ospf *ospf = oi->ospf;
if (oi->obuf) {
- ospf_fifo_free(oi->obuf);
- oi->obuf = NULL;
-
+ /* flush the interface packet queue */
+ ospf_fifo_flush(oi->obuf);
/*reset protocol stats */
ospf_if_reset_stats(oi);
@@ -781,7 +786,6 @@ int ospf_if_up(struct ospf_interface *oi)
if (oi->type == OSPF_IFTYPE_LOOPBACK)
OSPF_ISM_EVENT_SCHEDULE(oi, ISM_LoopInd);
else {
- ospf_if_stream_set(oi);
OSPF_ISM_EVENT_SCHEDULE(oi, ISM_InterfaceUp);
}
diff --git a/pbrd/pbr_vty.c b/pbrd/pbr_vty.c
index ba5c49ad5c..b7d2b1a928 100644
--- a/pbrd/pbr_vty.c
+++ b/pbrd/pbr_vty.c
@@ -38,7 +38,7 @@
#include "pbrd/pbr_vty_clippy.c"
#endif
-DEFUN_NOSH(pbr_map, pbr_map_cmd, "pbr-map WORD seq (1-1000)",
+DEFUN_NOSH(pbr_map, pbr_map_cmd, "pbr-map WORD seq (1-700)",
"Create pbr-map or enter pbr-map command mode\n"
"The name of the PBR MAP\n"
"Sequence to insert in existing pbr-map entry\n"
@@ -54,7 +54,7 @@ DEFUN_NOSH(pbr_map, pbr_map_cmd, "pbr-map WORD seq (1-1000)",
return CMD_SUCCESS;
}
-DEFUN_NOSH(no_pbr_map, no_pbr_map_cmd, "no pbr-map WORD [seq (1-65535)]",
+DEFUN_NOSH(no_pbr_map, no_pbr_map_cmd, "no pbr-map WORD [seq (1-700)]",
NO_STR
"Delete pbr-map\n"
"The name of the PBR MAP\n"
diff --git a/pimd/COMMANDS b/pimd/COMMANDS
index 6f2e020bd8..141ec62aeb 100644
--- a/pimd/COMMANDS
+++ b/pimd/COMMANDS
@@ -24,6 +24,7 @@ verification commands:
show ip igmp groups retransmissions IGMP group retransmission
show ip igmp sources IGMP sources information
show ip igmp sources retransmissions IGMP source retransmission
+ show ip igmp statistics IGMP statistics information
show ip pim address PIM interface address
show ip pim assert PIM interface assert
show ip pim assert-internal PIM interface internal assert state
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index 35514a85da..81191eb96c 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -1294,6 +1294,76 @@ static void pim_show_interfaces_single(struct pim_instance *pim,
}
}
+static void igmp_show_statistics(struct pim_instance *pim, struct vty *vty,
+ const char *ifname, uint8_t uj)
+{
+ struct interface *ifp;
+ struct igmp_stats rx_stats;
+
+ igmp_stats_init(&rx_stats);
+
+ FOR_ALL_INTERFACES (pim->vrf, ifp) {
+ struct pim_interface *pim_ifp;
+ struct listnode *sock_node;
+ struct igmp_sock *igmp;
+
+ pim_ifp = ifp->info;
+
+ if (!pim_ifp)
+ continue;
+
+ if (ifname && strcmp(ifname, ifp->name))
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
+ igmp)) {
+ igmp_stats_add(&rx_stats, &igmp->rx_stats);
+ }
+ }
+ if (uj) {
+ json_object *json = NULL;
+ json_object *json_row = NULL;
+
+ json = json_object_new_object();
+ json_row = json_object_new_object();
+
+ json_object_string_add(json_row, "name", ifname ? ifname :
+ "global");
+ json_object_int_add(json_row, "queryV1", rx_stats.query_v1);
+ json_object_int_add(json_row, "queryV2", rx_stats.query_v2);
+ json_object_int_add(json_row, "queryV3", rx_stats.query_v3);
+ json_object_int_add(json_row, "leaveV3", rx_stats.leave_v2);
+ json_object_int_add(json_row, "reportV1", rx_stats.report_v1);
+ json_object_int_add(json_row, "reportV2", rx_stats.report_v2);
+ json_object_int_add(json_row, "reportV3", rx_stats.report_v3);
+ json_object_int_add(json_row, "mtraceResponse",
+ rx_stats.mtrace_rsp);
+ json_object_int_add(json_row, "mtraceRequest",
+ rx_stats.mtrace_req);
+ json_object_int_add(json_row, "unsupported",
+ rx_stats.unsupported);
+ json_object_object_add(json, ifname ? ifname : "global",
+ json_row);
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ } else {
+ vty_out(vty, "IGMP RX statistics\n");
+ vty_out(vty, "Interface : %s\n",
+ ifname ? ifname : "global");
+ vty_out(vty, "V1 query : %u\n", rx_stats.query_v1);
+ vty_out(vty, "V2 query : %u\n", rx_stats.query_v2);
+ vty_out(vty, "V3 query : %u\n", rx_stats.query_v3);
+ vty_out(vty, "V2 leave : %u\n", rx_stats.leave_v2);
+ vty_out(vty, "V1 report : %u\n", rx_stats.report_v1);
+ vty_out(vty, "V2 report : %u\n", rx_stats.report_v2);
+ vty_out(vty, "V3 report : %u\n", rx_stats.report_v3);
+ vty_out(vty, "mtrace response : %u\n", rx_stats.mtrace_rsp);
+ vty_out(vty, "mtrace request : %u\n", rx_stats.mtrace_req);
+ vty_out(vty, "unsupported : %u\n", rx_stats.unsupported);
+ }
+}
+
static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty,
uint8_t uj)
{
@@ -3527,6 +3597,33 @@ DEFUN (show_ip_igmp_sources_retransmissions,
return CMD_SUCCESS;
}
+DEFUN (show_ip_igmp_statistics,
+ show_ip_igmp_statistics_cmd,
+ "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
+ SHOW_STR
+ IP_STR
+ IGMP_STR
+ VRF_CMD_HELP_STR
+ "IGMP statistics\n"
+ "interface\n"
+ "IGMP interface\n"
+ JSON_STR)
+{
+ int idx = 2;
+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ uint8_t uj = use_json(argc, argv);
+
+ if (!vrf)
+ return CMD_WARNING;
+
+ if (argv_find(argv, argc, "WORD", &idx))
+ igmp_show_statistics(vrf->info, vty, argv[idx]->arg, uj);
+ else
+ igmp_show_statistics(vrf->info, vty, NULL, uj);
+
+ return CMD_SUCCESS;
+}
+
DEFUN (show_ip_pim_assert,
show_ip_pim_assert_cmd,
"show ip pim [vrf NAME] assert",
@@ -8644,6 +8741,7 @@ void pim_cmd_init(void)
install_element(VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
install_element(VIEW_NODE, &show_ip_igmp_sources_cmd);
install_element(VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
+ install_element(VIEW_NODE, &show_ip_igmp_statistics_cmd);
install_element(VIEW_NODE, &show_ip_pim_assert_cmd);
install_element(VIEW_NODE, &show_ip_pim_assert_internal_cmd);
install_element(VIEW_NODE, &show_ip_pim_assert_metric_cmd);
diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c
index 5e1aecc3a3..c980f5fcba 100644
--- a/pimd/pim_igmp.c
+++ b/pimd/pim_igmp.c
@@ -303,6 +303,21 @@ static int igmp_recv_query(struct igmp_sock *igmp, int query_version,
return -1;
}
+ /* Collecting IGMP Rx stats */
+ switch (query_version) {
+ case 1:
+ igmp->rx_stats.query_v1++;
+ break;
+ case 2:
+ igmp->rx_stats.query_v2++;
+ break;
+ case 3:
+ igmp->rx_stats.query_v3++;
+ break;
+ default:
+ igmp->rx_stats.unsupported++;
+ }
+
/*
* RFC 3376 defines some guidelines on operating in backwards
* compatibility with older versions of IGMP but there are some gaps in
@@ -400,6 +415,9 @@ static int igmp_v1_recv_report(struct igmp_sock *igmp, struct in_addr from,
return -1;
}
+ /* Collecting IGMP Rx stats */
+ igmp->rx_stats.report_v1++;
+
if (PIM_DEBUG_IGMP_TRACE) {
zlog_warn("%s %s: FIXME WRITEME", __FILE__,
__PRETTY_FUNCTION__);
@@ -524,6 +542,9 @@ int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len)
zlog_warn("Ignoring unsupported IGMP message type: %d", msg_type);
+ /* Collecting IGMP Rx stats */
+ igmp->rx_stats.unsupported++;
+
return -1;
}
@@ -867,6 +888,8 @@ static struct igmp_sock *igmp_sock_new(int fd, struct in_addr ifaddr,
pim_ifp->igmp_default_robustness_variable;
igmp->sock_creation = pim_time_monotonic_sec();
+ igmp_stats_init(&igmp->rx_stats);
+
if (mtrace_only) {
igmp->mtrace_only = mtrace_only;
return igmp;
diff --git a/pimd/pim_igmp.h b/pimd/pim_igmp.h
index 561a127d0f..c8b880ddd7 100644
--- a/pimd/pim_igmp.h
+++ b/pimd/pim_igmp.h
@@ -25,6 +25,7 @@
#include <zebra.h>
#include "vty.h"
#include "linklist.h"
+#include "pim_igmp_stats.h"
/*
The following sizes are likely to support
@@ -94,6 +95,8 @@ struct igmp_sock {
struct list *igmp_group_list; /* list of struct igmp_group */
struct hash *igmp_group_hash;
+
+ struct igmp_stats rx_stats;
};
struct igmp_sock *pim_igmp_sock_lookup_ifaddr(struct list *igmp_sock_list,
diff --git a/pimd/pim_igmp_mtrace.c b/pimd/pim_igmp_mtrace.c
index d3ae185709..673e2ca5b8 100644
--- a/pimd/pim_igmp_mtrace.c
+++ b/pimd/pim_igmp_mtrace.c
@@ -671,6 +671,9 @@ int igmp_mtrace_recv_qry_req(struct igmp_sock *igmp, struct ip *ip_hdr,
return -1;
}
+ /* Collecting IGMP Rx stats */
+ igmp->rx_stats.mtrace_req++;
+
if (PIM_DEBUG_MTRACE)
mtrace_debug(pim_ifp, mtracep, igmp_msg_len);
@@ -881,6 +884,9 @@ int igmp_mtrace_recv_response(struct igmp_sock *igmp, struct ip *ip_hdr,
mtracep->checksum = checksum;
+ /* Collecting IGMP Rx stats */
+ igmp->rx_stats.mtrace_rsp++;
+
if (PIM_DEBUG_MTRACE)
mtrace_debug(pim_ifp, mtracep, igmp_msg_len);
diff --git a/pimd/pim_igmp_stats.c b/pimd/pim_igmp_stats.c
new file mode 100644
index 0000000000..428816e1f0
--- /dev/null
+++ b/pimd/pim_igmp_stats.c
@@ -0,0 +1,42 @@
+/*
+ * PIM for FRRouting
+ * Copyright (C) 2018 Mladen Sablic
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "pim_igmp_stats.h"
+
+void igmp_stats_init(struct igmp_stats *stats)
+{
+ memset(stats, 0, sizeof(struct igmp_stats));
+}
+
+void igmp_stats_add(struct igmp_stats *a, struct igmp_stats *b)
+{
+ if (!a || !b)
+ return;
+
+ a->query_v1 += b->query_v1;
+ a->query_v2 += b->query_v2;
+ a->query_v3 += b->query_v3;
+ a->report_v1 += b->report_v1;
+ a->report_v2 += b->report_v2;
+ a->report_v3 += b->report_v3;
+ a->leave_v2 += b->leave_v2;
+ a->mtrace_rsp += b->mtrace_rsp;
+ a->mtrace_req += b->mtrace_req;
+ a->unsupported += b->unsupported;
+}
diff --git a/pimd/pim_igmp_stats.h b/pimd/pim_igmp_stats.h
new file mode 100644
index 0000000000..57b5cc62f4
--- /dev/null
+++ b/pimd/pim_igmp_stats.h
@@ -0,0 +1,41 @@
+/*
+ * PIM for FRRouting
+ * Copyright (C) 2018 Mladen Sablic
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef PIM_IGMP_STATS_H
+#define PIM_IGMP_STATS_H
+
+#include <zebra.h>
+
+struct igmp_stats {
+ uint32_t query_v1;
+ uint32_t query_v2;
+ uint32_t query_v3;
+ uint32_t report_v1;
+ uint32_t report_v2;
+ uint32_t report_v3;
+ uint32_t leave_v2;
+ uint32_t mtrace_rsp;
+ uint32_t mtrace_req;
+ uint32_t unsupported;
+};
+
+void igmp_stats_init(struct igmp_stats *stats);
+void igmp_stats_add(struct igmp_stats *a, struct igmp_stats *b);
+
+#endif /* PIM_IGMP_STATS_H */
diff --git a/pimd/pim_igmpv2.c b/pimd/pim_igmpv2.c
index dbbe83a965..19c3768813 100644
--- a/pimd/pim_igmpv2.c
+++ b/pimd/pim_igmpv2.c
@@ -121,6 +121,9 @@ int igmp_v2_recv_report(struct igmp_sock *igmp, struct in_addr from,
return -1;
}
+ /* Collecting IGMP Rx stats */
+ igmp->rx_stats.report_v2++;
+
memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr));
if (PIM_DEBUG_IGMP_PACKETS) {
@@ -167,6 +170,9 @@ int igmp_v2_recv_leave(struct igmp_sock *igmp, struct in_addr from,
return -1;
}
+ /* Collecting IGMP Rx stats */
+ igmp->rx_stats.leave_v2++;
+
memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr));
if (PIM_DEBUG_IGMP_PACKETS) {
diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c
index 3360e36b4a..5ccad39b33 100644
--- a/pimd/pim_igmpv3.c
+++ b/pimd/pim_igmpv3.c
@@ -1900,6 +1900,9 @@ int igmp_v3_recv_report(struct igmp_sock *igmp, struct in_addr from,
return -1;
}
+ /* Collecting IGMP Rx stats */
+ igmp->rx_stats.report_v3++;
+
num_groups = ntohs(
*(uint16_t *)(igmp_msg + IGMP_V3_REPORT_NUMGROUPS_OFFSET));
if (num_groups < 1) {
diff --git a/pimd/subdir.am b/pimd/subdir.am
index 2254362221..0696d9b1e8 100644
--- a/pimd/subdir.am
+++ b/pimd/subdir.am
@@ -20,6 +20,7 @@ pimd_libpim_a_SOURCES = \
pimd/pim_ifchannel.c \
pimd/pim_igmp.c \
pimd/pim_igmp_mtrace.c \
+ pimd/pim_igmp_stats.c \
pimd/pim_igmpv2.c \
pimd/pim_igmpv3.c \
pimd/pim_instance.c \
@@ -69,6 +70,7 @@ noinst_HEADERS += \
pimd/pim_igmp.h \
pimd/pim_igmp_join.h \
pimd/pim_igmp_mtrace.h \
+ pimd/pim_igmp_stats.h \
pimd/pim_igmpv2.h \
pimd/pim_igmpv3.h \
pimd/pim_instance.h \
diff --git a/redhat/frr.spec.in b/redhat/frr.spec.in
index f83c08e611..8632a4fb2f 100644
--- a/redhat/frr.spec.in
+++ b/redhat/frr.spec.in
@@ -534,7 +534,7 @@ rm -rf %{buildroot}
%defattr(-,root,root)
%doc */*.sample* AUTHORS COPYING
%doc doc/mpls
-%doc ChangeLog INSTALL NEWS README REPORTING-BUGS SERVICES
+%doc ChangeLog NEWS README SERVICES
%if 0%{?frr_user:1}
%dir %attr(751,%frr_user,%frr_user) %{_sysconfdir}
%dir %attr(750,%frr_user,%frr_user) /var/log/frr
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 867dc9cd15..01ba007767 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -1537,7 +1537,7 @@ DEFUNSH(VTYSH_RMAP, vtysh_route_map, vtysh_route_map_cmd,
}
DEFUNSH(VTYSH_PBRD, vtysh_pbr_map, vtysh_pbr_map_cmd,
- "pbr-map NAME seq (1-1000)",
+ "pbr-map NAME seq (1-700)",
"Create pbr-map or enter pbr-map command mode\n"
"The name of the PBR MAP\n"
"Sequence to insert to/delete from existing pbr-map entry\n"
@@ -1547,7 +1547,7 @@ DEFUNSH(VTYSH_PBRD, vtysh_pbr_map, vtysh_pbr_map_cmd,
return CMD_SUCCESS;
}
-DEFSH(VTYSH_PBRD, vtysh_no_pbr_map_cmd, "no pbr-map WORD [seq (1-65535)]",
+DEFSH(VTYSH_PBRD, vtysh_no_pbr_map_cmd, "no pbr-map WORD [seq (1-700)]",
NO_STR
"Delete pbr-map\n"
"The name of the PBR MAP\n"
@@ -2361,13 +2361,20 @@ DEFUNSH(VTYSH_ALL, no_vtysh_service_password_encrypt,
DEFUNSH(VTYSH_ALL, vtysh_config_password, vtysh_password_cmd,
"password [(8-8)] LINE",
- "Assign the terminal connection password\n"
+ "Modify the terminal connection password\n"
"Specifies a HIDDEN password will follow\n"
"The password string\n")
{
return CMD_SUCCESS;
}
+DEFUNSH(VTYSH_ALL, no_vtysh_config_password, no_vtysh_password_cmd,
+ "no password", NO_STR
+ "Modify the terminal connection password\n")
+{
+ return CMD_SUCCESS;
+}
+
DEFUNSH(VTYSH_ALL, vtysh_config_enable_password, vtysh_enable_password_cmd,
"enable password [(8-8)] LINE",
"Modify enable password parameters\n"
@@ -3605,6 +3612,7 @@ void vtysh_init_vty(void)
install_element(CONFIG_NODE, &no_vtysh_service_password_encrypt_cmd);
install_element(CONFIG_NODE, &vtysh_password_cmd);
+ install_element(CONFIG_NODE, &no_vtysh_password_cmd);
install_element(CONFIG_NODE, &vtysh_enable_password_cmd);
install_element(CONFIG_NODE, &no_vtysh_enable_password_cmd);
}
diff --git a/zebra/connected.c b/zebra/connected.c
index 23f2f666a0..a9a4dfe08f 100644
--- a/zebra/connected.c
+++ b/zebra/connected.c
@@ -403,10 +403,10 @@ void connected_down(struct interface *ifp, struct connected *ifc)
* head.
*/
rib_delete(afi, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0,
- &p, NULL, &nh, 0, 0, false, NULL);
+ &p, NULL, &nh, 0, 0, false);
rib_delete(afi, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0,
- &p, NULL, &nh, 0, 0, false, NULL);
+ &p, NULL, &nh, 0, 0, false);
if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
char buf[PREFIX_STRLEN];
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index e28c189f86..7423e9237f 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -1025,7 +1025,7 @@ static void if_netlink_check_ifp_instance_consistency(uint16_t cmd,
struct interface *ifp,
ns_id_t ns_id)
{
- struct interface *old_ifp;
+ struct interface *other_ifp;
/*
* look if interface name is also found on other netns
@@ -1037,29 +1037,42 @@ static void if_netlink_check_ifp_instance_consistency(uint16_t cmd,
if (!vrf_is_backend_netns() ||
!strcmp(ifp->name, "lo"))
return;
- old_ifp = if_lookup_by_name_not_ns(ns_id, ifp->name);
- if (!old_ifp)
+ other_ifp = if_lookup_by_name_not_ns(ns_id, ifp->name);
+ if (!other_ifp)
+ return;
+ /* because previous interface may be inactive,
+ * interface is moved back to default vrf
+ * then one may find the same pointer; ignore
+ */
+ if (other_ifp == ifp)
return;
if ((cmd == RTM_NEWLINK)
- && (CHECK_FLAG(old_ifp->status, ZEBRA_INTERFACE_ACTIVE)))
+ && (CHECK_FLAG(other_ifp->status, ZEBRA_INTERFACE_ACTIVE)))
return;
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug("%s %s(%u) %s VRF %u",
- cmd == RTM_DELLINK ?
- "RTM_DELLINK replaced by" :
- "RTM_NEWLINK replaces",
+ if (IS_ZEBRA_DEBUG_KERNEL && cmd == RTM_NEWLINK) {
+ zlog_debug("RTM_NEWLINK %s(%u, VRF %u) replaces %s(%u, VRF %u)\n",
ifp->name,
- old_ifp->ifindex,
- cmd == RTM_DELLINK ?
- "in" : "from",
- old_ifp->vrf_id);
+ ifp->ifindex,
+ ifp->vrf_id,
+ other_ifp->name,
+ other_ifp->ifindex,
+ other_ifp->vrf_id);
+ } else if (IS_ZEBRA_DEBUG_KERNEL && cmd == RTM_DELLINK) {
+ zlog_debug("RTM_DELLINK %s(%u, VRF %u) is replaced by %s(%u, VRF %u)\n",
+ ifp->name,
+ ifp->ifindex,
+ ifp->vrf_id,
+ other_ifp->name,
+ other_ifp->ifindex,
+ other_ifp->vrf_id);
+ }
/* the found interface replaces the current one
* remove it
*/
if (cmd == RTM_DELLINK)
if_delete(ifp);
else
- if_delete(old_ifp);
+ if_delete(other_ifp);
/* the found interface is replaced by the current one
* suppress it
*/
diff --git a/zebra/interface.c b/zebra/interface.c
index 6f59a2d399..7de18d683c 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -202,6 +202,7 @@ struct interface *if_link_per_ns(struct zebra_ns *ns, struct interface *ifp)
if (rn->info) {
ifp = (struct interface *)rn->info;
route_unlock_node(rn); /* get */
+ ifp->node = rn;
return ifp;
}
@@ -725,6 +726,9 @@ void if_delete_update(struct interface *ifp)
return;
}
+ if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE))
+ return;
+
/* Mark interface as inactive */
UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE);
@@ -1224,8 +1228,13 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp)
br_slave->bridge_ifindex);
}
- if (zebra_if->link_ifindex != IFINDEX_INTERNAL)
- vty_out(vty, " Link ifindex %u\n", zebra_if->link_ifindex);
+ if (zebra_if->link_ifindex != IFINDEX_INTERNAL) {
+ vty_out(vty, " Link ifindex %u", zebra_if->link_ifindex);
+ if (zebra_if->link)
+ vty_out(vty, "(%s)\n", zebra_if->link->name);
+ else
+ vty_out(vty, "(Unknown)\n");
+ }
if (HAS_LINK_PARAMS(ifp)) {
int i;
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c
index db4f19460a..6b587dab38 100644
--- a/zebra/kernel_netlink.c
+++ b/zebra/kernel_netlink.c
@@ -463,7 +463,7 @@ int netlink_parse_info(int (*filter)(struct sockaddr_nl *, struct nlmsghdr *,
int read_in = 0;
while (1) {
- char buf[NL_PKT_BUF_SIZE];
+ char buf[NL_RCV_PKT_BUF_SIZE];
struct iovec iov = {.iov_base = buf, .iov_len = sizeof buf};
struct sockaddr_nl snl;
struct msghdr msg = {.msg_name = (void *)&snl,
diff --git a/zebra/kernel_netlink.h b/zebra/kernel_netlink.h
index 8441eeac76..dc075b9aff 100644
--- a/zebra/kernel_netlink.h
+++ b/zebra/kernel_netlink.h
@@ -23,6 +23,7 @@
#ifdef HAVE_NETLINK
+#define NL_RCV_PKT_BUF_SIZE 32768
#define NL_PKT_BUF_SIZE 8192
extern void netlink_parse_rtattr(struct rtattr **tb, int max,
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index e60e05bcdf..b85c4748c4 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -1043,7 +1043,7 @@ void rtm_read(struct rt_msghdr *rtm)
if (rtm->rtm_type == RTM_CHANGE)
rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
- NULL, 0, 0, true, NULL);
+ NULL, 0, 0, true);
if (!nh.type) {
nh.type = NEXTHOP_TYPE_IPV4;
@@ -1058,7 +1058,7 @@ void rtm_read(struct rt_msghdr *rtm)
else
rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
- &nh, 0, 0, true, NULL);
+ &nh, 0, 0, true);
}
if (dest.sa.sa_family == AF_INET6) {
/* One day we might have a debug section here like one in the
@@ -1089,7 +1089,7 @@ void rtm_read(struct rt_msghdr *rtm)
if (rtm->rtm_type == RTM_CHANGE)
rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
- NULL, 0, 0, true, NULL);
+ NULL, 0, 0, true);
if (!nh.type) {
nh.type = ifindex ? NEXTHOP_TYPE_IPV6_IFINDEX
@@ -1106,7 +1106,7 @@ void rtm_read(struct rt_msghdr *rtm)
else
rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
- &nh, 0, 0, true, NULL);
+ &nh, 0, 0, true);
}
}
diff --git a/zebra/redistribute.c b/zebra/redistribute.c
index 810ee33839..5a6565aec9 100644
--- a/zebra/redistribute.c
+++ b/zebra/redistribute.c
@@ -592,7 +592,7 @@ int zebra_del_import_table_entry(struct route_node *rn, struct route_entry *re)
rib_delete(afi, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE, re->table,
re->flags, &p, NULL, re->ng.nexthop,
- zebrad.rtm_table_default, re->metric, false, NULL);
+ zebrad.rtm_table_default, re->metric, false);
return 0;
}
diff --git a/zebra/rib.h b/zebra/rib.h
index d68bf787c0..7b9e6d56a7 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -313,8 +313,7 @@ extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
extern void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
unsigned short instance, int flags, struct prefix *p,
struct prefix_ipv6 *src_p, const struct nexthop *nh,
- uint32_t table_id, uint32_t metric, bool fromkernel,
- struct ethaddr *rmac);
+ uint32_t table_id, uint32_t metric, bool fromkernel);
extern struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
union g_addr *addr,
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index a35dc9a177..9510a0e12c 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -613,12 +613,12 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
if (gate)
memcpy(&nh.gate, gate, sz);
rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0, flags,
- &p, NULL, &nh, table, metric, true, NULL);
+ &p, NULL, &nh, table, metric, true);
} else {
/* XXX: need to compare the entire list of nexthops
* here for NLM_F_APPEND stupidity */
rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0, flags,
- &p, NULL, NULL, table, metric, true, NULL);
+ &p, NULL, NULL, table, metric, true);
}
}
@@ -1233,14 +1233,6 @@ static void _netlink_route_build_multipath(const char *routedesc, int bytelen,
"netlink_route_multipath() (%s): "
"nexthop via if %u",
routedesc, nexthop->ifindex);
- } else if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) {
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug(
- "netlink_route_multipath() (%s): "
- "nexthop via if %u",
- routedesc, nexthop->ifindex);
- } else {
- rtnh->rtnh_ifindex = 0;
}
}
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index 2ff660b3f9..6bd12391db 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -1382,7 +1382,7 @@ static void zread_route_add(ZAPI_HANDLER_ARGS)
&(api_nh->gate.ipv4),
sizeof(struct in_addr));
zebra_vxlan_evpn_vrf_route_add(
- vrf_id, &api.rmac, &vtep_ip,
+ vrf_id, &api_nh->rmac, &vtep_ip,
&api.prefix);
}
break;
@@ -1415,7 +1415,7 @@ static void zread_route_add(ZAPI_HANDLER_ARGS)
&(api_nh->gate.ipv6),
sizeof(struct in6_addr));
zebra_vxlan_evpn_vrf_route_add(
- vrf_id, &api.rmac, &vtep_ip,
+ vrf_id, &api_nh->rmac, &vtep_ip,
&api.prefix);
}
break;
@@ -1522,7 +1522,7 @@ static void zread_route_del(ZAPI_HANDLER_ARGS)
rib_delete(afi, api.safi, zvrf_id(zvrf), api.type, api.instance,
api.flags, &api.prefix, src_p, NULL, table_id, api.metric,
- false, &api.rmac);
+ false);
/* Stats */
switch (api.prefix.family) {
@@ -1724,7 +1724,7 @@ static void zread_ipv4_delete(ZAPI_HANDLER_ARGS)
table_id = zvrf->table_id;
rib_delete(AFI_IP, api.safi, zvrf_id(zvrf), api.type, api.instance,
- api.flags, &p, NULL, NULL, table_id, 0, false, NULL);
+ api.flags, &p, NULL, NULL, table_id, 0, false);
client->v4_route_del_cnt++;
stream_failure:
@@ -2148,8 +2148,7 @@ static void zread_ipv6_delete(ZAPI_HANDLER_ARGS)
src_pp = NULL;
rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type, api.instance,
- api.flags, &p, src_pp, NULL, client->rtm_table, 0, false,
- NULL);
+ api.flags, &p, src_pp, NULL, client->rtm_table, 0, false);
client->v6_route_del_cnt++;
diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c
index 07e81aa020..d20f93f521 100644
--- a/zebra/zebra_ptm.c
+++ b/zebra/zebra_ptm.c
@@ -298,6 +298,9 @@ DEFUN (zebra_ptm_enable_if,
int old_ptm_enable;
int send_linkdown = 0;
+ if_data = ifp->info;
+ if_data->ptm_enable = ZEBRA_IF_PTM_ENABLE_UNSPEC;
+
if (ifp->ifindex == IFINDEX_INTERNAL) {
return CMD_SUCCESS;
}
@@ -317,9 +320,6 @@ DEFUN (zebra_ptm_enable_if,
}
}
- if_data = ifp->info;
- if_data->ptm_enable = ZEBRA_IF_PTM_ENABLE_UNSPEC;
-
return CMD_SUCCESS;
}
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 67832f2d3f..7ec640164a 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -2394,8 +2394,7 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
unsigned short instance, int flags, struct prefix *p,
struct prefix_ipv6 *src_p, const struct nexthop *nh,
- uint32_t table_id, uint32_t metric, bool fromkernel,
- struct ethaddr *rmac)
+ uint32_t table_id, uint32_t metric, bool fromkernel)
{
struct route_table *table;
struct route_node *rn;
@@ -2569,7 +2568,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
&(tmp_nh->gate.ipv6),
sizeof(struct in6_addr));
}
- zebra_vxlan_evpn_vrf_route_del(re->vrf_id, rmac,
+ zebra_vxlan_evpn_vrf_route_del(re->vrf_id,
&vtep_ip, p);
}
}
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 2ae9ac5082..e6f80f92a7 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -2798,12 +2798,14 @@ DEFUN (vrf_vni_mapping,
DEFUN (no_vrf_vni_mapping,
no_vrf_vni_mapping_cmd,
- "no vni " CMD_VNI_RANGE,
+ "no vni " CMD_VNI_RANGE "[prefix-routes-only]",
NO_STR
"VNI corresponding to tenant VRF\n"
- "VNI-ID")
+ "VNI-ID\n"
+ "prefix-routes-only\n")
{
int ret = 0;
+ int filter = 0;
char err[ERR_STR_SZ];
vni_t vni = strtoul(argv[2]->arg, NULL, 10);
@@ -2812,7 +2814,11 @@ DEFUN (no_vrf_vni_mapping,
assert(vrf);
assert(zvrf);
- ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 0, 0);
+ if (argc == 4)
+ filter = 1;
+
+ ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err,
+ ERR_STR_SZ, filter, 0);
if (ret != 0) {
vty_out(vty, "%s\n", err);
return CMD_WARNING;
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 6e901a0457..3278c86b99 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -3238,15 +3238,9 @@ static int zl3vni_remote_rmac_add(zebra_l3vni_t *zl3vni, struct ethaddr *rmac,
/* handle rmac delete */
-static int zl3vni_remote_rmac_del(zebra_l3vni_t *zl3vni, struct ethaddr *rmac,
+static void zl3vni_remote_rmac_del(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac,
struct prefix *host_prefix)
{
- zebra_mac_t *zrmac = NULL;
-
- zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
- if (!zrmac)
- return -1;
-
host_list_delete_host(zrmac->host_list, host_prefix);
if (list_isempty(zrmac->host_list)) {
@@ -3256,7 +3250,6 @@ static int zl3vni_remote_rmac_del(zebra_l3vni_t *zl3vni, struct ethaddr *rmac,
/* del the rmac entry */
zl3vni_rmac_del(zl3vni, zrmac);
}
- return 0;
}
/*
@@ -3394,15 +3387,9 @@ static int zl3vni_remote_nh_add(zebra_l3vni_t *zl3vni, struct ipaddr *vtep_ip,
}
/* handle nh neigh delete */
-static int zl3vni_remote_nh_del(zebra_l3vni_t *zl3vni, struct ipaddr *vtep_ip,
- struct prefix *host_prefix)
+static void zl3vni_remote_nh_del(zebra_l3vni_t *zl3vni, zebra_neigh_t *nh,
+ struct prefix *host_prefix)
{
- zebra_neigh_t *nh = NULL;
-
- nh = zl3vni_nh_lookup(zl3vni, vtep_ip);
- if (!nh)
- return -1;
-
host_list_delete_host(nh->host_list, host_prefix);
if (list_isempty(nh->host_list)) {
@@ -3412,8 +3399,6 @@ static int zl3vni_remote_nh_del(zebra_l3vni_t *zl3vni, struct ipaddr *vtep_ip,
/* delete the nh entry */
zl3vni_nh_del(zl3vni, nh);
}
-
- return 0;
}
/* handle neigh update from kernel - the only thing of interest is to
@@ -3958,34 +3943,65 @@ void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id, struct ethaddr *rmac,
struct prefix *host_prefix)
{
zebra_l3vni_t *zl3vni = NULL;
+ struct ipaddr ipv4_vtep;
zl3vni = zl3vni_from_vrf(vrf_id);
if (!zl3vni || !is_l3vni_oper_up(zl3vni))
return;
- /* add the next hop neighbor */
+ /*
+ * add the next hop neighbor -
+ * neigh to be installed is the ipv6 nexthop neigh
+ */
zl3vni_remote_nh_add(zl3vni, vtep_ip, rmac, host_prefix);
- /* add the rmac */
- zl3vni_remote_rmac_add(zl3vni, rmac, vtep_ip, host_prefix);
+ /*
+ * if the remote vtep is a ipv4 mapped ipv6 address convert it to ipv4
+ * address. Rmac is programmed against the ipv4 vtep because we only
+ * support ipv4 tunnels in the h/w right now
+ */
+ memset(&ipv4_vtep, 0, sizeof(struct ipaddr));
+ ipv4_vtep.ipa_type = IPADDR_V4;
+ if (vtep_ip->ipa_type == IPADDR_V6)
+ ipv4_mapped_ipv6_to_ipv4(&vtep_ip->ipaddr_v6,
+ &(ipv4_vtep.ipaddr_v4));
+ else
+ memcpy(&(ipv4_vtep.ipaddr_v4), &vtep_ip->ipaddr_v4,
+ sizeof(struct in_addr));
+
+ /*
+ * add the rmac - remote rmac to be installed is against the ipv4
+ * nexthop address
+ */
+ zl3vni_remote_rmac_add(zl3vni, rmac, &ipv4_vtep, host_prefix);
}
/* handle evpn vrf route delete */
-void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id, struct ethaddr *rmac,
+void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id,
struct ipaddr *vtep_ip,
struct prefix *host_prefix)
{
zebra_l3vni_t *zl3vni = NULL;
+ zebra_neigh_t *nh = NULL;
+ zebra_mac_t *zrmac = NULL;
zl3vni = zl3vni_from_vrf(vrf_id);
if (!zl3vni)
return;
+ /* find the next hop entry and rmac entry */
+ nh = zl3vni_nh_lookup(zl3vni, vtep_ip);
+ if (!nh)
+ return;
+ zrmac = zl3vni_rmac_lookup(zl3vni, &nh->emac);
+
/* delete the next hop entry */
- zl3vni_remote_nh_del(zl3vni, vtep_ip, host_prefix);
+ zl3vni_remote_nh_del(zl3vni, nh, host_prefix);
/* delete the rmac entry */
- zl3vni_remote_rmac_del(zl3vni, rmac, host_prefix);
+ if (zrmac)
+ zl3vni_remote_rmac_del(zl3vni, zrmac, host_prefix);
+
}
void zebra_vxlan_print_specific_rmac_l3vni(struct vty *vty, vni_t l3vni,
@@ -5143,7 +5159,7 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
l += IPV4_MAX_BYTELEN;
/* Get flags - sticky mac and/or gateway mac */
- flags = stream_getc(s);
+ STREAM_GETC(s, flags);
sticky = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
l++;
@@ -6516,6 +6532,12 @@ int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni,
return -1;
}
+ if (filter && !CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)) {
+ snprintf(err, ERR_STR_SZ,
+ "prefix-routes-only is not set for the vni");
+ return -1;
+ }
+
zebra_vxlan_process_l3vni_oper_down(zl3vni);
/* delete and uninstall all rmacs */
@@ -6602,7 +6624,7 @@ void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS)
}
s = msg;
- advertise = stream_getc(s);
+ STREAM_GETC(s, advertise);
vni = stream_get3(s);
zvni = zvni_lookup(vni);
@@ -6641,6 +6663,9 @@ void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS)
zvni_advertise_subnet(zvni, vlan_if, 1);
else
zvni_advertise_subnet(zvni, vlan_if, 0);
+
+stream_failure:
+ return;
}
/*
@@ -6663,7 +6688,7 @@ void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS)
s = msg;
STREAM_GETC(s, advertise);
- STREAM_GET(&vni, s, 3);
+ STREAM_GETL(s, vni);
if (!vni) {
if (IS_ZEBRA_DEBUG_VXLAN)
diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h
index 6153c7d7e3..34d1152751 100644
--- a/zebra/zebra_vxlan.h
+++ b/zebra/zebra_vxlan.h
@@ -160,7 +160,6 @@ extern void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id,
struct ipaddr *ip,
struct prefix *host_prefix);
extern void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id,
- struct ethaddr *rmac,
struct ipaddr *vtep_ip,
struct prefix *host_prefix);