# Release Notes {#release_notes} * @subpage release_notes_2009 * @subpage release_notes_20051 * @subpage release_notes_2005 * @subpage release_notes_2001 * @subpage release_notes_19083 * @subpage release_notes_19082 * @subpage release_notes_19081 * @subpage release_notes_1908 * @subpage release_notes_19043 * @subpage release_notes_19042 * @subpage release_notes_19041 * @subpage release_notes_1904 * @subpage release_notes_19013 * @subpage release_notes_19012 * @subpage release_notes_19011 * @subpage release_notes_1901 * @subpage release_notes_1810 * @subpage release_notes_1807 * @subpage release_notes_1804 * @subpage release_notes_18012 * @subpage release_notes_18011 * @subpage release_notes_1801 * @subpage release_notes_1710 * @subpage release_notes_1707 * @subpage release_notes_1704 * @subpage release_notes_17011 * @subpage release_notes_1701 * @subpage release_notes_1609 * @subpage release_notes_1606 @page release_notes_2009 Release notes for VPP 20.09 More than 458 commits since the previous release, including 266 fixes. ## Release Highlights The FD.io VPP 20.09 release added a number of notable new features. In plugins, the I/O layer added support for the Linux AF\_XDP interface with the AF\_XDP plugin. New plugins where added supporting both the Wireguard security protocol and CNAT destination based address translation, and the existing IKEv2 plugin added support for NAT-T. In the cryptography layer, support was added for synchronous software crypto engines, enabling users to allocate dedicated crypto worker threads. The flow layer added support for steering IPSEC ESP/AH flows to worker threads. GRO support was added to the packet coalescing library. This release introduces the new FD.io VPP API change policy to ensure backwards-compatibility. The policy will ensure seamless upgrades to new versions of FD.io VPP in future, provided no "in-progress" or deprecated APIs are in use. Enabling the FD.io community to enjoy the benefits of new releases, while minimizing the work involved in staying current. If you dive into the implementation, you will note that policy in action. A number of modified API messages have had their original versions maintained to ensure compatibility. Reflecting the new policy we added two new sections to the release notes describing: - Newly deprecated API messages: please note that if you are using a deprecated message, they will soon be removed in a subsequent release. Collaborate with the feature maintainer on the best approach to mitigate. - In-progress API messages: They are work-in-progress, and are *not* subject to the policy, and may change or even be removed at any time. Please collaborate with the feature maintainer on plans to productize the message before using in any product. In-progress APIs must eventually become stable or be removed. ## Features - VNET - Crypto Infra - Add chacha20-poly1305 algo (61f49aa38) - Asynchronous crypto engines (2284817ea) - Add asynchronous crypto APIs (0c936b147) - Added support for optimized cryptodev API (ef80ad6bf) - FLOW - Added ability to steer IPSec ESP/AH flows to worker threads (d4c3666b9) - Added the vnet/flow API (d0236f725) - GENEVE - Support geneve interface acting as a bvi (7fc88cf3a) - GSO - Added software GRO support (f382b06fe) - IPSec - Dedicated IPSec interface type (dd4ccf262) - Deprecate old interface API (e6df80de4) - Interface Common - Support configuring RSS steering queues (c4665093c) - Native Virtio Drivers - Add vhost sw\_if\_index filter for sw\_interface\_vhost\_user\_dump (a0e8d9669) - Add modern device support (379aac395) - Add virtio 1.1 api flags (518251bc8) - TAP Drivers - Add gro support (9e2a78564) - Add virtio 1.1 API flag (50bd16559) - TCP - Track reorder with selective acknowledgments (cc4d6d022) - Plugins - AF\_XDP driver - New plugin for Linux AF\_XDP input (4a76d6f6d) - CNat - New plugin for destination based NAT (29f3c7d2e) - Wireguard - New plugin, initial implementation of wireguard protocol (edca1325c) - Crypto - OpenSSL - Add chacha20-poly1305 support to crypto-openssl (1b6ed022e) - DPDK - Device\_id sorted order for cryptodev (5a849e3b3) - Call the meson-based build instead of Makefiles (73903d7e8) - Internet Key Exchange (IKEv2) Protocol - Add support for NAT traversal (NAT-T) (4362baa33) - Add profile dump API (6a9bd8188) - Add support for AES-GCM cipher in IKE (a7b963df2) - Add SA dump API (a340fe1ac) - Network Delay Simulator - Basic reorder support (e6c3e8f0e) - VPP Comms Library - Nest vcl\_mq\_epfd to support epoll\_wait without high CPU usage (4266d4d5f) - Support connected udp listens (1e96617d9) - Support inter worker rpc (40c07ce7a) - Support multi-threads with session migration (a3a489691) - Vector Library - Add recursive macro expander to debug cli (961e3c842) - Binary API Libraries - Add new stream message convention (f5db3711b) - Make VPP api handlers endian independent (e796a1873) - Infrastructure Library - Multiarch support for OCTEONTX2 SoC (e2f5236dc) ## Known issues For the full list of issues please refer to fd.io [JIRA](https://jira.fd.io). ## Fixed issues For the full list of fixed issues please refer to: - fd.io [JIRA](https://jira.fd.io) - git [commit log](https://git.fd.io/vpp/log/?h=stable/2009) ## API changes Description of results: * _Definition changed_: indicates that the API file was modified between releases. * _Only in image_: indicates the API is new for this release. * _Only in file_: indicates the API has been removed in this release. Message Name | Result -------------------------------------------------------------|------------------ adl_allowlist_enable_disable | only in image adl_allowlist_enable_disable_reply | only in image adl_interface_enable_disable | only in image adl_interface_enable_disable_reply | only in image bond_add_member | only in image bond_add_member_reply | only in image bond_create2 | only in image bond_create2_reply | only in image bond_detach_member | only in image bond_detach_member_reply | only in image cnat_add_del_snat_prefix | only in image cnat_add_del_snat_prefix_reply | only in image cnat_session_details | only in image cnat_session_dump | only in image cnat_session_purge | only in image cnat_session_purge_reply | only in image cnat_set_snat_addresses | only in image cnat_set_snat_addresses_reply | only in image cnat_translation_del | only in image cnat_translation_del_reply | only in image cnat_translation_details | only in image cnat_translation_dump | only in image cnat_translation_update | only in image cnat_translation_update_reply | only in image crypto_set_async_dispatch | only in image crypto_set_async_dispatch_reply | only in image crypto_set_handler | only in image crypto_set_handler_reply | only in image crypto_sw_scheduler_set_worker | only in image crypto_sw_scheduler_set_worker_reply | only in image det44_add_del_map | only in image det44_add_del_map_reply | only in image det44_close_session_in | only in image det44_close_session_in_reply | only in image det44_close_session_out | only in image det44_close_session_out_reply | only in image det44_forward | only in image det44_forward_reply | only in image det44_get_timeouts | only in image det44_get_timeouts_reply | only in image det44_interface_add_del_feature | only in image det44_interface_add_del_feature_reply | only in image det44_interface_details | only in image det44_interface_dump | only in image det44_map_details | only in image det44_map_dump | only in image det44_plugin_enable_disable | only in image det44_plugin_enable_disable_reply | only in image det44_reverse | only in image det44_reverse_reply | only in image det44_session_details | only in image det44_session_dump | only in image det44_set_timeouts | only in image det44_set_timeouts_reply | only in image flow_add | only in image flow_add_reply | only in image flow_del | only in image flow_del_reply | only in image flow_disable | only in image flow_disable_reply | only in image flow_enable | only in image flow_enable_reply | only in image geneve_add_del_tunnel2 | only in image geneve_add_del_tunnel2_reply | only in image gtpu_add_del_tunnel | definition changed gtpu_tunnel_details | definition changed gtpu_tunnel_update_tteid | only in image gtpu_tunnel_update_tteid_reply | only in image ikev2_child_sa_details | only in image ikev2_child_sa_dump | only in image ikev2_nonce_get | only in image ikev2_nonce_get_reply | only in image ikev2_profile_details | only in image ikev2_profile_dump | only in image ikev2_profile_set_ts | definition changed ikev2_sa_details | only in image ikev2_sa_dump | only in image ikev2_set_esp_transforms | definition changed ikev2_set_ike_transforms | definition changed ikev2_set_responder | definition changed ikev2_traffic_selector_details | only in image ikev2_traffic_selector_dump | only in image ipsec_itf_create | only in image ipsec_itf_create_reply | only in image ipsec_itf_delete | only in image ipsec_itf_delete_reply | only in image ipsec_itf_details | only in image ipsec_itf_dump | only in image ipsec_set_async_mode | only in image ipsec_set_async_mode_reply | only in image map_domains_get | only in image map_domains_get_reply | only in image nat44_add_del_static_mapping_v2 | only in image nat44_add_del_static_mapping_v2_reply | only in image nat_show_config_2 | only in image nat_show_config_2_reply | only in image nsim_configure2 | only in image nsim_configure2_reply | only in image pg_interface_enable_disable_coalesce | only in image pg_interface_enable_disable_coalesce_reply | only in image sr_policies_with_sl_index_details | only in image sr_policies_with_sl_index_dump | only in image sw_bond_interface_details | only in image sw_bond_interface_dump | only in image sw_member_interface_details | only in image sw_member_interface_dump | only in image trace_details | only in image trace_dump | only in image trace_dump_reply | only in image virtio_pci_create_v2 | only in image virtio_pci_create_v2_reply | only in image wireguard_interface_create | only in image wireguard_interface_create_reply | only in image wireguard_interface_delete | only in image wireguard_interface_delete_reply | only in image wireguard_interface_details | only in image wireguard_interface_dump | only in image wireguard_peer_add | only in image wireguard_peer_add_reply | only in image wireguard_peer_remove | only in image wireguard_peer_remove_reply | only in image wireguard_peers_details | only in image wireguard_peers_dump | only in image Found 123 api message signature differences ### Newly deprecated API messages These messages are still there in the API, but can and probably will disappear in the next release. - bond_create - bond_detach_slave - bond_detach_slave_reply - bond_enslave - cop_interface_enable_disable - cop_interface_enable_disable_reply - cop_whitelist_enable_disable - cop_whitelist_enable_disable_reply - geneve_add_del_tunnel - ipsec_tunnel_if_add_del - ipsec_tunnel_if_set_sa - ipsec_tunnel_if_set_sa_reply - map_domain_dump - nat_det_add_del_map - nat_det_add_del_map_reply - nat_det_close_session_in - nat_det_close_session_in_reply - nat_det_close_session_out - nat_det_close_session_out_reply - nat_det_forward - nat_det_forward_reply - nat_det_map_details - nat_det_map_dump - nat_det_reverse - nat_det_reverse_reply - nat_det_session_details - nat_det_session_dump - nat_show_config - nsim_configure - nsim_configure_reply - sw_interface_bond_dump - sw_interface_slave_dump - virtio_pci_create - virtio_pci_create_reply ### In-progress API messages These messages are provided for testing and experimentation only. They are *not* subject to any compatibility process, and therefore can arbitrarily change or disappear at *any* moment. Also they may have less than satisfactory testing, making them unsuitable for other use than the technology preview. If you are intending to use these messages in production projects, please collaborate with the feature maintainer on their productization. - abf_itf_attach_add_del - abf_itf_attach_add_del_reply - abf_itf_attach_details - abf_itf_attach_dump - abf_plugin_get_version - abf_plugin_get_version_reply - abf_policy_add_del - abf_policy_add_del_reply - abf_policy_details - abf_policy_dump - adl_allowlist_enable_disable - adl_allowlist_enable_disable_reply - adl_interface_enable_disable - adl_interface_enable_disable_reply - af_xdp_create - af_xdp_create_reply - af_xdp_delete - af_xdp_delete_reply - cnat_add_del_snat_prefix - cnat_add_del_snat_prefix_reply - cnat_session_details - cnat_session_dump - cnat_session_purge - cnat_session_purge_reply - cnat_set_snat_addresses - cnat_set_snat_addresses_reply - cnat_translation_del - cnat_translation_del_reply - cnat_translation_details - cnat_translation_dump - cnat_translation_update - cnat_translation_update_reply - crypto_sw_scheduler_set_worker - crypto_sw_scheduler_set_worker_reply - det44_get_timeouts_reply - det44_interface_add_del_feature - det44_interface_add_del_feature_reply - det44_interface_details - det44_interface_dump - det44_plugin_enable_disable - det44_plugin_enable_disable_reply - det44_set_timeouts - det44_set_timeouts_reply - flow_add - flow_add_reply - flow_del - flow_del_reply - flow_disable - flow_disable_reply - flow_enable - flow_enable_reply - gbp_bridge_domain_add - gbp_bridge_domain_add_reply - gbp_bridge_domain_del - gbp_bridge_domain_del_reply - gbp_bridge_domain_details - gbp_bridge_domain_dump - gbp_bridge_domain_dump_reply - gbp_contract_add_del - gbp_contract_add_del_reply - gbp_contract_details - gbp_contract_dump - gbp_endpoint_add - gbp_endpoint_add_reply - gbp_endpoint_del - gbp_endpoint_del_reply - gbp_endpoint_details - gbp_endpoint_dump - gbp_endpoint_group_add - gbp_endpoint_group_add_reply - gbp_endpoint_group_del - gbp_endpoint_group_del_reply - gbp_endpoint_group_details - gbp_endpoint_group_dump - gbp_ext_itf_add_del - gbp_ext_itf_add_del_reply - gbp_ext_itf_details - gbp_ext_itf_dump - gbp_recirc_add_del - gbp_recirc_add_del_reply - gbp_recirc_details - gbp_recirc_dump - gbp_route_domain_add - gbp_route_domain_add_reply - gbp_route_domain_del - gbp_route_domain_del_reply - gbp_route_domain_details - gbp_route_domain_dump - gbp_route_domain_dump_reply - gbp_subnet_add_del - gbp_subnet_add_del_reply - gbp_subnet_details - gbp_subnet_dump - gbp_vxlan_tunnel_add - gbp_vxlan_tunnel_add_reply - gbp_vxlan_tunnel_del - gbp_vxlan_tunnel_del_reply - gbp_vxlan_tunnel_details - gbp_vxlan_tunnel_dump - ikev2_child_sa_details - ikev2_child_sa_dump - ikev2_initiate_del_child_sa - ikev2_initiate_del_child_sa_reply - ikev2_initiate_del_ike_sa - ikev2_initiate_del_ike_sa_reply - ikev2_initiate_rekey_child_sa - ikev2_initiate_rekey_child_sa_reply - ikev2_initiate_sa_init - ikev2_initiate_sa_init_reply - ikev2_nonce_get - ikev2_nonce_get_reply - ikev2_profile_add_del - ikev2_profile_add_del_reply - ikev2_profile_details - ikev2_profile_dump - ikev2_profile_set_auth - ikev2_profile_set_auth_reply - ikev2_profile_set_id - ikev2_profile_set_id_reply - ikev2_profile_set_ipsec_udp_port - ikev2_profile_set_ipsec_udp_port_reply - ikev2_profile_set_liveness - ikev2_profile_set_liveness_reply - ikev2_profile_set_ts - ikev2_profile_set_ts_reply - ikev2_profile_set_udp_encap - ikev2_profile_set_udp_encap_reply - ikev2_sa_details - ikev2_sa_dump - ikev2_set_esp_transforms - ikev2_set_esp_transforms_reply - ikev2_set_ike_transforms - ikev2_set_ike_transforms_reply - ikev2_set_local_key - ikev2_set_local_key_reply - ikev2_set_responder - ikev2_set_responder_reply - ikev2_set_sa_lifetime - ikev2_set_sa_lifetime_reply - ikev2_set_tunnel_interface - ikev2_set_tunnel_interface_reply - ikev2_traffic_selector_details - ikev2_traffic_selector_dump - l2_emulation - l2_emulation_reply - mdata_enable_disable - mdata_enable_disable_reply - nat44_add_del_static_mapping_v2 - nat44_add_del_static_mapping_v2_reply - oddbuf_enable_disable - oddbuf_enable_disable_reply - pg_interface_enable_disable_coalesce - pg_interface_enable_disable_coalesce_reply - sample_macswap_enable_disable - sample_macswap_enable_disable_reply - sr_policies_with_sl_index_details - sr_policies_with_sl_index_dump - sw_interface_set_vxlan_gbp_bypass - sw_interface_set_vxlan_gbp_bypass_reply - trace_details - trace_dump - trace_dump_reply - vxlan_gbp_tunnel_add_del - vxlan_gbp_tunnel_add_del_reply - vxlan_gbp_tunnel_details - vxlan_gbp_tunnel_dump - wireguard_interface_create - wireguard_interface_create_reply - wireguard_interface_delete - wireguard_interface_delete_reply - wireguard_interface_details - wireguard_interface_dump - wireguard_peer_add - wireguard_peer_add_reply - wireguard_peer_remove - wireguard_peer_remove_reply - wireguard_peers_details - wireguard_peers_dump ### Patches that changed API definitions | @c src/vpp/api/vpe.api || | ------- | ------- | | [d0236f725](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=d0236f725) | flow: add vnet/flow formal API | | @c src/vnet/crypto/crypto.api || | ------- | ------- | | [4035daffd](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=4035daffd) | crypto: Crypto set handler API to support set all as CLI | | [0c936b147](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=0c936b147) | crypto: Add async crypto APIs | | @c src/vnet/cop/cop.api || | ------- | ------- | | [00f21fb2f](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=00f21fb2f) | api: clean up use of deprecated flag | | [ac0326fc5](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=ac0326fc5) | adl: move allow/deny list function to plugin | | @c src/vnet/lisp-gpe/lisp_gpe.api || | ------- | ------- | | [4ab5190eb](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=4ab5190eb) | lisp: API cleanup | | @c src/vnet/vxlan-gbp/vxlan_gbp.api || | ------- | ------- | | [f72b1aff7](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=f72b1aff7) | vxlan-gbp: Mark APIs as in-progress | | @c src/vnet/flow/flow_types.api || | ------- | ------- | | [34bfa50b6](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=34bfa50b6) | flow: code refactor | | [d0236f725](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=d0236f725) | flow: add vnet/flow formal API | | @c src/vnet/flow/flow.api || | ------- | ------- | | [d0236f725](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=d0236f725) | flow: add vnet/flow formal API | | @c src/vnet/srv6/sr.api || | ------- | ------- | | [30fa97dc6](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=30fa97dc6) | sr: new messages created to return sl index for segment lists in a sr policy | | @c src/vnet/pg/pg.api || | ------- | ------- | | [f382b06fe](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=f382b06fe) | gso: packet coalesce library | | [0cf528233](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=0cf528233) | gso: fix the udp checksum in test | | @c src/vnet/geneve/geneve.api || | ------- | ------- | | [00f21fb2f](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=00f21fb2f) | api: clean up use of deprecated flag | | [7fc88cf3a](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=7fc88cf3a) | geneve: support geneve interface acting as a bvi | | @c src/vnet/lisp-cp/one.api || | ------- | ------- | | [4ab5190eb](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=4ab5190eb) | lisp: API cleanup | | @c src/vnet/lisp-cp/lisp.api || | ------- | ------- | | [4ab5190eb](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=4ab5190eb) | lisp: API cleanup | | @c src/vnet/devices/tap/tapv2.api || | ------- | ------- | | [50bd16559](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=50bd16559) | tap: add virtio 1.1 API flag | | @c src/vnet/devices/virtio/vhost_user.api || | ------- | ------- | | [a0e8d9669](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=a0e8d9669) | virtio: add vhost sw_if_index filter for sw_interface_vhost_user_dump | | @c src/vnet/devices/virtio/virtio.api || | ------- | ------- | | [00f21fb2f](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=00f21fb2f) | api: clean up use of deprecated flag | | [518251bc8](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=518251bc8) | virtio: add virtio 1.1 api flags | | @c src/vnet/ipsec/ipsec.api || | ------- | ------- | | [00f21fb2f](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=00f21fb2f) | api: clean up use of deprecated flag | | [2e84d6655](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=2e84d6655) | ipsec: add ipsec set async mode api | | [e6df80de4](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=e6df80de4) | ipsec: Deprecate old interface API | | [dd4ccf262](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=dd4ccf262) | ipsec: Dedicated IPSec interface type | | @c src/vnet/bonding/bond.api || | ------- | ------- | | [ea7178631](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=ea7178631) | bonding: add bond_create2 API to include gso option | | [4c4223edf](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=4c4223edf) | bonding lacp: replace slave string with member | | @c src/vnet/ip/ip_types.api || | ------- | ------- | | [d0236f725](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=d0236f725) | flow: add vnet/flow formal API | | @c src/plugins/wireguard/wireguard.api || | ------- | ------- | | [edca1325c](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=edca1325c) | wireguard: initial implementation of wireguard protocol | | @c src/plugins/map/map.api || | ------- | ------- | | [00f21fb2f](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=00f21fb2f) | api: clean up use of deprecated flag | | [ac0326fc5](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=ac0326fc5) | adl: move allow/deny list function to plugin | | [f5db3711b](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=f5db3711b) | api: add new stream message convention | | @c src/plugins/lacp/lacp.api || | ------- | ------- | | [4c4223edf](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=4c4223edf) | bonding lacp: replace slave string with member | | @c src/plugins/l2e/l2e.api || | ------- | ------- | | [f733e7ade](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=f733e7ade) | l2e: mark API as in-progress | | @c src/plugins/ikev2/ikev2.api || | ------- | ------- | | [a340fe1ac](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=a340fe1ac) | ikev2: add SA dump API | | [459d17bb7](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=459d17bb7) | ikev2: refactor and test profile dump API | | [ac46e3b1d](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=ac46e3b1d) | ikev2: API downgrade due to lack of ikev2 tests | | [6a9bd8188](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=6a9bd8188) | ikev2: add profile dump API | | @c src/plugins/ikev2/ikev2_types.api || | ------- | ------- | | [a340fe1ac](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=a340fe1ac) | ikev2: add SA dump API | | [459d17bb7](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=459d17bb7) | ikev2: refactor and test profile dump API | | [6a9bd8188](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=6a9bd8188) | ikev2: add profile dump API | | @c src/plugins/tracedump/tracedump.api || | ------- | ------- | | [65b65a469](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=65b65a469) | misc: add tracedump API plugin | | @c src/plugins/gtpu/gtpu.api || | ------- | ------- | | [9ebbb5c41](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=9ebbb5c41) | gtpu: support separate rx-decap and encap-tx teid values | | @c src/plugins/gbp/gbp.api || | ------- | ------- | | [d2f8fb9c7](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=d2f8fb9c7) | gbp: mark APIs as in-progress | | @c src/plugins/acl/acl.api || | ------- | ------- | | [24ee40a5c](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=24ee40a5c) | acl: correct acl vat help message | | @c src/plugins/nat/dslite/dslite.api || | ------- | ------- | | [603e75465](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=603e75465) | nat: move deterministic nat to det44 sub feature | | @c src/plugins/nat/det44/det44.api || | ------- | ------- | | [00f21fb2f](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=00f21fb2f) | api: clean up use of deprecated flag | | [603e75465](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=603e75465) | nat: move deterministic nat to det44 sub feature | | @c src/plugins/nat/nat_types.api || | ------- | ------- | | [96068d6b9](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=96068d6b9) | nat: nat66 to plugin | | @c src/plugins/nat/nat.api || | ------- | ------- | | [6484f4b9c](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=6484f4b9c) | nat: twice-nat static mapping pool address | | [edc816355](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=edc816355) | nat: fix type in api message | | [603e75465](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=603e75465) | nat: move deterministic nat to det44 sub feature | | [96068d6b9](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=96068d6b9) | nat: nat66 to plugin | | @c src/plugins/nat/nat66/nat66.api || | ------- | ------- | | [96068d6b9](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=96068d6b9) | nat: nat66 to plugin | | @c src/plugins/cnat/cnat.api || | ------- | ------- | | [29f3c7d2e](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=29f3c7d2e) | cnat: Destination based NAT | | @c src/plugins/abf/abf.api || | ------- | ------- | | [df494dafa](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=df494dafa) | abf: mark API as in-progress | | @c src/plugins/adl/adl.api || | ------- | ------- | | [ac0326fc5](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=ac0326fc5) | adl: move allow/deny list function to plugin | | @c src/plugins/nsim/nsim.api || | ------- | ------- | | [00f21fb2f](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=00f21fb2f) | api: clean up use of deprecated flag | | [e6c3e8f0e](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=e6c3e8f0e) | nsim: basic reorder support | | @c src/plugins/crypto_sw_scheduler/crypto_sw_scheduler.api || | ------- | ------- | | [0c936b147](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=0c936b147) | crypto: Add async crypto APIs | | @c src/plugins/dhcp/dhcp.api || | ------- | ------- | | [bad679291](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=bad679291) | api: register endian handlers for reply messages | | @c src/plugins/af_xdp/af_xdp.api || | ------- | ------- | | [4a76d6f6d](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=4a76d6f6d) | af_xdp: AF_XDP input plugin | @page release_notes_20051 Release notes for VPP 20.05.1 This is bug fix release. For the full list of fixed issues please refer to: - fd.io [JIRA](https://jira.fd.io) - git [commit log](https://git.fd.io/vpp/log/?h=stable/2005) @page release_notes_2005 Release notes for VPP 20.05 More than 751 commits since the 20.01 release. ## Release Highlights ### Feature Highlights As per commits involving FEATURE.yaml edits between the previous release and this release. They are mentioned in the below "features" section as well, together with the corresponding commits. - TAP Drivers - Implement sw_interface_tap_v2_dump filtering by sw_if_index - Add support for persistence - Native Virtio Drivers - Support virtio 1.1 packed ring in vhost - gso - Add support for IP-IP - Add vxlan tunnel support - VRRP - Add plugin providing VRRP support ### Ongoing Work On More Semantic-Typed API This release, like the 20.01, continues the journey on defining the semantic-based types instead of storage-based types within the API, so you may have noticed this in the API changes. Some of the changes are related to the infrastructure, and may be bugfixes, they do not change the CRC of the message but affect the representation on the wire. One particular commit we want you to pay attention to, is [b5c0d35f](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b5c0d35f), which fixes the bug with the enum representation on the wire - before it, even the enums declared as u8 or u16 were represented as u32 in the API messages. Another important commit we would like to call out explicitly as well is [7dd63e5c](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=7dd63e5c), which pinned the address_family and ip_proto enum types to be u8 instead of the default u32. The above two commits will be primarily interesting for those who work with the low-level APIs on VPP - the API frameworks should make these under-the-hood changes transparent. However, we decided to call these out, given that for those affected these will be pretty important changes. Another commit, that does not have the immediate impact at the moment, but that is poised to improve the user interaction with the API is [5c318c70](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=5c318c70). This adds the tooling and ability to implement a structured process, by which the API messages can evolve, while minimizing the impact to the API users. ## Features - Binary API Compiler for Python - Api crc checker (5c318c70d) - Binary API Libraries - Add macro that zeros out api reply buffer (f24de1795) - Build System - Add snap packaging (experimental) (6d97e62c0) - Support arch-specific compiling for Neoverse N1 (690ce8672) - Crypto native Plugin - Add ARMv8 AES-CBC implementation (776644efe) - Add AArch64 AES-GCM native implementation (622b5ce61) - Calculate ghash using vpclmulqdq instructions (627fb6a16) - GCM implementation with vector AESNI instructions (47d8f5dcd) - Infrastructure Library - Add x86 CPU definitions (38e0413b2) - Numa vector placement support (a690fdbfe) - Add cmake option to grow vectors by 1 (98bd75778) - Add tw\_timer\_2t\_2w\_512sl variant (907678977) - Link Bonding - Add GSO support (2e1fa54b7) - Plugins - DPDK - Output switch information (2347278d9) - Use port\_id as interface name suffix for representors (a80f8f371) - Add iova-mode to startup (4e96ddaec) - Bump DPDK version to 20.02 (76be887d8) - Enable DPDK iAVF PMD (162ea767c) - DPDK 20.05 iavf flow director backporting to DPDK 20.02 (7f83738b4) - GTPU - Offload RX flow (00fdf53c7) - RX offload for IPv6 payload supporting (ed63a0ff7) - Host Stack Applications - Proxy rcv wnd update acks after full fifos (dda2dbeda) - IPv6 Segment Routing Mobile - Support GTP4/6.DT and User Plane message mapping (9e722bd46) - Internet Key Exchange (IKEv2) Protocol - Configure a profile with an existing interface (44476c6b2) - Responder honours the protected tunnel config (685001f0a) - Add support for custom ipsec-over-udp port (e5d34919b) - Dead peer detection (c415d0a8e) - NAT - In2out-output nodes work with acl reflect (d539e256b) - Api & cli command for forcing session cleanup (edf777272) - Dslite ce mode in separate config entry (958919f36) - QUIC protocol - Update quicly to v0.0.10-VPP (62b1cea6e) - Quicly crypto offloading (92de6b65b) - Check quicly version tag at compile time (ffdc72da4) - RDMA (ibverb) driver - Bunp rdma-core version to v28.0 (eb89b9093) - Add Mellanox mlx5 Direct Verbs receive support (dd648aac0) - Introduce direct verb for Cx4/5 tx (dc812d9a7) - Unicast Reverse Path forwarding - Unicast reverse Path Forwarding (plugin) (d724e4f43) - VRRP - Add plugin providing vrrp support (39e9428b9) - SVM Library - Numa awareness for ssvm segments (6fe8998fe) - Support multi-chunk fifo chunk alloc (8e755a16a) - Chunk alloc stats (d35887297) - New FIFO design/architecture (f22f4e562) - Fifo test (64e96613d) - Test Infrastructure - Add running\_gcov\_tests to framework.py (d498c9eb2) - Implement ipaddress convenience methods (e64e5fff4) - VNET - Crypto Infra - Add chained buffer support in ipsecmb (AES-GCM) (2fc409131) - Add support for testing quad loops in crypto algos (a9075dcf6) - Introduce async crypto infra (f539578ba) - Ethernet - Configure system default ethernet MTU (5fa452554) - FLOW - Add vlan tagged types for IPv4/IPv6 5-tuple flows (f13830ce7) - Add RSS support (24e2c50bf) - Add l2tpv3oip flow (8b43aaaf1) - GRE - Tunnel encap/decap flags (e5b94dded) - GSO - Add vxlan tunnel support (0b04209ed) - Add support for IP-IP (84f91fa9c) - IP Neighbors - Populate neighbor age via API (9c1928f81) - Replace feature for the ip-neighbor data-base (c87fbb417) - Add flush API (240dcb24a) - IPIP - Multi-point interface (14053c9db) - IPSec - Add support for chained buffers (efcad1a9d) - IPSec protection for multi-point tunnel interfaces (282872127) - Add input node bypass/discard functionality (0546483ce) - User can choose the UDP source port (abc5660c6) - Support 4o6 and 6o4 for SPD tunnel mode SAs (b1fd80f09) - IPv4 LPM - More detailed show reassembly commands (a877cf9f3) - Replace Sematics for Interface IP addresses (59f71132e) - MPLS - Add user defined name tag to mpls tunnels (39ae0a07a) - Native Virtio Drivers - Support virtio 1.1 packed ring in vhost (bc0d9ff67) - Packet Generator - Set vnet buffer flags in pg streams (08eb2bb20) - Segment Routing (IPv6 and MPLS) - Change the CLI keyword from address to prefix. (b24e287b9) - Support uSID function. (ec9cb9668) - Session Layer - Tracking segment memory usage (234fe894d) - Basic fifo-tuning-logic (d8f48e216) - Api to add new transport types (07063b8ea) - Support connect on listeners (0a1e183e5) - Adding debug events (7357043d2) - Add option to preallocate fifo headers (9845c20d7) - TAP Drivers - Add support for persistance (b49bc1ae6) - Add initial support for tun (206acf84d) - Implement sw\_interface\_tap\_v2\_dump filtering by sw\_if\_index (073d74d0b) - TCP - Add option to avoid endpoint cleanup (43818c1e0) - Minimal set of worker stats (5e6305fb0) - Allow custom mss on connects (ff19e3bf4) - TLS and TLS engine plugins - Picotls engine symmetric crypto enhancement by VPP crypto framework (3b8518164) - UDP - Track connection port sharing (a039620c2) - VPP Comms Library - Udp session migration notifications (68b7e5888) - Propagate cleanup notifications to apps (9ace36d0f) - Vector Library - Add plugin override support (8dc954a4e) - Calculate per-worker loops/second metric (000a029e4) - Leave SIGPROF signal with its default handler (6f533d780) - Add nosyslog unix option (e31820af1) - Gomemif - Introduce gomemif (07363a45f) ## Known issues For the full list of issues please refer to fd.io [JIRA](https://jira.fd.io). ## Fixed issues For the full list of fixed issues please refer to: - fd.io [JIRA](https://jira.fd.io) - git [commit log](https://git.fd.io/vpp/log/?h=stable/2005) ## API changes Description of results: * _Definition changed_: indicates that the API file was modified between releases. * _Only in image_: indicates the API is new for this release. * _Only in file_: indicates the API has been removed in this release. Message Name | Result -------------------------------------------------------------|------------------ acl_add_replace | definition changed acl_details | definition changed acl_interface_add_del | definition changed acl_interface_etype_whitelist_details | definition changed acl_interface_etype_whitelist_dump | definition changed acl_interface_list_details | definition changed acl_interface_list_dump | definition changed acl_interface_set_acl_list | definition changed acl_interface_set_etype_whitelist | definition changed add_node_next | definition changed app_attach | definition changed app_attach_reply | definition changed app_cut_through_registration_add | only in file app_cut_through_registration_add_reply | only in file app_namespace_add_del | definition changed app_worker_add_del | definition changed app_worker_add_del_reply | definition changed application_attach | only in file application_attach_reply | only in file bd_ip_mac_add_del | definition changed bind_sock | only in file bind_sock_reply | only in file bind_uri | only in file bind_uri_reply | only in file bridge_domain_add_del | definition changed bridge_domain_details | definition changed bridge_domain_dump | definition changed bridge_flags | definition changed bvi_create_reply | definition changed bvi_delete | definition changed connect_sock | only in file connect_sock_reply | only in file connect_uri | only in file connect_uri_reply | only in file create_vhost_user_if | definition changed disconnect_session | only in file disconnect_session_reply | only in file get_next_index | definition changed get_node_index | definition changed gpe_add_del_fwd_entry | definition changed gpe_add_del_iface | definition changed gpe_add_del_native_fwd_rpath | definition changed gpe_enable_disable | definition changed gpe_fwd_entries_get_reply | definition changed gpe_fwd_entry_path_details | definition changed gpe_native_fwd_rpaths_get | definition changed gpe_native_fwd_rpaths_get_reply | definition changed gpe_set_encap_mode | definition changed gre_tunnel_add_del | definition changed gre_tunnel_details | definition changed gtpu_offload_rx | only in image gtpu_offload_rx_reply | only in image ikev2_profile_set_ipsec_udp_port | only in image ikev2_profile_set_ipsec_udp_port_reply | only in image ikev2_profile_set_liveness | only in image ikev2_profile_set_liveness_reply | only in image ikev2_profile_set_udp_encap | only in image ikev2_profile_set_udp_encap_reply | only in image ikev2_set_local_key | definition changed ikev2_set_tunnel_interface | only in image ikev2_set_tunnel_interface_reply | only in image ip_neighbor_details | definition changed ip_neighbor_flush | only in image ip_neighbor_flush_reply | only in image ip_neighbor_replace_begin | only in image ip_neighbor_replace_begin_reply | only in image ip_neighbor_replace_end | only in image ip_neighbor_replace_end_reply | only in image ip_route_lookup | only in image ip_route_lookup_reply | only in image ip_source_check_interface_add_del | only in file ip_source_check_interface_add_del_reply | only in file ipfix_classify_table_add_del | definition changed ipfix_classify_table_details | definition changed ipip_add_tunnel | definition changed ipip_tunnel_details | definition changed ipsec_backend_details | definition changed ipsec_interface_add_del_spd | definition changed ipsec_sa_details | definition changed ipsec_sad_entry_add_del | definition changed ipsec_select_backend | definition changed ipsec_spd_add_del | definition changed ipsec_spd_details | definition changed ipsec_spd_entry_add_del | definition changed ipsec_spd_interface_details | definition changed ipsec_tunnel_if_add_del | definition changed ipsec_tunnel_if_add_del_reply | definition changed ipsec_tunnel_if_set_sa | definition changed ipsec_tunnel_protect_del | definition changed ipsec_tunnel_protect_details | definition changed ipsec_tunnel_protect_update | definition changed l2_fib_table_details | definition changed l2_flags | definition changed l2_interface_efp_filter | definition changed l2_interface_pbb_tag_rewrite | definition changed l2_interface_vlan_tag_rewrite | definition changed l2_macs_event | definition changed l2_patch_add_del | definition changed l2_xconnect_details | definition changed l2fib_add_del | definition changed l2fib_flush_int | definition changed lisp_add_del_adjacency | definition changed lisp_add_del_local_eid | definition changed lisp_add_del_locator | definition changed lisp_add_del_locator_set | definition changed lisp_add_del_map_request_itr_rlocs | definition changed lisp_add_del_map_resolver | definition changed lisp_add_del_map_server | definition changed lisp_add_del_remote_mapping | definition changed lisp_adjacencies_get_reply | definition changed lisp_eid_table_add_del_map | definition changed lisp_eid_table_details | definition changed lisp_eid_table_dump | definition changed lisp_eid_table_map_dump | definition changed lisp_enable_disable | definition changed lisp_get_map_request_itr_rlocs_reply | definition changed lisp_locator_details | definition changed lisp_locator_dump | definition changed lisp_locator_set_details | definition changed lisp_locator_set_dump | definition changed lisp_map_register_enable_disable | definition changed lisp_map_request_mode | definition changed lisp_map_resolver_details | definition changed lisp_map_server_details | definition changed lisp_pitr_set_locator_set | definition changed lisp_rloc_probe_enable_disable | definition changed lisp_use_petr | definition changed lldp_config | definition changed macip_acl_add | definition changed macip_acl_add_replace | definition changed macip_acl_details | definition changed macip_acl_interface_add_del | definition changed macip_acl_interface_list_details | definition changed macip_acl_interface_list_dump | definition changed map_another_segment | only in file map_another_segment_reply | only in file modify_vhost_user_if | definition changed mpls_tunnel_add_del | definition changed mpls_tunnel_details | definition changed nat44_del_user | only in image nat44_del_user_reply | only in image nat44_session_cleanup | only in image nat44_session_cleanup_reply | only in image nat44_set_session_limit | only in image nat44_set_session_limit_reply | only in image nat_show_config_reply | definition changed netmap_create | only in file netmap_create_reply | only in file netmap_delete | only in file netmap_delete_reply | only in file nhrp_details | only in file nhrp_dump | only in file nhrp_entry_add_del | only in file nhrp_entry_add_del_reply | only in file one_add_del_adjacency | definition changed one_add_del_l2_arp_entry | definition changed one_add_del_local_eid | definition changed one_add_del_locator | definition changed one_add_del_locator_set | definition changed one_add_del_map_request_itr_rlocs | definition changed one_add_del_map_resolver | definition changed one_add_del_map_server | definition changed one_add_del_ndp_entry | definition changed one_add_del_remote_mapping | definition changed one_adjacencies_get_reply | definition changed one_eid_table_add_del_map | definition changed one_eid_table_details | definition changed one_eid_table_dump | definition changed one_eid_table_map_dump | definition changed one_enable_disable | definition changed one_enable_disable_petr_mode | definition changed one_enable_disable_pitr_mode | definition changed one_enable_disable_xtr_mode | definition changed one_get_map_request_itr_rlocs_reply | definition changed one_l2_arp_entries_get_reply | definition changed one_locator_details | definition changed one_locator_dump | definition changed one_locator_set_details | definition changed one_locator_set_dump | definition changed one_map_register_enable_disable | definition changed one_map_request_mode | definition changed one_map_resolver_details | definition changed one_map_server_details | definition changed one_ndp_entries_get_reply | definition changed one_nsh_set_locator_set | definition changed one_pitr_set_locator_set | definition changed one_rloc_probe_enable_disable | definition changed one_show_petr_mode_reply | definition changed one_show_pitr_mode_reply | definition changed one_show_xtr_mode_reply | definition changed one_stats_details | definition changed one_stats_enable_disable | definition changed one_use_petr | definition changed pg_capture | definition changed pg_create_interface | definition changed pg_create_interface_reply | definition changed pg_enable_disable | definition changed policer_add_del | definition changed policer_details | definition changed policer_dump | definition changed session_enable_disable | definition changed session_rule_add_del | definition changed session_rules_details | definition changed show_lisp_map_register_state_reply | definition changed show_lisp_map_request_mode_reply | definition changed show_lisp_pitr_reply | definition changed show_lisp_rloc_probe_state_reply | definition changed show_lisp_status_reply | definition changed show_lisp_use_petr_reply | definition changed show_one_map_register_state_reply | definition changed show_one_map_request_mode_reply | definition changed show_one_nsh_mapping_reply | definition changed show_one_pitr_reply | definition changed show_one_rloc_probe_state_reply | definition changed show_one_stats_enable_disable_reply | definition changed show_one_status_reply | definition changed show_one_use_petr_reply | definition changed show_threads_reply | definition changed sr_localsid_add_del | definition changed sr_localsids_details | definition changed sr_mpls_policy_add | definition changed sr_mpls_policy_assign_endpoint_color | definition changed sr_mpls_policy_mod | definition changed sr_mpls_steering_add_del | definition changed sr_policies_details | definition changed sr_policy_add | definition changed sr_policy_del | definition changed sr_policy_mod | definition changed sr_set_encap_source | definition changed sr_steering_add_del | definition changed sr_steering_pol_details | definition changed sw_interface_address_replace_begin | only in image sw_interface_address_replace_begin_reply | only in image sw_interface_address_replace_end | only in image sw_interface_address_replace_end_reply | only in image sw_interface_set_l2_bridge | definition changed sw_interface_set_l2_xconnect | definition changed sw_interface_set_lldp | definition changed sw_interface_set_vpath | definition changed sw_interface_set_vxlan_bypass | definition changed sw_interface_set_vxlan_gpe_bypass | definition changed sw_interface_span_details | definition changed sw_interface_span_dump | definition changed sw_interface_span_enable_disable | definition changed teib_details | only in image teib_dump | only in image teib_entry_add_del | only in image teib_entry_add_del_reply | only in image unbind_sock | only in file unbind_sock_reply | only in file unbind_uri | only in file unbind_uri_reply | only in file unmap_segment | only in file unmap_segment_reply | only in file urpf_update | only in image urpf_update_reply | only in image vrrp_vr_add_del | only in image vrrp_vr_add_del_reply | only in image vrrp_vr_details | only in image vrrp_vr_dump | only in image vrrp_vr_peer_details | only in image vrrp_vr_peer_dump | only in image vrrp_vr_set_peers | only in image vrrp_vr_set_peers_reply | only in image vrrp_vr_start_stop | only in image vrrp_vr_start_stop_reply | only in image vrrp_vr_track_if_add_del | only in image vrrp_vr_track_if_add_del_reply | only in image vrrp_vr_track_if_details | only in image vrrp_vr_track_if_dump | only in image vxlan_add_del_tunnel | definition changed vxlan_add_del_tunnel_reply | definition changed vxlan_gpe_add_del_tunnel | definition changed vxlan_gpe_add_del_tunnel_reply | definition changed vxlan_gpe_tunnel_details | definition changed vxlan_gpe_tunnel_dump | definition changed vxlan_offload_rx | definition changed vxlan_tunnel_details | definition changed vxlan_tunnel_dump | definition changed Found 279 api message signature differences ### Patches that changed API definitions | @c extras/deprecated/dpdk-hqos/api/dpdk.api || | ------- | ------- | | [548d70de6](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=548d70de6) | misc: deprecate dpdk hqos | | @c extras/deprecated/netmap/netmap.api || | ------- | ------- | | [7db6ab03d](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=7db6ab03d) | misc: deprecate netmap and ixge drivers | | @c src/vpp/api/vpe.api || | ------- | ------- | | [933fcf489](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=933fcf489) | api: API cleanup | | [7db6ab03d](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=7db6ab03d) | misc: deprecate netmap and ixge drivers | | @c src/vnet/tunnel/tunnel_types.api || | ------- | ------- | | [14053c9db](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=14053c9db) | ipip: Multi-point interface | | [59ff918ea](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=59ff918ea) | tunnel: Common types for IP tunnels | | @c src/vnet/policer/policer_types.api || | ------- | ------- | | [cd01fb423](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=cd01fb423) | policer: API cleanup | | @c src/vnet/policer/policer.api || | ------- | ------- | | [cd01fb423](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=cd01fb423) | policer: API cleanup | | @c src/vnet/lisp-gpe/lisp_gpe.api || | ------- | ------- | | [58db6e16c](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=58db6e16c) | lisp: API cleanup | | @c src/vnet/teib/teib.api || | ------- | ------- | | [03ce46219](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=03ce46219) | teib: Rename NHRP to TEIB | | @c src/vnet/ip-neighbor/ip_neighbor.api || | ------- | ------- | | [240dcb24a](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=240dcb24a) | ip-neighbor: Add flush API | | [e64e5fff4](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=e64e5fff4) | tests: implement ipaddress convenience methods | | [c87fbb417](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=c87fbb417) | ip-neighbor: Replace feature for the ip-neighbor data-base | | [8e7fdddd3](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=8e7fdddd3) | ip-neighbor: add description to the age parameter | | [9c1928f81](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=9c1928f81) | ip-neighbor: populate neighbor age via API | | @c src/vnet/session/session.api || | ------- | ------- | | [6fdd7a5f7](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=6fdd7a5f7) | session: improve .api comments slightly | | [9845c20d7](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=9845c20d7) | session: add option to preallocate fifo headers | | [c0e9441e7](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=c0e9441e7) | tests: move defaults from defaultmapping to .api files | | [256779c85](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=256779c85) | udp: remove connected udp transport proto | | [888d9f05e](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=888d9f05e) | session: remove obsolete apis | | [07063b8ea](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=07063b8ea) | session: api to add new transport types | | [b4e5e50fe](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b4e5e50fe) | session: API cleanup | | [2de9c0f92](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=2de9c0f92) | svm: minimal initial fifo | | @c src/vnet/interface_types.api || | ------- | ------- | | [c4ae0fffb](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=c4ae0fffb) | interface: fix interface_types.api enums | | @c src/vnet/vxlan/vxlan.api || | ------- | ------- | | [7c0eb56f4](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=7c0eb56f4) | vxlan: vxlan/vxlan.api API cleanup | | @c src/vnet/vxlan-gbp/vxlan_gbp.api || | ------- | ------- | | [c0e9441e7](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=c0e9441e7) | tests: move defaults from defaultmapping to .api files | | @c src/vnet/gre/gre.api || | ------- | ------- | | [48ac1c2b2](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=48ac1c2b2) | gre: improve .api descriptions | | [8ab4e507c](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=8ab4e507c) | gre: add missing .api edits | | [e5b94dded](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=e5b94dded) | gre: Tunnel encap/decap flags | | [59ff918ea](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=59ff918ea) | tunnel: Common types for IP tunnels | | @c src/vnet/span/span.api || | ------- | ------- | | [908965db7](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=908965db7) | span: API cleanup | | @c src/vnet/srv6/sr.api || | ------- | ------- | | [c0e9441e7](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=c0e9441e7) | tests: move defaults from defaultmapping to .api files | | [0938eba15](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=0938eba15) | sr: srv6 API cleanup | | [79bfd2725](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=79bfd2725) | sr: SRv6 uN behavior | | @c src/vnet/srv6/sr_types.api || | ------- | ------- | | [0938eba15](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=0938eba15) | sr: srv6 API cleanup | | @c src/vnet/pg/pg.api || | ------- | ------- | | [db86329ab](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=db86329ab) | pg: API cleanup | | @c src/vnet/l2/l2.api || | ------- | ------- | | [c0e9441e7](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=c0e9441e7) | tests: move defaults from defaultmapping to .api files | | [145e330f0](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=145e330f0) | l2: API cleanup | | @c src/vnet/lldp/lldp.api || | ------- | ------- | | [1c684f9af](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=1c684f9af) | lldp: API cleanup | | @c src/vnet/vxlan-gpe/vxlan_gpe.api || | ------- | ------- | | [1c2002a31](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=1c2002a31) | vxlan: vxlan-gpe/vxlan-gpe.cpi API cleanup | | @c src/vnet/lisp-cp/one.api || | ------- | ------- | | [58db6e16c](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=58db6e16c) | lisp: API cleanup | | @c src/vnet/lisp-cp/lisp_types.api || | ------- | ------- | | [58db6e16c](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=58db6e16c) | lisp: API cleanup | | @c src/vnet/lisp-cp/lisp.api || | ------- | ------- | | [58db6e16c](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=58db6e16c) | lisp: API cleanup | | @c src/vnet/devices/tap/tapv2.api || | ------- | ------- | | [d88fc0fce](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=d88fc0fce) | tap: refactor existing flags | | [073d74d0b](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=073d74d0b) | tap: implement sw_interface_tap_v2_dump filtering by sw_if_index | | [206acf84d](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=206acf84d) | tap: add initial support for tun | | [b49bc1ae6](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b49bc1ae6) | tap: add support for persistance | | @c src/vnet/devices/virtio/vhost_user.api || | ------- | ------- | | [bc0d9ff67](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=bc0d9ff67) | virtio: support virtio 1.1 packed ring in vhost | | @c src/vnet/devices/virtio/virtio.api || | ------- | ------- | | [53f06a014](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=53f06a014) | vlib: move pci api types from vnet/pci to vlib/pci | | @c src/vnet/ipsec/ipsec_types.api || | ------- | ------- | | [abc5660c6](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=abc5660c6) | ipsec: User can choose the UDP source port | | [287d5e109](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=287d5e109) | ipsec: API cleanup | | [5893747d7](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=5893747d7) | api: ipsec: add missing IS_INBOUND flag. | | [2fcd265d3](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=2fcd265d3) | ipsec: Revert API cleanup | | [666ece35c](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=666ece35c) | ipsec: API cleanup | | @c src/vnet/ipsec/ipsec.api || | ------- | ------- | | [48d32b43c](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=48d32b43c) | ipsec: provide stat index in sa details | | [287d5e109](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=287d5e109) | ipsec: API cleanup | | [2fcd265d3](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=2fcd265d3) | ipsec: Revert API cleanup | | [666ece35c](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=666ece35c) | ipsec: API cleanup | | [282872127](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=282872127) | ipsec: IPSec protection for multi-point tunnel interfaces | | @c src/vnet/ethernet/p2p_ethernet.api || | ------- | ------- | | [bdfe5955f](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=bdfe5955f) | ethernet: add sanity checks to p2p_ethernet_add/del | | @c src/vnet/bonding/bond.api || | ------- | ------- | | [c0e9441e7](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=c0e9441e7) | tests: move defaults from defaultmapping to .api files | | @c src/vnet/mpls/mpls.api || | ------- | ------- | | [c0e9441e7](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=c0e9441e7) | tests: move defaults from defaultmapping to .api files | | [39ae0a07a](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=39ae0a07a) | mpls: add user defined name tag to mpls tunnels | | @c src/vnet/syslog/syslog.api || | ------- | ------- | | [c0e9441e7](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=c0e9441e7) | tests: move defaults from defaultmapping to .api files | | @c src/vnet/interface.api || | ------- | ------- | | [59f71132e](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=59f71132e) | ip: Replace Sematics for Interface IP addresses | | @c src/vnet/ipip/ipip.api || | ------- | ------- | | [14053c9db](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=14053c9db) | ipip: Multi-point interface | | [59ff918ea](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=59ff918ea) | tunnel: Common types for IP tunnels | | @c src/vnet/srmpls/sr_mpls.api || | ------- | ------- | | [0938eba15](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=0938eba15) | sr: srv6 API cleanup | | [00ec4019b](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=00ec4019b) | sr: API cleanup | | @c src/vnet/ip/ip.api || | ------- | ------- | | [f5d38e05a](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=f5d38e05a) | api: ip: add IP_ROUTE_LOOKUP API | | [c0e9441e7](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=c0e9441e7) | tests: move defaults from defaultmapping to .api files | | [d724e4f43](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=d724e4f43) | urpf: Unicast reverse Path Forwarding (plugin) | | @c src/vnet/ip/ip_types.api || | ------- | ------- | | [164c44f0b](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=164c44f0b) | ip: Fix the AH/ESP protocol numbers on the API | | [7dd63e5cc](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=7dd63e5cc) | ip: change ip API enums address_family and ip_proto size to u8 | | [3ec09e924](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=3ec09e924) | ip: ip_address_t uses ip46_address_t | | @c src/plugins/map/map.api || | ------- | ------- | | [c0e9441e7](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=c0e9441e7) | tests: move defaults from defaultmapping to .api files | | @c src/plugins/ikev2/ikev2.api || | ------- | ------- | | [933c4ca5a](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=933c4ca5a) | ikev2: fix string in api | | [59fea5a6a](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=59fea5a6a) | ikev2: make liveness params configurable | | [8ceb44a89](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=8ceb44a89) | ikev2: fix typo in .api description | | [e5d34919b](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=e5d34919b) | ikev2: add support for custom ipsec-over-udp port | | [b29d523af](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b29d523af) | ikev2: make UDP encap flag configurable | | [44476c6b2](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=44476c6b2) | ikev2: Configure a profile with an existing interface | | @c src/plugins/urpf/urpf.api || | ------- | ------- | | [d724e4f43](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=d724e4f43) | urpf: Unicast reverse Path Forwarding (plugin) | | @c src/plugins/lb/lb.api || | ------- | ------- | | [c0e9441e7](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=c0e9441e7) | tests: move defaults from defaultmapping to .api files | | @c src/plugins/gtpu/gtpu.api || | ------- | ------- | | [00fdf53c7](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=00fdf53c7) | gtpu: offload RX flow | | @c src/plugins/acl/acl_types.api || | ------- | ------- | | [2f8cd9145](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=2f8cd9145) | acl: API cleanup | | [492a5d0bd](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=492a5d0bd) | acl: revert acl: api cleanup | | [aad1ee149](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=aad1ee149) | acl: API cleanup | | @c src/plugins/acl/acl.api || | ------- | ------- | | [c0e9441e7](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=c0e9441e7) | tests: move defaults from defaultmapping to .api files | | [2f8cd9145](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=2f8cd9145) | acl: API cleanup | | [492a5d0bd](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=492a5d0bd) | acl: revert acl: api cleanup | | [aad1ee149](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=aad1ee149) | acl: API cleanup | | @c src/plugins/nat/dslite/dslite.api || | ------- | ------- | | [2c6639c69](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=2c6639c69) | nat: move dslite to separate sub-plugin | | @c src/plugins/nat/nat.api || | ------- | ------- | | [6bb080f1e](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=6bb080f1e) | nat: per vrf session limits | | [61717cc38](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=61717cc38) | nat: use correct data types for memory sizes | | [98301bd56](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=98301bd56) | nat: user deletion function & extra metrics | | [edf777272](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=edf777272) | nat: api & cli command for forcing session cleanup | | [2c6639c69](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=2c6639c69) | nat: move dslite to separate sub-plugin | | @c src/plugins/vrrp/vrrp.api || | ------- | ------- | | [3fccd0278](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=3fccd0278) | vrrp: do not define _details as autoreply | | [39e9428b9](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=39e9428b9) | vrrp: add plugin providing vrrp support | | @c src/vlib/pci/pci_types.api || | ------- | ------- | | [53f06a014](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=53f06a014) | vlib: move pci api types from vnet/pci to vlib/pci | @page release_notes_2001 Release notes for VPP 20.01 More than 1039 commits since the 19.08 release. ## Features - API trace tool - Add text output (a2ac36c91) - Binary API Compiler for Python - Raise ValueError when fieldname is python keyword (ff47fb645) - Binary API Libraries - Add API support for marvell PP2 plugin (859b59133) - Add bapi thread handle to api main structure. (8229580e8) - Multiple connections per process (39d69112f) - Multiple socket connections per single process (59cea1a9d) - Build System - Add build types helpstring to cmake project (952a7b8b7) - Add env variable to pass extra cmake args (297365403) - Add yaml file linting to make checkstyle (6b0dd5502) - Export vapi generation in vpp-dev (dc20371f8) - Fix 3rd party CI systems. (86a9441c2) - Pass 'no-pci' to autgenerated config (be7ef3b5c) - Crypto ipsecmb Plugin - Bump to intel-ipsec-mb version 0.53 (d35fefe8b) - Improve gcm performance using dedicated API. (76a36e83e) - Infrastructure Library - Bihash walk cb typedef and continue/stop controls (f50bac1bb) - Create unformat function for data size parsing (579b16506) - Implement CLIB\_PAUSE () for aarch64 platforms (18512b002) - libmemif - Introduce 'memif\_per\_thread\_' namespace (17f2a7bbf) - Link Bonding - Add/del secondary mac address callback (e83aa456b) - Add /if/lacp/bond-sw-if-index/slave-sw-if-index/partner-state (aa7257863) - Add weight support for active-backup mode (a1876b84e) - Fix interface deletion (cc3aac056) - Miscellaneous - Add address sanitizer heap instrumentation (9fb6d40eb) - Add CentOS 8 package support (c025329bb) - Add gdb helpers for vlib buffers (2b65f9ca0) - Add lcov scripts, README.md (8d74caa0a) - Add "maxframe" and "rate" to packet-generator cli. (87d7bac5c) - Add "show run summary" (ac78f8
/*
* Test suite for class VppOM
*
* Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
#define BOOST_TEST_MODULE "VPP OBJECT MODEL"
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>
#include <boost/assign/list_inserter.hpp>
#include <iostream>
#include <deque>
#include "vom/om.hpp"
#include "vom/interface.hpp"
#include "vom/interface_cmds.hpp"
#include "vom/bond_interface_cmds.hpp"
#include "vom/bond_group_binding.hpp"
#include "vom/bond_group_binding_cmds.hpp"
#include "vom/l2_binding.hpp"
#include "vom/l2_binding_cmds.hpp"
#include "vom/l2_xconnect.hpp"
#include "vom/l2_xconnect_cmds.hpp"
#include "vom/l3_binding.hpp"
#include "vom/l3_binding_cmds.hpp"
#include "vom/bridge_domain.hpp"
#include "vom/bridge_domain_entry.hpp"
#include "vom/bridge_domain_arp_entry.hpp"
#include "vom/bridge_domain_cmds.hpp"
#include "vom/bridge_domain_entry_cmds.hpp"
#include "vom/bridge_domain_arp_entry_cmds.hpp"
#include "vom/prefix.hpp"
#include "vom/route.hpp"
#include "vom/route_cmds.hpp"
#include "vom/route_domain.hpp"
#include "vom/route_domain_cmds.hpp"
#include "vom/vxlan_tunnel.hpp"
#include "vom/vxlan_tunnel_cmds.hpp"
#include "vom/sub_interface.hpp"
#include "vom/sub_interface_cmds.hpp"
#include "vom/acl_ethertype.hpp"
#include "vom/acl_ethertype_cmds.hpp"
#include "vom/acl_list.hpp"
#include "vom/acl_binding.hpp"
#include "vom/acl_list_cmds.hpp"
#include "vom/acl_binding_cmds.hpp"
#include "vom/acl_l3_rule.hpp"
#include "vom/acl_l2_rule.hpp"
#include "vom/arp_proxy_config.hpp"
#include "vom/arp_proxy_binding.hpp"
#include "vom/arp_proxy_config_cmds.hpp"
#include "vom/arp_proxy_binding_cmds.hpp"
#include "vom/igmp_binding.hpp"
#include "vom/igmp_binding_cmds.hpp"
#include "vom/igmp_listen.hpp"
#include "vom/igmp_listen_cmds.hpp"
#include "vom/ip_punt_redirect.hpp"
#include "vom/ip_punt_redirect_cmds.hpp"
#include "vom/ip_unnumbered.hpp"
#include "vom/ip_unnumbered_cmds.hpp"
#include "vom/interface_ip6_nd.hpp"
#include "vom/interface_span.hpp"
#include "vom/interface_span_cmds.hpp"
#include "vom/neighbour.hpp"
#include "vom/neighbour_cmds.hpp"
#include "vom/nat_static.hpp"
#include "vom/nat_static_cmds.hpp"
#include "vom/nat_binding.hpp"
#include "vom/nat_binding_cmds.hpp"
#include "vom/pipe.hpp"
#include "vom/pipe_cmds.hpp"
using namespace boost;
using namespace VOM;
/**
* An expectation exception
*/
class ExpException
{
public:
ExpException(unsigned int number)
{
// a neat place to add a break point
std::cout << " ExpException here: " << number << std::endl;
}
};
class MockListener : public interface::event_listener,
public interface::stat_listener
{
void handle_interface_stat(interface_cmds::stats_enable_cmd *cmd)
{
}
void handle_interface_event(interface_cmds::events_cmd *cmd)
{
}
};
class MockCmdQ : public HW::cmd_q
{
public:
MockCmdQ():
m_strict_order(true)
{
}
virtual ~MockCmdQ()
{
}
void expect(cmd *f)
{
m_exp_queue.push_back(f);
}
void enqueue(cmd *f)
{
m_act_queue.push_back(f);
}
void enqueue(std::queue<cmd*> &cmds)
{
while (cmds.size())
{
m_act_queue.push_back(cmds.front());
cmds.pop();
}
}
void enqueue(std::shared_ptr<cmd> f)
{
m_act_queue.push_back(f.get());
}
void dequeue(cmd *f)
{
}
void dequeue(std::shared_ptr<cmd> cmd)
{
}
void strict_order(bool on)
{
m_strict_order = on;
}
bool is_empty()
{
return ((0 == m_exp_queue.size()) &&
(0 == m_act_queue.size()));
}
rc_t write()
{
cmd *f_exp, *f_act;
rc_t rc = rc_t::OK;
while (m_act_queue.size())
{
bool matched = false;
auto it_exp = m_exp_queue.begin();
auto it_act = m_act_queue.begin();
f_act = *it_act;
std::cout << " Act: " << f_act->to_string() << std::endl;
while (it_exp != m_exp_queue.end())
{
f_exp = *it_exp;
try
{
std::cout << " Exp: " << f_exp->to_string() << std::endl;
if (typeid(*f_exp) != typeid(*f_act))
{
throw ExpException(1);
}
if (typeid(*f_exp) == typeid(interface_cmds::af_packet_create_cmd))
{
rc = handle_derived<interface_cmds::af_packet_create_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(interface_cmds::loopback_create_cmd))
{
rc = handle_derived<interface_cmds::loopback_create_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(interface_cmds::vhost_create_cmd))
{
rc = handle_derived<interface_cmds::vhost_create_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(bond_interface_cmds::create_cmd))
{
rc = handle_derived<bond_interface_cmds::create_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(interface_cmds::loopback_delete_cmd))
{
rc = handle_derived<interface_cmds::loopback_delete_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(interface_cmds::af_packet_delete_cmd))
{
rc = handle_derived<interface_cmds::af_packet_delete_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(interface_cmds::vhost_delete_cmd))
{
rc = handle_derived<interface_cmds::vhost_delete_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(bond_interface_cmds::delete_cmd))
{
rc = handle_derived<bond_interface_cmds::delete_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(interface_cmds::state_change_cmd))
{
rc = handle_derived<interface_cmds::state_change_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(interface_cmds::set_table_cmd))
{
rc = handle_derived<interface_cmds::set_table_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(interface_cmds::set_mac_cmd))
{
rc = handle_derived<interface_cmds::set_mac_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(interface_cmds::set_tag))
{
rc = handle_derived<interface_cmds::set_tag>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(bond_group_binding_cmds::bind_cmd))
{
rc = handle_derived<bond_group_binding_cmds::bind_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(bond_group_binding_cmds::unbind_cmd))
{
rc = handle_derived<bond_group_binding_cmds::unbind_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(route_domain_cmds::create_cmd))
{
rc = handle_derived<route_domain_cmds::create_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(route_domain_cmds::delete_cmd))
{
rc = handle_derived<route_domain_cmds::delete_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(route::ip_route_cmds::update_cmd))
{
rc = handle_derived<route::ip_route_cmds::update_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(route::ip_route_cmds::delete_cmd))
{
rc = handle_derived<route::ip_route_cmds::delete_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(neighbour_cmds::create_cmd))
{
rc = handle_derived<neighbour_cmds::create_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(neighbour_cmds::delete_cmd))
{
rc = handle_derived<neighbour_cmds::delete_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(l3_binding_cmds::bind_cmd))
{
rc = handle_derived<l3_binding_cmds::bind_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(l3_binding_cmds::unbind_cmd))
{
rc = handle_derived<l3_binding_cmds::unbind_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(bridge_domain_cmds::create_cmd))
{
rc = handle_derived<bridge_domain_cmds::create_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(bridge_domain_cmds::delete_cmd))
{
rc = handle_derived<bridge_domain_cmds::delete_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(bridge_domain_entry_cmds::create_cmd))
{
rc = handle_derived<bridge_domain_entry_cmds::create_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(bridge_domain_entry_cmds::delete_cmd))
{
rc = handle_derived<bridge_domain_entry_cmds::delete_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(bridge_domain_arp_entry_cmds::create_cmd))
{
rc = handle_derived<bridge_domain_arp_entry_cmds::create_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(bridge_domain_arp_entry_cmds::delete_cmd))
{
rc = handle_derived<bridge_domain_arp_entry_cmds::delete_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(l2_binding_cmds::bind_cmd))
{
rc = handle_derived<l2_binding_cmds::bind_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(l2_binding_cmds::unbind_cmd))
{
rc = handle_derived<l2_binding_cmds::unbind_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(l2_binding_cmds::set_vtr_op_cmd))
{
rc = handle_derived<l2_binding_cmds::set_vtr_op_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(l2_xconnect_cmds::bind_cmd))
{
rc = handle_derived<l2_xconnect_cmds::bind_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(l2_xconnect_cmds::unbind_cmd))
{
rc = handle_derived<l2_xconnect_cmds::unbind_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(vxlan_tunnel_cmds::create_cmd))
{
rc = handle_derived<vxlan_tunnel_cmds::create_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(vxlan_tunnel_cmds::delete_cmd))
{
rc = handle_derived<vxlan_tunnel_cmds::delete_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(sub_interface_cmds::create_cmd))
{
rc = handle_derived<sub_interface_cmds::create_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(sub_interface_cmds::delete_cmd))
{
rc = handle_derived<sub_interface_cmds::delete_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(ACL::acl_ethertype_cmds::bind_cmd))
{
rc = handle_derived<ACL::acl_ethertype_cmds::bind_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(ACL::acl_ethertype_cmds::unbind_cmd))
{
rc = handle_derived<ACL::acl_ethertype_cmds::unbind_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(ACL::list_cmds::l3_update_cmd))
{
rc = handle_derived<ACL::list_cmds::l3_update_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(ACL::list_cmds::l3_delete_cmd))
{
rc = handle_derived<ACL::list_cmds::l3_delete_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(ACL::binding_cmds::l3_bind_cmd))
{
rc = handle_derived<ACL::binding_cmds::l3_bind_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(ACL::binding_cmds::l3_unbind_cmd))
{
rc = handle_derived<ACL::binding_cmds::l3_unbind_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(ACL::list_cmds::l2_update_cmd))
{
rc = handle_derived<ACL::list_cmds::l2_update_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(ACL::list_cmds::l2_delete_cmd))
{
rc = handle_derived<ACL::list_cmds::l2_delete_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(ACL::binding_cmds::l2_bind_cmd))
{
rc = handle_derived<ACL::binding_cmds::l2_bind_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(ACL::binding_cmds::l2_unbind_cmd))
{
rc = handle_derived<ACL::binding_cmds::l2_unbind_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(arp_proxy_binding_cmds::bind_cmd))
{
rc = handle_derived<arp_proxy_binding_cmds::bind_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(arp_proxy_binding_cmds::unbind_cmd))
{
rc = handle_derived<arp_proxy_binding_cmds::unbind_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(arp_proxy_config_cmds::config_cmd))
{
rc = handle_derived<arp_proxy_config_cmds::config_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(arp_proxy_config_cmds::unconfig_cmd))
{
rc = handle_derived<arp_proxy_config_cmds::unconfig_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(igmp_binding_cmds::bind_cmd))
{
rc = handle_derived<igmp_binding_cmds::bind_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(igmp_binding_cmds::unbind_cmd))
{
rc = handle_derived<igmp_binding_cmds::unbind_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(igmp_listen_cmds::listen_cmd))
{
rc = handle_derived<igmp_listen_cmds::listen_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(igmp_listen_cmds::unlisten_cmd))
{
rc = handle_derived<igmp_listen_cmds::unlisten_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(ip_punt_redirect_cmds::config_cmd))
{
rc = handle_derived<ip_punt_redirect_cmds::config_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(ip_punt_redirect_cmds::unconfig_cmd))
{
rc = handle_derived<ip_punt_redirect_cmds::unconfig_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(ip_unnumbered_cmds::config_cmd))
{
rc = handle_derived<ip_unnumbered_cmds::config_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(ip_unnumbered_cmds::unconfig_cmd))
{
rc = handle_derived<ip_unnumbered_cmds::unconfig_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(ip6nd_ra_config::config_cmd))
{
rc = handle_derived<ip6nd_ra_config::config_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(ip6nd_ra_config::unconfig_cmd))
{
rc = handle_derived<ip6nd_ra_config::unconfig_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(ip6nd_ra_prefix::config_cmd))
{
rc = handle_derived<ip6nd_ra_prefix::config_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(ip6nd_ra_prefix::unconfig_cmd))
{
rc = handle_derived<ip6nd_ra_prefix::unconfig_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(interface_span_cmds::config_cmd))
{
rc = handle_derived<interface_span_cmds::config_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(interface_span_cmds::unconfig_cmd))
{
rc = handle_derived<interface_span_cmds::unconfig_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(nat_static_cmds::create_44_cmd))
{
rc = handle_derived<nat_static_cmds::create_44_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(nat_static_cmds::delete_44_cmd))
{
rc = handle_derived<nat_static_cmds::delete_44_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(nat_binding_cmds::bind_44_input_cmd))
{
rc = handle_derived<nat_binding_cmds::bind_44_input_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(nat_binding_cmds::unbind_44_input_cmd))
{
rc = handle_derived<nat_binding_cmds::unbind_44_input_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(interface_cmds::events_cmd))
{
rc = handle_derived<interface_cmds::events_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(pipe_cmds::create_cmd))
{
rc = handle_derived<pipe_cmds::create_cmd>(f_exp, f_act);
}
else if (typeid(*f_exp) == typeid(pipe_cmds::delete_cmd))
{
rc = handle_derived<pipe_cmds::delete_cmd>(f_exp, f_act);
}
else
{
throw ExpException(2);
}
// if we get here then we found the match.
m_exp_queue.erase(it_exp);
m_act_queue.erase(it_act);
delete f_exp;
delete f_act;
// return any injected failures to the agent
if (rc_t::OK != rc && rc_t::NOOP != rc)
{
return (rc);
}
matched = true;
break;
}
catch (ExpException &e)
{
// The expected and actual do not match
if (m_strict_order)
{
// in strict ordering mode this is fatal, so rethrow
throw e;
}
else
{
// move the iterator onto the next in the expected list and
// check for a match
++it_exp;
}
}
}
if (!matched)
throw ExpException(3);
}
return (rc);
}
private:
template <typename T>
rc_t handle_derived(const cmd *f_exp, cmd *f_act)
{
const T *i_exp;
T *i_act;
i_exp = dynamic_cast<const T*>(f_exp);
i_act = dynamic_cast<T*>(f_act);
if (!(*i_exp == *i_act))
{
throw ExpException(4);
}
// pass the data and return code to the agent
i_act->item() = i_exp->item();
return (i_act->item().rc());
}
// The Q to push the expectations on
std::deque<cmd*> m_exp_queue;
// the queue to push the actual events on
std::deque<cmd*> m_act_queue;
// control whether the expected queue is strictly ordered.
bool m_strict_order;
};
class VppInit {
public:
std::string name;
MockCmdQ *f;
VppInit()
: name("vpp-ut"),
f(new MockCmdQ())
{
HW::init(f);
OM::init();
logger().set(log_level_t::DEBUG);
}
~VppInit() {
delete f;
}
};
BOOST_AUTO_TEST_SUITE(vom)
#define TRY_CHECK_RC(stmt) \
{ \
try { \
BOOST_CHECK(rc_t::OK == stmt); \
} \
catch (ExpException &e) \
{ \
BOOST_CHECK(false); \
} \
BOOST_CHECK(vi.f->is_empty()); \
}
#define TRY_CHECK(stmt) \
{ \
try { \
stmt; \
} \
catch (ExpException &e) \
{ \
BOOST_CHECK(false); \
} \
BOOST_CHECK(vi.f->is_empty()); \
}
#define ADD_EXPECT(stmt) \
vi.f->expect(new stmt)
#define STRICT_ORDER_OFF() \
vi.f->strict_order(false)
BOOST_AUTO_TEST_CASE(test_interface) {
VppInit vi;
const std::string go = "GeorgeOrwell";
const std::string js = "JohnSteinbeck";
rc_t rc = rc_t::OK;
/*
* George creates and deletes the interface
*/
std::string itf1_name = "afpacket1";
interface itf1(itf1_name,
interface::type_t::AFPACKET,
interface::admin_state_t::UP);
/*
* set the expectation for a afpacket interface create.
* 2 is the interface handle VPP [mock] assigns
*/
HW::item<handle_t> hw_ifh(2, rc_t::OK);
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name));
HW::item<interface::admin_state_t> hw_as_up(interface::admin_state_t::UP, rc_t::OK);
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh));
TRY_CHECK_RC(OM::write(go, itf1));
HW::item<interface::admin_state_t> hw_as_down(interface::admin_state_t::DOWN, rc_t::OK);
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name));
TRY_CHECK(OM::remove(go));
/*
* George creates the interface, then John brings it down.
* George's remove is a no-op, sice John also owns the interface
*/
interface itf1b(itf1_name,
interface::type_t::AFPACKET,
interface::admin_state_t::DOWN);
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh));
TRY_CHECK_RC(OM::write(go, itf1));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh));
TRY_CHECK_RC(OM::write(js, itf1b));
TRY_CHECK(OM::remove(go));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name));
TRY_CHECK(OM::remove(js));
/*
* George adds an interface, then we flush all of Geroge's state
*/
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh));
TRY_CHECK_RC(OM::write(go, itf1));
TRY_CHECK(OM::mark(go));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name));
TRY_CHECK(OM::sweep(go));
/*
* George adds an interface. mark stale. update the same interface. sweep
* and expect no delete
*/
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh));
TRY_CHECK_RC(OM::write(go, itf1b));
TRY_CHECK(OM::mark(go));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh));
TRY_CHECK_RC(OM::write(go, itf1));
TRY_CHECK(OM::sweep(go));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name));
TRY_CHECK(OM::remove(go));
/*
* George adds an insterface, then we mark that state. Add a second interface
* an flush the first that is now stale.
*/
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh));
TRY_CHECK_RC(OM::write(go, itf1));
TRY_CHECK(OM::mark(go));
std::string itf2_name = "afpacket2";
std::string itf2_tag = "uuid-of-afpacket2-interface";
interface itf2(itf2_name,
interface::type_t::AFPACKET,
interface::admin_state_t::UP,
itf2_tag);
HW::item<handle_t> hw_ifh2(3, rc_t::OK);
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh2, itf2_name));
ADD_EXPECT(interface_cmds::set_tag(hw_ifh2, itf2_tag));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh2));
TRY_CHECK_RC(OM::write(go, itf2));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name));
TRY_CHECK(OM::sweep(go));
TRY_CHECK(OM::mark(go));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh2));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh2, itf2_name));
TRY_CHECK(OM::sweep(go));
std::string itf3_name = "/PATH/TO/vhost_user1.sock";
std::string itf3_tag = "uuid-of-vhost_user1-interface";
interface itf3(itf3_name,
interface::type_t::VHOST,
interface::admin_state_t::UP,
itf3_tag);
HW::item<handle_t> hw_ifh3(4, rc_t::OK);
ADD_EXPECT(interface_cmds::vhost_create_cmd(hw_ifh3, itf3_name, itf3_tag));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh3));
TRY_CHECK_RC(OM::write(go, itf3));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh3));
ADD_EXPECT(interface_cmds::vhost_delete_cmd(hw_ifh3, itf3_name));
TRY_CHECK(OM::remove(go));
}
BOOST_AUTO_TEST_CASE(test_bvi) {
VppInit vi;
const std::string ernest = "ErnestHemmingway";
const std::string graham = "GrahamGreene";
rc_t rc = rc_t::OK;
l3_binding *l3;
HW::item<interface::admin_state_t> hw_as_up(interface::admin_state_t::UP,
rc_t::OK);
HW::item<interface::admin_state_t> hw_as_down(interface::admin_state_t::DOWN,
rc_t::OK);
/*
* Enrest creates a BVI with address 10.10.10.10/24
*/
route::prefix_t pfx_10("10.10.10.10", 24);
const std::string bvi_name = "bvi1";
interface itf(bvi_name,
interface::type_t::BVI,
interface::admin_state_t::UP);
HW::item<handle_t> hw_ifh(4, rc_t::OK);
HW::item<route::prefix_t> hw_pfx_10(pfx_10, rc_t::OK);
ADD_EXPECT(interface_cmds::loopback_create_cmd(hw_ifh, bvi_name));
ADD_EXPECT(interface_cmds::set_tag(hw_ifh, bvi_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh));
TRY_CHECK_RC(OM::write(ernest, itf));
l3 = new l3_binding(itf, pfx_10);
HW::item<bool> hw_l3_bind(true, rc_t::OK);
HW::item<bool> hw_l3_unbind(false, rc_t::OK);
ADD_EXPECT(l3_binding_cmds::bind_cmd(hw_l3_bind, hw_ifh.data(), pfx_10));
TRY_CHECK_RC(OM::write(ernest, *l3));
// change the MAC address on the BVI
interface itf_new_mac(bvi_name,
interface::type_t::BVI,
interface::admin_state_t::UP);
l2_address_t l2_addr({0,1,2,3,4,5});
HW::item<l2_address_t> hw_mac(l2_addr, rc_t::OK);
itf_new_mac.set(l2_addr);
ADD_EXPECT(interface_cmds::set_mac_cmd(hw_mac, hw_ifh));
TRY_CHECK_RC(OM::write(ernest, itf_new_mac));
// create/write the interface to the OM again but with an unset MAC
// this should not generate a MAC address update
TRY_CHECK_RC(OM::write(ernest, itf));
// change the MAC address on the BVI - again
interface itf_new_mac2(bvi_name,
interface::type_t::BVI,
interface::admin_state_t::UP);
l2_address_t l2_addr2({0,1,2,3,4,6});
HW::item<l2_address_t> hw_mac2(l2_addr2, rc_t::OK);
itf_new_mac2.set(l2_addr2);
ADD_EXPECT(interface_cmds::set_mac_cmd(hw_mac2, hw_ifh));
TRY_CHECK_RC(OM::write(ernest, itf_new_mac2));
delete l3;
ADD_EXPECT(l3_binding_cmds::unbind_cmd(hw_l3_unbind, hw_ifh.data(), pfx_10));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh));
ADD_EXPECT(interface_cmds::loopback_delete_cmd(hw_ifh));
TRY_CHECK(OM::remove(ernest));
/*
* Graham creates a BVI with address 10.10.10.10/24 in Routing Domain
*/
route_domain rd(1);
HW::item<bool> hw_rd4_create(true, rc_t::OK);
HW::item<bool> hw_rd4_delete(false, rc_t::OK);
HW::item<bool> hw_rd6_create(true, rc_t::OK);
HW::item<bool> hw_rd6_delete(false, rc_t::OK);
HW::item<route::table_id_t> hw_rd4_bind(1, rc_t::OK);
HW::item<route::table_id_t> hw_rd4_unbind(route::DEFAULT_TABLE, rc_t::OK);
HW::item<route::table_id_t> hw_rd6_bind(1, rc_t::OK);
HW::item<route::table_id_t> hw_rd6_unbind(route::DEFAULT_TABLE, rc_t::OK);
ADD_EXPECT(route_domain_cmds::create_cmd(hw_rd4_create, l3_proto_t::IPV4, 1));
ADD_EXPECT(route_domain_cmds::create_cmd(hw_rd6_create, l3_proto_t::IPV6, 1));
TRY_CHECK_RC(OM::write(graham, rd));
const std::string bvi2_name = "bvi2";
interface *itf2 = new interface(bvi2_name,
interface::type_t::BVI,
interface::admin_state_t::UP,
rd);
HW::item<handle_t> hw_ifh2(5, rc_t::OK);
ADD_EXPECT(interface_cmds::loopback_create_cmd(hw_ifh2, bvi2_name));
ADD_EXPECT(interface_cmds::set_tag(hw_ifh2, bvi2_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh2));
ADD_EXPECT(interface_cmds::set_table_cmd(hw_rd4_bind, l3_proto_t::IPV4, hw_ifh2));
ADD_EXPECT(interface_cmds::set_table_cmd(hw_rd6_bind, l3_proto_t::IPV6, hw_ifh2));
TRY_CHECK_RC(OM::write(graham, *itf2));
l3 = new l3_binding(*itf2, pfx_10);
ADD_EXPECT(l3_binding_cmds::bind_cmd(hw_l3_bind, hw_ifh2.data(), pfx_10));
TRY_CHECK_RC(OM::write(graham, *l3));
delete l3;
delete itf2;
ADD_EXPECT(l3_binding_cmds::unbind_cmd(hw_l3_unbind, hw_ifh2.data(), pfx_10));
ADD_EXPECT(interface_cmds::set_table_cmd(hw_rd4_unbind, l3_proto_t::IPV4, hw_ifh2));
ADD_EXPECT(interface_cmds::set_table_cmd(hw_rd6_unbind, l3_proto_t::IPV6, hw_ifh2));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh2));
ADD_EXPECT(interface_cmds::loopback_delete_cmd(hw_ifh2));
ADD_EXPECT(route_domain_cmds::delete_cmd(hw_rd4_delete, l3_proto_t::IPV4, 1));
ADD_EXPECT(route_domain_cmds::delete_cmd(hw_rd6_delete, l3_proto_t::IPV6, 1));
TRY_CHECK(OM::remove(graham));
}
BOOST_AUTO_TEST_CASE(test_bond) {
VppInit vi;
const std::string cb = "CarolBerg";
rc_t rc = rc_t::OK;
/*
* creates the interfaces
*/
std::string itf1_name = "afpacket1";
interface itf1(itf1_name,
interface::type_t::AFPACKET,
interface::admin_state_t::UP);
HW::item<handle_t> hw_ifh(2, rc_t::OK);
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name));
HW::item<interface::admin_state_t> hw_as_up(interface::admin_state_t::UP, rc_t::OK);
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh));
TRY_CHECK_RC(OM::write(cb, itf1));
std::string itf2_name = "afpacket2";
interface itf2(itf2_name,
interface::type_t::AFPACKET,
interface::admin_state_t::UP);
HW::item<handle_t> hw_ifh2(4, rc_t::OK);
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh2, itf2_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh2));
TRY_CHECK_RC(OM::write(cb, itf2));
std::string bond_name = "bond";
bond_interface bond_itf(bond_name, interface::admin_state_t::UP,
bond_interface::mode_t::LACP);
HW::item<handle_t> hw_ifh3(6, rc_t::OK);
ADD_EXPECT(bond_interface_cmds::create_cmd(hw_ifh3, bond_name,
bond_interface::mode_t::LACP, bond_interface::lb_t::L2, l2_address_t::ZERO));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh3));
TRY_CHECK_RC(OM::write(cb, bond_itf));
bond_member *bm1 = new bond_member(itf1, bond_member::mode_t::ACTIVE,
bond_member::rate_t::SLOW);
bond_member *bm2 = new bond_member(itf2, bond_member::mode_t::ACTIVE,
bond_member::rate_t::SLOW);
bond_group_binding *bgb = new bond_group_binding(bond_itf, {*bm1, *bm2});
HW::item<bool> bond_hw_bind(true, rc_t::OK);
ADD_EXPECT(bond_group_binding_cmds::bind_cmd(bond_hw_bind, hw_ifh3.data(), *bm1));
ADD_EXPECT(bond_group_binding_cmds::bind_cmd(bond_hw_bind, hw_ifh3.data(), *bm2));
TRY_CHECK_RC(OM::write(cb, *bgb));
delete bgb;
delete bm2;
delete bm1;
STRICT_ORDER_OFF();
HW::item<interface::admin_state_t> hw_as_down(interface::admin_state_t::DOWN, rc_t::OK);
ADD_EXPECT(bond_group_binding_cmds::unbind_cmd(bond_hw_bind, hw_ifh.data()));
ADD_EXPECT(bond_group_binding_cmds::unbind_cmd(bond_hw_bind, hw_ifh2.data()));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh2));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh2, itf2_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh3));
ADD_EXPECT(bond_interface_cmds::delete_cmd(hw_ifh3));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name));
TRY_CHECK(OM::remove(cb));
}
BOOST_AUTO_TEST_CASE(test_bridge) {
VppInit vi;
const std::string franz = "FranzKafka";
const std::string dante = "Dante";
const std::string jkr = "jkrowling";
rc_t rc = rc_t::OK;
/*
* Franz creates an interface, Bridge-domain, then binds the two
*/
// interface create
std::string itf1_name = "afpacket1";
interface itf1(itf1_name,
interface::type_t::AFPACKET,
interface::admin_state_t::UP);
HW::item<handle_t> hw_ifh(3, rc_t::OK);
HW::item<interface::admin_state_t> hw_as_up(interface::admin_state_t::UP,
rc_t::OK);
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh));
TRY_CHECK_RC(OM::write(franz, itf1));
// bridge-domain create
bridge_domain bd1(33);
HW::item<uint32_t> hw_bd(33, rc_t::OK);
ADD_EXPECT(bridge_domain_cmds::create_cmd(hw_bd,
bridge_domain::learning_mode_t::ON,
bridge_domain::arp_term_mode_t::ON,
bridge_domain::flood_mode_t::ON,
bridge_domain::mac_age_mode_t::OFF));
TRY_CHECK_RC(OM::write(franz, bd1));
// L2-interface create and bind
// this needs to be delete'd before the flush below, since it too maintains
// references to the BD and Interface
l2_binding *l2itf = new l2_binding(itf1, bd1);
HW::item<bool> hw_l2_bind(true, rc_t::OK);
ADD_EXPECT(l2_binding_cmds::bind_cmd(hw_l2_bind,
hw_ifh.data(),
hw_bd.data(),
l2_binding::l2_port_type_t::L2_PORT_TYPE_NORMAL));
TRY_CHECK_RC(OM::write(franz, *l2itf));
/*
* Dante adds an interface to the same BD
*/
std::string itf2_name = "afpacket2";
interface itf2(itf2_name,
interface::type_t::AFPACKET,
interface::admin_state_t::UP);
HW::item<handle_t> hw_ifh2(4, rc_t::OK);
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh2, itf2_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh2));
TRY_CHECK_RC(OM::write(dante, itf2));
// BD add is a no-op since it exists
TRY_CHECK_RC(OM::write(dante, bd1));
l2_binding *l2itf2 = new l2_binding(itf2, bd1);
HW::item<l2_binding::l2_vtr_op_t> hw_set_vtr(l2_binding::l2_vtr_op_t::L2_VTR_POP_1, rc_t::OK);
l2itf2->set(l2_binding::l2_vtr_op_t::L2_VTR_POP_1, 68);
ADD_EXPECT(l2_binding_cmds::bind_cmd(hw_l2_bind,
hw_ifh2.data(),
hw_bd.data(),
l2_binding::l2_port_type_t::L2_PORT_TYPE_NORMAL));
ADD_EXPECT(l2_binding_cmds::set_vtr_op_cmd(hw_set_vtr, hw_ifh2.data(), 68));
TRY_CHECK_RC(OM::write(dante, *l2itf2));
// Add some static entries to the bridge-domain
HW::item<bool> hw_be1(true, rc_t::OK);
mac_address_t mac1({0,1,2,3,4,5});
bridge_domain_entry *be1 = new bridge_domain_entry(bd1, mac1, itf2);
ADD_EXPECT(bridge_domain_entry_cmds::create_cmd(hw_be1, mac1, bd1.id(), hw_ifh2.data(),
false));
TRY_CHECK_RC(OM::write(dante, *be1));
// Add some entries to the bridge-domain ARP termination table
HW::item<bool> hw_bea1(true, rc_t::OK);
boost::asio::ip::address ip1 = boost::asio::ip::address::from_string("10.10.10.10");
bridge_domain_arp_entry *bea1 = new bridge_domain_arp_entry(bd1, ip1, mac1);
ADD_EXPECT(bridge_domain_arp_entry_cmds::create_cmd(hw_be1, bd1.id(), mac1, ip1));
TRY_CHECK_RC(OM::write(dante, *bea1));
// flush Franz's state
delete l2itf;
HW::item<interface::admin_state_t> hw_as_down(interface::admin_state_t::DOWN,
rc_t::OK);
ADD_EXPECT(l2_binding_cmds::unbind_cmd(hw_l2_bind,
hw_ifh.data(),
hw_bd.data(),
l2_binding::l2_port_type_t::L2_PORT_TYPE_NORMAL));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name));
TRY_CHECK(OM::remove(franz));
// flush Dante's state - the order the interface and BD are deleted
// is an uncontrollable artifact of the C++ object destruction.
delete l2itf2;
delete be1;
delete bea1;
STRICT_ORDER_OFF();
ADD_EXPECT(bridge_domain_arp_entry_cmds::delete_cmd(hw_be1, bd1.id(), mac1, ip1));
ADD_EXPECT(bridge_domain_entry_cmds::delete_cmd(hw_be1, mac1, bd1.id(), false));
ADD_EXPECT(l2_binding_cmds::unbind_cmd(hw_l2_bind,
hw_ifh2.data(),
hw_bd.data(),
l2_binding::l2_port_type_t::L2_PORT_TYPE_NORMAL));
ADD_EXPECT(bridge_domain_cmds::delete_cmd(hw_bd));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh2));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh2, itf2_name));
TRY_CHECK(OM::remove(dante));
// test the BVI entry in l2fib
bridge_domain bd2(99);
HW::item<uint32_t> hw_bd2(99, rc_t::OK);
ADD_EXPECT(bridge_domain_cmds::create_cmd(hw_bd2,
bridge_domain::learning_mode_t::ON,
bridge_domain::arp_term_mode_t::ON,
bridge_domain::flood_mode_t::ON,
bridge_domain::mac_age_mode_t::OFF));
TRY_CHECK_RC(OM::write(jkr, bd2));
std::string itf3_name = "bvi";
interface itf3(itf3_name,
interface::type_t::BVI,
interface::admin_state_t::UP);
HW::item<handle_t> hw_ifh3(5, rc_t::OK);
ADD_EXPECT(interface_cmds::loopback_create_cmd(hw_ifh3, itf3_name));
ADD_EXPECT(interface_cmds::set_tag(hw_ifh3, itf3_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh3));
TRY_CHECK_RC(OM::write(jkr, itf3));
l2_binding *l2itf3 = new l2_binding(itf3, bd2);
ADD_EXPECT(l2_binding_cmds::bind_cmd(hw_l2_bind,
hw_ifh3.data(),
hw_bd2.data(),
l2_binding::l2_port_type_t::L2_PORT_TYPE_BVI));
TRY_CHECK_RC(OM::write(jkr, *l2itf3));
HW::item<bool> hw_be2(true, rc_t::OK);
mac_address_t mac2({0,1,2,3,4,5});
bridge_domain_entry *be2 = new bridge_domain_entry(bd2, mac2, itf3);
ADD_EXPECT(bridge_domain_entry_cmds::create_cmd(hw_be2, mac2, bd2.id(), hw_ifh3.data(), true));
TRY_CHECK_RC(OM::write(jkr, *be2));
delete l2itf3;
delete be2;
STRICT_ORDER_OFF();
ADD_EXPECT(l2_binding_cmds::unbind_cmd(hw_l2_bind,
hw_ifh3.data(),
hw_bd2.data(),
l2_binding::l2_port_type_t::L2_PORT_TYPE_BVI));
ADD_EXPECT(bridge_domain_entry_cmds::delete_cmd(hw_be2, mac2, bd2.id(), true));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh3));
ADD_EXPECT(interface_cmds::loopback_delete_cmd(hw_ifh3));
ADD_EXPECT(bridge_domain_cmds::delete_cmd(hw_bd2));
TRY_CHECK(OM::remove(jkr));
}
BOOST_AUTO_TEST_CASE(test_l2_xconnect) {
VppInit vi;
const std::string nicholas = "NicholasAbercrombie";
rc_t rc = rc_t::OK;
/*
* Interface 1
*/
std::string itf1_name = "host1";
interface itf1(itf1_name,
interface::type_t::AFPACKET,
interface::admin_state_t::UP);
HW::item<handle_t> hw_ifh(2, rc_t::OK);
HW::item<interface::admin_state_t> hw_as_up(interface::admin_state_t::UP, rc_t::OK);
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh));
TRY_CHECK_RC(OM::write(nicholas, itf1));
/*
* Interface 2
*/
std::string itf2_name = "host2";
interface itf2(itf2_name,
interface::type_t::AFPACKET,
interface::admin_state_t::UP);
HW::item<handle_t> hw_ifh2(4, rc_t::OK);
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh2, itf2_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh2));
TRY_CHECK_RC(OM::write(nicholas, itf2));
l2_xconnect *l2_xconn = new l2_xconnect(itf1, itf2);
HW::item<bool> xconnect_east(true, rc_t::OK);
HW::item<bool> xconnect_west(true, rc_t::OK);
HW::item<bool> xconnect_east_unbind(false, rc_t::OK);
HW::item<bool> xconnect_west_unbind(false, rc_t::OK);
ADD_EXPECT(l2_xconnect_cmds::bind_cmd(xconnect_east, hw_ifh.data(), hw_ifh2.data()));
ADD_EXPECT(l2_xconnect_cmds::bind_cmd(xconnect_west, hw_ifh2.data(), hw_ifh.data()));
TRY_CHECK_RC(OM::write(nicholas, *l2_xconn));
delete l2_xconn;
HW::item<interface::admin_state_t> hw_as_down(interface::admin_state_t::DOWN, rc_t::OK);
STRICT_ORDER_OFF();
ADD_EXPECT(l2_xconnect_cmds::unbind_cmd(xconnect_east_unbind, hw_ifh.data(), hw_ifh2.data()));
ADD_EXPECT(l2_xconnect_cmds::unbind_cmd(xconnect_west_unbind, hw_ifh2.data(), hw_ifh.data()));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh2));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh2, itf2_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name));
TRY_CHECK(OM::remove(nicholas));
}
BOOST_AUTO_TEST_CASE(test_vxlan) {
VppInit vi;
const std::string franz = "FranzKafka";
rc_t rc = rc_t::OK;
/*
* Franz creates an interface, Bridge-domain, then binds the two
*/
// VXLAN create
vxlan_tunnel::endpoint_t ep(boost::asio::ip::address::from_string("10.10.10.10"),
boost::asio::ip::address::from_string("10.10.10.11"),
322);
vxlan_tunnel vxt(ep.src, ep.dst, ep.vni);
HW::item<handle_t> hw_vxt(3, rc_t::OK);
ADD_EXPECT(vxlan_tunnel_cmds::create_cmd(hw_vxt, "don't-care", ep));
TRY_CHECK_RC(OM::write(franz, vxt));
// bridge-domain create
bridge_domain bd1(33, bridge_domain::learning_mode_t::OFF,
bridge_domain::arp_term_mode_t::OFF,
bridge_domain::flood_mode_t::OFF,
bridge_domain::mac_age_mode_t::ON);
HW::item<uint32_t> hw_bd(33, rc_t::OK);
ADD_EXPECT(bridge_domain_cmds::create_cmd(hw_bd,
bridge_domain::learning_mode_t::OFF,
bridge_domain::arp_term_mode_t::OFF,
bridge_domain::flood_mode_t::OFF,
bridge_domain::mac_age_mode_t::ON));
TRY_CHECK_RC(OM::write(franz, bd1));
// L2-interface create and bind
// this needs to be delete'd before the flush below, since it too maintains
// references to the BD and Interface
l2_binding *l2itf = new l2_binding(vxt, bd1);
HW::item<bool> hw_l2_bind(true, rc_t::OK);
ADD_EXPECT(l2_binding_cmds::bind_cmd(hw_l2_bind,
hw_vxt.data(),
hw_bd.data(),
l2_binding::l2_port_type_t::L2_PORT_TYPE_NORMAL));
TRY_CHECK_RC(OM::write(franz, *l2itf));
// flush Franz's state
delete l2itf;
HW::item<handle_t> hw_vxtdel(3, rc_t::NOOP);
STRICT_ORDER_OFF();
ADD_EXPECT(l2_binding_cmds::unbind_cmd(hw_l2_bind,
hw_vxt.data(),
hw_bd.data(),
l2_binding::l2_port_type_t::L2_PORT_TYPE_NORMAL));
ADD_EXPECT(bridge_domain_cmds::delete_cmd(hw_bd));
ADD_EXPECT(vxlan_tunnel_cmds::delete_cmd(hw_vxtdel, ep));
TRY_CHECK(OM::remove(franz));
}
BOOST_AUTO_TEST_CASE(test_vlan) {
VppInit vi;
const std::string noam = "NoamChomsky";
rc_t rc = rc_t::OK;
std::string itf1_name = "host1";
interface itf1(itf1_name,
interface::type_t::AFPACKET,
interface::admin_state_t::UP);
HW::item<handle_t> hw_ifh(2, rc_t::OK);
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name));
HW::item<interface::admin_state_t> hw_as_up(interface::admin_state_t::UP, rc_t::OK);
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh));
TRY_CHECK_RC(OM::write(noam, itf1));
sub_interface *vl33 = new sub_interface(itf1,
interface::admin_state_t::UP,
33);
HW::item<handle_t> hw_vl33(3, rc_t::OK);
ADD_EXPECT(sub_interface_cmds::create_cmd(hw_vl33, itf1_name+".33", hw_ifh.data(), 33));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_vl33));
TRY_CHECK_RC(OM::write(noam, *vl33));
delete vl33;
HW::item<interface::admin_state_t> hw_as_down(interface::admin_state_t::DOWN, rc_t::OK);
HW::item<handle_t> hw_vl33_down(3, rc_t::NOOP);
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_vl33));
ADD_EXPECT(sub_interface_cmds::delete_cmd(hw_vl33_down));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name));
TRY_CHECK(OM::remove(noam));
}
BOOST_AUTO_TEST_CASE(test_acl) {
VppInit vi;
const std::string fyodor = "FyodorDostoyevsky";
const std::string leo = "LeoTolstoy";
rc_t rc = rc_t::OK;
/*
* Fyodor adds an ACL in the input direction
*/
std::string itf1_name = "host1";
interface itf1(itf1_name,
interface::type_t::AFPACKET,
interface::admin_state_t::UP);
HW::item<handle_t> hw_ifh(2, rc_t::OK);
HW::item<interface::admin_state_t> hw_as_up(interface::admin_state_t::UP, rc_t::OK);
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh));
TRY_CHECK_RC(OM::write(fyodor, itf1));
ACL::ethertype_rule_t e1(ethertype_t::ARP, direction_t::INPUT);
ACL::ethertype_rule_t e2(ethertype_t::ARP, direction_t::OUTPUT);
ACL::ethertype_rule_t e3(ethertype_t::IPV4, direction_t::INPUT);
ACL::acl_ethertype::ethertype_rules_t l_e = {e1, e2, e3};
ACL::acl_ethertype *a_e = new ACL::acl_ethertype(itf1, l_e);
HW::item<bool> ae_binding(true, rc_t::OK);
ADD_EXPECT(ACL::acl_ethertype_cmds::bind_cmd(ae_binding, hw_ifh.data(), l_e));
TRY_CHECK_RC(OM::write(fyodor, *a_e));
route::prefix_t src("10.10.10.10", 32);
ACL::l3_rule r1(10, ACL::action_t::PERMIT, src, route::prefix_t::ZERO);
ACL::l3_rule r2(20, ACL::action_t::DENY, route::prefix_t::ZERO, route::prefix_t::ZERO);
std::string acl_name = "acl1";
ACL::l3_list acl1(acl_name);
acl1.insert(r2);
acl1.insert(r1);
ACL::l3_list::rules_t rules = {r1, r2};
HW::item<handle_t> hw_acl(2, rc_t::OK);
ADD_EXPECT(ACL::list_cmds::l3_update_cmd(hw_acl, acl_name, rules));
TRY_CHECK_RC(OM::write(fyodor, acl1));
ACL::l3_rule r3(30, ACL::action_t::PERMIT, route::prefix_t::ZERO, route::prefix_t::ZERO);
ACL::l3_list acl2(acl_name);
acl2.insert(r3);
ACL::l3_list::rules_t rules2 = {r3};
ADD_EXPECT(ACL::list_cmds::l3_update_cmd(hw_acl, acl_name, rules2));
TRY_CHECK_RC(OM::write(fyodor, acl2));
ACL::l3_binding *l3b = new ACL::l3_binding(direction_t::INPUT, itf1, acl1);
HW::item<bool> hw_binding(true, rc_t::OK);
ADD_EXPECT(ACL::binding_cmds::l3_bind_cmd(hw_binding, direction_t::INPUT,
hw_ifh.data(), hw_acl.data()));
TRY_CHECK_RC(OM::write(fyodor, *l3b));
/**
* Leo adds an L2 ACL in the output direction
*/
TRY_CHECK_RC(OM::write(leo, itf1));
std::string l2_acl_name = "l2_acl1";
mac_address_t mac({0x0, 0x0, 0x1, 0x2, 0x3, 0x4});
mac_address_t mac_mask({0xff, 0xff, 0xff, 0x0, 0x0, 0x0});
ACL::l2_rule l2_r1(10, ACL::action_t::PERMIT, src, mac, mac_mask);
ACL::l2_rule l2_r2(20, ACL::action_t::DENY, src, {}, {});
ACL::l2_list l2_acl(l2_acl_name);
l2_acl.insert(l2_r2);
l2_acl.insert(l2_r1);
ACL::l2_list::rules_t l2_rules = {l2_r1, l2_r2};
HW::item<handle_t> l2_hw_acl(3, rc_t::OK);
ADD_EXPECT(ACL::list_cmds::l2_update_cmd(l2_hw_acl, l2_acl_name, l2_rules));
TRY_CHECK_RC(OM::write(leo, l2_acl));
ACL::l2_binding *l2b = new ACL::l2_binding(direction_t::OUTPUT, itf1, l2_acl);
HW::item<bool> l2_hw_binding(true, rc_t::OK);
ADD_EXPECT(ACL::binding_cmds::l2_bind_cmd(l2_hw_binding, direction_t::OUTPUT,
hw_ifh.data(), l2_hw_acl.data()));
TRY_CHECK_RC(OM::write(leo, *l2b));
delete l2b;
ADD_EXPECT(ACL::binding_cmds::l2_unbind_cmd(l2_hw_binding, direction_t::OUTPUT,
hw_ifh.data(), l2_hw_acl.data()));
ADD_EXPECT(ACL::list_cmds::l2_delete_cmd(l2_hw_acl));
TRY_CHECK(OM::remove(leo));
delete l3b;
delete a_e;
HW::item<interface::admin_state_t> hw_as_down(interface::admin_state_t::DOWN,
rc_t::OK);
STRICT_ORDER_OFF();
ADD_EXPECT(ACL::binding_cmds::l3_unbind_cmd(hw_binding, direction_t::INPUT,
hw_ifh.data(), hw_acl.data()));
ADD_EXPECT(ACL::list_cmds::l3_delete_cmd(hw_acl));
ADD_EXPECT(ACL::acl_ethertype_cmds::unbind_cmd(ae_binding, hw_ifh.data()));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name));
TRY_CHECK(OM::remove(fyodor));
}
BOOST_AUTO_TEST_CASE(test_igmp) {
VppInit vi;
const std::string Isaiah = "IsaiahBerlin";
rc_t rc = rc_t::OK;
boost::asio::ip::address gaddr = boost::asio::ip::address::from_string("232.0.0.1");
boost::asio::ip::address saddr1 = boost::asio::ip::address::from_string("192.168.0.20");
boost::asio::ip::address saddr2 = boost::asio::ip::address::from_string("192.168.0.30");
std::string itf3_name = "host3";
interface itf3(itf3_name,
interface::type_t::AFPACKET,
interface::admin_state_t::UP);
HW::item<handle_t> hw_ifh(2, rc_t::OK);
HW::item<interface::admin_state_t> hw_as_up(interface::admin_state_t::UP, rc_t::OK);
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf3_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh));
TRY_CHECK_RC(OM::write(Isaiah, itf3));
igmp_binding *ib = new igmp_binding(itf3);
HW::item<bool> hw_binding(true, rc_t::OK);
ADD_EXPECT(igmp_binding_cmds::bind_cmd(hw_binding, hw_ifh.data()));
TRY_CHECK_RC(OM::write(Isaiah, *ib));
igmp_listen::src_addrs_t saddrs = {saddr1, saddr2};
igmp_listen *il = new igmp_listen(*ib, gaddr, saddrs);
HW::item<bool> hw_as_listen(true, rc_t::OK);
ADD_EXPECT(igmp_listen_cmds::listen_cmd(hw_as_listen, hw_ifh.data(), gaddr, saddrs));
TRY_CHECK_RC(OM::write(Isaiah, *il));
delete il;
delete ib;
HW::item<interface::admin_state_t> hw_as_down(interface::admin_state_t::DOWN,
rc_t::OK);
STRICT_ORDER_OFF();
ADD_EXPECT(igmp_listen_cmds::unlisten_cmd(hw_as_listen, hw_ifh.data(), gaddr));
ADD_EXPECT(igmp_binding_cmds::unbind_cmd(hw_binding, hw_ifh.data()));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf3_name));
TRY_CHECK(OM::remove(Isaiah));
}
BOOST_AUTO_TEST_CASE(test_arp_proxy) {
VppInit vi;
const std::string kurt = "KurtVonnegut";
rc_t rc = rc_t::OK;
asio::ip::address_v4 low = asio::ip::address_v4::from_string("10.0.0.0");
asio::ip::address_v4 high = asio::ip::address_v4::from_string("10.0.0.255");
arp_proxy_config ap(low, high);
HW::item<bool> hw_ap_cfg(true, rc_t::OK);
ADD_EXPECT(arp_proxy_config_cmds::config_cmd(hw_ap_cfg, low, high));
TRY_CHECK_RC(OM::write(kurt, ap));
std::string itf3_name = "host3";
interface itf3(itf3_name,
interface::type_t::AFPACKET,
interface::admin_state_t::UP);
HW::item<handle_t> hw_ifh(2, rc_t::OK);
HW::item<interface::admin_state_t> hw_as_up(interface::admin_state_t::UP, rc_t::OK);
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf3_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh));
TRY_CHECK_RC(OM::write(kurt, itf3));
arp_proxy_binding *apb = new arp_proxy_binding(itf3);
HW::item<bool> hw_binding(true, rc_t::OK);
ADD_EXPECT(arp_proxy_binding_cmds::bind_cmd(hw_binding, hw_ifh.data()));
TRY_CHECK_RC(OM::write(kurt, *apb));
delete apb;
HW::item<interface::admin_state_t> hw_as_down(interface::admin_state_t::DOWN,
rc_t::OK);
STRICT_ORDER_OFF();
ADD_EXPECT(arp_proxy_binding_cmds::unbind_cmd(hw_binding, hw_ifh.data()));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf3_name));
ADD_EXPECT(arp_proxy_config_cmds::unconfig_cmd(hw_ap_cfg, low, high));
TRY_CHECK(OM::remove(kurt));
}
BOOST_AUTO_TEST_CASE(test_ip_punt_redirect) {
VppInit vi;
const std::string eliot = "EliotReed";
rc_t rc = rc_t::OK;
/*
* Interface 1 is the tx interface
*/
std::string itf1_name = "tx-itf";
interface itf1(itf1_name,
interface::type_t::AFPACKET,
interface::admin_state_t::UP);
HW::item<handle_t> hw_ifh(2, rc_t::OK);
HW::item<interface::admin_state_t> hw_as_up(interface::admin_state_t::UP, rc_t::OK);
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh));
TRY_CHECK_RC(OM::write(eliot, itf1));
boost::asio::ip::address addr = boost::asio::ip::address::from_string("192.168.0.20");
/*
* Interface 2 is the rx interface
*/
std::string itf2_name = "rx-itf";
interface itf2(itf2_name,
interface::type_t::AFPACKET,
interface::admin_state_t::UP);
HW::item<handle_t> hw_ifh2(4, rc_t::OK);
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh2, itf2_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh2));
TRY_CHECK_RC(OM::write(eliot, itf2));
ip_punt_redirect *ip_punt = new ip_punt_redirect(itf2, itf1, addr);
HW::item<bool> hw_ip_cfg(true, rc_t::OK);
HW::item<bool> hw_ip_uncfg(false, rc_t::OK);
ADD_EXPECT(ip_punt_redirect_cmds::config_cmd(hw_ip_cfg, hw_ifh2.data(), hw_ifh.data(), addr));
TRY_CHECK_RC(OM::write(eliot, *ip_punt));
delete ip_punt;
HW::item<interface::admin_state_t> hw_as_down(interface::admin_state_t::DOWN, rc_t::OK);
STRICT_ORDER_OFF();
ADD_EXPECT(ip_punt_redirect_cmds::unconfig_cmd(hw_ip_uncfg, hw_ifh2.data(), hw_ifh.data(), addr));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh2));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh2, itf2_name));
TRY_CHECK(OM::remove(eliot));
}
BOOST_AUTO_TEST_CASE(test_ip_unnumbered) {
VppInit vi;
const std::string eric = "EricAmbler";
rc_t rc = rc_t::OK;
/*
* Interface 1 has the L3 address
*/
std::string itf1_name = "host1";
interface itf1(itf1_name,
interface::type_t::AFPACKET,
interface::admin_state_t::UP);
HW::item<handle_t> hw_ifh(2, rc_t::OK);
HW::item<interface::admin_state_t> hw_as_up(interface::admin_state_t::UP, rc_t::OK);
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh));
TRY_CHECK_RC(OM::write(eric, itf1));
route::prefix_t pfx_10("10.10.10.10", 24);
l3_binding *l3 = new l3_binding(itf1, pfx_10);
HW::item<bool> hw_l3_bind(true, rc_t::OK);
HW::item<bool> hw_l3_unbind(false, rc_t::OK);
ADD_EXPECT(l3_binding_cmds::bind_cmd(hw_l3_bind, hw_ifh.data(), pfx_10));
TRY_CHECK_RC(OM::write(eric, *l3));
/*
* Interface 2 is unnumbered
*/
std::string itf2_name = "host2";
interface itf2(itf2_name,
interface::type_t::AFPACKET,
interface::admin_state_t::UP);
HW::item<handle_t> hw_ifh2(4, rc_t::OK);
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh2, itf2_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh2));
TRY_CHECK_RC(OM::write(eric, itf2));
ip_unnumbered *ipun = new ip_unnumbered(itf2, itf1);
HW::item<bool> hw_ip_cfg(true, rc_t::OK);
HW::item<bool> hw_ip_uncfg(false, rc_t::OK);
ADD_EXPECT(ip_unnumbered_cmds::config_cmd(hw_ip_cfg, hw_ifh2.data(), hw_ifh.data()));
TRY_CHECK_RC(OM::write(eric, *ipun));
delete l3;
delete ipun;
HW::item<interface::admin_state_t> hw_as_down(interface::admin_state_t::DOWN, rc_t::OK);
STRICT_ORDER_OFF();
ADD_EXPECT(ip_unnumbered_cmds::unconfig_cmd(hw_ip_uncfg, hw_ifh2.data(), hw_ifh.data()));
ADD_EXPECT(l3_binding_cmds::unbind_cmd(hw_l3_unbind, hw_ifh.data(), pfx_10));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh2));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh2, itf2_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name));
TRY_CHECK(OM::remove(eric));
}
BOOST_AUTO_TEST_CASE(test_ip6nd) {
VppInit vi;
const std::string paulo = "PauloCoelho";
rc_t rc = rc_t::OK;
/*
* ra config
*/
std::string itf_name = "host_ip6nd";
interface itf(itf_name,
interface::type_t::AFPACKET,
interface::admin_state_t::UP);
HW::item<handle_t> hw_ifh(3, rc_t::OK);
HW::item<interface::admin_state_t> hw_as_up(interface::admin_state_t::UP, rc_t::OK);
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh));
TRY_CHECK_RC(OM::write(paulo, itf));
route::prefix_t pfx_10("fd8f:69d8:c12c:ca62::3", 128);
l3_binding *l3 = new l3_binding(itf, pfx_10);
HW::item<bool> hw_l3_bind(true, rc_t::OK);
HW::item<bool> hw_l3_unbind(false, rc_t::OK);
ADD_EXPECT(l3_binding_cmds::bind_cmd(hw_l3_bind, hw_ifh.data(), pfx_10));
TRY_CHECK_RC(OM::write(paulo, *l3));
ra_config ra(0, 1, 0, 4);
ip6nd_ra_config *ip6ra = new ip6nd_ra_config(itf, ra);
HW::item<bool> hw_ip6nd_ra_config_config(true, rc_t::OK);
HW::item<bool> hw_ip6nd_ra_config_unconfig(false, rc_t::OK);
ADD_EXPECT(ip6nd_ra_config::config_cmd(hw_ip6nd_ra_config_config, hw_ifh.data(), ra));
TRY_CHECK_RC(OM::write(paulo, *ip6ra));
/*
* ra prefix
*/
ra_prefix ra_pfx(pfx_10, 0, 0, 2592000, 604800);
ip6nd_ra_prefix *ip6pfx = new ip6nd_ra_prefix(itf, ra_pfx);
HW::item<bool> hw_ip6nd_ra_prefix_config(true, rc_t::OK);
HW::item<bool> hw_ip6nd_ra_prefix_unconfig(false, rc_t::OK);
ADD_EXPECT(ip6nd_ra_prefix::config_cmd(hw_ip6nd_ra_prefix_config, hw_ifh.data(), ra_pfx));
TRY_CHECK_RC(OM::write(paulo, *ip6pfx));
delete ip6pfx;
ADD_EXPECT(ip6nd_ra_prefix::unconfig_cmd(hw_ip6nd_ra_prefix_unconfig, hw_ifh.data(), ra_pfx));
delete ip6ra;
delete l3;
HW::item<interface::admin_state_t> hw_as_down(interface::admin_state_t::DOWN, rc_t::OK);
STRICT_ORDER_OFF();
ADD_EXPECT(ip6nd_ra_config::unconfig_cmd(hw_ip6nd_ra_config_unconfig, hw_ifh.data(), ra));
ADD_EXPECT(l3_binding_cmds::unbind_cmd(hw_l3_unbind, hw_ifh.data(), pfx_10));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf_name));
TRY_CHECK(OM::remove(paulo));
}
BOOST_AUTO_TEST_CASE(test_interface_span) {
VppInit vi;
const std::string elif = "ElifShafak";
rc_t rc = rc_t::OK;
/*
* Interface 1 to be mirrored
*/
std::string itf1_name = "port-from";
interface itf1(itf1_name,
interface::type_t::AFPACKET,
interface::admin_state_t::UP);
HW::item<handle_t> hw_ifh(2, rc_t::OK);
HW::item<interface::admin_state_t> hw_as_up(interface::admin_state_t::UP, rc_t::OK);
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh));
TRY_CHECK_RC(OM::write(elif, itf1));
/*
* Interface 2 where traffic is mirrored
*/
std::string itf2_name = "port-to";
interface itf2(itf2_name,
interface::type_t::AFPACKET,
interface::admin_state_t::UP);
HW::item<handle_t> hw_ifh2(4, rc_t::OK);
HW::item<interface::admin_state_t> hw_as_up2(interface::admin_state_t::UP, rc_t::OK);
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh2, itf2_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up2, hw_ifh2));
TRY_CHECK_RC(OM::write(elif, itf2));
interface_span *itf_span = new interface_span(itf1, itf2, interface_span::state_t::TX_RX_ENABLED);
HW::item<bool> hw_is_cfg(true, rc_t::OK);
HW::item<bool> hw_is_uncfg(true, rc_t::OK);
ADD_EXPECT(interface_span_cmds::config_cmd(hw_is_cfg, hw_ifh.data(), hw_ifh2.data(), interface_span::state_t::TX_RX_ENABLED));
TRY_CHECK_RC(OM::write(elif, *itf_span));
HW::item<interface::admin_state_t> hw_as_down(interface::admin_state_t::DOWN, rc_t::OK);
HW::item<interface::admin_state_t> hw_as_down2(interface::admin_state_t::DOWN, rc_t::OK);
delete itf_span;
STRICT_ORDER_OFF();
ADD_EXPECT(interface_span_cmds::unconfig_cmd(hw_is_uncfg, hw_ifh.data(), hw_ifh2.data()));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down2, hw_ifh2));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh2, itf2_name));
TRY_CHECK(OM::remove(elif));
}
BOOST_AUTO_TEST_CASE(test_routing) {
VppInit vi;
const std::string ian = "IanFleming";
rc_t rc = rc_t::OK;
/*
* non-default route domain
*/
route_domain rd4(1);
HW::item<bool> hw_rd4_create(true, rc_t::OK);
HW::item<bool> hw_rd4_delete(false, rc_t::OK);
HW::item<bool> hw_rd6_create(true, rc_t::OK);
HW::item<bool> hw_rd6_delete(false, rc_t::OK);
HW::item<route::table_id_t> hw_rd4_bind(1, rc_t::OK);
HW::item<route::table_id_t> hw_rd4_unbind(route::DEFAULT_TABLE, rc_t::OK);
HW::item<route::table_id_t> hw_rd6_bind(1, rc_t::OK);
HW::item<route::table_id_t> hw_rd7_unbind(route::DEFAULT_TABLE, rc_t::OK);
ADD_EXPECT(route_domain_cmds::create_cmd(hw_rd4_create, l3_proto_t::IPV4, 1));
ADD_EXPECT(route_domain_cmds::create_cmd(hw_rd6_create, l3_proto_t::IPV6, 1));
TRY_CHECK_RC(OM::write(ian, rd4));
/*
* a couple of interfaces
*/
std::string itf1_name = "af1";
interface itf1(itf1_name,
interface::type_t::AFPACKET,
interface::admin_state_t::UP);
HW::item<handle_t> hw_ifh(2, rc_t::OK);
HW::item<interface::admin_state_t> hw_as_up(interface::admin_state_t::UP, rc_t::OK);
HW::item<interface::admin_state_t> hw_as_down(interface::admin_state_t::DOWN, rc_t::OK);
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh));
TRY_CHECK_RC(OM::write(ian, itf1));
std::string itf2_name = "af2";
interface *itf2 = new interface(itf2_name,
interface::type_t::AFPACKET,
interface::admin_state_t::UP,
rd4);
HW::item<handle_t> hw_ifh2(4, rc_t::OK);
HW::item<interface::admin_state_t> hw_as_up2(interface::admin_state_t::UP, rc_t::OK);
HW::item<interface::admin_state_t> hw_as_down2(interface::admin_state_t::DOWN, rc_t::OK);
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh2, itf2_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up2, hw_ifh2));
ADD_EXPECT(interface_cmds::set_table_cmd(hw_rd4_bind, l3_proto_t::IPV4, hw_ifh2));
ADD_EXPECT(interface_cmds::set_table_cmd(hw_rd6_bind, l3_proto_t::IPV6, hw_ifh2));
TRY_CHECK_RC(OM::write(ian, *itf2));
/*
* prefix on each interface
*/
route::prefix_t pfx_10("10.10.10.10", 24);
l3_binding *l3_10 = new l3_binding(itf1, pfx_10);
HW::item<bool> hw_l3_10_bind(true, rc_t::OK);
HW::item<bool> hw_l3_10_unbind(false, rc_t::OK);
ADD_EXPECT(l3_binding_cmds::bind_cmd(hw_l3_10_bind, hw_ifh.data(), pfx_10));
TRY_CHECK_RC(OM::write(ian, *l3_10));
route::prefix_t pfx_11("11.11.11.11", 24);
l3_binding *l3_11 = new l3_binding(*itf2, pfx_11);
HW::item<bool> hw_l3_11_bind(true, rc_t::OK);
HW::item<bool> hw_l3_11_unbind(false, rc_t::OK);
ADD_EXPECT(l3_binding_cmds::bind_cmd(hw_l3_11_bind, hw_ifh2.data(), pfx_11));
TRY_CHECK_RC(OM::write(ian, *l3_11));
/*
* A route via interface 1 in the default table
*/
route::prefix_t pfx_5("5.5.5.5", 32);
boost::asio::ip::address nh_10 = boost::asio::ip::address::from_string("10.10.10.11");
route::path *path_10 = new route::path(nh_10, itf1);
route::ip_route *route_5 = new route::ip_route(pfx_5);
route_5->add(*path_10);
HW::item<bool> hw_route_5(true, rc_t::OK);
ADD_EXPECT(route::ip_route_cmds::update_cmd(hw_route_5, 0, pfx_5, {*path_10}));
TRY_CHECK_RC(OM::write(ian, *route_5));
/*
* A route via interface 2 in the non-default table
*/
boost::asio::ip::address nh_11 = boost::asio::ip::address::from_string("11.11.11.10");
route::path *path_11 = new route::path(nh_11, *itf2);
route::ip_route *route_5_2 = new route::ip_route(rd4, pfx_5);
route_5_2->add(*path_11);
HW::item<bool> hw_route_5_2(true, rc_t::OK);
ADD_EXPECT(route::ip_route_cmds::update_cmd(hw_route_5_2, 1, pfx_5, {*path_11}));
TRY_CHECK_RC(OM::write(ian, *route_5_2));
/*
* An ARP entry for the neighbour on itf1
*/
HW::item<bool> hw_neighbour(true, rc_t::OK);
mac_address_t mac_n({0,1,2,4,5,6});
neighbour *ne = new neighbour(itf1, nh_10, mac_n);
ADD_EXPECT(neighbour_cmds::create_cmd(hw_neighbour, hw_ifh.data(), mac_n, nh_10));
TRY_CHECK_RC(OM::write(ian, *ne));
/*
* A DVR route
*/
route::prefix_t pfx_6("6.6.6.6", 32);
route::path *path_l2 = new route::path(*itf2, nh_proto_t::ETHERNET);
route::ip_route *route_dvr = new route::ip_route(pfx_6);
route_dvr->add(*path_l2);
HW::item<bool> hw_route_dvr(true, rc_t::OK);
ADD_EXPECT(route::ip_route_cmds::update_cmd(hw_route_dvr, 0, pfx_6, {*path_l2}));
TRY_CHECK_RC(OM::write(ian, *route_dvr));
STRICT_ORDER_OFF();
// delete the stack objects that hold references to others
// so the OM::remove is the call that removes the last reference
delete l3_11;
delete l3_10;
delete itf2;
delete route_5;
delete path_10;
delete route_5_2;
delete path_11;
delete route_dvr;
delete path_l2;
delete ne;
ADD_EXPECT(neighbour_cmds::delete_cmd(hw_neighbour, hw_ifh.data(), mac_n, nh_10));
ADD_EXPECT(route::ip_route_cmds::delete_cmd(hw_route_dvr, 0, pfx_6));
ADD_EXPECT(route::ip_route_cmds::delete_cmd(hw_route_5_2, 1, pfx_5));
ADD_EXPECT(route::ip_route_cmds::delete_cmd(hw_route_5, 0, pfx_5));
ADD_EXPECT(l3_binding_cmds::unbind_cmd(hw_l3_10_unbind, hw_ifh.data(), pfx_10));
ADD_EXPECT(l3_binding_cmds::unbind_cmd(hw_l3_11_unbind, hw_ifh2.data(), pfx_11));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name));
ADD_EXPECT(interface_cmds::set_table_cmd(hw_rd4_unbind, l3_proto_t::IPV4, hw_ifh2));
ADD_EXPECT(interface_cmds::set_table_cmd(hw_rd4_unbind, l3_proto_t::IPV6, hw_ifh2));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down2, hw_ifh2));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh2, itf2_name));
ADD_EXPECT(route_domain_cmds::delete_cmd(hw_rd4_delete, l3_proto_t::IPV4, 1));
ADD_EXPECT(route_domain_cmds::delete_cmd(hw_rd6_delete, l3_proto_t::IPV6, 1));
TRY_CHECK(OM::remove(ian));
}
BOOST_AUTO_TEST_CASE(test_nat) {
VppInit vi;
const std::string gs = "GeorgeSimenon";
rc_t rc = rc_t::OK;
/*
* Inside Interface
*/
std::string itf_in_name = "inside";
interface itf_in(itf_in_name,
interface::type_t::AFPACKET,
interface::admin_state_t::UP);
HW::item<handle_t> hw_ifh(2, rc_t::OK);
HW::item<interface::admin_state_t> hw_as_up(interface::admin_state_t::UP, rc_t::OK);
HW::item<interface::admin_state_t> hw_as_down(interface::admin_state_t::DOWN, rc_t::OK);
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf_in_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh));
TRY_CHECK_RC(OM::write(gs, itf_in));
/*
* outside
*/
std::string itf_out_name = "port-to";
interface itf_out(itf_out_name,
interface::type_t::AFPACKET,
interface::admin_state_t::UP);
HW::item<handle_t> hw_ifh2(4, rc_t::OK);
HW::item<interface::admin_state_t> hw_as_up2(interface::admin_state_t::UP, rc_t::OK);
HW::item<interface::admin_state_t> hw_as_down2(interface::admin_state_t::DOWN, rc_t::OK);
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh2, itf_out_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up2, hw_ifh2));
TRY_CHECK_RC(OM::write(gs, itf_out));
/*
* A NAT static mapping
*/
boost::asio::ip::address in_addr = boost::asio::ip::address::from_string("10.0.0.1");
boost::asio::ip::address_v4 out_addr = boost::asio::ip::address_v4::from_string("1.1.1.1");
nat_static ns(in_addr, out_addr);
HW::item<bool> hw_ns(true, rc_t::OK);
ADD_EXPECT(nat_static_cmds::create_44_cmd(hw_ns, 0, in_addr.to_v4(), out_addr));
TRY_CHECK_RC(OM::write(gs, ns));
/*
* bind nat inside and out
*/
nat_binding *nb_in = new nat_binding(itf_in,
direction_t::INPUT,
l3_proto_t::IPV4,
nat_binding::zone_t::INSIDE);
HW::item<bool> hw_nb_in(true, rc_t::OK);
ADD_EXPECT(nat_binding_cmds::bind_44_input_cmd(hw_nb_in,
hw_ifh.data().value(),
nat_binding::zone_t::INSIDE));
TRY_CHECK_RC(OM::write(gs, *nb_in));
nat_binding *nb_out = new nat_binding(itf_out,
direction_t::INPUT,
l3_proto_t::IPV4,
nat_binding::zone_t::OUTSIDE);
HW::item<bool> hw_nb_out(true, rc_t::OK);
ADD_EXPECT(nat_binding_cmds::bind_44_input_cmd(hw_nb_out,
hw_ifh2.data().value(),
nat_binding::zone_t::OUTSIDE));
TRY_CHECK_RC(OM::write(gs, *nb_out));
STRICT_ORDER_OFF();
delete nb_in;
delete nb_out;
ADD_EXPECT(nat_binding_cmds::unbind_44_input_cmd(hw_nb_in,
hw_ifh.data().value(),
nat_binding::zone_t::INSIDE));
ADD_EXPECT(nat_binding_cmds::unbind_44_input_cmd(hw_nb_out,
hw_ifh2.data().value(),
nat_binding::zone_t::OUTSIDE));
ADD_EXPECT(nat_static_cmds::delete_44_cmd(hw_ns, 0, in_addr.to_v4(), out_addr));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf_in_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down2, hw_ifh2));
ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh2, itf_out_name));
TRY_CHECK(OM::remove(gs));
}
BOOST_AUTO_TEST_CASE(test_interface_events) {
VppInit vi;
MockListener ml;
HW::item<bool> hw_want(true, rc_t::OK);
ADD_EXPECT(interface_cmds::events_cmd(ml));
cmd* itf = new interface_cmds::events_cmd(ml);
HW::enqueue(itf);
HW::write();
}
BOOST_AUTO_TEST_CASE(test_interface_route_domain_change) {
VppInit vi;
const std::string rene = "ReneGoscinny";
rc_t rc = rc_t::OK;
/*
* Create an interface with two IP addresses
*/
std::string itf1_name = "host1";
interface itf1(itf1_name,
interface::type_t::AFPACKET,
interface::admin_state_t::UP);
HW::item<handle_t> hw_ifh1(2, rc_t::OK);
HW::item<interface::admin_state_t> hw_as_up(interface::admin_state_t::UP, rc_t::OK);
HW::item<interface::admin_state_t> hw_as_down(interface::admin_state_t::DOWN, rc_t::OK);
ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh1, itf1_name));
ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh1));
TRY_CHECK_RC(OM::write(rene, itf1));
route::prefix_t pfx_10("10.10.10.10", 24);
l3_binding *l3_1 = new l3_binding(itf1, pfx_10);
HW::item<bool> hw_l3_bind1(true, rc_t::OK);
HW::item<bool> hw_l3_unbind1(false, rc_t::OK);
ADD_EXPECT(l3_binding_cmds::bind_cmd(hw_l3_bind1, hw_ifh1.data(), pfx_10));
TRY_CHECK_RC(OM::write(rene, *l3_1));
route::prefix_t pfx_11("10.10.11.11", 24);
l3_binding *l3_2 = new l3_binding(itf1, pfx_11);
HW::item<bool> hw_l3_bind2(true, rc_t::OK);
HW::item<bool> hw_l3_unbind2(false, rc_t::OK);
ADD_EXPECT(l3_binding_cmds::bind_cmd(hw_l3_bind2, hw_ifh1.data(), pfx_11));
TRY_CHECK_RC(OM::write(rene, *l3_2));
route_domain rd(1);
HW::item<bool> hw_rd_create(true, rc_t::OK);
HW::item<bool> hw_rd_delete(false, rc_t::OK);
HW::item<route::table_id_t> hw_rd_bind(1, rc_t::OK);
HW::item<route::table_id_t> hw_rd_unbind(route::DEFAULT_TABLE, rc_t::OK);
ADD_EXPECT(route_domain_cmds::create_cmd(hw_rd_create, l3_proto_t::IPV4, 1));
ADD_EXPECT(route_domain_cmds::create_cmd(hw_rd_create, l3_proto_t::IPV6, 1));
TRY_CHECK_RC(OM::write(rene,