diff options
| -rw-r--r-- | bgpd/bgp_evpn.c | 33 | ||||
| -rw-r--r-- | bgpd/bgp_main.c | 27 | ||||
| -rw-r--r-- | bgpd/bgp_mplsvpn.c | 2 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 21 | ||||
| -rw-r--r-- | bgpd/bgp_vty.c | 2 | ||||
| -rw-r--r-- | bgpd/bgp_zebra.c | 2 | ||||
| -rwxr-xr-x | configure.ac | 3 | ||||
| -rw-r--r-- | doc/developer/building-frr-on-ubuntu1204.rst | 9 | ||||
| -rw-r--r-- | doc/developer/building-frr-on-ubuntu1404.rst | 9 | ||||
| -rw-r--r-- | doc/developer/building-frr-on-ubuntu1604.rst | 11 | ||||
| -rw-r--r-- | doc/developer/building-frr-on-ubuntu1804.rst | 252 | ||||
| -rw-r--r-- | doc/manpages/common-options.rst | 7 | ||||
| -rw-r--r-- | doc/manpages/zebra.rst | 8 | ||||
| -rw-r--r-- | doc/user/bgp.rst | 4 | ||||
| -rw-r--r-- | doc/user/eigrpd.rst | 4 | ||||
| -rw-r--r-- | doc/user/ripd.rst | 3 | ||||
| -rw-r--r-- | doc/user/setup.rst | 4 | ||||
| -rw-r--r-- | doc/user/zebra.rst | 11 | ||||
| -rw-r--r-- | redhat/frr.spec.in | 12 | ||||
| -rw-r--r-- | ripd/rip_main.c | 29 | ||||
| -rw-r--r-- | ripngd/ripng_main.c | 31 | ||||
| -rw-r--r-- | tools/lsan-suppressions.txt | 1 | ||||
| -rw-r--r-- | vtysh/vtysh.c | 97 | ||||
| -rw-r--r-- | vtysh/vtysh_main.c | 7 | ||||
| -rw-r--r-- | zebra/main.c | 53 | ||||
| -rw-r--r-- | zebra/rib.h | 1 | ||||
| -rw-r--r-- | zebra/rt_netlink.c | 2 | ||||
| -rw-r--r-- | zebra/zebra_pbr.c | 11 | ||||
| -rw-r--r-- | zebra/zebra_pbr.h | 3 |
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 */ |
