diff options
53 files changed, 784 insertions, 308 deletions
diff --git a/bgpd/bgp_evpn_mh.h b/bgpd/bgp_evpn_mh.h index ee1f74989b..cebabb9fd0 100644 --- a/bgpd/bgp_evpn_mh.h +++ b/bgpd/bgp_evpn_mh.h @@ -388,11 +388,6 @@ static inline bool bgp_evpn_attr_is_local_es(struct attr *attr) return attr ? !!(attr->es_flags & ATTR_ES_IS_LOCAL) : false; } -static inline uint32_t bgp_evpn_attr_get_df_pref(struct attr *attr) -{ - return (attr) ? attr->df_pref : 0; -} - static inline bool bgp_evpn_local_es_is_active(struct bgp_evpn_es *es) { return (es->flags & BGP_EVPNES_OPER_UP) diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 32436861f4..cd5cf5be54 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -2209,12 +2209,22 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */ /* If the path has accept-own community and the source VRF * is valid, reset next-hop to self, to allow importing own * routes between different VRFs on the same node. - * Set the nh ifindex to VRF's interface, not the real interface. + */ + + if (src_bgp) + subgroup_announce_reset_nhop(nhfamily, &static_attr); + + bpi_ultimate = bgp_get_imported_bpi_ultimate(path_vpn); + + /* The nh ifindex may not be defined (when the route is + * imported from the network statement => BGP_ROUTE_STATIC) + * or to the real interface. + * Rewrite the nh ifindex to VRF's interface. * Let the kernel to decide with double lookup the real next-hop * interface when installing the route. */ - if (src_bgp) { - subgroup_announce_reset_nhop(nhfamily, &static_attr); + if (src_bgp || bpi_ultimate->sub_type == BGP_ROUTE_STATIC || + bpi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE) { ifp = if_get_vrf_loopback(src_vrf->vrf_id); if (ifp) static_attr.nh_ifindex = ifp->ifindex; @@ -2300,9 +2310,6 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */ */ if (!CHECK_FLAG(to_bgp->af_flags[afi][safi], BGP_CONFIG_VRF_TO_VRF_IMPORT)) { - /* work back to original route */ - bpi_ultimate = bgp_get_imported_bpi_ultimate(path_vpn); - /* * if original route was unicast, * then it did not arrive over vpn diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index f94b64d0bd..9d484d901a 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -1534,7 +1534,8 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi, iana_safi2str(pkt_safi)); break; case CAPABILITY_CODE_FQDN: - if (hostname) { + if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_FQDN) && + hostname) { SET_FLAG(peer->cap, PEER_CAP_HOSTNAME_ADV); stream_putc(s, action); stream_putc(s, CAPABILITY_CODE_FQDN); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index b8d6c660b7..32d822aad7 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -3520,7 +3520,8 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, */ if (old_select && is_route_parent_evpn(old_select)) - bgp_zebra_withdraw(p, old_select, bgp, safi); + bgp_zebra_withdraw(p, old_select, bgp, afi, + safi); bgp_zebra_announce(dest, p, new_select, bgp, afi, safi); } else { @@ -3530,7 +3531,8 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, || old_select->sub_type == BGP_ROUTE_AGGREGATE || old_select->sub_type == BGP_ROUTE_IMPORTED)) - bgp_zebra_withdraw(p, old_select, bgp, safi); + bgp_zebra_withdraw(p, old_select, bgp, afi, + safi); } } @@ -4185,7 +4187,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, int aspath_loop_count = 0; struct bgp_dest *dest; struct bgp *bgp; - struct attr new_attr; + struct attr new_attr = {}; struct attr *attr_new; struct bgp_path_info *pi; struct bgp_path_info *new = NULL; @@ -4218,10 +4220,6 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, if (orig_safi == SAFI_LABELED_UNICAST) safi = SAFI_UNICAST; - memset(&new_attr, 0, sizeof(new_attr)); - new_attr.label_index = BGP_INVALID_LABEL_INDEX; - new_attr.label = MPLS_INVALID_LABEL; - bgp = peer->bgp; dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd); /* TODO: Check to see if we can get rid of "is_valid_label" */ @@ -4431,7 +4429,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) { if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) /* remove from RIB previous entry */ - bgp_zebra_withdraw(p, pi, bgp, safi); + bgp_zebra_withdraw(p, pi, bgp, afi, safi); } if (peer->sort == BGP_PEER_EBGP) { @@ -6033,7 +6031,7 @@ bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter) } static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table, - safi_t safi) + afi_t afi, safi_t safi) { struct bgp_dest *dest; struct bgp_path_info *pi; @@ -6057,7 +6055,8 @@ static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table, || pi->sub_type == BGP_ROUTE_IMPORTED)) { if (bgp_fibupd_safi(safi)) - bgp_zebra_withdraw(p, pi, bgp, safi); + bgp_zebra_withdraw(p, pi, bgp, afi, + safi); } dest = bgp_path_info_reap(dest, pi); @@ -6075,7 +6074,7 @@ void bgp_cleanup_routes(struct bgp *bgp) for (afi = AFI_IP; afi < AFI_MAX; ++afi) { if (afi == AFI_L2VPN) continue; - bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST], + bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST], afi, SAFI_UNICAST); /* * VPN and ENCAP and EVPN tables are two-level (RD is top level) @@ -6087,7 +6086,7 @@ void bgp_cleanup_routes(struct bgp *bgp) dest = bgp_route_next(dest)) { table = bgp_dest_get_bgp_table_info(dest); if (table != NULL) { - bgp_cleanup_table(bgp, table, safi); + bgp_cleanup_table(bgp, table, afi, safi); bgp_table_finish(&table); bgp_dest_set_bgp_table_info(dest, NULL); dest = bgp_dest_unlock_node(dest); @@ -6100,7 +6099,7 @@ void bgp_cleanup_routes(struct bgp *bgp) dest = bgp_route_next(dest)) { table = bgp_dest_get_bgp_table_info(dest); if (table != NULL) { - bgp_cleanup_table(bgp, table, safi); + bgp_cleanup_table(bgp, table, afi, safi); bgp_table_finish(&table); bgp_dest_set_bgp_table_info(dest, NULL); dest = bgp_dest_unlock_node(dest); @@ -6114,7 +6113,7 @@ void bgp_cleanup_routes(struct bgp *bgp) dest = bgp_route_next(dest)) { table = bgp_dest_get_bgp_table_info(dest); if (table != NULL) { - bgp_cleanup_table(bgp, table, SAFI_EVPN); + bgp_cleanup_table(bgp, table, afi, SAFI_EVPN); bgp_table_finish(&table); bgp_dest_set_bgp_table_info(dest, NULL); dest = bgp_dest_unlock_node(dest); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 09f9667a9a..33884d0452 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -5746,17 +5746,24 @@ DEFPY (neighbor_capability_fqdn, "Advertise fqdn capability to the peer\n") { struct peer *peer; + int ret; peer = peer_and_group_lookup_vty(vty, neighbor); if (!peer) return CMD_WARNING_CONFIG_FAILED; if (no) - return peer_flag_unset_vty(vty, neighbor, + ret = peer_flag_unset_vty(vty, neighbor, PEER_FLAG_CAPABILITY_FQDN); else - return peer_flag_set_vty(vty, neighbor, + ret = peer_flag_set_vty(vty, neighbor, PEER_FLAG_CAPABILITY_FQDN); + + bgp_capability_send(peer, AFI_IP, SAFI_UNICAST, CAPABILITY_CODE_FQDN, + no ? CAPABILITY_ACTION_UNSET + : CAPABILITY_ACTION_SET); + + return ret; } /* neighbor capability extended next hop encoding */ diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 0db0ac4873..dcbb87e969 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1724,7 +1724,7 @@ void bgp_zebra_announce_table_all_subtypes(struct bgp *bgp, afi_t afi, } void bgp_zebra_withdraw(const struct prefix *p, struct bgp_path_info *info, - struct bgp *bgp, safi_t safi) + struct bgp *bgp, afi_t afi, safi_t safi) { struct zapi_route api; struct peer *peer; @@ -1743,7 +1743,7 @@ void bgp_zebra_withdraw(const struct prefix *p, struct bgp_path_info *info, if (safi == SAFI_FLOWSPEC) { peer = info->peer; - bgp_pbr_update_entry(peer->bgp, p, info, AFI_IP, safi, false); + bgp_pbr_update_entry(peer->bgp, p, info, afi, safi, false); return; } @@ -1784,7 +1784,7 @@ void bgp_zebra_withdraw_table_all_subtypes(struct bgp *bgp, afi_t afi, safi_t sa if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED) && (pi->type == ZEBRA_ROUTE_BGP)) bgp_zebra_withdraw(bgp_dest_get_prefix(dest), - pi, bgp, safi); + pi, bgp, afi, safi); } } } diff --git a/bgpd/bgp_zebra.h b/bgpd/bgp_zebra.h index 4696e4dc44..396c8335f8 100644 --- a/bgpd/bgp_zebra.h +++ b/bgpd/bgp_zebra.h @@ -34,7 +34,7 @@ extern void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, extern void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi); extern void bgp_zebra_withdraw(const struct prefix *p, struct bgp_path_info *path, struct bgp *bgp, - safi_t safi); + afi_t afi, safi_t safi); /* Announce routes of any bgp subtype of a table to zebra */ extern void bgp_zebra_announce_table_all_subtypes(struct bgp *bgp, afi_t afi, diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 58514566ef..b8517199af 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -4574,7 +4574,7 @@ static const struct peer_flag_action peer_flag_action_list[] = { {PEER_FLAG_AIGP, 0, peer_change_none}, {PEER_FLAG_GRACEFUL_SHUTDOWN, 0, peer_change_none}, {PEER_FLAG_CAPABILITY_SOFT_VERSION, 0, peer_change_none}, - {PEER_FLAG_CAPABILITY_FQDN, 0, peer_change_reset}, + {PEER_FLAG_CAPABILITY_FQDN, 0, peer_change_none}, {0, 0, 0}}; static const struct peer_flag_action peer_af_flag_action_list[] = { diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c index 8e88550ddf..5da99dbc4e 100644 --- a/bgpd/rfapi/rfapi_vty.c +++ b/bgpd/rfapi/rfapi_vty.c @@ -419,22 +419,21 @@ void rfapi_vty_out_vncinfo(struct vty *vty, const struct prefix *p, else vty_out(vty, " label=%u", decode_label(&bpi->extra->label[0])); + } - if (bpi->attr->srv6_l3vpn || bpi->attr->srv6_vpn) { - struct in6_addr *sid_tmp = - bpi->attr->srv6_l3vpn - ? (&bpi->attr->srv6_l3vpn->sid) - : (&bpi->attr->srv6_vpn->sid); - vty_out(vty, " sid=%pI6", sid_tmp); - - if (bpi->attr->srv6_l3vpn && - bpi->attr->srv6_l3vpn->loc_block_len != 0) { - vty_out(vty, " sid_structure=[%d,%d,%d,%d]", - bpi->attr->srv6_l3vpn->loc_block_len, - bpi->attr->srv6_l3vpn->loc_node_len, - bpi->attr->srv6_l3vpn->func_len, - bpi->attr->srv6_l3vpn->arg_len); - } + if (bpi->attr->srv6_l3vpn || bpi->attr->srv6_vpn) { + struct in6_addr *sid_tmp = + bpi->attr->srv6_l3vpn ? (&bpi->attr->srv6_l3vpn->sid) + : (&bpi->attr->srv6_vpn->sid); + vty_out(vty, " sid=%pI6", sid_tmp); + + if (bpi->attr->srv6_l3vpn && + bpi->attr->srv6_l3vpn->loc_block_len != 0) { + vty_out(vty, " sid_structure=[%d,%d,%d,%d]", + bpi->attr->srv6_l3vpn->loc_block_len, + bpi->attr->srv6_l3vpn->loc_node_len, + bpi->attr->srv6_l3vpn->func_len, + bpi->attr->srv6_l3vpn->arg_len); } } diff --git a/doc/developer/northbound/plugins-sysrepo.rst b/doc/developer/northbound/plugins-sysrepo.rst index 1797157573..0cfdb825e5 100644 --- a/doc/developer/northbound/plugins-sysrepo.rst +++ b/doc/developer/northbound/plugins-sysrepo.rst @@ -1,140 +1,193 @@ -Plugins Sysrepo (old) -===================== +Plugins Sysrepo +=============== Installation ------------ Required dependencies ^^^^^^^^^^^^^^^^^^^^^ +Install FRR build required dependencies, check `Building FRR +<https://docs.frrouting.org/projects/dev-guide/en/latest/building.html>`_ document for specific platform required packages. +Below are debian systems required packages: -:: +.. code-block:: console - # apt-get install git cmake build-essential bison flex libpcre3-dev libev-dev \ - libavl-dev libprotobuf-c-dev protobuf-c-compiler libcmocka0 \ - libcmocka-dev doxygen libssl-dev libssl-dev libssh-dev + sudo apt-get install git autoconf automake libtool make \ + libprotobuf-c-dev protobuf-c-compiler build-essential \ + python3-dev python3-pytest python3-sphinx libjson-c-dev \ + libelf-dev libreadline-dev cmake libcap-dev bison flex \ + pkg-config texinfo gdb libgrpc-dev python3-grpc-tools libpcre2-dev libyang ^^^^^^^ -:: +.. note:: - # apt-get install libyang0.16 libyang-dev + FRR requires version 2.1.128 or newer, in this document we will + be compiling and installing libyang version 2.1.148. -Sysrepo -^^^^^^^ +.. code-block:: console -:: + git clone https://github.com/CESNET/libyang.git + cd libyang + git checkout v2.1.148 + mkdir build; cd build + cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr \ + -DCMAKE_BUILD_TYPE:String="Release" .. + make + sudo make install - $ git clone https://github.com/sysrepo/sysrepo.git - $ cd sysrepo/ - $ mkdir build; cd build - $ cmake -DCMAKE_BUILD_TYPE=Release -DGEN_LANGUAGE_BINDINGS=OFF .. && make - # make install +Sysrepo +^^^^^^^ -libnetconf2 -^^^^^^^^^^^ +.. note:: -:: + The following code block assumes you have installed libyang v2.1.148, if you have + libyang v2.1.128 change sysrepo version to 2.2.105. - $ git clone https://github.com/CESNET/libnetconf2.git - $ cd libnetconf2/ - $ mkdir build; cd build - $ cmake .. && make - # make install +.. code-block:: console -netopeer2 -^^^^^^^^^ + git clone https://github.com/sysrepo/sysrepo.git + cd sysrepo/ + git checkout v2.2.150 + mkdir build; cd build + cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr \ + -DCMAKE_BUILD_TYPE:String="Release" .. + make + sudo make install -:: +Verify that sysrepo is installed correctly: - $ git clone https://github.com/CESNET/Netopeer2.git - $ cd Netopeer2 - $ cd server - $ mkdir build; cd build - $ cmake .. && make - # make install +.. code-block:: console -**Note:** If ``make install`` fails as it can’t find -``libsysrepo.so.0.7``, then run ``ldconfig`` and try again as it might -not have updated the lib search path + sudo sysrepoctl -l FRR ^^^ -Build and install FRR using the ``--enable-sysrepo`` configure-time -option. +Follow the steps of `Building FRR +<https://docs.frrouting.org/projects/dev-guide/en/latest/building.html>`_ + + +Make sure to use ``--enable-sysrepo`` configure-time option while building FRR. + +Below is an example of frr configure-time options, your options +might vary, however in order to allow sysrepo plugin you have +to keep ``--enable-sysrepo`` option: + +.. code-block:: console + + ./bootstrap.sh + ./configure \ + --localstatedir=/var/opt/frr \ + --sbindir=/usr/lib/frr \ + --sysconfdir=/etc/frr \ + --enable-multipath=64 \ + --enable-user=frr \ + --enable-group=frr \ + --enable-vty-group=frrvty \ + --enable-configfile-mask=0640 \ + --enable-logfile-mask=0640 \ + --enable-fpm \ + --enable-sysrepo \ + --with-pkg-git-version \ + --with-pkg-extra-version=-MyOwnFRRVersion + make + make check + sudo make install + Initialization -------------- -Install the FRR YANG modules in the Sysrepo datastore: - -:: +Install FRR YANG modules in Sysrepo datastore: - # sysrepoctl --install /usr/local/share/yang/ietf-interfaces@2018-01-09.yang - # sysrepoctl --install /usr/local/share/yang/frr-vrf.yang - # sysrepoctl --install /usr/local/share/yang/frr-interface.yang - # sysrepoctl --install /usr/local/share/yang/frr-route-types.yang - # sysrepoctl --install /usr/local/share/yang/frr-filter.yang - # sysrepoctl --install /usr/local/share/yang/frr-route-map.yang - # sysrepoctl --install /usr/local/share/yang/frr-isisd.yang - # sysrepoctl --install /usr/local/share/yang/frr-ripd.yang - # sysrepoctl --install /usr/local/share/yang/frr-ripngd.yang - # sysrepoctl -c frr-vrf --owner frr --group frr - # sysrepoctl -c frr-interface --owner frr --group frr - # sysrepoctl -c frr-route-types --owner frr --group frr - # sysrepoctl -c frr-filter --owner frr --group frr - # sysrepoctl -c frr-route-map --owner frr --group frr - # sysrepoctl -c frr-isisd --owner frr --group frr - # sysrepoctl -c frr-ripd --owner frr --group frr - # sysrepoctl -c frr-ripngd --owner frr --group frr +.. code-block:: console -Start netopeer2-server: + cd frr/yang/ + sudo sysrepoctl -i ./ietf/ietf-interfaces.yang -o frr -g frr + sudo sysrepoctl -i frr-vrf.yang -o frr -g frr + sudo sysrepoctl -i frr-interface.yang -o frr -g frr + sudo sysrepoctl -i frr-route-types.yang -o frr -g frr + sudo sysrepoctl -i frr-filter.yang -o frr -g frr + sudo sysrepoctl -i frr-route-map.yang -o frr -g frr + sudo sysrepoctl -i frr-isisd.yang -o frr -g frr + sudo sysrepoctl -i frr-bfdd.yang -o frr -g frr + sudo sysrepoctl -i ./ietf/ietf-routing-types.yang -o frr -g frr + sudo sysrepoctl -i frr-nexthop.yang -o frr -g frr + sudo sysrepoctl -i frr-if-rmap.yang -o frr -g frr + sudo sysrepoctl -i frr-ripd.yang -o frr -g frr + sudo sysrepoctl -i frr-ripngd.yang -o frr -g frr + sudo sysrepoctl -i frr-affinity-map.yang -o frr -g frr + sudo sysrepoctl -i ./ietf/frr-deviations-ietf-interfaces.yang -o frr -g frr -:: - # netopeer2-server -d & +Start FRR daemons with sysrepo plugin: -Start the FRR daemons with the sysrepo module: +.. code-block:: console -:: + sudo /usr/lib/frr/isisd -M sysrepo --log stdout - # isisd -M sysrepo --log=stdout +Any daemon running with ``-M sysrepo`` will subscribe to its frr yang moduels +on sysrepo and you be able to configure it by editing module configuration on sysrepo. Managing the configuration -------------------------- -The following NETCONF scripts can be used to show and edit the FRR -configuration: -https://github.com/rzalamena/ietf-hackathon-brazil-201907/tree/master/netconf-scripts +Testing +^^^^^^^ -Example: +To test FRR intergartion with sysrepo, ``sysrepocfg`` tool can be used +to edit frr configuration on sysrepo -:: +Example: - # ./netconf-edit.py 127.0.0.1 - # ./netconf-get-config.py 127.0.0.1 - <?xml version="1.0" encoding="UTF-8"?><data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"><isis xmlns="http://frrouting.org/yang/isisd"><instance><area-tag>testnet</area-tag><is-type>level-1</is-type></instance></isis></data> +Edit sysrepo running datastore configuration for the desiged frr module: -.. +.. code-block:: console - NOTE: the ncclient library needs to be installed first: - ``apt install -y python3-ncclient`` + sudo sysrepocfg -E nano -d running -m frr-isisd -f json -The *sysrepocfg* tool can also be used to show/edit the FRR -configuration. Example: +Paste the following json configuration: -:: +.. code-block:: console - # sysrepocfg --format=json --import=frr-isisd.json --datastore=running frr-isisd - # sysrepocfg --format=json --export --datastore=running frr-isisd { "frr-isisd:isis": { "instance": [ { "area-tag": "testnet", + "vrf": "default", "is-type": "level-1" } ] } } + +Exit and save config to the same file. + +After that, this configuration should get reflected to vtysh: + +.. code-block:: console + + show run + Building configuration... + + Current configuration: + ! + frr version 9.2-dev-MyOwnFRRVersion + frr defaults traditional + hostname bullseye + ! + router isis testnet + is-type level-1 + exit + ! + end + +NETCONF +^^^^^^^ + +To manage sysrepo configuration through netconf +you can use `netopeer2 <https://github.com/CESNET/netopeer2>`_ as a netfconf server that can +be easily integrated with sysrepo. diff --git a/doc/developer/rcu.rst b/doc/developer/rcu.rst index 4fd56587ae..2335e8faed 100644 --- a/doc/developer/rcu.rst +++ b/doc/developer/rcu.rst @@ -232,6 +232,15 @@ Internals that case, either all of the library's threads must be registered for RCU, or the code must instead pass a (non-RCU) copy of the data to the library. +.. c:function:: int frr_pthread_non_controlled_startup(pthread_t thread, const char *name, const char *os_name) + + If a pthread is started outside the control of normal pthreads in frr + then frr_pthread_non_controlled_startup should be called. This will + properly setup both the pthread with rcu usage as well as some data + structures pertaining to the name of the pthread. This is especially + important if the pthread created ends up calling back into FRR and + one of the various zlog_XXX functions is called. + .. c:function:: void rcu_shutdown(void) Stop the RCU sweeper thread and make sure all cleanup has finished. diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index 914e879e31..86d7c402ed 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -1626,10 +1626,12 @@ Configuring Peers .. clicmd:: neighbor PEER update-source <IFNAME|ADDRESS> - Specify the IPv4 source address to use for the :abbr:`BGP` session to this - neighbour, may be specified as either an IPv4 address directly or as an + Specify the IPv4 or IPv6 source address to use for the :abbr:`BGP` session to this + neighbour, may be specified as either an IP address directly or as an interface name (in which case the *zebra* daemon MUST be running in order - for *bgpd* to be able to retrieve interface state). + for *bgpd* to be able to retrieve interface state). When there are multiple + addresses on the choosen IFNAME then BGP will use the address that matches + the most number of bits in comparison to the destination peer address. .. code-block:: frr @@ -3473,7 +3475,7 @@ The import filtering described in item (2) is constrained just to Type-2 The EVPN MAC-VRF Site-of-Origin can be configured using a single CLI command under ``address-family l2vpn evpn`` of the EVPN underlay BGP instance. -.. clicmd:: [no] mac-vrf soo <site-of-origin-string> +.. clicmd:: mac-vrf soo <site-of-origin-string> Example configuration: @@ -3619,7 +3621,7 @@ route maybe fragmented. The number of EVIs per-EAD route can be configured via the following BGP command - -.. clicmd:: [no] ead-es-frag evi-limit (1-1000) +.. clicmd:: ead-es-frag evi-limit (1-1000) Sample Configuration ^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/user/mgmtd.rst b/doc/user/mgmtd.rst index 42bc860b72..aa7ccaac3a 100644 --- a/doc/user/mgmtd.rst +++ b/doc/user/mgmtd.rst @@ -371,22 +371,22 @@ MGMT Daemon debug commands The following debug commands enable debugging within the management daemon: -.. clicmd:: [no] debug mgmt backend +.. clicmd:: debug mgmt backend Enable[/Disable] debugging messages related to backend operations within the management daemon. -.. clicmd:: [no] debug mgmt datastore +.. clicmd:: debug mgmt datastore Enable[/Disable] debugging messages related to YANG datastore operations within the management daemon. -.. clicmd:: [no] debug mgmt frontend +.. clicmd:: debug mgmt frontend Enable[/Disable] debugging messages related to frontend operations within the management daemon. -.. clicmd:: [no] debug mgmt transaction +.. clicmd:: debug mgmt transaction Enable[/Disable] debugging messages related to transactions within the management daemon. @@ -398,12 +398,12 @@ MGMT Client debug commands The following debug commands enable debugging within the management front and backend clients: -.. clicmd:: [no] debug mgmt client backend +.. clicmd:: debug mgmt client backend Enable[/Disable] debugging messages related to backend operations inside the backend mgmtd clients. -.. clicmd:: [no] debug mgmt client frontend +.. clicmd:: debug mgmt client frontend Enable[/Disable] debugging messages related to frontend operations inside the frontend mgmtd clients. diff --git a/doc/user/routemap.rst b/doc/user/routemap.rst index 18a261d940..791762aa7b 100644 --- a/doc/user/routemap.rst +++ b/doc/user/routemap.rst @@ -380,13 +380,13 @@ Route Map Exit Action Command .. clicmd:: on-match next -.. clicmd:: continue - Proceed on to the next entry in the route-map. -.. clicmd:: on-match goto N +.. clicmd:: continue (1-65535) -.. clicmd:: continue N + Proceed to the specified sequence in the route-map. + +.. clicmd:: on-match goto N Proceed processing the route-map at the first entry whose order is >= N diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst index a80580ec71..30b0204254 100644 --- a/doc/user/zebra.rst +++ b/doc/user/zebra.rst @@ -246,7 +246,7 @@ Under link parameter statement, the following commands set the different TE valu as specified in RFC3630 (OSPF) or RFC5305 (ISIS). Admin-group is also known as Resource Class/Color in the OSPF protocol. -.. clicmd:: [no] affinity AFFINITY-MAP-NAME +.. clicmd:: affinity AFFINITY-MAP-NAME This commands configures the Traffic Engineering Admin-Group of the interface using the affinity-map definitions (:ref:`affinity-map`). @@ -257,7 +257,7 @@ Under link parameter statement, the following commands set the different TE valu ``admin-grp`` and ``affinity`` commands provide two ways of setting admin-groups. They cannot be both set on the same interface. -.. clicmd:: [no] affinity-mode [extended|standard|both] +.. clicmd:: affinity-mode [extended|standard|both] This commands configures which admin-group format is set by the affinity command. ``extended`` Admin-Group is the default and uses the RFC7308 format. diff --git a/lib/filter_cli.c b/lib/filter_cli.c index 28790f69e7..c40c2a75fe 100644 --- a/lib/filter_cli.c +++ b/lib/filter_cli.c @@ -128,7 +128,7 @@ static int filter_remove_check_empty(struct vty *vty, const char *ftype, */ DEFPY_YANG( access_list_std, access_list_std_cmd, - "access-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <[host] A.B.C.D$host|A.B.C.D$host A.B.C.D$mask>", + "access-list ACCESSLIST4_NAME$name [seq (1-4294967295)$seq] <deny|permit>$action <[host] A.B.C.D$host|A.B.C.D$host A.B.C.D$mask>", ACCESS_LIST_STR ACCESS_LIST_ZEBRA_STR ACCESS_LIST_SEQ_STR @@ -204,7 +204,7 @@ DEFPY_YANG( DEFPY_YANG( no_access_list_std, no_access_list_std_cmd, - "no access-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <[host] A.B.C.D$host|A.B.C.D$host A.B.C.D$mask>", + "no access-list ACCESSLIST4_NAME$name [seq (1-4294967295)$seq] <deny|permit>$action <[host] A.B.C.D$host|A.B.C.D$host A.B.C.D$mask>", NO_STR ACCESS_LIST_STR ACCESS_LIST_ZEBRA_STR @@ -251,7 +251,7 @@ DEFPY_YANG( DEFPY_YANG( access_list_ext, access_list_ext_cmd, - "access-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action ip <A.B.C.D$src A.B.C.D$src_mask|host A.B.C.D$src|any> <A.B.C.D$dst A.B.C.D$dst_mask|host A.B.C.D$dst|any>", + "access-list ACCESSLIST4_NAME$name [seq (1-4294967295)$seq] <deny|permit>$action ip <A.B.C.D$src A.B.C.D$src_mask|host A.B.C.D$src|any> <A.B.C.D$dst A.B.C.D$dst_mask|host A.B.C.D$dst|any>", ACCESS_LIST_STR ACCESS_LIST_ZEBRA_STR ACCESS_LIST_SEQ_STR @@ -369,7 +369,7 @@ DEFPY_YANG( DEFPY_YANG( no_access_list_ext, no_access_list_ext_cmd, - "no access-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action ip <A.B.C.D$src A.B.C.D$src_mask|host A.B.C.D$src|any> <A.B.C.D$dst A.B.C.D$dst_mask|host A.B.C.D$dst|any>", + "no access-list ACCESSLIST4_NAME$name [seq (1-4294967295)$seq] <deny|permit>$action ip <A.B.C.D$src A.B.C.D$src_mask|host A.B.C.D$src|any> <A.B.C.D$dst A.B.C.D$dst_mask|host A.B.C.D$dst|any>", NO_STR ACCESS_LIST_STR ACCESS_LIST_ZEBRA_STR @@ -448,7 +448,7 @@ DEFPY_YANG( */ DEFPY_YANG( access_list, access_list_cmd, - "access-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <A.B.C.D/M$prefix [exact-match$exact]|any>", + "access-list ACCESSLIST4_NAME$name [seq (1-4294967295)$seq] <deny|permit>$action <A.B.C.D/M$prefix [exact-match$exact]|any>", ACCESS_LIST_STR ACCESS_LIST_ZEBRA_STR ACCESS_LIST_SEQ_STR @@ -521,7 +521,7 @@ DEFPY_YANG( DEFPY_YANG( no_access_list, no_access_list_cmd, - "no access-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <A.B.C.D/M$prefix [exact-match$exact]|any>", + "no access-list ACCESSLIST4_NAME$name [seq (1-4294967295)$seq] <deny|permit>$action <A.B.C.D/M$prefix [exact-match$exact]|any>", NO_STR ACCESS_LIST_STR ACCESS_LIST_ZEBRA_STR @@ -567,7 +567,7 @@ DEFPY_YANG( DEFPY_YANG( no_access_list_all, no_access_list_all_cmd, - "no access-list WORD$name", + "no access-list ACCESSLIST4_NAME$name", NO_STR ACCESS_LIST_STR ACCESS_LIST_ZEBRA_STR) @@ -583,7 +583,7 @@ DEFPY_YANG( DEFPY_YANG( access_list_remark, access_list_remark_cmd, - "access-list WORD$name remark LINE...", + "access-list ACCESSLIST4_NAME$name remark LINE...", ACCESS_LIST_STR ACCESS_LIST_ZEBRA_STR ACCESS_LIST_REMARK_STR @@ -607,7 +607,7 @@ DEFPY_YANG( DEFPY_YANG( no_access_list_remark, no_access_list_remark_cmd, - "no access-list WORD$name remark", + "no access-list ACCESSLIST4_NAME$name remark", NO_STR ACCESS_LIST_STR ACCESS_LIST_ZEBRA_STR @@ -618,7 +618,7 @@ DEFPY_YANG( ALIAS( no_access_list_remark, no_access_list_remark_line_cmd, - "no access-list WORD$name remark LINE...", + "no access-list ACCESSLIST4_NAME$name remark LINE...", NO_STR ACCESS_LIST_STR ACCESS_LIST_ZEBRA_STR @@ -627,7 +627,7 @@ ALIAS( DEFPY_YANG( ipv6_access_list, ipv6_access_list_cmd, - "ipv6 access-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <X:X::X:X/M$prefix [exact-match$exact]|any>", + "ipv6 access-list ACCESSLIST6_NAME$name [seq (1-4294967295)$seq] <deny|permit>$action <X:X::X:X/M$prefix [exact-match$exact]|any>", IPV6_STR ACCESS_LIST_STR ACCESS_LIST_ZEBRA_STR @@ -701,7 +701,7 @@ DEFPY_YANG( DEFPY_YANG( no_ipv6_access_list, no_ipv6_access_list_cmd, - "no ipv6 access-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <X:X::X:X/M$prefix [exact-match$exact]|any>", + "no ipv6 access-list ACCESSLIST6_NAME$name [seq (1-4294967295)$seq] <deny|permit>$action <X:X::X:X/M$prefix [exact-match$exact]|any>", NO_STR IPV6_STR ACCESS_LIST_STR @@ -748,7 +748,7 @@ DEFPY_YANG( DEFPY_YANG( no_ipv6_access_list_all, no_ipv6_access_list_all_cmd, - "no ipv6 access-list WORD$name", + "no ipv6 access-list ACCESSLIST6_NAME$name", NO_STR IPV6_STR ACCESS_LIST_STR @@ -765,7 +765,7 @@ DEFPY_YANG( DEFPY_YANG( ipv6_access_list_remark, ipv6_access_list_remark_cmd, - "ipv6 access-list WORD$name remark LINE...", + "ipv6 access-list ACCESSLIST6_NAME$name remark LINE...", IPV6_STR ACCESS_LIST_STR ACCESS_LIST_ZEBRA_STR @@ -790,7 +790,7 @@ DEFPY_YANG( DEFPY_YANG( no_ipv6_access_list_remark, no_ipv6_access_list_remark_cmd, - "no ipv6 access-list WORD$name remark", + "no ipv6 access-list ACCESSLIST6_NAME$name remark", NO_STR IPV6_STR ACCESS_LIST_STR @@ -1166,7 +1166,7 @@ static int plist_remove(struct vty *vty, const char *iptype, const char *name, DEFPY_YANG( ip_prefix_list, ip_prefix_list_cmd, - "ip prefix-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <any|A.B.C.D/M$prefix [{ge (0-32)$ge|le (0-32)$le}]>", + "ip prefix-list PREFIXLIST4_NAME$name [seq (1-4294967295)$seq] <deny|permit>$action <any|A.B.C.D/M$prefix [{ge (0-32)$ge|le (0-32)$le}]>", IP_STR PREFIX_LIST_STR PREFIX_LIST_NAME_STR @@ -1260,7 +1260,7 @@ DEFPY_YANG( DEFPY_YANG( no_ip_prefix_list, no_ip_prefix_list_cmd, - "no ip prefix-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <any|A.B.C.D/M$prefix [{ge (0-32)|le (0-32)}]>", + "no ip prefix-list PREFIXLIST4_NAME$name [seq (1-4294967295)$seq] <deny|permit>$action <any|A.B.C.D/M$prefix [{ge (0-32)|le (0-32)}]>", NO_STR IP_STR PREFIX_LIST_STR @@ -1280,7 +1280,7 @@ DEFPY_YANG( DEFPY_YANG( no_ip_prefix_list_seq, no_ip_prefix_list_seq_cmd, - "no ip prefix-list WORD$name seq (1-4294967295)$seq", + "no ip prefix-list PREFIXLIST4_NAME$name seq (1-4294967295)$seq", NO_STR IP_STR PREFIX_LIST_STR @@ -1292,7 +1292,7 @@ DEFPY_YANG( DEFPY_YANG( no_ip_prefix_list_all, no_ip_prefix_list_all_cmd, - "no ip prefix-list WORD$name", + "no ip prefix-list PREFIXLIST4_NAME$name", NO_STR IP_STR PREFIX_LIST_STR @@ -1309,7 +1309,7 @@ DEFPY_YANG( DEFPY_YANG( ip_prefix_list_remark, ip_prefix_list_remark_cmd, - "ip prefix-list WORD$name description LINE...", + "ip prefix-list PREFIXLIST4_NAME$name description LINE...", IP_STR PREFIX_LIST_STR PREFIX_LIST_NAME_STR @@ -1334,7 +1334,7 @@ DEFPY_YANG( DEFPY_YANG( no_ip_prefix_list_remark, no_ip_prefix_list_remark_cmd, - "no ip prefix-list WORD$name description", + "no ip prefix-list PREFIXLIST4_NAME$name description", NO_STR IP_STR PREFIX_LIST_STR @@ -1346,7 +1346,7 @@ DEFPY_YANG( ALIAS( no_ip_prefix_list_remark, no_ip_prefix_list_remark_line_cmd, - "no ip prefix-list WORD$name description LINE...", + "no ip prefix-list PREFIXLIST4_NAME$name description LINE...", NO_STR IP_STR PREFIX_LIST_STR @@ -1356,7 +1356,7 @@ ALIAS( DEFPY_YANG( ipv6_prefix_list, ipv6_prefix_list_cmd, - "ipv6 prefix-list WORD$name [seq (1-4294967295)] <deny|permit>$action <any|X:X::X:X/M$prefix [{ge (0-128)$ge|le (0-128)$le}]>", + "ipv6 prefix-list PREFIXLIST6_NAME$name [seq (1-4294967295)] <deny|permit>$action <any|X:X::X:X/M$prefix [{ge (0-128)$ge|le (0-128)$le}]>", IPV6_STR PREFIX_LIST_STR PREFIX_LIST_NAME_STR @@ -1450,7 +1450,7 @@ DEFPY_YANG( DEFPY_YANG( no_ipv6_prefix_list, no_ipv6_prefix_list_cmd, - "no ipv6 prefix-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <any|X:X::X:X/M$prefix [{ge (0-128)$ge|le (0-128)$le}]>", + "no ipv6 prefix-list PREFIXLIST6_NAME$name [seq (1-4294967295)$seq] <deny|permit>$action <any|X:X::X:X/M$prefix [{ge (0-128)$ge|le (0-128)$le}]>", NO_STR IPV6_STR PREFIX_LIST_STR @@ -1470,7 +1470,7 @@ DEFPY_YANG( DEFPY_YANG( no_ipv6_prefix_list_seq, no_ipv6_prefix_list_seq_cmd, - "no ipv6 prefix-list WORD$name seq (1-4294967295)$seq", + "no ipv6 prefix-list PREFIXLIST6_NAME$name seq (1-4294967295)$seq", NO_STR IPV6_STR PREFIX_LIST_STR @@ -1482,7 +1482,7 @@ DEFPY_YANG( DEFPY_YANG( no_ipv6_prefix_list_all, no_ipv6_prefix_list_all_cmd, - "no ipv6 prefix-list WORD$name", + "no ipv6 prefix-list PREFIXLIST6_NAME$name", NO_STR IPV6_STR PREFIX_LIST_STR @@ -1499,7 +1499,7 @@ DEFPY_YANG( DEFPY_YANG( ipv6_prefix_list_remark, ipv6_prefix_list_remark_cmd, - "ipv6 prefix-list WORD$name description LINE...", + "ipv6 prefix-list PREFIXLIST6_NAME$name description LINE...", IPV6_STR PREFIX_LIST_STR PREFIX_LIST_NAME_STR @@ -1524,7 +1524,7 @@ DEFPY_YANG( DEFPY_YANG( no_ipv6_prefix_list_remark, no_ipv6_prefix_list_remark_cmd, - "no ipv6 prefix-list WORD$name description", + "no ipv6 prefix-list PREFIXLIST6_NAME$name description", NO_STR IPV6_STR PREFIX_LIST_STR @@ -1536,7 +1536,7 @@ DEFPY_YANG( ALIAS( no_ipv6_prefix_list_remark, no_ipv6_prefix_list_remark_line_cmd, - "no ipv6 prefix-list WORD$name description LINE...", + "no ipv6 prefix-list PREFIXLIST6_NAME$name description LINE...", NO_STR IPV6_STR PREFIX_LIST_STR @@ -1748,6 +1748,8 @@ lib_interface_state_phy_address_get_elem(struct nb_cb_get_elem_args *args) } /* clang-format off */ + +/* cli_show callbacks are kept here for daemons not yet converted to mgmtd */ const struct frr_yang_module_info frr_interface_info = { .name = "frr-interface", .nodes = { @@ -1830,3 +1832,26 @@ const struct frr_yang_module_info frr_interface_info = { }, } }; + +const struct frr_yang_module_info frr_interface_cli_info = { + .name = "frr-interface", + .ignore_cfg_cbs = true, + .nodes = { + { + .xpath = "/frr-interface:lib/interface", + .cbs = { + .cli_show = cli_show_interface, + .cli_show_end = cli_show_interface_end, + }, + }, + { + .xpath = "/frr-interface:lib/interface/description", + .cbs = { + .cli_show = cli_show_interface_desc, + }, + }, + { + .xpath = NULL, + }, + } +}; @@ -636,6 +636,7 @@ extern void if_down_via_zapi(struct interface *ifp); extern void if_destroy_via_zapi(struct interface *ifp); extern const struct frr_yang_module_info frr_interface_info; +extern const struct frr_yang_module_info frr_interface_cli_info; #ifdef __cplusplus } diff --git a/lib/northbound_sysrepo.c b/lib/northbound_sysrepo.c index 198d96e381..4942d66850 100644 --- a/lib/northbound_sysrepo.c +++ b/lib/northbound_sysrepo.c @@ -279,11 +279,12 @@ static int frr_sr_config_change_cb_prepare(sr_session_ctx_t *session, ret = nb_candidate_commit_prepare(context, candidate, NULL, &transaction, false, false, errmsg, sizeof(errmsg)); - if (ret != NB_OK && ret != NB_ERR_NO_CHANGES) - flog_warn( - EC_LIB_LIBSYSREPO, - "%s: failed to prepare configuration transaction: %s (%s)", - __func__, nb_err_name(ret), errmsg); + if (ret != NB_OK && ret != NB_ERR_NO_CHANGES) { + flog_warn(EC_LIB_LIBSYSREPO, + "%s: failed to prepare configuration transaction: %s (%s)", + __func__, nb_err_name(ret), errmsg); + sr_session_set_error_message(session, errmsg); + } if (!transaction) nb_config_free(candidate); diff --git a/lib/plist.c b/lib/plist.c index 605e7e73ea..618d92b549 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -1229,7 +1229,7 @@ static int vty_clear_prefix_list(struct vty *vty, afi_t afi, const char *name, DEFPY (show_ip_prefix_list, show_ip_prefix_list_cmd, - "show ip prefix-list [WORD [seq$dseq (1-4294967295)$arg]] [json$uj]", + "show ip prefix-list [PREFIXLIST4_NAME$name [seq$dseq (1-4294967295)$arg]] [json$uj]", SHOW_STR IP_STR PREFIX_LIST_STR @@ -1242,13 +1242,13 @@ DEFPY (show_ip_prefix_list, if (dseq) dtype = sequential_display; - return vty_show_prefix_list(vty, AFI_IP, prefix_list, arg_str, dtype, + return vty_show_prefix_list(vty, AFI_IP, name, arg_str, dtype, !!uj); } DEFPY (show_ip_prefix_list_prefix, show_ip_prefix_list_prefix_cmd, - "show ip prefix-list WORD A.B.C.D/M$prefix [longer$dl|first-match$dfm]", + "show ip prefix-list PREFIXLIST4_NAME$name A.B.C.D/M$prefix [longer$dl|first-match$dfm]", SHOW_STR IP_STR PREFIX_LIST_STR @@ -1263,13 +1263,13 @@ DEFPY (show_ip_prefix_list_prefix, else if (dfm) dtype = first_match_display; - return vty_show_prefix_list_prefix(vty, AFI_IP, prefix_list, prefix_str, + return vty_show_prefix_list_prefix(vty, AFI_IP, name, prefix_str, dtype); } DEFPY (show_ip_prefix_list_summary, show_ip_prefix_list_summary_cmd, - "show ip prefix-list summary [WORD$prefix_list] [json$uj]", + "show ip prefix-list summary [PREFIXLIST4_NAME$name] [json$uj]", SHOW_STR IP_STR PREFIX_LIST_STR @@ -1277,13 +1277,13 @@ DEFPY (show_ip_prefix_list_summary, "Name of a prefix list\n" JSON_STR) { - return vty_show_prefix_list(vty, AFI_IP, prefix_list, NULL, + return vty_show_prefix_list(vty, AFI_IP, name, NULL, summary_display, !!uj); } DEFPY (show_ip_prefix_list_detail, show_ip_prefix_list_detail_cmd, - "show ip prefix-list detail [WORD$prefix_list] [json$uj]", + "show ip prefix-list detail [PREFIXLIST4_NAME$name] [json$uj]", SHOW_STR IP_STR PREFIX_LIST_STR @@ -1291,25 +1291,25 @@ DEFPY (show_ip_prefix_list_detail, "Name of a prefix list\n" JSON_STR) { - return vty_show_prefix_list(vty, AFI_IP, prefix_list, NULL, + return vty_show_prefix_list(vty, AFI_IP, name, NULL, detail_display, !!uj); } DEFPY (clear_ip_prefix_list, clear_ip_prefix_list_cmd, - "clear ip prefix-list [WORD [A.B.C.D/M$prefix]]", + "clear ip prefix-list [PREFIXLIST4_NAME$name [A.B.C.D/M$prefix]]", CLEAR_STR IP_STR PREFIX_LIST_STR "Name of a prefix list\n" "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n") { - return vty_clear_prefix_list(vty, AFI_IP, prefix_list, prefix_str); + return vty_clear_prefix_list(vty, AFI_IP, name, prefix_str); } DEFPY (show_ipv6_prefix_list, show_ipv6_prefix_list_cmd, - "show ipv6 prefix-list [WORD [seq$dseq (1-4294967295)$arg]] [json$uj]", + "show ipv6 prefix-list [PREFIXLIST6_NAME$name [seq$dseq (1-4294967295)$arg]] [json$uj]", SHOW_STR IPV6_STR PREFIX_LIST_STR @@ -1322,13 +1322,13 @@ DEFPY (show_ipv6_prefix_list, if (dseq) dtype = sequential_display; - return vty_show_prefix_list(vty, AFI_IP6, prefix_list, arg_str, dtype, + return vty_show_prefix_list(vty, AFI_IP6, name, arg_str, dtype, !!uj); } DEFPY (show_ipv6_prefix_list_prefix, show_ipv6_prefix_list_prefix_cmd, - "show ipv6 prefix-list WORD X:X::X:X/M$prefix [longer$dl|first-match$dfm]", + "show ipv6 prefix-list PREFIXLIST6_NAME$name X:X::X:X/M$prefix [longer$dl|first-match$dfm]", SHOW_STR IPV6_STR PREFIX_LIST_STR @@ -1343,13 +1343,13 @@ DEFPY (show_ipv6_prefix_list_prefix, else if (dfm) dtype = first_match_display; - return vty_show_prefix_list_prefix(vty, AFI_IP6, prefix_list, + return vty_show_prefix_list_prefix(vty, AFI_IP6, name, prefix_str, dtype); } DEFPY (show_ipv6_prefix_list_summary, show_ipv6_prefix_list_summary_cmd, - "show ipv6 prefix-list summary [WORD$prefix-list] [json$uj]", + "show ipv6 prefix-list summary [PREFIXLIST6_NAME$name] [json$uj]", SHOW_STR IPV6_STR PREFIX_LIST_STR @@ -1357,13 +1357,13 @@ DEFPY (show_ipv6_prefix_list_summary, "Name of a prefix list\n" JSON_STR) { - return vty_show_prefix_list(vty, AFI_IP6, prefix_list, NULL, + return vty_show_prefix_list(vty, AFI_IP6, name, NULL, summary_display, !!uj); } DEFPY (show_ipv6_prefix_list_detail, show_ipv6_prefix_list_detail_cmd, - "show ipv6 prefix-list detail [WORD$prefix-list] [json$uj]", + "show ipv6 prefix-list detail [PREFIXLIST6_NAME$name] [json$uj]", SHOW_STR IPV6_STR PREFIX_LIST_STR @@ -1371,20 +1371,20 @@ DEFPY (show_ipv6_prefix_list_detail, "Name of a prefix list\n" JSON_STR) { - return vty_show_prefix_list(vty, AFI_IP6, prefix_list, NULL, + return vty_show_prefix_list(vty, AFI_IP6, name, NULL, detail_display, !!uj); } DEFPY (clear_ipv6_prefix_list, clear_ipv6_prefix_list_cmd, - "clear ipv6 prefix-list [WORD [X:X::X:X/M$prefix]]", + "clear ipv6 prefix-list [PREFIXLIST6_NAME$name [X:X::X:X/M$prefix]]", CLEAR_STR IPV6_STR PREFIX_LIST_STR "Name of a prefix list\n" "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n") { - return vty_clear_prefix_list(vty, AFI_IP6, prefix_list, prefix_str); + return vty_clear_prefix_list(vty, AFI_IP6, name, prefix_str); } DEFPY (debug_prefix_list_match, diff --git a/lib/routemap_cli.c b/lib/routemap_cli.c index f24d574278..88b341cac0 100644 --- a/lib/routemap_cli.c +++ b/lib/routemap_cli.c @@ -188,7 +188,7 @@ DEFPY_YANG( DEFPY_YANG( match_ip_address_prefix_list, match_ip_address_prefix_list_cmd, - "match ip address prefix-list PREFIXLIST_NAME$name", + "match ip address prefix-list PREFIXLIST4_NAME$name", MATCH_STR IP_STR "Match address of route\n" @@ -209,7 +209,7 @@ DEFPY_YANG( DEFPY_YANG( no_match_ip_address_prefix_list, no_match_ip_address_prefix_list_cmd, - "no match ip address prefix-list [PREFIXLIST_NAME]", + "no match ip address prefix-list [PREFIXLIST4_NAME]", NO_STR MATCH_STR IP_STR @@ -265,7 +265,7 @@ DEFPY_YANG( DEFPY_YANG( match_ip_next_hop_prefix_list, match_ip_next_hop_prefix_list_cmd, - "match ip next-hop prefix-list PREFIXLIST_NAME$name", + "match ip next-hop prefix-list PREFIXLIST4_NAME$name", MATCH_STR IP_STR "Match next-hop address of route\n" @@ -287,7 +287,7 @@ DEFPY_YANG( DEFPY_YANG( no_match_ip_next_hop_prefix_list, no_match_ip_next_hop_prefix_list_cmd, - "no match ip next-hop prefix-list [PREFIXLIST_NAME]", + "no match ip next-hop prefix-list [PREFIXLIST4_NAME]", NO_STR MATCH_STR IP_STR @@ -379,7 +379,7 @@ DEFPY_YANG( DEFPY_YANG( match_ipv6_address_prefix_list, match_ipv6_address_prefix_list_cmd, - "match ipv6 address prefix-list PREFIXLIST_NAME$name", + "match ipv6 address prefix-list PREFIXLIST6_NAME$name", MATCH_STR IPV6_STR "Match address of route\n" @@ -401,7 +401,7 @@ DEFPY_YANG( DEFPY_YANG( no_match_ipv6_address_prefix_list, no_match_ipv6_address_prefix_list_cmd, - "no match ipv6 address prefix-list [PREFIXLIST_NAME]", + "no match ipv6 address prefix-list [PREFIXLIST6_NAME]", NO_STR MATCH_STR IPV6_STR diff --git a/lib/routing_nb.c b/lib/routing_nb.c index 3d837bcc11..33372d113a 100644 --- a/lib/routing_nb.c +++ b/lib/routing_nb.c @@ -27,3 +27,13 @@ const struct frr_yang_module_info frr_routing_info = { }, } }; + +const struct frr_yang_module_info frr_routing_cli_info = { + .name = "frr-routing", + .ignore_cfg_cbs = true, + .nodes = { + { + .xpath = NULL, + }, + } +}; diff --git a/lib/routing_nb.h b/lib/routing_nb.h index cc83d8469d..e805e1cd0f 100644 --- a/lib/routing_nb.h +++ b/lib/routing_nb.h @@ -6,6 +6,7 @@ extern "C" { #endif extern const struct frr_yang_module_info frr_routing_info; +extern const struct frr_yang_module_info frr_routing_cli_info; /* Mandatory callbacks. */ int routing_control_plane_protocols_control_plane_protocol_create( diff --git a/lib/sockopt.c b/lib/sockopt.c index b9b9a71167..74bc034ccd 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -672,6 +672,9 @@ int sockopt_tcp_mss_get(int sock) int tcp_maxseg = 0; socklen_t tcp_maxseg_len = sizeof(tcp_maxseg); + if (sock < 0) + return 0; + ret = getsockopt(sock, IPPROTO_TCP, TCP_MAXSEG, &tcp_maxseg, &tcp_maxseg_len); if (ret != 0) { @@ -1034,6 +1034,8 @@ lib_vrf_state_active_get_elem(struct nb_cb_get_elem_args *args) } /* clang-format off */ + +/* cli_show callbacks are kept here for daemons not yet converted to mgmtd */ const struct frr_yang_module_info frr_vrf_info = { .name = "frr-vrf", .nodes = { @@ -1069,3 +1071,19 @@ const struct frr_yang_module_info frr_vrf_info = { } }; +const struct frr_yang_module_info frr_vrf_cli_info = { + .name = "frr-vrf", + .ignore_cfg_cbs = true, + .nodes = { + { + .xpath = "/frr-vrf:lib/vrf", + .cbs = { + .cli_show = lib_vrf_cli_write, + .cli_show_end = lib_vrf_cli_write_end, + }, + }, + { + .xpath = NULL, + }, + } +}; @@ -294,6 +294,7 @@ extern int vrf_enable(struct vrf *vrf); extern void vrf_delete(struct vrf *vrf); extern const struct frr_yang_module_info frr_vrf_info; +extern const struct frr_yang_module_info frr_vrf_cli_info; #ifdef __cplusplus } @@ -232,10 +232,6 @@ struct vty { uintptr_t mgmt_req_pending_data; bool mgmt_locked_candidate_ds; bool mgmt_locked_running_ds; - /* Need to track when we file-lock in vtysh to re-lock on end/conf t - * workaround - */ - bool vtysh_file_locked; }; static inline void vty_push_context(struct vty *vty, int node, uint64_t id) diff --git a/lib/yang.c b/lib/yang.c index 2b360376d3..adf2ba2ab0 100644 --- a/lib/yang.c +++ b/lib/yang.c @@ -40,7 +40,8 @@ static LY_ERR yang_module_imp_clb(const char *mod_name, const char *mod_rev, struct yang_module_embed *e; if (!strcmp(mod_name, "ietf-inet-types") || - !strcmp(mod_name, "ietf-yang-types")) + !strcmp(mod_name, "ietf-yang-types") || + !strcmp(mod_name, "ietf-yang-metadata")) /* libyang has these built in, don't try finding them here */ return LY_ENOTFOUND; diff --git a/mgmtd/mgmt_fe_adapter.c b/mgmtd/mgmt_fe_adapter.c index 001da7680b..ec8e773354 100644 --- a/mgmtd/mgmt_fe_adapter.c +++ b/mgmtd/mgmt_fe_adapter.c @@ -711,9 +711,6 @@ mgmt_fe_session_handle_setcfg_req_msg(struct mgmt_fe_session_ctx *session, } if (session->cfg_txn_id == MGMTD_TXN_ID_NONE) { - /* as we have the lock no-one else should have a config txn */ - assert(!mgmt_config_txn_in_progress()); - /* Start a CONFIG Transaction (if not started already) */ session->cfg_txn_id = mgmt_create_txn(session->session_id, MGMTD_TXN_TYPE_CONFIG); diff --git a/mgmtd/mgmt_main.c b/mgmtd/mgmt_main.c index 5be849b63c..cce16f51f6 100644 --- a/mgmtd/mgmt_main.c +++ b/mgmtd/mgmt_main.c @@ -48,7 +48,6 @@ struct zebra_privs_t mgmt_privs = { }; static struct frr_daemon_info mgmtd_di; -char backup_config_file[256]; /* SIGHUP handler. */ static void sighup(void) @@ -171,10 +170,10 @@ const struct frr_yang_module_info zebra_route_map_info = { */ static const struct frr_yang_module_info *const mgmt_yang_modules[] = { &frr_filter_cli_info, - &frr_interface_info, + &frr_interface_cli_info, &frr_route_map_cli_info, - &frr_routing_info, - &frr_vrf_info, + &frr_routing_cli_info, + &frr_vrf_cli_info, &frr_affinity_map_cli_info, /* mgmtd-only modules */ @@ -212,7 +211,7 @@ FRR_DAEMON_INFO(mgmtd, MGMTD, .n_yang_modules = array_size(mgmt_yang_modules), /* avoid libfrr trying to read our config file for us */ - .flags = FRR_MANUAL_VTY_START, + .flags = FRR_MANUAL_VTY_START | FRR_NO_SPLIT_CONFIG, ); /* clang-format on */ @@ -230,8 +229,9 @@ int main(int argc, char **argv) frr_preinit(&mgmtd_di, argc, argv); frr_opt_add( - "s:" DEPRECATED_OPTIONS, longopts, - " -s, --socket_size Set MGMTD peer socket send buffer size\n"); + "s:n" DEPRECATED_OPTIONS, longopts, + " -s, --socket_size Set MGMTD peer socket send buffer size\n" + " -n, --vrfwnetns Use NetNS as VRF backend\n"); /* Command line argument treatment. */ while (1) { @@ -274,11 +274,6 @@ int main(int argc, char **argv) /* MGMTD related initialization. */ mgmt_init(); - snprintf(backup_config_file, sizeof(backup_config_file), - "%s/zebra.conf", frr_sysconfdir); - mgmtd_di.backup_config_file = backup_config_file; - - /* this will queue a read configs event */ frr_config_fork(); frr_run(mm->master); diff --git a/mgmtd/mgmt_txn.c b/mgmtd/mgmt_txn.c index df2a1d852d..664f42f4ba 100644 --- a/mgmtd/mgmt_txn.c +++ b/mgmtd/mgmt_txn.c @@ -105,6 +105,7 @@ struct mgmt_commit_cfg_req { uint8_t abort : 1; uint8_t implicit : 1; uint8_t rollback : 1; + uint8_t init : 1; /* Track commit phases */ enum mgmt_commit_phase phase; @@ -750,6 +751,14 @@ static int mgmt_txn_send_commit_cfg_reply(struct mgmt_txn_ctx *txn, mgmt_history_rollback_complete(success); } + if (txn->commit_cfg_req->req.commit_cfg.init) { + /* + * This is the backend init request. + * We need to unlock the running datastore. + */ + mgmt_ds_unlock(txn->commit_cfg_req->req.commit_cfg.dst_ds_ctx); + } + txn->commit_cfg_req->req.commit_cfg.cmt_stats = NULL; mgmt_txn_req_free(&txn->commit_cfg_req); @@ -2081,15 +2090,26 @@ int mgmt_txn_notify_be_adapter_conn(struct mgmt_be_client_adapter *adapter, struct mgmt_commit_cfg_req *cmtcfg_req; static struct mgmt_commit_stats dummy_stats; struct nb_config_cbs *adapter_cfgs = NULL; + struct mgmt_ds_ctx *ds_ctx; memset(&dummy_stats, 0, sizeof(dummy_stats)); if (connect) { - /* Get config for this single backend client */ + ds_ctx = mgmt_ds_get_ctx_by_id(mm, MGMTD_DS_RUNNING); + assert(ds_ctx); + + /* + * Lock the running datastore to prevent any changes while we + * are initializing the backend. + */ + if (mgmt_ds_lock(ds_ctx, 0) != 0) + return -1; + /* Get config for this single backend client */ mgmt_be_get_adapter_config(adapter, &adapter_cfgs); if (!adapter_cfgs || RB_EMPTY(nb_config_cbs, adapter_cfgs)) { SET_FLAG(adapter->flags, MGMTD_BE_ADAPTER_FLAGS_CFG_SYNCED); + mgmt_ds_unlock(ds_ctx); return 0; } @@ -2101,6 +2121,7 @@ int mgmt_txn_notify_be_adapter_conn(struct mgmt_be_client_adapter *adapter, if (!txn) { __log_err("Failed to create CONFIG Transaction for downloading CONFIGs for client '%s'", adapter->name); + mgmt_ds_unlock(ds_ctx); nb_config_diff_del_changes(adapter_cfgs); return -1; } @@ -2114,10 +2135,11 @@ int mgmt_txn_notify_be_adapter_conn(struct mgmt_be_client_adapter *adapter, txn_req = mgmt_txn_req_alloc(txn, 0, MGMTD_TXN_PROC_COMMITCFG); txn_req->req.commit_cfg.src_ds_id = MGMTD_DS_NONE; txn_req->req.commit_cfg.src_ds_ctx = 0; - txn_req->req.commit_cfg.dst_ds_id = MGMTD_DS_NONE; - txn_req->req.commit_cfg.dst_ds_ctx = 0; + txn_req->req.commit_cfg.dst_ds_id = MGMTD_DS_RUNNING; + txn_req->req.commit_cfg.dst_ds_ctx = ds_ctx; txn_req->req.commit_cfg.validate_only = false; txn_req->req.commit_cfg.abort = false; + txn_req->req.commit_cfg.init = true; txn_req->req.commit_cfg.cmt_stats = &dummy_stats; txn_req->req.commit_cfg.cfg_chgs = adapter_cfgs; diff --git a/mgmtd/subdir.am b/mgmtd/subdir.am index 0af64dc0be..1624c6e4f9 100644 --- a/mgmtd/subdir.am +++ b/mgmtd/subdir.am @@ -19,7 +19,6 @@ mgmtd_libmgmt_be_nb_la_SOURCES = \ zebra/zebra_cli.c \ # end nodist_mgmtd_libmgmt_be_nb_la_SOURCES = \ - lib/affinitymap_cli.c \ # end mgmtd_libmgmt_be_nb_la_CFLAGS = $(AM_CFLAGS) -DINCLUDE_MGMTD_CMDDEFS_ONLY mgmtd_libmgmt_be_nb_la_CPPFLAGS = $(AM_CPPFLAGS) -DINCLUDE_MGMTD_CMDDEFS_ONLY @@ -61,6 +60,7 @@ mgmtd_mgmtd_SOURCES = \ # end nodist_mgmtd_mgmtd_SOURCES = \ yang/frr-zebra.yang.c \ + yang/frr-zebra-route-map.yang.c \ yang/ietf/ietf-netconf-acm.yang.c \ yang/ietf/ietf-netconf.yang.c \ yang/ietf/ietf-netconf-with-defaults.yang.c \ diff --git a/nhrpd/netlink_arp.c b/nhrpd/netlink_arp.c index 88628999ab..be909c862a 100644 --- a/nhrpd/netlink_arp.c +++ b/nhrpd/netlink_arp.c @@ -191,6 +191,11 @@ int nhrp_neighbor_operation(ZAPI_CALLBACK_ARGS) "Netlink: update binding for %pSU dev %s from c %pSU peer.vc.nbma %pSU to lladdr %pSU", &addr, ifp->name, &c->cur.remote_nbma_natoa, &c->cur.peer->vc->remote.nbma, &lladdr); + + if (lladdr.sa.sa_family == AF_UNSPEC) + /* nothing from zebra, so use nhrp peer */ + lladdr = c->cur.peer->vc->remote.nbma; + /* In case of shortcuts, nbma is given by lladdr, not * vc->remote.nbma. */ diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index 69c711bf06..cf5479e18c 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -731,7 +731,7 @@ void ospf6_area_config_write(struct vty *vty, struct ospf6 *ospf6) DEFUN (area_filter_list, area_filter_list_cmd, - "area <A.B.C.D|(0-4294967295)> filter-list prefix PREFIXLIST_NAME <in|out>", + "area <A.B.C.D|(0-4294967295)> filter-list prefix PREFIXLIST6_NAME <in|out>", "OSPF6 area parameters\n" "OSPF6 area ID in IP address format\n" "OSPF6 area ID as a decimal value\n" @@ -774,7 +774,7 @@ DEFUN (area_filter_list, DEFUN (no_area_filter_list, no_area_filter_list_cmd, - "no area <A.B.C.D|(0-4294967295)> filter-list prefix PREFIXLIST_NAME <in|out>", + "no area <A.B.C.D|(0-4294967295)> filter-list prefix PREFIXLIST6_NAME <in|out>", NO_STR "OSPF6 area parameters\n" "OSPF6 area ID in IP address format\n" diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index 652d502c8e..b9dace2fe8 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -2396,7 +2396,7 @@ DEFUN(no_ipv6_ospf6_mtu_ignore, no_ipv6_ospf6_mtu_ignore_cmd, } DEFUN(ipv6_ospf6_advertise_prefix_list, ipv6_ospf6_advertise_prefix_list_cmd, - "ipv6 ospf6 advertise prefix-list WORD", + "ipv6 ospf6 advertise prefix-list PREFIXLIST6_NAME", IP6_STR OSPF6_STR "Advertising options\n" "Filter prefix using prefix-list\n" "Prefix list name\n") @@ -2431,7 +2431,7 @@ DEFUN(ipv6_ospf6_advertise_prefix_list, ipv6_ospf6_advertise_prefix_list_cmd, DEFUN(no_ipv6_ospf6_advertise_prefix_list, no_ipv6_ospf6_advertise_prefix_list_cmd, - "no ipv6 ospf6 advertise prefix-list [WORD]", + "no ipv6 ospf6 advertise prefix-list [PREFIXLIST6_NAME]", NO_STR IP6_STR OSPF6_STR "Advertising options\n" "Filter prefix using prefix-list\n" "Prefix list name\n") diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 877c9bd634..93dd12ce49 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -1872,7 +1872,7 @@ DEFUN (no_ospf_area_import_list, DEFUN (ospf_area_filter_list, ospf_area_filter_list_cmd, - "area <A.B.C.D|(0-4294967295)> filter-list prefix PREFIXLIST_NAME <in|out>", + "area <A.B.C.D|(0-4294967295)> filter-list prefix PREFIXLIST4_NAME <in|out>", "OSPF area parameters\n" "OSPF area ID in IP address format\n" "OSPF area ID as a decimal value\n" @@ -1917,7 +1917,7 @@ DEFUN (ospf_area_filter_list, DEFUN (no_ospf_area_filter_list, no_ospf_area_filter_list_cmd, - "no area <A.B.C.D|(0-4294967295)> filter-list prefix PREFIXLIST_NAME <in|out>", + "no area <A.B.C.D|(0-4294967295)> filter-list prefix PREFIXLIST4_NAME <in|out>", NO_STR "OSPF area parameters\n" "OSPF area ID in IP address format\n" diff --git a/pimd/pim6_cmd.c b/pimd/pim6_cmd.c index 262ce86c29..4db11572d8 100644 --- a/pimd/pim6_cmd.c +++ b/pimd/pim6_cmd.c @@ -77,7 +77,7 @@ DEFPY (ipv6_pim_spt_switchover_infinity, DEFPY (ipv6_pim_spt_switchover_infinity_plist, ipv6_pim_spt_switchover_infinity_plist_cmd, - "ipv6 pim spt-switchover infinity-and-beyond prefix-list WORD$plist", + "ipv6 pim spt-switchover infinity-and-beyond prefix-list PREFIXLIST6_NAME$plist", IPV6_STR PIM_STR "SPT-Switchover\n" @@ -102,7 +102,7 @@ DEFPY (no_ipv6_pim_spt_switchover_infinity, DEFPY (no_ipv6_pim_spt_switchover_infinity_plist, no_ipv6_pim_spt_switchover_infinity_plist_cmd, - "no ipv6 pim spt-switchover infinity-and-beyond prefix-list WORD", + "no ipv6 pim spt-switchover infinity-and-beyond prefix-list PREFIXLIST6_NAME", NO_STR IPV6_STR PIM_STR @@ -436,7 +436,7 @@ DEFPY (no_ipv6_pim_rp, DEFPY (ipv6_pim_rp_prefix_list, ipv6_pim_rp_prefix_list_cmd, - "ipv6 pim rp X:X::X:X$rp prefix-list WORD$plist", + "ipv6 pim rp X:X::X:X$rp prefix-list PREFIXLIST6_NAME$plist", IPV6_STR PIM_STR "Rendezvous Point\n" @@ -449,7 +449,7 @@ DEFPY (ipv6_pim_rp_prefix_list, DEFPY (no_ipv6_pim_rp_prefix_list, no_ipv6_pim_rp_prefix_list_cmd, - "no ipv6 pim rp X:X::X:X$rp prefix-list WORD$plist", + "no ipv6 pim rp X:X::X:X$rp prefix-list PREFIXLIST6_NAME$plist", NO_STR IPV6_STR PIM_STR diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 628a445945..be36a07687 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -2999,7 +2999,7 @@ DEFUN (ip_pim_spt_switchover_infinity, DEFPY (ip_pim_spt_switchover_infinity_plist, ip_pim_spt_switchover_infinity_plist_cmd, - "ip pim spt-switchover infinity-and-beyond prefix-list WORD$plist", + "ip pim spt-switchover infinity-and-beyond prefix-list PREFIXLIST4_NAME$plist", IP_STR PIM_STR "SPT-Switchover\n" @@ -3024,7 +3024,7 @@ DEFUN (no_ip_pim_spt_switchover_infinity, DEFUN (no_ip_pim_spt_switchover_infinity_plist, no_ip_pim_spt_switchover_infinity_plist_cmd, - "no ip pim spt-switchover infinity-and-beyond prefix-list WORD", + "no ip pim spt-switchover infinity-and-beyond prefix-list PREFIXLIST4_NAME", NO_STR IP_STR PIM_STR @@ -3038,7 +3038,7 @@ DEFUN (no_ip_pim_spt_switchover_infinity_plist, DEFPY (pim_register_accept_list, pim_register_accept_list_cmd, - "[no] ip pim register-accept-list WORD$word", + "[no] ip pim register-accept-list PREFIXLIST4_NAME$word", NO_STR IP_STR PIM_STR @@ -3283,7 +3283,7 @@ DEFPY (ip_pim_rp, DEFPY (ip_pim_rp_prefix_list, ip_pim_rp_prefix_list_cmd, - "ip pim rp A.B.C.D$rp prefix-list WORD$plist", + "ip pim rp A.B.C.D$rp prefix-list PREFIXLIST4_NAME$plist", IP_STR "pim multicast routing\n" "Rendezvous Point\n" @@ -3311,7 +3311,7 @@ DEFPY (no_ip_pim_rp, DEFPY (no_ip_pim_rp_prefix_list, no_ip_pim_rp_prefix_list_cmd, - "no ip pim rp A.B.C.D$rp prefix-list WORD$plist", + "no ip pim rp A.B.C.D$rp prefix-list PREFIXLIST4_NAME$plist", NO_STR IP_STR "pim multicast routing\n" @@ -3325,7 +3325,7 @@ DEFPY (no_ip_pim_rp_prefix_list, DEFUN (ip_pim_ssm_prefix_list, ip_pim_ssm_prefix_list_cmd, - "ip pim ssm prefix-list WORD", + "ip pim ssm prefix-list PREFIXLIST4_NAME", IP_STR "pim multicast routing\n" "Source Specific Multicast\n" @@ -3376,7 +3376,7 @@ DEFUN (no_ip_pim_ssm_prefix_list, DEFUN (no_ip_pim_ssm_prefix_list_name, no_ip_pim_ssm_prefix_list_name_cmd, - "no ip pim ssm prefix-list WORD", + "no ip pim ssm prefix-list PREFIXLIST4_NAME", NO_STR IP_STR "pim multicast routing\n" diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c index 66659e9034..c4efc14a9d 100644 --- a/staticd/static_zebra.c +++ b/staticd/static_zebra.c @@ -164,10 +164,14 @@ static int route_notify_owner(ZAPI_CALLBACK_ARGS) static void zebra_connected(struct zclient *zclient) { + struct vrf *vrf; + zebra_route_notify_send(ZEBRA_ROUTE_NOTIFY_REQUEST, zclient, true); zclient_send_reg_requests(zclient, VRF_DEFAULT); - static_fixup_vrf_ids(vrf_lookup_by_id(VRF_DEFAULT)); + vrf = vrf_lookup_by_id(VRF_DEFAULT); + assert(vrf); + static_fixup_vrf_ids(vrf); } /* API to check whether the configured nexthop address is diff --git a/tests/topotests/bgp_srv6l3vpn_route_leak/pe1/results/vrf20_ipv4.json b/tests/topotests/bgp_srv6l3vpn_route_leak/pe1/results/vrf20_ipv4.json index 9f78447255..2ce936b291 100644 --- a/tests/topotests/bgp_srv6l3vpn_route_leak/pe1/results/vrf20_ipv4.json +++ b/tests/topotests/bgp_srv6l3vpn_route_leak/pe1/results/vrf20_ipv4.json @@ -12,7 +12,7 @@ { "fib": true, "directlyConnected": true, - "interfaceName": "eth0", + "interfaceName": "vrf10", "vrf": "vrf10", "active": true } diff --git a/tests/topotests/bgp_vrf_route_leak_basic/r1/bgpd.conf b/tests/topotests/bgp_vrf_route_leak_basic/r1/bgpd.conf index 03dfbf9322..f52f56b0e0 100644 --- a/tests/topotests/bgp_vrf_route_leak_basic/r1/bgpd.conf +++ b/tests/topotests/bgp_vrf_route_leak_basic/r1/bgpd.conf @@ -1,10 +1,19 @@ hostname r1 +router bgp 99 + no bgp ebgp-requires-policy + address-family ipv4 unicast + redistribute connected + import vrf DONNA + ! +! router bgp 99 vrf DONNA no bgp ebgp-requires-policy address-family ipv4 unicast redistribute connected import vrf EVA + import vrf NOTEXISTING + import vrf default ! ! router bgp 99 vrf EVA @@ -12,5 +21,13 @@ router bgp 99 vrf EVA address-family ipv4 unicast redistribute connected import vrf DONNA + import vrf NOTEXISTING + ! +! +router bgp 99 vrf NOTEXISTING + no bgp ebgp-requires-policy + no bgp network import-check + address-family ipv4 unicast + network 172.16.101.0/24 ! ! diff --git a/tests/topotests/bgp_vrf_route_leak_basic/r1/zebra.conf b/tests/topotests/bgp_vrf_route_leak_basic/r1/zebra.conf index 35038557df..4de9e895a2 100644 --- a/tests/topotests/bgp_vrf_route_leak_basic/r1/zebra.conf +++ b/tests/topotests/bgp_vrf_route_leak_basic/r1/zebra.conf @@ -1,5 +1,9 @@ hostname r1 +int dummy0 + ip address 10.0.4.1/24 + no shut +! int dummy1 ip address 10.0.0.1/24 no shut @@ -16,3 +20,9 @@ int dummy4 ip address 10.0.3.1/24 no shut ! +int EVA + no shut +! +int DONNA + no shut +! diff --git a/tests/topotests/bgp_vrf_route_leak_basic/setup_vrfs b/tests/topotests/bgp_vrf_route_leak_basic/setup_vrfs index fb67953fe3..f62c5cd211 100644 --- a/tests/topotests/bgp_vrf_route_leak_basic/setup_vrfs +++ b/tests/topotests/bgp_vrf_route_leak_basic/setup_vrfs @@ -3,6 +3,7 @@ ip link add DONNA type vrf table 1001 ip link add EVA type vrf table 1002 +ip link add dummy0 type dummy # vrf default ip link add dummy1 type dummy ip link add dummy2 type dummy ip link add dummy3 type dummy diff --git a/tests/topotests/bgp_vrf_route_leak_basic/test_bgp-vrf-route-leak-basic.py b/tests/topotests/bgp_vrf_route_leak_basic/test_bgp-vrf-route-leak-basic.py index fd7ffff17c..ef813e9541 100644 --- a/tests/topotests/bgp_vrf_route_leak_basic/test_bgp-vrf-route-leak-basic.py +++ b/tests/topotests/bgp_vrf_route_leak_basic/test_bgp-vrf-route-leak-basic.py @@ -64,7 +64,7 @@ def teardown_module(mod): tgen.stop_topology() -def test_vrf_route_leak(): +def test_vrf_route_leak_donna(): logger.info("Ensure that routes are leaked back and forth") tgen = get_topogen() # Don't run this test if we have any failure. @@ -81,11 +81,59 @@ def test_vrf_route_leak(): } ], "10.0.1.0/24": [ - {"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]} + { + "protocol": "bgp", + "selected": True, + "nexthops": [ + { + "fib": True, + "interfaceName": "EVA", + "vrf": "EVA", + "active": True, + }, + ], + }, ], "10.0.2.0/24": [{"protocol": "connected"}], "10.0.3.0/24": [ - {"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]} + { + "protocol": "bgp", + "selected": True, + "nexthops": [ + { + "fib": True, + "interfaceName": "EVA", + "vrf": "EVA", + "active": True, + }, + ], + }, + ], + "10.0.4.0/24": [ + { + "protocol": "bgp", + "selected": True, + "nexthops": [ + { + "fib": True, + "interfaceName": "lo", + "vrf": "default", + "active": True, + }, + ], + }, + ], + "172.16.101.0/24": [ + { + "protocol": "bgp", + "nexthops": [ + { + "interfaceIndex": 0, + "interfaceName": "unknown", + "vrf": "Unknown", + }, + ], + }, ], } @@ -95,10 +143,31 @@ def test_vrf_route_leak(): result, diff = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert result, "BGP VRF DONNA check failed:\n{}".format(diff) + +def test_vrf_route_leak_eva(): + logger.info("Ensure that routes are leaked back and forth") + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + # Test EVA VRF. expect = { "10.0.0.0/24": [ - {"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]} + { + "protocol": "bgp", + "selected": True, + "nexthops": [ + { + "fib": True, + "interfaceName": "DONNA", + "vrf": "DONNA", + "active": True, + }, + ], + }, ], "10.0.1.0/24": [ { @@ -106,13 +175,36 @@ def test_vrf_route_leak(): } ], "10.0.2.0/24": [ - {"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]} + { + "protocol": "bgp", + "selected": True, + "nexthops": [ + { + "fib": True, + "interfaceName": "DONNA", + "vrf": "DONNA", + "active": True, + }, + ], + }, ], "10.0.3.0/24": [ { "protocol": "connected", } ], + "172.16.101.0/24": [ + { + "protocol": "bgp", + "nexthops": [ + { + "interfaceIndex": 0, + "interfaceName": "unknown", + "vrf": "Unknown", + }, + ], + }, + ], } test_func = partial( @@ -122,6 +214,217 @@ def test_vrf_route_leak(): assert result, "BGP VRF EVA check failed:\n{}".format(diff) +def test_vrf_route_leak_donna(): + logger.info("Ensure that routes are leaked back and forth") + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + + # Test DONNA VRF. + expect = { + "10.0.0.0/24": [ + { + "protocol": "connected", + } + ], + "10.0.1.0/24": [ + { + "protocol": "bgp", + "selected": True, + "nexthops": [ + { + "fib": True, + "interfaceName": "EVA", + "vrf": "EVA", + "active": True, + }, + ], + }, + ], + "10.0.2.0/24": [{"protocol": "connected"}], + "10.0.3.0/24": [ + { + "protocol": "bgp", + "selected": True, + "nexthops": [ + { + "fib": True, + "interfaceName": "EVA", + "vrf": "EVA", + "active": True, + }, + ], + }, + ], + "10.0.4.0/24": [ + { + "protocol": "bgp", + "selected": True, + "nexthops": [ + { + "fib": True, + "interfaceName": "lo", + "vrf": "default", + "active": True, + }, + ], + }, + ], + "172.16.101.0/24": [ + { + "protocol": "bgp", + "nexthops": [ + { + "interfaceIndex": 0, + "interfaceName": "unknown", + "vrf": "Unknown", + }, + ], + }, + ], + } + + test_func = partial( + topotest.router_json_cmp, r1, "show ip route vrf DONNA json", expect + ) + result, diff = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + assert result, "BGP VRF DONNA check failed:\n{}".format(diff) + + +def test_vrf_route_leak_eva(): + logger.info("Ensure that routes are leaked back and forth") + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + + # Test EVA VRF. + expect = { + "10.0.0.0/24": [ + { + "protocol": "bgp", + "selected": True, + "nexthops": [ + { + "fib": True, + "interfaceName": "DONNA", + "vrf": "DONNA", + "active": True, + }, + ], + }, + ], + "10.0.1.0/24": [ + { + "protocol": "connected", + } + ], + "10.0.2.0/24": [ + { + "protocol": "bgp", + "selected": True, + "nexthops": [ + { + "fib": True, + "interfaceName": "DONNA", + "vrf": "DONNA", + "active": True, + }, + ], + }, + ], + "10.0.3.0/24": [ + { + "protocol": "connected", + } + ], + "172.16.101.0/24": [ + { + "protocol": "bgp", + "nexthops": [ + { + "interfaceIndex": 0, + "interfaceName": "unknown", + "vrf": "Unknown", + }, + ], + }, + ], + } + + +def test_vrf_route_leak_default(): + logger.info("Ensure that routes are leaked back and forth") + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + + # Test default VRF. + expect = { + "10.0.0.0/24": [ + { + "protocol": "bgp", + "selected": True, + "nexthops": [ + { + "fib": True, + "interfaceName": "DONNA", + "vrf": "DONNA", + "active": True, + }, + ], + }, + ], + "10.0.2.0/24": [ + { + "protocol": "bgp", + "selected": True, + "nexthops": [ + { + "fib": True, + "interfaceName": "DONNA", + "vrf": "DONNA", + "active": True, + }, + ], + }, + ], + "10.0.4.0/24": [ + { + "protocol": "connected", + } + ], + } + + test_func = partial(topotest.router_json_cmp, r1, "show ip route json", expect) + result, diff = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + assert result, "BGP VRF default check failed:\n{}".format(diff) + + +def test_ping(): + "Simple ping tests" + + tgen = get_topogen() + + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + + logger.info("Ping from default to DONNA") + output = r1.run("ping -c 4 -w 4 -I 10.0.4.1 10.0.0.1") + assert " 0% packet loss" in output, "Ping default->DONNA FAILED" + + def test_memory_leak(): "Run the memory leak test and report results." tgen = get_topogen() diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt index ca9ca77bf5..248375dc6c 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt @@ -7,5 +7,5 @@ O>* 10.0.4.0/24 [110/20] via 10.0.20.2, r1-eth1, weight 1, XX:XX:XX O 10.0.20.0/24 [110/10] is directly connected, r1-eth1, weight 1, XX:XX:XX C>* 10.0.20.0/24 is directly connected, r1-eth1, XX:XX:XX L>* 10.0.20.1/32 is directly connected, r1-eth1, XX:XX:XX -B>* 10.0.30.0/24 [20/0] is directly connected, r1-eth2 (vrf neno), weight 1, XX:XX:XX +B>* 10.0.30.0/24 [20/0] is directly connected, neno (vrf neno), weight 1, XX:XX:XX O>* 10.0.40.0/24 [110/20] via 10.0.20.2, r1-eth1, weight 1, XX:XX:XX diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt index 70ae987894..d7d31434c6 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt @@ -9,4 +9,4 @@ O 10.0.20.0/24 [110/10] is directly connected, r2-eth1, weight 1, XX:XX:XX C>* 10.0.20.0/24 is directly connected, r2-eth1, XX:XX:XX L>* 10.0.20.2/32 is directly connected, r2-eth1, XX:XX:XX O>* 10.0.30.0/24 [110/20] via 10.0.20.1, r2-eth1, weight 1, XX:XX:XX -B>* 10.0.40.0/24 [20/0] is directly connected, r2-eth2 (vrf ray), weight 1, XX:XX:XX +B>* 10.0.40.0/24 [20/0] is directly connected, ray (vrf ray), weight 1, XX:XX:XX diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt index 1495c88936..6ab1bb8f92 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt @@ -1,9 +1,9 @@ VRF ray: B 10.0.1.0/24 [20/20] via 10.0.20.1, r2-eth1 (vrf default) inactive, weight 1, XX:XX:XX -B 10.0.2.0/24 [20/0] is directly connected, r2-eth0 (vrf default) inactive, weight 1, XX:XX:XX +B 10.0.2.0/24 [20/0] is directly connected, lo (vrf default) inactive, weight 1, XX:XX:XX B>* 10.0.3.0/24 [20/20] via 10.0.20.1, r2-eth1 (vrf default), weight 1, XX:XX:XX O>* 10.0.4.0/24 [110/20] via 10.0.40.4, r2-eth2, weight 1, XX:XX:XX -B 10.0.20.0/24 [20/0] is directly connected, r2-eth1 (vrf default) inactive, weight 1, XX:XX:XX +B 10.0.20.0/24 [20/0] is directly connected, lo (vrf default) inactive, weight 1, XX:XX:XX B>* 10.0.30.0/24 [20/20] via 10.0.20.1, r2-eth1 (vrf default), weight 1, XX:XX:XX O 10.0.40.0/24 [110/10] is directly connected, r2-eth2, weight 1, XX:XX:XX C>* 10.0.40.0/24 is directly connected, r2-eth2, XX:XX:XX diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 4cb46b87a5..3290c8d54a 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -1669,7 +1669,6 @@ static int vtysh_end(void) /* Nothing to do. */ break; default: - vty->vtysh_file_locked = false; vty->node = ENABLE_NODE; break; } @@ -2393,23 +2392,12 @@ DEFUNSH(VTYSH_REALLYALL, vtysh_disable, vtysh_disable_cmd, "disable", } DEFUNSH(VTYSH_REALLYALL, vtysh_config_terminal, vtysh_config_terminal_cmd, - "configure [terminal]", - "Configuration from vty interface\n" - "Configuration terminal\n") -{ - vty->node = CONFIG_NODE; - return CMD_SUCCESS; -} - -DEFUNSH(VTYSH_REALLYALL, vtysh_config_terminal_file_lock, - vtysh_config_terminal_file_lock_cmd, - "configure terminal file-lock", + "configure [terminal [file-lock]]", "Configuration from vty interface\n" "Configuration terminal\n" "Configuration with locked datastores\n") { vty->node = CONFIG_NODE; - vty->vtysh_file_locked = true; return CMD_SUCCESS; } @@ -2424,21 +2412,6 @@ static int vtysh_exit(struct vty *vty) if (cnode->parent_node) vty->node = cnode->parent_node; - if (vty->node == CONFIG_NODE) { - bool locked = vty->vtysh_file_locked; - - /* resync in case one of the daemons is somewhere else */ - vtysh_execute("end"); - /* NOTE: a rather expensive thing to do, can we avoid it? */ - - if (locked) - vtysh_execute("configure terminal file-lock"); - else - vtysh_execute("configure terminal"); - } else if (vty->node == ENABLE_NODE) { - vty->vtysh_file_locked = false; - } - return CMD_SUCCESS; } @@ -5125,7 +5098,6 @@ void vtysh_init_vty(void) if (!user_mode) install_element(VIEW_NODE, &vtysh_enable_cmd); install_element(ENABLE_NODE, &vtysh_config_terminal_cmd); - install_element(ENABLE_NODE, &vtysh_config_terminal_file_lock_cmd); install_element(ENABLE_NODE, &vtysh_disable_cmd); /* "exit" command. */ diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c index 888f6a8c21..c207e4d427 100644 --- a/vtysh/vtysh_config.c +++ b/vtysh/vtysh_config.c @@ -616,8 +616,13 @@ static int vtysh_read_file(FILE *confp, bool dry_run) vty->node = CONFIG_NODE; vtysh_execute_no_pager("enable"); - vtysh_execute_no_pager("conf term file-lock"); - vty->vtysh_file_locked = true; + /* + * When reading the config, we need to wait until the lock is acquired. + * If we ignore the failure and continue without the lock, the config + * will be fully ignored. + */ + while (vtysh_execute_no_pager("conf term file-lock") == CMD_WARNING_CONFIG_FAILED) + usleep(100000); if (!dry_run) vtysh_execute_no_pager("XFRR_start_configuration"); @@ -629,7 +634,6 @@ static int vtysh_read_file(FILE *confp, bool dry_run) vtysh_execute_no_pager("XFRR_end_configuration"); vtysh_execute_no_pager("end"); - vty->vtysh_file_locked = false; vtysh_execute_no_pager("disable"); vty_close(vty); diff --git a/zebra/rib.h b/zebra/rib.h index 4c817eca71..a721f4bac4 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -85,25 +85,12 @@ struct route_entry { */ struct nhg_hash_entry *nhe; - /* Nexthop group from FIB (optional), reflecting what is actually - * installed in the FIB if that differs. The 'backup' group is used - * when backup nexthops are present in the route's nhg. - */ - struct nexthop_group fib_ng; - struct nexthop_group fib_backup_ng; - /* Nexthop group hash entry IDs. The "installed" id is the id * used in linux/netlink, if available. */ uint32_t nhe_id; uint32_t nhe_installed_id; - /* Tag */ - route_tag_t tag; - - /* Uptime. */ - time_t uptime; - /* Type of this route. */ int type; @@ -160,7 +147,20 @@ struct route_entry { /* Distance. */ uint8_t distance; + /* Tag */ + route_tag_t tag; + + /* Uptime. */ + time_t uptime; + struct re_opaque *opaque; + + /* Nexthop group from FIB (optional), reflecting what is actually + * installed in the FIB if that differs. The 'backup' group is used + * when backup nexthops are present in the route's nhg. + */ + struct nexthop_group fib_ng; + struct nexthop_group fib_backup_ng; }; #define RIB_SYSTEM_ROUTE(R) RSYSTEM_ROUTE((R)->type) diff --git a/zebra/zebra_cli.c b/zebra/zebra_cli.c index 8fedcfedc0..00e0a49cb8 100644 --- a/zebra/zebra_cli.c +++ b/zebra/zebra_cli.c @@ -437,13 +437,19 @@ DEFPY_YANG (link_params_admin_grp, char value_str[YANG_VALUE_MAXLEN]; if (!no) { + assert(bitpattern); + if (bitpattern[0] != '0' || bitpattern[1] != 'x' || strlen(bitpattern) > 10) { vty_out(vty, "Invalid bitpattern value\n"); return CMD_WARNING_CONFIG_FAILED; } - sscanf(bitpattern, "%x", &value); + if (sscanf(bitpattern, "%x", &value) != 1) { + vty_out(vty, "Invalid bitpattern value\n"); + return CMD_WARNING_CONFIG_FAILED; + } + snprintf(value_str, sizeof(value_str), "%u", value); nb_cli_enqueue_change(vty, "./legacy-admin-group", NB_OP_MODIFY, @@ -610,6 +616,8 @@ DEFPY_YANG (link_params_res_bw, float bw; if (!no) { + assert(bandwidth); + if (sscanf(bandwidth, "%g", &bw) != 1) { vty_out(vty, "Invalid bandwidth value\n"); return CMD_WARNING_CONFIG_FAILED; @@ -647,6 +655,8 @@ DEFPY_YANG (link_params_ava_bw, float bw; if (!no) { + assert(bandwidth); + if (sscanf(bandwidth, "%g", &bw) != 1) { vty_out(vty, "Invalid bandwidth value\n"); return CMD_WARNING_CONFIG_FAILED; @@ -684,6 +694,8 @@ DEFPY_YANG (link_params_use_bw, float bw; if (!no) { + assert(bandwidth); + if (sscanf(bandwidth, "%g", &bw) != 1) { vty_out(vty, "Invalid bandwidth value\n"); return CMD_WARNING_CONFIG_FAILED; @@ -817,6 +829,7 @@ DEFPY_YANG (ip_address, strlcpy(ip, address_str, sizeof(ip)); mask = strchr(ip, '/'); + assert(mask); *mask = 0; mask++; @@ -886,6 +899,7 @@ DEFPY_YANG (ip_address_peer, strlcpy(peer_ip, peer_str, sizeof(peer_ip)); peer_mask = strchr(peer_ip, '/'); + assert(peer_mask); *peer_mask = 0; peer_mask++; @@ -934,6 +948,7 @@ DEFPY_YANG (ipv6_address, strlcpy(ip, address_str, sizeof(ip)); mask = strchr(ip, '/'); + assert(mask); *mask = 0; mask++; diff --git a/zebra/zebra_evpn_mh.h b/zebra/zebra_evpn_mh.h index 6080048976..34ef79f155 100644 --- a/zebra/zebra_evpn_mh.h +++ b/zebra/zebra_evpn_mh.h @@ -154,7 +154,7 @@ struct zebra_evpn_es_vtep { /* Parameters for DF election */ uint8_t df_alg; - uint32_t df_pref; + uint16_t df_pref; /* XXX - maintain a backpointer to struct zebra_vtep */ }; diff --git a/zebra/zebra_nb_config.c b/zebra/zebra_nb_config.c index f24af16a2e..46c95e6c0f 100644 --- a/zebra/zebra_nb_config.c +++ b/zebra/zebra_nb_config.c @@ -2220,7 +2220,8 @@ int lib_interface_zebra_link_params_packet_loss_destroy( static bool evpn_mh_dnode_to_esi(const struct lyd_node *dnode, esi_t *esi) { if (yang_dnode_exists(dnode, "type-0/esi")) { - str_to_esi(yang_dnode_get_string(dnode, "type-0/esi"), esi); + if (!str_to_esi(yang_dnode_get_string(dnode, "type-0/esi"), esi)) + assert(false); } else if (yang_dnode_exists(dnode, "type-3/system-mac") && yang_dnode_exists(dnode, "type-3/local-discriminator")) { struct ethaddr mac; @@ -2301,7 +2302,8 @@ int lib_interface_zebra_evpn_mh_type_0_esi_modify(struct nb_cb_modify_args *args break; case NB_EV_APPLY: ifp = nb_running_get_entry(args->dnode, NULL, true); - str_to_esi(yang_dnode_get_string(args->dnode, NULL), &esi); + if (!str_to_esi(yang_dnode_get_string(args->dnode, NULL), &esi)) + assert(false); zebra_evpn_es_type0_esi_update(ifp->info, &esi); break; } @@ -3031,7 +3033,7 @@ int lib_interface_zebra_ipv6_router_advertisements_rdnss_rdnss_address_create( struct nb_cb_create_args *args) { struct interface *ifp; - struct rtadv_rdnss rdnss, *p; + struct rtadv_rdnss rdnss = {0}, *p; if (args->event != NB_EV_APPLY) return NB_OK; @@ -3110,7 +3112,7 @@ int lib_interface_zebra_ipv6_router_advertisements_dnssl_dnssl_domain_create( struct nb_cb_create_args *args) { struct interface *ifp; - struct rtadv_dnssl dnssl, *p; + struct rtadv_dnssl dnssl = {0}, *p; int ret; strlcpy(dnssl.name, yang_dnode_get_string(args->dnode, "domain"), |
