summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_evpn.c33
-rw-r--r--bgpd/bgp_main.c27
-rw-r--r--bgpd/bgp_mplsvpn.c2
-rw-r--r--bgpd/bgp_route.c21
-rw-r--r--bgpd/bgp_vty.c2
-rw-r--r--bgpd/bgp_zebra.c2
-rwxr-xr-xconfigure.ac3
-rw-r--r--doc/developer/building-frr-on-ubuntu1204.rst9
-rw-r--r--doc/developer/building-frr-on-ubuntu1404.rst9
-rw-r--r--doc/developer/building-frr-on-ubuntu1604.rst11
-rw-r--r--doc/developer/building-frr-on-ubuntu1804.rst252
-rw-r--r--doc/manpages/common-options.rst7
-rw-r--r--doc/manpages/zebra.rst8
-rw-r--r--doc/user/bgp.rst4
-rw-r--r--doc/user/eigrpd.rst4
-rw-r--r--doc/user/ripd.rst3
-rw-r--r--doc/user/setup.rst4
-rw-r--r--doc/user/zebra.rst11
-rw-r--r--redhat/frr.spec.in12
-rw-r--r--ripd/rip_main.c29
-rw-r--r--ripngd/ripng_main.c31
-rw-r--r--tools/lsan-suppressions.txt1
-rw-r--r--vtysh/vtysh.c97
-rw-r--r--vtysh/vtysh_main.c7
-rw-r--r--zebra/main.c53
-rw-r--r--zebra/rib.h1
-rw-r--r--zebra/rt_netlink.c2
-rw-r--r--zebra/zebra_pbr.c11
-rw-r--r--zebra/zebra_pbr.h3
29 files changed, 356 insertions, 303 deletions
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index 8394c3a7b7..9f3fb3498c 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -164,6 +164,7 @@ static void vrf_import_rt_free(struct vrf_irt_node *irt)
}
hash_release(bgp_def->vrf_import_rt_hash, irt);
+ list_delete_and_null(&irt->vrfs);
XFREE(MTYPE_BGP_EVPN_VRF_IMPORT_RT, irt);
}
@@ -265,6 +266,7 @@ static struct irt_node *import_rt_new(struct bgp *bgp,
static void import_rt_free(struct bgp *bgp, struct irt_node *irt)
{
hash_release(bgp->import_rt_hash, irt);
+ list_delete_and_null(&irt->vnis);
XFREE(MTYPE_BGP_EVPN_IMPORT_RT, irt);
}
@@ -393,7 +395,6 @@ static void unmap_vrf_from_rt(struct bgp *bgp_vrf, struct vrf_irt_node *irt)
/* Delete VRF from list for this RT. */
listnode_delete(irt->vrfs, bgp_vrf);
if (!listnode_head(irt->vrfs)) {
- list_delete_and_null(&irt->vrfs);
vrf_import_rt_free(irt);
}
}
@@ -416,7 +417,7 @@ static void map_vni_to_rt(struct bgp *bgp, struct bgpevpn *vpn,
mask_ecom_global_admin(&eval_tmp, eval);
irt = lookup_import_rt(bgp, &eval_tmp);
- if (irt && irt->vnis)
+ if (irt)
if (is_vni_present_in_irt_vnis(irt->vnis, vpn))
/* Already mapped. */
return;
@@ -440,7 +441,6 @@ static void unmap_vni_from_rt(struct bgp *bgp, struct bgpevpn *vpn,
/* Delete VNI from hash list for this RT. */
listnode_delete(irt->vnis, vpn);
if (!listnode_head(irt->vnis)) {
- list_delete_and_null(&irt->vnis);
import_rt_free(bgp, irt);
}
}
@@ -771,8 +771,11 @@ static void add_mac_mobility_to_attr(uint32_t seq_num, struct attr *attr)
ecom_tmp.size = 1;
ecom_tmp.val = (uint8_t *)eval.val;
- attr->ecommunity =
- ecommunity_merge(attr->ecommunity, &ecom_tmp);
+ if (attr->ecommunity)
+ attr->ecommunity =
+ ecommunity_merge(attr->ecommunity, &ecom_tmp);
+ else
+ attr->ecommunity = ecommunity_dup(&ecom_tmp);
}
}
@@ -1853,6 +1856,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
SET_FLAG(ri->flags, BGP_INFO_VALID);
bgp_info_extra_get(ri);
ri->extra->parent = bgp_info_lock(parent_ri);
+ bgp_lock_node((struct bgp_node *)parent_ri->net);
if (parent_ri->extra) {
memcpy(&ri->extra->label, &parent_ri->extra->label,
sizeof(ri->extra->label));
@@ -1925,6 +1929,7 @@ static int install_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
SET_FLAG(ri->flags, BGP_INFO_VALID);
bgp_info_extra_get(ri);
ri->extra->parent = bgp_info_lock(parent_ri);
+ bgp_lock_node((struct bgp_node *)parent_ri->net);
if (parent_ri->extra) {
memcpy(&ri->extra->label, &parent_ri->extra->label,
sizeof(ri->extra->label));
@@ -2105,7 +2110,7 @@ static int is_route_matching_for_vrf(struct bgp *bgp_vrf, struct bgp_info *ri)
/* See if this RT matches specified VNIs import RTs */
irt = lookup_vrf_import_rt(eval);
- if (irt && irt->vrfs)
+ if (irt)
if (is_vrf_present_in_irt_vrfs(irt->vrfs, bgp_vrf))
return 1;
@@ -2123,7 +2128,7 @@ static int is_route_matching_for_vrf(struct bgp *bgp_vrf, struct bgp_info *ri)
mask_ecom_global_admin(&eval_tmp, eval);
irt = lookup_vrf_import_rt(&eval_tmp);
}
- if (irt && irt->vrfs)
+ if (irt)
if (is_vrf_present_in_irt_vrfs(irt->vrfs, bgp_vrf))
return 1;
}
@@ -2172,7 +2177,7 @@ static int is_route_matching_for_vni(struct bgp *bgp, struct bgpevpn *vpn,
/* See if this RT matches specified VNIs import RTs */
irt = lookup_import_rt(bgp, eval);
- if (irt && irt->vnis)
+ if (irt)
if (is_vni_present_in_irt_vnis(irt->vnis, vpn))
return 1;
@@ -2190,7 +2195,7 @@ static int is_route_matching_for_vni(struct bgp *bgp, struct bgpevpn *vpn,
mask_ecom_global_admin(&eval_tmp, eval);
irt = lookup_import_rt(bgp, &eval_tmp);
}
- if (irt && irt->vnis)
+ if (irt)
if (is_vni_present_in_irt_vnis(irt->vnis, vpn))
return 1;
}
@@ -2544,7 +2549,7 @@ static int install_uninstall_evpn_route(struct bgp *bgp, afi_t afi, safi_t safi,
* into l2vni table)
*/
irt = lookup_import_rt(bgp, eval);
- if (irt && irt->vnis)
+ if (irt)
install_uninstall_route_in_vnis(bgp, afi, safi, evp, ri,
irt->vnis, import);
@@ -2552,7 +2557,7 @@ static int install_uninstall_evpn_route(struct bgp *bgp, afi_t afi, safi_t safi,
* into l3vni/vrf table)
*/
vrf_irt = lookup_vrf_import_rt(eval);
- if (vrf_irt && vrf_irt->vrfs)
+ if (vrf_irt)
install_uninstall_route_in_vrfs(bgp, afi, safi, evp, ri,
vrf_irt->vrfs, import);
@@ -2572,10 +2577,10 @@ static int install_uninstall_evpn_route(struct bgp *bgp, afi_t afi, safi_t safi,
irt = lookup_import_rt(bgp, &eval_tmp);
vrf_irt = lookup_vrf_import_rt(&eval_tmp);
}
- if (irt && irt->vnis)
+ if (irt)
install_uninstall_route_in_vnis(bgp, afi, safi, evp, ri,
irt->vnis, import);
- if (vrf_irt && vrf_irt->vrfs)
+ if (vrf_irt)
install_uninstall_route_in_vrfs(bgp, afi, safi, evp, ri,
vrf_irt->vrfs, import);
}
@@ -3326,7 +3331,7 @@ void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf, struct prefix *p,
int ret = 0;
struct prefix_evpn evp;
char buf[PREFIX_STRLEN];
-
+
build_type5_prefix_from_ip_prefix(&evp, p);
ret = update_evpn_type5_route(bgp_vrf, &evp, src_attr);
if (ret)
diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index 004bdd90a2..acb4272cd1 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -68,6 +68,9 @@
static const struct option longopts[] = {
{"bgp_port", required_argument, NULL, 'p'},
{"listenon", required_argument, NULL, 'l'},
+#if CONFDATE > 20190521
+ CPP_NOTICE("-r / --retain has reached deprecation EOL, remove")
+#endif
{"retain", no_argument, NULL, 'r'},
{"no_kernel", no_argument, NULL, 'n'},
{"skip_runas", no_argument, NULL, 'S'},
@@ -101,9 +104,6 @@ static struct quagga_signal_t bgp_signals[] = {
},
};
-/* Route retain mode flag. */
-static int retain_mode = 0;
-
/* privileges */
static zebra_capabilities_t _caps_p[] = {ZCAP_BIND, ZCAP_NET_RAW,
ZCAP_NET_ADMIN, ZCAP_SYS_ADMIN};
@@ -146,8 +146,7 @@ __attribute__((__noreturn__)) void sigint(void)
assert(bm->terminating == false);
bm->terminating = true; /* global flag that shutting down */
- if (!retain_mode)
- bgp_terminate();
+ bgp_terminate();
bgp_exit(0);
@@ -324,6 +323,11 @@ FRR_DAEMON_INFO(bgpd, BGP, .vty_port = BGP_VTY_PORT,
.privs = &bgpd_privs, )
+#if CONFDATE > 20190521
+CPP_NOTICE("-r / --retain has reached deprecation EOL, remove")
+#endif
+#define DEPRECATED_OPTIONS "r"
+
/* Main routine of bgpd. Treatment of argument and start bgp finite
state machine is handled at here. */
int main(int argc, char **argv)
@@ -338,10 +342,9 @@ int main(int argc, char **argv)
frr_preinit(&bgpd_di, argc, argv);
frr_opt_add(
- "p:l:rSne:", longopts,
+ "p:l:Sne:" DEPRECATED_OPTIONS, longopts,
" -p, --bgp_port Set BGP listen port number (0 means do not listen).\n"
" -l, --listenon Listen on specified address (implies -n)\n"
- " -r, --retain When program terminates, retain added route by bgpd.\n"
" -n, --no_kernel Do not install route to kernel.\n"
" -S, --skip_runas Skip capabilities checks, and changing user and group IDs.\n"
" -e, --ecmp Specify ECMP to use.\n");
@@ -350,6 +353,13 @@ int main(int argc, char **argv)
while (1) {
opt = frr_getopt(argc, argv, 0);
+ if (opt && opt < 128 && strchr(DEPRECATED_OPTIONS, opt)) {
+ fprintf(stderr,
+ "The -%c option no longer exists.\nPlease refer to the manual.\n",
+ opt);
+ continue;
+ }
+
if (opt == EOF)
break;
@@ -373,9 +383,6 @@ int main(int argc, char **argv)
return 1;
}
break;
- case 'r':
- retain_mode = 1;
- break;
case 'l':
bgp_address = optarg;
/* listenon implies -n */
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index bcc448119c..b58e9da6f4 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -571,7 +571,7 @@ leak_update(
setlabels(new, label, num_labels);
new->extra->parent = bgp_info_lock(parent);
-
+ bgp_lock_node((struct bgp_node *)((struct bgp_info *)parent)->net);
if (bgp_orig)
new->extra->bgp_orig = bgp_orig;
if (nexthop_orig)
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 7bfeee9669..d0c2ff8186 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -205,6 +205,14 @@ struct bgp_info *bgp_info_new(void)
/* Free bgp route information. */
static void bgp_info_free(struct bgp_info *binfo)
{
+ /* unlink reference to parent, if any. */
+ if (binfo->extra && binfo->extra->parent) {
+ bgp_info_unlock((struct bgp_info *)binfo->extra->parent);
+ bgp_unlock_node((struct bgp_node *)((struct bgp_info *)binfo
+ ->extra->parent)->net);
+ binfo->extra->parent = NULL;
+ }
+
if (binfo->attr)
bgp_attr_unintern(&binfo->attr);
@@ -225,11 +233,6 @@ struct bgp_info *bgp_info_lock(struct bgp_info *binfo)
struct bgp_info *bgp_info_unlock(struct bgp_info *binfo)
{
- /* unlink reference to parent, if any. */
- if (binfo->extra && binfo->extra->parent) {
- bgp_info_unlock((struct bgp_info *)binfo->extra->parent);
- binfo->extra->parent = NULL;
- }
assert(binfo && binfo->lock > 0);
binfo->lock--;
@@ -9645,13 +9648,13 @@ static struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,
json_object *json_no = NULL;
json_no = json_object_new_object();
json_object_string_add(json_no, "warning",
- "No such neighbor");
+ "No such neighbor in this view/vrf");
vty_out(vty, "%s\n",
json_object_to_json_string_ext(
json_no, JSON_C_TO_STRING_PRETTY));
json_object_free(json_no);
} else
- vty_out(vty, "No such neighbor\n");
+ vty_out(vty, "No such neighbor in this view/vrf\n");
return NULL;
}
@@ -10749,10 +10752,8 @@ DEFUN (show_ip_bgp_neighbor_routes,
peerstr = argv[++idx]->arg;
peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
- if (!peer) {
- vty_out(vty, "No such neighbor\n");
+ if (!peer)
return CMD_WARNING;
- }
if (argv_find(argv, argc, "flap-statistics", &idx))
sh_type = bgp_show_type_flap_neighbor;
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index f4f4e63264..a81a83edde 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -10655,7 +10655,7 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp,
if (use_json)
json_object_boolean_true_add(json, "bgpNoSuchNeighbor");
else
- vty_out(vty, "%% No such neighbor\n");
+ vty_out(vty, "%% No such neighbor in this view/vrf\n");
}
if (use_json) {
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 4a909d8cdc..390eb44eb8 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -1193,7 +1193,7 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
return;
if (bgp_debug_zebra(p))
- prefix2str(&api.prefix, buf_prefix, sizeof(buf_prefix));
+ prefix2str(p, buf_prefix, sizeof(buf_prefix));
if (safi == SAFI_FLOWSPEC)
return bgp_pbr_update_entry(bgp, &rn->p,
diff --git a/configure.ac b/configure.ac
index 8b49295444..7c7de19e1f 100755
--- a/configure.ac
+++ b/configure.ac
@@ -192,6 +192,7 @@ AC_ARG_ENABLE([address-sanitizer], AS_HELP_STRING([--enable-address-sanitizer],
[AC_DEFINE(HAVE_ADDRESS_SANITIZER, 1, [enable AddressSanitizer])
CFLAGS="$CFLAGS -fsanitize=address"
CXXFLAGS="$CXXFLAGS -fsanitize=address"
+ LIBS="-ldl $LIBS"
AC_TRY_COMPILE([],[const int i=0;],[AC_MSG_NOTICE([Address Sanitizer Enabled])],
[AC_MSG_ERROR([Address Sanitizer not available])])
])
@@ -202,6 +203,7 @@ AC_ARG_ENABLE([thread-sanitizer], AS_HELP_STRING([--enable-thread-sanitizer], \
[AC_DEFINE(HAVE_THREAD_SANITIZER, 1, [enable ThreadSanitizer])
CFLAGS="$CFLAGS -fsanitize=thread"
CXXFLAGS="$CXXFLAGS -fsanitize=thread"
+ LIBS="-ldl $LIBS"
AC_TRY_COMPILE([],[const int i=0;],[AC_MSG_NOTICE([Thread Sanitizer Enabled])],
[AC_MSG_ERROR([Thread Sanitizer not available])])
])
@@ -212,6 +214,7 @@ AC_ARG_ENABLE([memory-sanitizer], AS_HELP_STRING([--enable-memory-sanitizer], \
[AC_DEFINE(HAVE_THREAD_SANITIZER, 1, [enable MemorySanitizer])
CFLAGS="$CFLAGS -fsanitize=memory -fPIE -pie"
CXXFLAGS="$CXXFLAGS -fsanitize=memory -fPIE -pie"
+ LIBS="-ldl $LIBS"
AC_TRY_COMPILE([],[const int i=0;],[AC_MSG_NOTICE([Memory Sanitizer Enabled])],
[AC_MSG_ERROR([Memory Sanitizer not available])])
])
diff --git a/doc/developer/building-frr-on-ubuntu1204.rst b/doc/developer/building-frr-on-ubuntu1204.rst
index bba49c1ce7..459d411ebc 100644
--- a/doc/developer/building-frr-on-ubuntu1204.rst
+++ b/doc/developer/building-frr-on-ubuntu1204.rst
@@ -13,9 +13,10 @@ Add packages:
::
- apt-get install git autoconf automake libtool make gawk libreadline-dev \
- texinfo libpam0g-dev dejagnu libjson0-dev pkg-config libpam0g-dev \
- libjson0-dev flex python-pip libc-ares-dev python3-dev python3-sphinx
+ apt-get install \
+ git autoconf automake libtool make gawk libreadline-dev texinfo \
+ dejagnu pkg-config libpam0g-dev libjson0-dev flex python-pip \
+ libc-ares-dev python3-dev python3-sphinx install-info
Install newer bison from 14.04 package source (Ubuntu 12.04 package
source is too old)
@@ -74,7 +75,7 @@ Add frr groups and user
::
- sudo groupadd -g 92 frr
+ sudo groupadd -r -g 92 frr
sudo groupadd -r -g 85 frrvty
sudo adduser --system --ingroup frr --home /var/run/frr/ \
--gecos "FRR suite" --shell /sbin/nologin frr
diff --git a/doc/developer/building-frr-on-ubuntu1404.rst b/doc/developer/building-frr-on-ubuntu1404.rst
index c86f1124a7..681cc30a3b 100644
--- a/doc/developer/building-frr-on-ubuntu1404.rst
+++ b/doc/developer/building-frr-on-ubuntu1404.rst
@@ -13,9 +13,10 @@ Add packages:
::
- apt-get install git autoconf automake libtool make gawk libreadline-dev \
- texinfo dejagnu pkg-config libpam0g-dev libjson-c-dev bison flex \
- python-pytest libc-ares-dev python3-dev python3-sphinx
+ apt-get install \
+ git autoconf automake libtool make gawk libreadline-dev texinfo dejagnu \
+ pkg-config libpam0g-dev libjson-c-dev bison flex python-pytest \
+ libc-ares-dev python3-dev python3-sphinx install-info
Get FRR, compile it and install it (from Git)
---------------------------------------------
@@ -28,7 +29,7 @@ Add frr groups and user
::
- sudo groupadd -g 92 frr
+ sudo groupadd -r -g 92 frr
sudo groupadd -r -g 85 frrvty
sudo adduser --system --ingroup frr --home /var/run/frr/ \
--gecos "FRR suite" --shell /sbin/nologin frr
diff --git a/doc/developer/building-frr-on-ubuntu1604.rst b/doc/developer/building-frr-on-ubuntu1604.rst
index 1b371893e2..69c4e44d98 100644
--- a/doc/developer/building-frr-on-ubuntu1604.rst
+++ b/doc/developer/building-frr-on-ubuntu1604.rst
@@ -13,10 +13,11 @@ Add packages:
::
- apt-get install git autoconf automake libtool make gawk libreadline-dev \
- texinfo dejagnu pkg-config libpam0g-dev libjson-c-dev bison flex \
- python-pytest libc-ares-dev python3-dev libsystemd-dev python-ipaddr \
- python3-sphinx
+ apt-get install \
+ git autoconf automake libtool make gawk libreadline-dev texinfo dejagnu \
+ pkg-config libpam0g-dev libjson-c-dev bison flex python-pytest \
+ libc-ares-dev python3-dev libsystemd-dev python-ipaddr python3-sphinx \
+ install-info
Get FRR, compile it and install it (from Git)
---------------------------------------------
@@ -29,7 +30,7 @@ Add frr groups and user
::
- sudo groupadd -g 92 frr
+ sudo groupadd -r -g 92 frr
sudo groupadd -r -g 85 frrvty
sudo adduser --system --ingroup frr --home /var/run/frr/ \
--gecos "FRR suite" --shell /sbin/nologin frr
diff --git a/doc/developer/building-frr-on-ubuntu1804.rst b/doc/developer/building-frr-on-ubuntu1804.rst
index d9fc37c172..50e90fc7ea 100644
--- a/doc/developer/building-frr-on-ubuntu1804.rst
+++ b/doc/developer/building-frr-on-ubuntu1804.rst
@@ -1,33 +1,19 @@
-Ubuntu 18.04LTS
-===============================================
+Ubuntu 18.04 LTS
+================
Install dependencies
--------------------------
+--------------------
+
Required packages
^^^^^^^^^^^^^^^^^
::
- sudo apt-get install \
- git \
- autoconf \
- automake \
- libtool \
- make \
- gawk \
- libreadline-dev \
- texinfo \
- pkg-config \
- libpam0g-dev \
- libjson-c-dev \
- bison \
- flex \
- python-pytest \
- libc-ares-dev \
- python3-dev \
- libsystemd-dev \
- python-ipaddr \
- python3-sphinx
+ sudo apt-get install \
+ git autoconf automake libtool make gawk libreadline-dev texinfo \
+ pkg-config libpam0g-dev libjson-c-dev bison flex python-pytest \
+ libc-ares-dev python3-dev libsystemd-dev python-ipaddr python3-sphinx \
+ install-info
Optional packages
^^^^^^^^^^^^^^^^^
@@ -39,18 +25,18 @@ Protobuf
::
- sudo apt-get install \
- protobuf-c-compiler \
- libprotobuf-c-dev
+ sudo apt-get install \
+ protobuf-c-compiler \
+ libprotobuf-c-dev
ZeroMQ
~~~~~~
::
- sudo apt-get install \
- libzmq5 \
- libzmq3-dev
+ sudo apt-get install \
+ libzmq5 \
+ libzmq3-dev
Get FRR, compile it and install it (from Git)
---------------------------------------------
@@ -63,18 +49,18 @@ Add frr groups and user
::
- sudo groupadd -g 92 frr
- sudo groupadd -r -g 85 frrvty
- sudo adduser --system --ingroup frr --home /var/run/frr/ \
- --gecos "FRR suite" --shell /sbin/nologin frr
- sudo usermod -a -G frrvty frr
+ sudo groupadd -r -g 92 frr
+ sudo groupadd -r -g 85 frrvty
+ sudo adduser --system --ingroup frr --home /var/run/frr/ \
+ --gecos "FRR suite" --shell /sbin/nologin frr
+ sudo usermod -a -G frrvty frr
Download source
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+^^^^^^^^^^^^^^^
::
- git clone https://github.com/frrouting/frr.git frr
+ git clone https://github.com/frrouting/frr.git frr
Configure
^^^^^^^^^
@@ -82,31 +68,31 @@ Options below are provided as an example.
.. seealso:: *Installation* section of user guide
-::
-
- cd frr
- ./bootstrap.sh
- ./configure \
- --prefix=/usr \
- --enable-exampledir=/usr/share/doc/frr/examples/ \
- --localstatedir=/var/run/frr \
- --sbindir=/usr/lib/frr \
- --sysconfdir=/etc/frr \
- --enable-pimd \
- --enable-watchfrr \
- --enable-ospfclient=yes \
- --enable-ospfapi=yes \
- --enable-multipath=64 \
- --enable-user=frr \
- --enable-group=frr \
- --enable-vty-group=frrvty \
- --enable-configfile-mask=0640 \
- --enable-logfile-mask=0640 \
- --enable-rtadv \
- --enable-fpm \
- --enable-systemd=yes \
- --with-pkg-git-version \
- --with-pkg-extra-version=-MyOwnFRRVersion
+.. code-block:: shell
+
+ cd frr
+ ./bootstrap.sh
+ ./configure \
+ --prefix=/usr \
+ --enable-exampledir=/usr/share/doc/frr/examples/ \
+ --localstatedir=/var/run/frr \
+ --sbindir=/usr/lib/frr \
+ --sysconfdir=/etc/frr \
+ --enable-pimd \
+ --enable-watchfrr \
+ --enable-ospfclient=yes \
+ --enable-ospfapi=yes \
+ --enable-multipath=64 \
+ --enable-user=frr \
+ --enable-group=frr \
+ --enable-vty-group=frrvty \
+ --enable-configfile-mask=0640 \
+ --enable-logfile-mask=0640 \
+ --enable-rtadv \
+ --enable-fpm \
+ --enable-systemd=yes \
+ --with-pkg-git-version \
+ --with-pkg-extra-version=-MyOwnFRRVersion
If optional packages were installed, the associated feature may now be
enabled.
@@ -124,9 +110,9 @@ Compile
::
- make
- make check
- sudo make install
+ make
+ make check
+ sudo make install
Create empty FRR configuration files
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -136,122 +122,128 @@ configuration files _before_ starting FRR. This assures that the permissions
are correct. If the files are not already present, FRR will create them.
It's also important to consider _which_ files to create. FRR supports writing
-configuration to a monolithic file, ``/etc/frr/frr.conf``, which is not
-recommended
+configuration to a monolithic file, :file:`/etc/frr/frr.conf`.
+
.. seealso:: *VTYSH* section of user guide
-The presence of ``/etc/frr/frr.conf`` on startup implicitly configures FRR to
-ignore daemon-specific configuration files.
+The presence of :file:`/etc/frr/frr.conf` on startup implicitly configures FRR
+to ignore daemon-specific configuration files.
Daemon-specific configuration
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
- sudo install -m 755 -o frr -g frr -d /var/log/frr
- sudo install -m 775 -o frr -g frrvty -d /etc/frr
- sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf
- sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf
- sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospfd.conf
- sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospf6d.conf
- sudo install -m 640 -o frr -g frr /dev/null /etc/frr/isisd.conf
- sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripd.conf
- sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripngd.conf
- sudo install -m 640 -o frr -g frr /dev/null /etc/frr/pimd.conf
- sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ldpd.conf
- sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf
+ sudo install -m 755 -o frr -g frr -d /var/log/frr
+ sudo install -m 775 -o frr -g frrvty -d /etc/frr
+ sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf
+ sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf
+ sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospfd.conf
+ sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospf6d.conf
+ sudo install -m 640 -o frr -g frr /dev/null /etc/frr/isisd.conf
+ sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripd.conf
+ sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripngd.conf
+ sudo install -m 640 -o frr -g frr /dev/null /etc/frr/pimd.conf
+ sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ldpd.conf
+ sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf
Monolithic configuration
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~
::
- sudo install -m 755 -o frr -g frr -d /var/log/frr
- sudo install -m 775 -o frr -g frrvty -d /etc/frr
- sudo install -m 640 -o frr -g frr /dev/null /etc/frr/frr.conf
+ sudo install -m 755 -o frr -g frr -d /var/log/frr
+ sudo install -m 775 -o frr -g frrvty -d /etc/frr
+ sudo install -m 640 -o frr -g frr /dev/null /etc/frr/frr.conf
Enable IPv4 & IPv6 forwarding
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Edit ``/etc/sysctl.conf`` and uncomment the following values (ignore the
-other settings)
+Edit :file:`/etc/sysctl.conf` and uncomment the following values (ignore the
+other settings):
::
- # Uncomment the next line to enable packet forwarding for IPv4
- net.ipv4.ip_forward=1
+ # Uncomment the next line to enable packet forwarding for IPv4
+ net.ipv4.ip_forward=1
- # Uncomment the next line to enable packet forwarding for IPv6
- # Enabling this option disables Stateless Address Autoconfiguration
- # based on Router Advertisements for this host
- net.ipv6.conf.all.forwarding=1
+ # Uncomment the next line to enable packet forwarding for IPv6
+ # Enabling this option disables Stateless Address Autoconfiguration
+ # based on Router Advertisements for this host
+ net.ipv6.conf.all.forwarding=1
Add MPLS kernel modules
^^^^^^^^^^^^^^^^^^^^^^^
-Ubuntu 18.04 ships with kernel 4.15. MPLS modules are present by default.
-To enable, add the following lines to ``/etc/modules-load.d/modules.conf``:
+Ubuntu 18.04 ships with kernel 4.15. MPLS modules are present by default. To
+enable, add the following lines to :file:`/etc/modules-load.d/modules.conf`:
::
- # Load MPLS Kernel Modules
- mpls_router
- mpls_iptunnel
+ # Load MPLS Kernel Modules
+ mpls_router
+ mpls_iptunnel
-**Reboot** or use ``sysctl -p`` to apply the same config to the running
-system
+Reboot or use ``sysctl -p`` to apply the same config to the running system.
Enable MPLS Forwarding
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+^^^^^^^^^^^^^^^^^^^^^^
-Edit ``/etc/sysctl.conf`` and the following lines. Make sure to add a
-line equal to ``net.mpls.conf.eth0.input`` or each interface used with
-MPLS
+Edit :file:`/etc/sysctl.conf` and the following lines. Make sure to add a line
+equal to :file:`net.mpls.conf.eth0.input` for each interface used with MPLS.
::
- # Enable MPLS Label processing on all interfaces
- net.mpls.conf.eth0.input=1
- net.mpls.conf.eth1.input=1
- net.mpls.conf.eth2.input=1
- net.mpls.platform_labels=100000
+ # Enable MPLS Label processing on all interfaces
+ net.mpls.conf.eth0.input=1
+ net.mpls.conf.eth1.input=1
+ net.mpls.conf.eth2.input=1
+ net.mpls.platform_labels=100000
-Install the systemd service (if rebooted from last step, change directory back to frr directory)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Install the systemd service
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- sudo install -m 644 tools/frr.service /etc/systemd/system/frr.service
- sudo install -m 644 tools/etc/default/frr /etc/default/frr
- sudo install -m 644 tools/etc/frr/daemons /etc/frr/daemons
- sudo install -m 644 tools/etc/frr/daemons.conf /etc/frr/daemons.conf
- sudo install -m 644 tools/etc/frr/frr.conf /etc/frr/frr.conf
- sudo install -m 644 -o frr -g frr tools/etc/frr/vtysh.conf /etc/frr/vtysh.conf
+ sudo install -m 644 tools/frr.service /etc/systemd/system/frr.service
+ sudo install -m 644 tools/etc/default/frr /etc/default/frr
+ sudo install -m 644 tools/etc/frr/daemons /etc/frr/daemons
+ sudo install -m 644 tools/etc/frr/daemons.conf /etc/frr/daemons.conf
+ sudo install -m 644 tools/etc/frr/frr.conf /etc/frr/frr.conf
+ sudo install -m 644 -o frr -g frr tools/etc/frr/vtysh.conf /etc/frr/vtysh.conf
Enable daemons
^^^^^^^^^^^^^^
-| Edit ``/etc/frr/daemons`` and change the value from "no" to "yes" for
- those daemons you want to start by systemd.
-| For example.
+Edit ``/etc/frr/daemons`` and change the value from "no" to "yes" for those
+daemons you want to start by systemd. For example:
::
- zebra=yes
- bgpd=yes
- ospfd=yes
- ospf6d=yes
- ripd=yes
- ripngd=yes
- isisd=yes
+ zebra=yes
+ bgpd=yes
+ ospfd=yes
+ ospf6d=yes
+ ripd=yes
+ ripngd=yes
+ isisd=yes
Enable the systemd service
^^^^^^^^^^^^^^^^^^^^^^^^^^
-- systemctl enable frr
+Enabling the systemd service causes FRR to be started upon boot. To enable it,
+use the following command:
+
+.. code-block:: shell
+
+ systemctl enable frr
Start the systemd service
^^^^^^^^^^^^^^^^^^^^^^^^^
-- systemctl start frr
-- use ``systemctl status frr`` to check its status.
+.. code-block:: shell
+
+ systemctl start frr
+
+After starting the service, you can use ``systemctl status frr`` to check its
+status.
diff --git a/doc/manpages/common-options.rst b/doc/manpages/common-options.rst
index e433c720af..e9241b7438 100644
--- a/doc/manpages/common-options.rst
+++ b/doc/manpages/common-options.rst
@@ -157,10 +157,3 @@ frr supports optional dynamically loadable modules, although these can only be l
The list of loaded modules can be inspected at runtime with the show modules VTY command.
-ROUTES
-------
-
-.. option:: -r, --retain
-
- When the program terminates, retain routes added by the daemon.
-
diff --git a/doc/manpages/zebra.rst b/doc/manpages/zebra.rst
index 4ddf989951..a8a9301588 100644
--- a/doc/manpages/zebra.rst
+++ b/doc/manpages/zebra.rst
@@ -42,6 +42,14 @@ OPTIONS available for the |DAEMON| command:
Enable namespace VRF backend. By default, the VRF backend relies on VRF-lite support from the Linux kernel. This option permits discovering Linux named network namespaces and mapping it to FRR VRF contexts.
+ROUTES
+------
+
+.. option:: -r, --retain
+
+ When the program terminates, do not flush routes installed by zebra from the kernel.
+
+
FILES
=====
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index 861e3d0d6d..9332fdf3b7 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -30,10 +30,6 @@ be specified (:ref:`common-invocation-options`).
Set the bgp protocol's port number. When port number is 0, that means do not
listen bgp port.
-.. option:: -r, --retain
-
- When program terminates, retain BGP routes added by zebra.
-
.. option:: -l, --listenon
Specify a specific IP address for bgpd to listen on, rather than its
diff --git a/doc/user/eigrpd.rst b/doc/user/eigrpd.rst
index 6034bf8948..330267a8ee 100644
--- a/doc/user/eigrpd.rst
+++ b/doc/user/eigrpd.rst
@@ -60,10 +60,6 @@ Certain signals have special meanings to *eigrpd*.
.. program:: eigrpd
-.. option:: -r, --retain
-
- When the program terminates, retain routes added by *eigrpd*.
-
.. _eigrp-configuration:
EIGRP Configuration
diff --git a/doc/user/ripd.rst b/doc/user/ripd.rst
index 973e61949e..372c30f587 100644
--- a/doc/user/ripd.rst
+++ b/doc/user/ripd.rst
@@ -60,9 +60,6 @@ Certain signals have special meanings to *ripd*.
*ripd* invocation options. Common options that can be specified
(:ref:`common-invocation-options`).
-.. option:: -r, --retain
-
- When the program terminates, retain routes added by *ripd*.
.. _rip-netmask:
diff --git a/doc/user/setup.rst b/doc/user/setup.rst
index 9971c43c5e..1bbbe36931 100644
--- a/doc/user/setup.rst
+++ b/doc/user/setup.rst
@@ -50,7 +50,7 @@ This file has several parts. Here is an example:
# Check /etc/pam.d/frr if you intend to use "vtysh"!
#
vtysh_enable=yes
- zebra_options=" -r -s 90000000 --daemon -A 127.0.0.1"
+ zebra_options=" -s 90000000 --daemon -A 127.0.0.1"
bgpd_options=" --daemon -A 127.0.0.1"
ospfd_options=" --daemon -A 127.0.0.1"
ospf6d_options=" --daemon -A ::1"
@@ -86,7 +86,7 @@ reasons touched on in the VTYSH documentation and should generally be enabled.
::
- zebra_options=" -r -s 90000000 --daemon -A 127.0.0.1"
+ zebra_options=" -s 90000000 --daemon -A 127.0.0.1"
bgpd_options=" --daemon -A 127.0.0.1"
...
diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst
index 9d927359ba..9e377330ee 100644
--- a/doc/user/zebra.rst
+++ b/doc/user/zebra.rst
@@ -29,7 +29,8 @@ Besides the common invocation options (:ref:`common-invocation-options`), the
.. option:: -r, --retain
- When program terminates, retain routes added by zebra.
+ When program terminates, do not flush routes installed by *zebra* from the
+ kernel.
.. option:: -e X, --ecmp X
@@ -47,6 +48,14 @@ Besides the common invocation options (:ref:`common-invocation-options`), the
.. seealso:: :ref:`vrf`
+.. option:: --v6-rr-semantics
+
+ The linux kernel is receiving the ability to use the same route
+ replacement semantics for v6 that v4 uses. If you are using a
+ kernel that supports this functionality then run *Zebra* with this
+ option and we will use Route Replace Semantics instead of delete
+ than add.
+
.. _interface-commands:
Interface Commands
diff --git a/redhat/frr.spec.in b/redhat/frr.spec.in
index 362be27a5f..b3e7e31aaa 100644
--- a/redhat/frr.spec.in
+++ b/redhat/frr.spec.in
@@ -322,10 +322,10 @@ developing OSPF-API and frr applications.
%if "%{initsystem}" == "systemd"
--enable-systemd=yes \
%endif
- --enable-poll=yes
%if %{with_rpki}
- --enable-rpki
+ --enable-rpki \
%endif
+ --enable-poll=yes
make %{?_smp_mflags} MAKEINFO="makeinfo --no-split" SPHINXBUILD=%{sphinx}
@@ -586,6 +586,9 @@ rm -rf %{buildroot}
%if %{with_fpm}
%attr(755,root,root) %{_libdir}/frr/modules/zebra_fpm.so
%endif
+%if %{with_rpki}
+%attr(755,root,root) %{_libdir}/frr/modules/bgpd_rpki.so
+%endif
%attr(755,root,root) %{_libdir}/frr/modules/zebra_irdp.so
%{_bindir}/*
%config(noreplace) /etc/frr/[!v]*.conf*
@@ -632,7 +635,10 @@ rm -rf %{buildroot}
%endif
%changelog
-* Sun Mar 4 2018 Martin Winter <mwinter@opensourcerouting.org> - %{version}
+* Sun May 20 2018 Martin Winter <mwinter@opensourcerouting.org> - %{version}
+- Fixed RPKI RPM build
+
+* Sun Mar 4 2018 Martin Winter <mwinter@opensourcerouting.org>
- Add option to build with RPKI (default: disabled)
* Tue Feb 20 2018 Martin Winter <mwinter@opensourcerouting.org>
diff --git a/ripd/rip_main.c b/ripd/rip_main.c
index 9a448e8958..0194e53128 100644
--- a/ripd/rip_main.c
+++ b/ripd/rip_main.c
@@ -39,6 +39,9 @@
#include "ripd/ripd.h"
/* ripd options. */
+#if CONFDATE > 20190521
+ CPP_NOTICE("-r / --retain has reached deprecation EOL, remove")
+#endif
static struct option longopts[] = {{"retain", no_argument, NULL, 'r'}, {0}};
/* ripd privileges */
@@ -58,9 +61,6 @@ struct zebra_privs_t ripd_privs = {
.cap_num_p = 2,
.cap_num_i = 0};
-/* Route retain mode flag. */
-int retain_mode = 0;
-
/* Master of threads. */
struct thread_master *master;
@@ -85,8 +85,7 @@ static void sigint(void)
{
zlog_notice("Terminating on signal");
- if (!retain_mode)
- rip_clean();
+ rip_clean();
rip_zclient_stop();
frr_fini();
@@ -127,13 +126,17 @@ FRR_DAEMON_INFO(ripd, RIP, .vty_port = RIP_VTY_PORT,
.privs = &ripd_privs, )
+#if CONFDATE > 20190521
+CPP_NOTICE("-r / --retain has reached deprecation EOL, remove")
+#endif
+#define DEPRECATED_OPTIONS "r"
+
/* Main routine of ripd. */
int main(int argc, char **argv)
{
frr_preinit(&ripd_di, argc, argv);
- frr_opt_add(
- "r", longopts,
- " -r, --retain When program terminates, retain added route by ripd.\n");
+
+ frr_opt_add("" DEPRECATED_OPTIONS, longopts, "");
/* Command line option parse. */
while (1) {
@@ -141,15 +144,19 @@ int main(int argc, char **argv)
opt = frr_getopt(argc, argv, NULL);
+ if (opt && opt < 128 && strchr(DEPRECATED_OPTIONS, opt)) {
+ fprintf(stderr,
+ "The -%c option no longer exists.\nPlease refer to the manual.\n",
+ opt);
+ continue;
+ }
+
if (opt == EOF)
break;
switch (opt) {
case 0:
break;
- case 'r':
- retain_mode = 1;
- break;
default:
frr_help_exit(1);
break;
diff --git a/ripngd/ripng_main.c b/ripngd/ripng_main.c
index 8ef27daaba..e4501d6f80 100644
--- a/ripngd/ripng_main.c
+++ b/ripngd/ripng_main.c
@@ -40,6 +40,9 @@
#include "ripngd/ripngd.h"
/* RIPngd options. */
+#if CONFDATE > 20190521
+ CPP_NOTICE("-r / --retain has reached deprecation EOL, remove")
+#endif
struct option longopts[] = {{"retain", no_argument, NULL, 'r'}, {0}};
/* ripngd privileges */
@@ -60,11 +63,6 @@ struct zebra_privs_t ripngd_privs = {
.cap_num_i = 0};
-/* RIPngd program name */
-
-/* Route retain mode flag. */
-int retain_mode = 0;
-
/* Master of threads. */
struct thread_master *master;
@@ -88,8 +86,7 @@ static void sigint(void)
{
zlog_notice("Terminating on signal");
- if (!retain_mode)
- ripng_clean();
+ ripng_clean();
ripng_zebra_stop();
frr_fini();
@@ -130,28 +127,36 @@ FRR_DAEMON_INFO(ripngd, RIPNG, .vty_port = RIPNG_VTY_PORT,
.privs = &ripngd_privs, )
+#if CONFDATE > 20190521
+CPP_NOTICE("-r / --retain has reached deprecation EOL, remove")
+#endif
+#define DEPRECATED_OPTIONS "r"
+
/* RIPngd main routine. */
int main(int argc, char **argv)
{
frr_preinit(&ripngd_di, argc, argv);
- frr_opt_add(
- "r", longopts,
- " -r, --retain When program terminates, retain added route by ripd.\n");
+
+ frr_opt_add("" DEPRECATED_OPTIONS, longopts, "");
while (1) {
int opt;
opt = frr_getopt(argc, argv, NULL);
+ if (opt && opt < 128 && strchr(DEPRECATED_OPTIONS, opt)) {
+ fprintf(stderr,
+ "The -%c option no longer exists.\nPlease refer to the manual.\n",
+ opt);
+ continue;
+ }
+
if (opt == EOF)
break;
switch (opt) {
case 0:
break;
- case 'r':
- retain_mode = 1;
- break;
default:
frr_help_exit(1);
break;
diff --git a/tools/lsan-suppressions.txt b/tools/lsan-suppressions.txt
index 5184b55699..5d8bf63580 100644
--- a/tools/lsan-suppressions.txt
+++ b/tools/lsan-suppressions.txt
@@ -3,3 +3,4 @@ leak:PyObject_Malloc
leak:PyObject_Realloc
leak:PyList_Append
leak:malloc
+leak:PyObject_GC_Resize
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 6bd7611ead..90c387b48c 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -369,11 +369,11 @@ static int vtysh_execute_func(const char *line, int pager)
saved_ret = ret = cmd_execute_command(vline, vty, &cmd, 1);
saved_node = vty->node;
- /* If command doesn't succeeded in current node, try to walk up in node
- * tree.
- * Changing vty->node is enough to try it just out without actual walkup
- * in
- * the vtysh. */
+ /*
+ * If command doesn't succeeded in current node, try to walk up in node
+ * tree. Changing vty->node is enough to try it just out without actual
+ * walkup in the vtysh.
+ */
while (ret != CMD_SUCCESS && ret != CMD_SUCCESS_DAEMON
&& ret != CMD_WARNING && ret != CMD_WARNING_CONFIG_FAILED
&& vty->node > CONFIG_NODE) {
@@ -384,9 +384,10 @@ static int vtysh_execute_func(const char *line, int pager)
vty->node = saved_node;
- /* If command succeeded in any other node than current (tried > 0) we
- * have
- * to move into node in the vtysh where it succeeded. */
+ /*
+ * If command succeeded in any other node than current (tried > 0) we
+ * have to move into node in the vtysh where it succeeded.
+ */
if (ret == CMD_SUCCESS || ret == CMD_SUCCESS_DAEMON
|| ret == CMD_WARNING) {
if ((saved_node == BGP_VPNV4_NODE
@@ -426,9 +427,10 @@ static int vtysh_execute_func(const char *line, int pager)
vtysh_execute("configure terminal");
}
}
- /* If command didn't succeed in any node, continue with return value
- * from
- * first try. */
+ /*
+ * If command didn't succeed in any node, continue with return value
+ * from first try.
+ */
else if (tried) {
ret = saved_ret;
}
@@ -654,8 +656,10 @@ int vtysh_mark_file(const char *filename)
continue;
}
- /* Ignore the "end" lines, we will generate these where
- * appropriate */
+ /*
+ * Ignore the "end" lines, we will generate these where
+ * appropriate
+ */
if (strlen(vty_buf_trimmed) == 3
&& strncmp("end", vty_buf_trimmed, 3) == 0) {
cmd_free_strvec(vline);
@@ -665,11 +669,11 @@ int vtysh_mark_file(const char *filename)
prev_node = vty->node;
saved_ret = ret = cmd_execute_command_strict(vline, vty, &cmd);
- /* If command doesn't succeeded in current node, try to walk up
- * in node tree.
- * Changing vty->node is enough to try it just out without
- * actual walkup in
- * the vtysh. */
+ /*
+ * If command doesn't succeeded in current node, try to walk up
+ * in node tree. Changing vty->node is enough to try it just
+ * out without actual walkup in the vtysh.
+ */
while (ret != CMD_SUCCESS && ret != CMD_SUCCESS_DAEMON
&& ret != CMD_WARNING && ret != CMD_WARNING_CONFIG_FAILED
&& vty->node > CONFIG_NODE) {
@@ -678,9 +682,11 @@ int vtysh_mark_file(const char *filename)
tried++;
}
- /* If command succeeded in any other node than current (tried >
- * 0) we have
- * to move into node in the vtysh where it succeeded. */
+ /*
+ * If command succeeded in any other node than current (tried >
+ * 0) we have to move into node in the vtysh where it
+ * succeeded.
+ */
if (ret == CMD_SUCCESS || ret == CMD_SUCCESS_DAEMON
|| ret == CMD_WARNING) {
if ((prev_node == BGP_VPNV4_NODE
@@ -706,9 +712,10 @@ int vtysh_mark_file(const char *filename)
fprintf(outputfile, "end\n");
}
}
- /* If command didn't succeed in any node, continue with return
- * value from
- * first try. */
+ /*
+ * If command didn't succeed in any node, continue with return
+ * value from first try.
+ */
else if (tried) {
ret = saved_ret;
vty->node = prev_node;
@@ -788,6 +795,7 @@ int vtysh_config_from_file(struct vty *vty, FILE *fp)
int ret;
const struct cmd_element *cmd;
int lineno = 0;
+ /* once we have an error, we remember & return that */
int retcode = CMD_SUCCESS;
while (fgets(vty->buf, VTY_BUFSIZ, fp)) {
@@ -801,30 +809,25 @@ int vtysh_config_from_file(struct vty *vty, FILE *fp)
if (vty->type == VTY_FILE)
fprintf(stderr, "line %d: Warning[%d]...: %s\n",
lineno, vty->node, vty->buf);
- retcode = ret; /* once we have an error, we remember &
- return that */
+ retcode = ret;
+
break;
case CMD_ERR_AMBIGUOUS:
fprintf(stderr,
"line %d: %% Ambiguous command[%d]: %s\n",
lineno, vty->node, vty->buf);
- retcode = CMD_ERR_AMBIGUOUS; /* once we have an error,
- we remember & return
- that */
+ retcode = CMD_ERR_AMBIGUOUS;
break;
case CMD_ERR_NO_MATCH:
fprintf(stderr, "line %d: %% Unknown command[%d]: %s",
lineno, vty->node, vty->buf);
- retcode = CMD_ERR_NO_MATCH; /* once we have an error, we
- remember & return that */
+ retcode = CMD_ERR_NO_MATCH;
break;
case CMD_ERR_INCOMPLETE:
fprintf(stderr,
"line %d: %% Command incomplete[%d]: %s\n",
lineno, vty->node, vty->buf);
- retcode = CMD_ERR_INCOMPLETE; /* once we have an error,
- we remember & return
- that */
+ retcode = CMD_ERR_INCOMPLETE;
break;
case CMD_SUCCESS_DAEMON: {
unsigned int i;
@@ -837,16 +840,12 @@ int vtysh_config_from_file(struct vty *vty, FILE *fp)
outputfile);
/*
* CMD_WARNING - Can mean that the
- * command was
- * parsed successfully but it was
- * already entered
- * in a few spots. As such if we
- * receive a
+ * command was parsed successfully but
+ * it was already entered in a few
+ * spots. As such if we receive a
* CMD_WARNING from a daemon we
- * shouldn't stop
- * talking to the other daemons for the
- * particular
- * command.
+ * shouldn't stop talking to the other
+ * daemons for the particular command.
*/
if (cmd_stat != CMD_SUCCESS
&& cmd_stat != CMD_WARNING) {
@@ -1046,8 +1045,10 @@ static char *command_generator(const char *text, int state)
}
if (matched && matched[index])
- /* this is free()'d by readline, but we leak 1 count of
- * MTYPE_COMPLETION */
+ /*
+ * this is free()'d by readline, but we leak 1 count of
+ * MTYPE_COMPLETION
+ */
return matched[index++];
XFREE(MTYPE_TMP, matched);
@@ -2058,8 +2059,10 @@ DEFUNSH(VTYSH_VRF, vtysh_quit_nexthop_group, vtysh_quit_nexthop_group_cmd,
return vtysh_exit_nexthop_group(self, vty, argc, argv);
}
-/* TODO Implement interface description commands in ripngd, ospf6d
- * and isisd. */
+/*
+ * TODO Implement interface description commands in ripngd, ospf6d
+ * and isisd.
+ */
DEFSH(VTYSH_ZEBRA | VTYSH_RIPD | VTYSH_OSPFD | VTYSH_EIGRPD,
vtysh_interface_desc_cmd, "description LINE...",
"Interface specific description\n"
diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c
index 3dd70983bc..ff5e6bb784 100644
--- a/vtysh/vtysh_main.c
+++ b/vtysh/vtysh_main.c
@@ -612,9 +612,10 @@ int main(int argc, char **argv, char **env)
log_it(cmd->line);
/*
- * Parsing logic for regular commands will be different than
- * for those commands requiring further processing, such as
- * cli instructions terminating with question-mark character.
+ * Parsing logic for regular commands will be different
+ * than for those commands requiring further
+ * processing, such as cli instructions terminating
+ * with question-mark character.
*/
if (!vtysh_execute_command_questionmark(cmd->line))
ret = CMD_SUCCESS;
diff --git a/zebra/main.c b/zebra/main.c
index 9a495c8940..9c721f0a7e 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -51,6 +51,7 @@
#include "zebra/label_manager.h"
#include "zebra/zebra_netns_notify.h"
#include "zebra/zebra_rnh.h"
+#include "zebra/zebra_pbr.h"
#define ZEBRA_PTM_SUPPORT
@@ -75,24 +76,29 @@ int allow_delete = 0;
/* Don't delete kernel route. */
int keep_kernel_mode = 0;
+bool v6_rr_semantics = false;
+
#ifdef HAVE_NETLINK
/* Receive buffer size for netlink socket */
uint32_t nl_rcvbufsize = 4194304;
#endif /* HAVE_NETLINK */
+#define OPTION_V6_RR_SEMANTICS 2000
/* Command line options. */
-struct option longopts[] = {{"batch", no_argument, NULL, 'b'},
- {"allow_delete", no_argument, NULL, 'a'},
- {"keep_kernel", no_argument, NULL, 'k'},
- {"socket", required_argument, NULL, 'z'},
- {"ecmp", required_argument, NULL, 'e'},
- {"label_socket", no_argument, NULL, 'l'},
- {"retain", no_argument, NULL, 'r'},
+struct option longopts[] = {
+ {"batch", no_argument, NULL, 'b'},
+ {"allow_delete", no_argument, NULL, 'a'},
+ {"keep_kernel", no_argument, NULL, 'k'},
+ {"socket", required_argument, NULL, 'z'},
+ {"ecmp", required_argument, NULL, 'e'},
+ {"label_socket", no_argument, NULL, 'l'},
+ {"retain", no_argument, NULL, 'r'},
#ifdef HAVE_NETLINK
- {"vrfwnetns", no_argument, NULL, 'n'},
- {"nl-bufsize", required_argument, NULL, 's'},
+ {"vrfwnetns", no_argument, NULL, 'n'},
+ {"nl-bufsize", required_argument, NULL, 's'},
+ {"v6-rr-semantics", no_argument, NULL, OPTION_V6_RR_SEMANTICS},
#endif /* HAVE_NETLINK */
- {0}};
+ {0}};
zebra_capabilities_t _caps_p[] = {
ZCAP_NET_ADMIN, ZCAP_SYS_ADMIN, ZCAP_NET_RAW,
@@ -224,21 +230,22 @@ int main(int argc, char **argv)
#endif
,
longopts,
- " -b, --batch Runs in batch mode\n"
- " -a, --allow_delete Allow other processes to delete zebra routes\n"
- " -z, --socket Set path of zebra socket\n"
- " -e, --ecmp Specify ECMP to use.\n"
- " -l, --label_socket Socket to external label manager\n"
- " -k, --keep_kernel Don't delete old routes which installed by zebra.\n"
- " -r, --retain When program terminates, retain added route by zebra.\n"
+ " -b, --batch Runs in batch mode\n"
+ " -a, --allow_delete Allow other processes to delete zebra routes\n"
+ " -z, --socket Set path of zebra socket\n"
+ " -e, --ecmp Specify ECMP to use.\n"
+ " -l, --label_socket Socket to external label manager\n"
+ " -k, --keep_kernel Don't delete old routes which installed by zebra.\n"
+ " -r, --retain When program terminates, retain added route by zebra.\n"
#ifdef HAVE_NETLINK
- " -n, --vrfwnetns Set VRF with NetNS\n"
- " -s, --nl-bufsize Set netlink receive buffer size\n"
+ " -n, --vrfwnetns Set VRF with NetNS\n"
+ " -s, --nl-bufsize Set netlink receive buffer size\n"
+ " --v6-rr-semantics Use v6 RR semantics\n"
#endif /* HAVE_NETLINK */
#if defined(HANDLE_ZAPI_FUZZING)
- " -c <file> Bypass normal startup use this file for tetsting of zapi"
+ " -c <file> Bypass normal startup use this file for tetsting of zapi"
#endif
- );
+ );
while (1) {
int opt = frr_getopt(argc, argv, NULL);
@@ -292,6 +299,9 @@ int main(int argc, char **argv)
logicalrouter_configure_backend(
LOGICALROUTER_BACKEND_OFF);
break;
+ case OPTION_V6_RR_SEMANTICS:
+ v6_rr_semantics = true;
+ break;
#endif /* HAVE_NETLINK */
#if defined(HANDLE_ZAPI_FUZZING)
case 'c':
@@ -333,6 +343,7 @@ int main(int argc, char **argv)
zebra_mpls_init();
zebra_mpls_vty_init();
zebra_pw_vty_init();
+ zebra_pbr_init();
/* For debug purpose. */
/* SET_FLAG (zebra_debug_event, ZEBRA_DEBUG_EVENT); */
diff --git a/zebra/rib.h b/zebra/rib.h
index 7b9e6d56a7..209f085ed1 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -456,4 +456,5 @@ extern void static_config_install_delayed_routes(struct zebra_vrf *zvrf);
extern pid_t pid;
+extern bool v6_rr_semantics;
#endif /*_ZEBRA_RIB_H */
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 2fd7bee056..8ab70c8d4b 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -1696,7 +1696,7 @@ void kernel_route_rib(struct route_node *rn, struct prefix *p,
assert(old || new);
if (new) {
- if (p->family == AF_INET)
+ if (p->family == AF_INET || v6_rr_semantics)
ret = netlink_route_multipath(RTM_NEWROUTE, p, src_p,
new, (old) ? 1 : 0);
else {
diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c
index 93c523bf50..54a9cdbc5b 100644
--- a/zebra/zebra_pbr.c
+++ b/zebra/zebra_pbr.c
@@ -320,11 +320,20 @@ static void zebra_pbr_cleanup_rules(struct hash_backet *b, void *data)
}
}
-void zebra_pbr_client_close_cleanup(int sock)
+static int zebra_pbr_client_close_cleanup(struct zserv *client)
{
+ int sock = client->sock;
struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT);
+ if (!sock)
+ return 0;
hash_iterate(zns->rules_hash, zebra_pbr_cleanup_rules, &sock);
+ return 1;
+}
+
+void zebra_pbr_init(void)
+{
+ hook_register(zapi_client_close, zebra_pbr_client_close_cleanup);
}
static void *pbr_ipset_alloc_intern(void *arg)
diff --git a/zebra/zebra_pbr.h b/zebra/zebra_pbr.h
index 0ac629cc65..6b5cd1e8d1 100644
--- a/zebra/zebra_pbr.h
+++ b/zebra/zebra_pbr.h
@@ -182,8 +182,6 @@ extern void kernel_pbr_iptable_add_del_status(struct zebra_pbr_iptable *iptable,
*/
extern int kernel_pbr_rule_del(struct zebra_pbr_rule *rule);
-extern void zebra_pbr_client_close_cleanup(int sock);
-
extern void zebra_pbr_rules_free(void *arg);
extern uint32_t zebra_pbr_rules_hash_key(void *arg);
extern int zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2);
@@ -205,4 +203,5 @@ extern void zebra_pbr_iptable_free(void *arg);
extern uint32_t zebra_pbr_iptable_hash_key(void *arg);
extern int zebra_pbr_iptable_hash_equal(const void *arg1, const void *arg2);
+extern void zebra_pbr_init(void);
#endif /* _ZEBRA_PBR_H */