# Release Notes {#release_notes} * @subpage release_notes_2001 * @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_2001 Release notes for VPP 20.01 TBD @page release_notes_1908 Release notes for VPP 19.08 More than 850 commits since the 19.04 release. ## Features ### Infrastructure - API - API language: new types and limits support - Python API - add support for defaults - Export ip_types.api for out-of-tree plugins use - Refactor ipip.api with explicit types - DPDK - 19.05 integration - Remove bonding code - Rework extended stats - Debugging & Servicability - debug CLI leak-checker - vlib: add "memory-trace stats-segment" - vppapitrace JSON/API trace converter - ARP: add arp-disabled node - igmp: Trace more data from input packets - ip: Trace the packet from the punt node - Python API debug introspection improvements - Pin dependencies for make test infra - FEATURE.yaml meta-data infrastructure - tcp: add cc stats plotting tools - Packet tracer support for thread handoffs - libmemif: support for multi-thread connection establishment - svm - fifo ooo reads/writes with multiple chunks - support addition/removal of chunks to fifos - vppinfra - Mapped pcap file support - More AVX2 and AVX512 inlines - VLIB_INIT_FUNCTION sequencing rework - refactor spinlocks and rwlocks - add rbtree - add doubly linked list - rdma: bump rdma-core to v25.0 - stats - Add the number of worker threads and per worker thread vector rates - Support multiple workers for error counters ### VNET & Plugins - New Plugins - HTTP static page server with TLS support - L3 cross connect - acl: implement stat-segment counters - arp: add feature arcs: arp-reply, arp-input, arp-proxy - avf: improved logging and added 2.5/5 Gbps speeds - bonding: NUMA-related improvements - crypto: add support for AES-CTR cipher - fib - FIB Entry tracking - Support the POP of a Pseudo Wire Control Word - gbp - Anonymous l3-out subnets support - ARP unicast forward in gbp bridge domain - An Endpoint can change sclass - Consider data-plane learnt source better than control-plane - VRF scoped contracts - gso (experimental) - Add support to pg interfaces - Add support to vhost user - Add support to native virtio - Add support for tagged interfaces - punt: allow to specify packets by IP protocol Type - ip6-local: hop-by-hop protocol demux table - ipsec - intel-ipsec-mb version 0.52 - AH encrypt rework - handle UDP keepalives - support GCM in ESP - virtio - Refactor control queue support - dhcp-client: DSCP marking for transmitted packets - Idle resource usage improvements - Allocate bihash virtual space on demand - gre: don't register gre input nodes unless a gre tunnel is created - gtpu: don't register udp ports unless a tunnel is created - lacp: create lacp-process on demand - lisp-cp: start lisp retry service on demand - start the cdp period and dns resolver process on demand - vat: unload unused vat plugins - nat: api cleanup & update - nsim: make available as an output feature - load-balance performance improvements - l2: Add support for arp unicast forwarding - mactime - Mini-ACLs - Per-MAC allow-with-quota feature - qos - QoS dump APIs - Store function - rdma: add support for promiscuous mode (l2-switching and xconnect) - sr: update the Segment Routing definition to be compliant with current in IETF - udp-ping: disable due to conflict with mldv2 - vxlan-gpe: improve encap performance - vom - QoS support - Bridge domain arp unicast forwarding flag - Bridge domain unknown unicast flooding flag ### Host stack - session - API to support manual svm fifo resizing - Improved session output scheduler and close state machine - Transport and session cleanup notifications for builtin apps - Session migration notifications for builtin apps - Support for no session layer lookup transports (quic and tls) - Ability to retrieve local/remote endpoint in transport vft - Cleanup segment manager and fifo segment - Fix vpp to app msg generation on enqueue fail - Improve event logging - Moved test applications to hsa plugin - tcp - Congestion control algorithm enhancements - Delivery rate estimator - ACK/retransmission refactor and pacing - Add tcp-input sibling nodes without full 6-tuple lookup - More RFC4898 connection statistics - Allow custom output next node - Allow custom congestion control algorithms - quic - Multi-thread support - Logs readability improvements - Multistream support - tls - Fix close with data and listen failures - Handle TCP transport rests - Support endpoint retrieval interface - vcl - support quic streams and "connectable listeners" - worker unregister api - fix epoll with large events batch - ldp: add option to eanble transparent TLS connections - udp: - support close with data - fixed session migration - sctp - add option to enable/disable default to disable - moved from vnet to plugins ## Known issues For the full list of issues please refer to fd.io [JIRA](https://jira.fd.io). ## Issues fixed 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/1908) ## 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 -------------------------------------------------------------|------------------ abf_itf_attach_add_del | definition changed abf_itf_attach_details | definition changed abf_policy_add_del | definition changed abf_policy_details | definition changed acl_add_replace | definition changed acl_details | definition changed acl_stats_intf_counters_enable | only in image acl_stats_intf_counters_enable_reply | only in image api_versions_reply | definition changed bd_ip_mac_add_del | definition changed bd_ip_mac_details | definition changed bier_disp_entry_add_del | definition changed bier_disp_entry_details | definition changed bier_imp_add | definition changed bier_imp_details | definition changed bier_route_add_del | definition changed bier_route_details | definition changed bier_route_dump | definition changed bier_table_add_del | definition changed bier_table_details | definition changed bond_create | definition changed bridge_domain_add_del | definition changed bridge_domain_details | definition changed bridge_flags | definition changed connect_sock | definition changed create_vhost_user_if | definition changed ct6_enable | only in file ct6_enable_disable | only in image ct6_enable_disable_reply | only in image ct6_enable_disable | only in file dhcp6_pd_reply_event | definition changed dhcp6_pd_send_client_message | definition changed dhcp6_reply_event | definition changed dhcp6_send_client_message | definition changed dhcp_client_config | definition changed dhcp_client_details | definition changed dhcp_compl_event | definition changed dhcp_proxy_details | definition changed dslite_add_del_pool_addr_range | definition changed dslite_address_details | definition changed dslite_get_aftr_addr_reply | definition changed dslite_get_b4_addr_reply | definition changed dslite_set_aftr_addr | definition changed dslite_set_b4_addr | definition changed gbp_bridge_domain_add | definition changed gbp_bridge_domain_details | definition changed gbp_contract_add_del | definition changed gbp_contract_details | definition changed gbp_endpoint_add | definition changed gbp_endpoint_details | definition changed gbp_endpoint_group_add | definition changed gbp_endpoint_group_details | definition changed gbp_ext_itf_add_del | definition changed gbp_ext_itf_details | definition changed gbp_recirc_add_del | definition changed gbp_recirc_details | definition changed gbp_route_domain_add | definition changed gbp_route_domain_details | definition changed gbp_subnet_add_del | definition changed gbp_subnet_details | definition changed gbp_vxlan_tunnel_add | definition changed gbp_vxlan_tunnel_details | definition changed get_f64_endian_value | only in image get_f64_endian_value_reply | only in image get_f64_increment_by_one | only in image get_f64_increment_by_one_reply | only in image gpe_add_del_fwd_entry | definition changed gpe_fwd_entries_get_reply | definition changed gpe_fwd_entry_path_details | definition changed gpe_native_fwd_rpaths_get_reply | definition changed gre_add_del_tunnel | only in file gre_add_del_tunnel_reply | only in file gre_tunnel_add_del | only in image gre_tunnel_add_del_reply | only in image gre_tunnel_details | definition changed gre_tunnel_dump | definition changed http_static_enable | only in image http_static_enable_reply | only in image igmp_event | definition changed igmp_group_prefix_details | definition changed igmp_group_prefix_set | definition changed igmp_listen | definition changed ip6_fib_details | only in file ip6_fib_dump | only in file ip6_mfib_details | only in file ip6_mfib_dump | only in file ip6_ra_event | definition changed ip_add_del_route | only in file ip_add_del_route_reply | only in file ip_address_details | definition changed ip_container_proxy_add_del | definition changed ip_container_proxy_details | definition changed ip_fib_details | only in file ip_fib_dump | only in file ip_mfib_details | only in file ip_mfib_dump | only in file ip_mroute_add_del | definition changed ip_mroute_details | only in image ip_mroute_dump | only in image ip_mtable_details | only in image ip_mtable_dump | only in image ip_neighbor_add_del | definition changed ip_neighbor_details | definition changed ip_probe_neighbor | definition changed ip_punt_redirect | definition changed ip_punt_redirect_details | definition changed ip_reassembly_get_reply | definition changed ip_reassembly_set | definition changed ip_route_add_del | only in image ip_route_add_del_reply | only in image ip_route_details | only in image ip_route_dump | only in image ip_source_and_port_range_check_add_del | definition changed ip_table_add_del | definition changed ip_table_details | only in image ip_table_dump | only in image ipfix_flush | only in image ipfix_flush_reply | only in image ipip_6rd_add_tunnel | definition changed ipip_add_tunnel | definition changed ipip_tunnel_details | definition changed ipsec_backend_details | definition changed ipsec_gre_tunnel_add_del | only in file ipsec_gre_tunnel_add_del_reply | only in file ipsec_gre_tunnel_details | only in file ipsec_gre_tunnel_dump | only in file ipsec_sa_details | definition changed ipsec_sa_set_key | only in file ipsec_sa_set_key_reply | only in file ipsec_sad_entry_add_del | definition changed ipsec_select_backend | definition changed ipsec_spd_details | definition changed ipsec_spd_entry_add_del | definition changed ipsec_tunnel_if_add_del | definition changed ipsec_tunnel_if_set_key | only in file ipsec_tunnel_if_set_key_reply | only in file ipsec_tunnel_protect_del | only in image ipsec_tunnel_protect_del_reply | only in image ipsec_tunnel_protect_details | only in image ipsec_tunnel_protect_dump | only in image ipsec_tunnel_protect_update | only in image ipsec_tunnel_protect_update_reply | only in image l2_macs_event | definition changed l3xc_del | only in image l3xc_del_reply | only in image l3xc_details | only in image l3xc_dump | only in image l3xc_plugin_get_version | only in image l3xc_plugin_get_version_reply | only in image l3xc_update | only in image l3xc_update_reply | only in image lb_add_del_as | definition changed lb_add_del_vip | definition changed lb_as_details | only in image lb_as_dump | only in image lb_flush_vip | definition changed lb_vip_details | only in image lb_vip_dump | only in image lisp_add_del_locator_set | definition changed lisp_add_del_remote_mapping | definition changed lisp_adjacencies_get_reply | definition changed log_details | only in image log_dump | only in image macip_acl_add | definition changed macip_acl_add_replace | definition changed macip_acl_details | definition changed mactime_add_del_range | definition changed map_add_domain | definition changed map_domain_details | definition changed mfib_signal_details | definition changed modify_vhost_user_if | definition changed mpls_fib_details | only in file mpls_fib_dump | only in file mpls_ip_bind_unbind | definition changed mpls_route_add_del | definition changed mpls_route_details | only in image mpls_route_dump | only in image mpls_table_add_del | definition changed mpls_table_details | only in image mpls_table_dump | only in image mpls_tunnel_add_del | definition changed mpls_tunnel_details | definition changed nat44_add_del_address_range | definition changed nat44_add_del_identity_mapping | definition changed nat44_add_del_interface_addr | definition changed nat44_add_del_lb_static_mapping | definition changed nat44_add_del_static_mapping | definition changed nat44_address_details | definition changed nat44_del_session | definition changed nat44_forwarding_enable_disable | definition changed nat44_forwarding_is_enabled_reply | definition changed nat44_identity_mapping_details | definition changed nat44_interface_add_del_feature | definition changed nat44_interface_add_del_output_feature | definition changed nat44_interface_addr_details | definition changed nat44_interface_details | definition changed nat44_interface_output_feature_details | definition changed nat44_lb_static_mapping_add_del_local | definition changed nat44_lb_static_mapping_details | definition changed nat44_static_mapping_details | definition changed nat44_user_details | definition changed nat44_user_session_details | definition changed nat44_user_session_dump | definition changed nat64_add_del_interface_addr | definition changed nat64_add_del_interface | definition changed nat64_add_del_pool_addr_range | definition changed nat64_add_del_prefix | definition changed nat64_add_del_static_bib | definition changed nat64_bib_details | definition changed nat64_interface_details | definition changed nat64_pool_addr_details | definition changed nat64_prefix_details | definition changed nat64_st_details | definition changed nat66_add_del_interface | definition changed nat66_add_del_static_mapping | definition changed nat66_interface_details | definition changed nat66_static_mapping_details | definition changed nat_det_add_del_map | definition changed nat_det_close_session_in | definition changed nat_det_close_session_out | definition changed nat_det_forward | definition changed nat_det_forward_reply | definition changed nat_det_map_details | definition changed nat_det_reverse | definition changed nat_det_reverse_reply | definition changed nat_det_session_details | definition changed nat_det_session_dump | definition changed nat_get_mss_clamping_reply | definition changed nat_ipfix_enable_disable | definition changed nat_reass_details | definition changed nat_set_log_level | only in image nat_set_log_level_reply | only in image nat_set_mss_clamping | definition changed nat_set_reass | definition changed nat_show_config_reply | definition changed nat_worker_details | definition changed nsim_cross_connect_enable_disable | only in image nsim_cross_connect_enable_disable_reply | only in image nsim_enable_disable | only in file nsim_enable_disable_reply | only in file nsim_output_feature_enable_disable | only in image nsim_output_feature_enable_disable_reply | only in image oam_add_del | only in file oam_add_del_reply | only in file oam_event | only in file one_add_del_locator_set | definition changed one_add_del_remote_mapping | definition changed one_adjacencies_get_reply | definition changed one_l2_arp_entries_get_reply | definition changed one_ndp_entries_get_reply | definition changed p2p_ethernet_add | definition changed p2p_ethernet_add_reply | definition changed p2p_ethernet_del | definition changed pg_create_interface | definition changed proxy_arp_add_del | definition changed proxy_arp_details | definition changed punt_details | only in file punt_dump | only in file punt_reason_details | only in image punt_reason_dump | only in image punt_socket_deregister | definition changed punt_socket_details | definition changed punt_socket_dump | definition changed punt_socket_register | definition changed qos_egress_map_delete | definition changed qos_egress_map_details | only in image qos_egress_map_dump | only in image qos_egress_map_update | definition changed qos_mark_details | only in image qos_mark_details_reply | only in image qos_mark_dump | only in image qos_mark_enable_disable | definition changed qos_record_details | only in image qos_record_dump | only in image qos_record_enable_disable | definition changed qos_store_details | only in image qos_store_dump | only in image qos_store_enable_disable | only in image qos_store_enable_disable_reply | only in image sctp_add_src_dst_connection | only in file sctp_add_src_dst_connection_reply | only in file sctp_config | only in file sctp_config_reply | only in file sctp_del_src_dst_connection | only in file sctp_del_src_dst_connection_reply | only in file set_punt | definition changed show_threads_reply | definition changed show_vpe_system_time | only in image show_vpe_system_time_reply | only in image sockclnt_create_reply | definition changed sr_localsid_add_del | definition changed sr_localsids_details | definition changed sr_policies_details | definition changed sr_policy_add | definition changed sr_policy_del | definition changed sr_policy_mod | definition changed sr_steering_pol_details | definition changed svs_details | definition changed svs_enable_disable | definition changed svs_route_add_del | definition changed svs_table_add_del | definition changed sw_interface_bond_details | definition changed sw_interface_dump | definition changed sw_interface_ip6_set_link_local_address | only in image sw_interface_ip6_set_link_local_address_reply | only in image sw_interface_ip6nd_ra_prefix | definition changed sw_interface_set_l2_bridge | definition changed sw_interface_tap_v2_details | definition changed syslog_get_filter_reply | definition changed syslog_set_filter | definition changed tap_create_v2 | definition changed udp_encap_add | definition changed udp_encap_details | definition changed virtio_pci_create | definition changed vmxnet3_details | definition changed vxlan_gbp_tunnel_add_del | definition changed vxlan_gbp_tunnel_details | definition changed want_oam_events | only in file want_oam_events_reply | only in file Found 319 api message signature differences ### Patches that changed API definitions | @c src/vpp/api/vpe_types.api || | ------- | ------- | | [b'a47a5f20a'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'a47a5f20a') | api papi: add alias for timestamp(datetime)/timedelta | | [b'3cf9e67f5'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'3cf9e67f5') | api: add vl_api_version_t type | | @c src/vpp/api/vpe.api || | ------- | ------- | | [b'a47a5f20a'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'a47a5f20a') | api papi: add alias for timestamp(datetime)/timedelta | | [b'888640a39'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'888640a39') | map gbp papi: match endianess of f64 | | [b'03f1af23b'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'03f1af23b') | api: Implement log_dump/log_details | | [b'c87b66c86'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'c87b66c86') | ipsec: ipsec-tun protect | | [b'9ac113815'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'9ac113815') | API: Add support for limits to language. | | @c src/examples/sample-plugin/sample/sample.api || | ------- | ------- | | [b'78d91cf9a'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'78d91cf9a') | sample-plugin: refactor .api to use explicit types | | @c src/vnet/interface.api || | ------- | ------- | | [b'0ad4a439d'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'0ad4a439d') | Fix vpp crash bug while deleting dhcp client | | [b'9a29f795a'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'9a29f795a') | vpp_papi_provider.py: update defautmapping. | | [b'b8591ac91'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'b8591ac91') | API sw_interface_dump: Dump all if index is zero | | [b'4a7240636'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'4a7240636') | Make sw_interface_dump more compatible with 2.2.0 | | [b'6407ba56a'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'6407ba56a') | api: Add to interface crud - read by sw_if_index. | | @c src/vnet/qos/qos.api || | ------- | ------- | | [b'83832e7ce'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'83832e7ce') | qos: Store function | | [b'5281a9029'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'5281a9029') | qos: QoS dump APIs | | @c src/vnet/bier/bier.api || | ------- | ------- | | [b'097fa66b9'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'097fa66b9') | fib: fib api updates | | [b'e6eefb6e3'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'e6eefb6e3') | Trivial Typo's in bier comments/docs. | | @c src/vnet/ipfix-export/ipfix_export.api || | ------- | ------- | | [b'21b83e96d'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'21b83e96d') | api: implement ipfix_flush | | @c src/vnet/session/session.api || | ------- | ------- | | [b'8ac1d6d05'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'8ac1d6d05') | session: Use parent_handle instead of transport_opts | | [b'ba65ca496'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'ba65ca496') | Add transport_opts to connect_sock bapi | | @c src/vnet/gre/gre.api || | ------- | ------- | | [b'814f15948'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'814f15948') | gre: update gre.api with explicit types | | [b'd0aed2eb3'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'd0aed2eb3') | GRE: set gre_tunnel_type init value to zero in API | | [b'5a8844bdb'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'5a8844bdb') | GRE: API update | | @c src/vnet/pg/pg.api || | ------- | ------- | | [b'22e9cfd76'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'22e9cfd76') | pg: add GSO support | | @c src/vnet/l2/l2.api || | ------- | ------- | | [b'bc764c8bc'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'bc764c8bc') | l2: BD ARP termination entry API update | | [b'54bc5e40c'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'54bc5e40c') | Update API description | | [b'5e6f7348c'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'5e6f7348c') | l2: Add support for arp unicast forwarding | | @c src/vnet/udp/udp.api || | ------- | ------- | | [b'10dc2eabd'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'10dc2eabd') | udp: fix copyright typo | | @c src/vnet/devices/tap/tapv2.api || | ------- | ------- | | [b'97d54ed43'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'97d54ed43') | tap: add support to configure tap interface host MTU size | | @c src/vnet/devices/virtio/vhost_user.api || | ------- | ------- | | [b'4208a4ce8'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'4208a4ce8') | devices interface tests: vhosst GSO support | | @c src/vnet/devices/virtio/virtio.api || | ------- | ------- | | [b'bbd6b746e'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'bbd6b746e') | virtio: Add gso support for native virtio driver | | [b'43b512cac'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'43b512cac') | virtio: remove configurable queue size support | | @c src/vnet/mfib/mfib_types.api || | ------- | ------- | | [b'097fa66b9'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'097fa66b9') | fib: fib api updates | | @c src/vnet/ipsec/ipsec.api || | ------- | ------- | | [b'c87b66c86'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'c87b66c86') | ipsec: ipsec-tun protect | | [b'f2922422d'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'f2922422d') | ipsec: remove the set_key API | | [b'80f6fd53f'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'80f6fd53f') | IPSEC: Pass the algorithm salt (used in GCM) over the API | | @c src/vnet/ethernet/p2p_ethernet.api || | ------- | ------- | | [b'8edca1361'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'8edca1361') | p2p ethernet: update p2p_ethernet.api with explicit types. | | @c src/vnet/bonding/bond.api || | ------- | ------- | | [b'751e3f382'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'751e3f382') | bonding: add support for numa-only in lacp mode | | @c src/vnet/mpls/mpls.api || | ------- | ------- | | [b'097fa66b9'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'097fa66b9') | fib: fib api updates | | @c src/vnet/ipip/ipip.api || | ------- | ------- | | [b'288e09362'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'288e09362') | ipip: refactor ipip.api with explicit types | | [b'cbd0824d6'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'cbd0824d6') | IPIP tunnel: use address types on API | | @c src/vnet/fib/fib_types.api || | ------- | ------- | | [b'1dbcf30b7'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'1dbcf30b7') | fib: Support the POP of a Psuedo Wire Control Word | | [b'097fa66b9'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'097fa66b9') | fib: fib api updates | | @c src/vnet/dhcp/dhcp.api || | ------- | ------- | | [b'038e1dfbd'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'038e1dfbd') | dhcp ip: DSCP settings for transmitted DHCP packets | | [b'56bc738dc'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'56bc738dc') | Fix VPP-1487 DHCP client does not support option 6-domain server | | @c src/vnet/ip/punt.api || | ------- | ------- | | [b'719beb709'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'719beb709') | ip ipsec: Remove IPSec SPI-0 punt reason | | [b'b538dd868'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'b538dd868') | Punt: specify packets by IP protocol Type | | [b'50f0ac0f0'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'50f0ac0f0') | Punt: socket register for exception dispatched/punted packets based on reason | | @c src/vnet/ip/ip.api || | ------- | ------- | | [b'097fa66b9'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'097fa66b9') | fib: fib api updates | | [b'3a343d42d'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'3a343d42d') | reassembly: prevent long chain attack | | @c src/vnet/ip/ip_types.api || | ------- | ------- | | [b'515eed425'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'515eed425') | api: add prefix matcher typedef | | [b'038e1dfbd'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'038e1dfbd') | dhcp ip: DSCP settings for transmitted DHCP packets | | [b'53c501512'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'53c501512') | api: add DSCP definitions to ip_types.api | | [b'ab05508e1'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'ab05508e1') | api: refactor format_vl_api_prefix_t return keys | | [b'b538dd868'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'b538dd868') | Punt: specify packets by IP protocol Type | | [b'50f0ac0f0'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'50f0ac0f0') | Punt: socket register for exception dispatched/punted packets based on reason | | @c src/plugins/l3xc/l3xc.api || | ------- | ------- | | [b'59fa121f8'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'59fa121f8') | L3 cross connect | | @c src/plugins/map/map.api || | ------- | ------- | | [b'4d376f67a'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'4d376f67a') | map: Use vl_api_string macros. | | @c src/plugins/http_static/http_static.api || | ------- | ------- | | [b'68b24e2c9'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'68b24e2c9') | plugins: http_static. Migrate to use api string type. | | [b'22bc2c46e'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'22bc2c46e') | Static http server | | @c src/plugins/igmp/igmp.api || | ------- | ------- | | [b'4ff09ae34'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'4ff09ae34') | API: Python and Unix domain socket improvement | | @c src/plugins/sctp/sctp.api || | ------- | ------- | | [b'3ffe6cadf'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'3ffe6cadf') | sctp: move to plugins, disabled by default | | @c src/plugins/lb/lb.api || | ------- | ------- | | [b'3efcd0d7c'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'3efcd0d7c') | lb: vip and as dump/detail api's | | [b'a0cb32cb9'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'a0cb32cb9') | lb: update api.c to use scaffolding from latest skel | | @c src/plugins/lb/lb_types.api || | ------- | ------- | | [b'3efcd0d7c'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'3efcd0d7c') | lb: vip and as dump/detail api's | | @c src/plugins/mactime/mactime.api || | ------- | ------- | | [b'7681b1c46'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'7681b1c46') | mactime: add per-mac allow-with-quota feature | | [b'0c6ac791d'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'0c6ac791d') | mactime: upstream new features | | @c src/plugins/gbp/gbp.api || | ------- | ------- | | [b'3918bdbcb'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'3918bdbcb') | gbp: update gbp-ext-itf API | | [b'3c0d84c98'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'3c0d84c98') | gbp: add anonymous l3-out subnets | | [b'cfc7a107e'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'cfc7a107e') | gbp: add anonymous l3-out external interfaces | | [b'160c923f9'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'160c923f9') | gbp: VRF scoped contracts | | @c src/plugins/acl/acl_types.api || | ------- | ------- | | [b'bb2e5221a'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'bb2e5221a') | api acl: breakout acl_types.api for reuse by others | | @c src/plugins/acl/acl.api || | ------- | ------- | | [b'bb2e5221a'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'bb2e5221a') | api acl: breakout acl_types.api for reuse by others | | [b'f995c7122'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'f995c7122') | acl: implement counters | | @c src/plugins/nat/nat.api || | ------- | ------- | | [b'e6e09a4ac'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'e6e09a4ac') | nat: elog rewrite for multi-worker support | | [b'c1f93067e'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'c1f93067e') | Add default value for API Nat flags | | [b'dd1e3e780'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'dd1e3e780') | NAT: VPP-1531 api cleanup & update | | [b'89fec713f'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'89fec713f') | Revert "NAT: VPP-1531 api cleanup & update" | | [b'bed1421b9'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'bed1421b9') | NAT: VPP-1531 api cleanup & update | | @c src/plugins/abf/abf.api || | ------- | ------- | | [b'097fa66b9'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'097fa66b9') | fib: fib api updates | | @c src/plugins/nsim/nsim.api || | ------- | ------- | | [b'7c91007e1'](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b'7c91007e1') | Make the loss / delay sim available as an output feature | @page release_notes_19043 Release notes for VPP 19.04.3 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/1904) @page release_notes_19042 Release notes for VPP 19.04.2 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/1904) @page release_notes_19041 Release notes for VPP 19.04.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/1904) @page release_notes_1904 Release notes for VPP 19.04 More than 700 commits since the 19.01 release. ## Features ### Infrastructure - DPDK 19.02 integration - Buffer manager rework and improvements - Python3 migration (work in progress) - vppapigen - Python API wrappers - Docs generation - vpp_config - "make test" python3 readiness and refactoring - Add "make test-gcov" target to main Makefile - Refactor multiarch code - vfctl script: bind VF to vfio-pci after VF is created - cmake cross-compilation support - CLI control of graph dispatch elogs - AppImage packaging (disabled by default) - Complete upstreaming of wireshark dissector - Remove JVPP which is now an FD.io project - Punt infra: manage dispatch of exception packets ### VNET & Plugins - BVI Interface - Deprecate TAP cli - Experimental TAP interface TCP segmentation offload - Vmxnet3 driver plugin - LACP passive mode - ACL plugin refactoring - RDMA (ibverb) driver plugin - MLX5 with multiqueue - IPSEC - Intel IPSEC-MB engine plugin - Tunnel fragmentation - CLI improvements - Performance improvements - API modernisation and improvements - New Tests and test refactoring - Crypto - Introduce crypto infra - crypto_ia32 plugin - Add support for AEAD and AES-GCM - Implement rfc4231 test cases - Implement crypto tests per RFC2202 - Perfmon improvements - Python to C parser for intel CPUs - 2-way parallel stat collection - Collect data on selected thread(s) ### Host stack - Improve ldp/vls/vcl support for multi-process and multi-threaded applications - Major refactor/cleanup of session layer - Refactor cut-through sessions to use a custom transport - Baseline QUIC transport support ## Known issues For the full list of issues please refer to fd.io [JIRA](https://jira.fd.io). ## Issues fixed 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/1904) ## 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 -------------------------------------------------------------|------------------ accept_session | only in file accept_session_reply | only in file bind_sock_reply | definition changed bind_uri_reply | definition changed bvi_create | only in image bvi_create_reply | only in image bvi_delete | only in image bvi_delete_reply | only in image connect_session | only in file connect_session_reply | only in file ct6_enable | only in image ct6_enable_disable | only in image gbp_contract_add_del_reply | definition changed gbp_endpoint_group_del | definition changed gbp_endpoint_learn_set_inactive_threshold | only in file gbp_endpoint_learn_set_inactive_threshold_reply | only in file ikev2_plugin_get_version | only in image ikev2_plugin_get_version_reply | only in image ip4_arp_event | definition changed ip6_nd_event | definition changed ip6_ra_event | definition changed ip6nd_proxy_add_del | definition changed ip6nd_proxy_details | definition changed ip_container_proxy_add_del | definition changed ip_neighbor_add_del | definition changed ip_neighbor_details | definition changed ip_probe_neighbor | definition changed ip_source_and_port_range_check_add_del | definition changed ipsec_backend_details | definition changed ipsec_gre_add_del_tunnel | only in file ipsec_gre_add_del_tunnel_reply | only in file ipsec_gre_tunnel_add_del | only in image ipsec_gre_tunnel_add_del_reply | only in image ipsec_gre_tunnel_details | definition changed ipsec_sa_details | definition changed ipsec_sa_set_key | definition changed ipsec_sad_add_del_entry | only in file ipsec_sad_add_del_entry_reply | only in file ipsec_sad_entry_add_del | only in image ipsec_sad_entry_add_del_reply | only in image ipsec_select_backend | definition changed ipsec_spd_add_del_entry | only in file ipsec_spd_add_del_entry_reply | only in file ipsec_spd_details | definition changed ipsec_spd_entry_add_del | only in image ipsec_spd_entry_add_del_reply | only in image ipsec_tunnel_if_add_del | definition changed lb_conf | definition changed map_add_domain | definition changed map_domain_details | definition changed nat_ha_flush | only in image nat_ha_flush_reply | only in image nat_ha_get_failover | only in image nat_ha_get_failover_reply | only in image nat_ha_get_listener | only in image nat_ha_get_listener_reply | only in image nat_ha_resync | only in image nat_ha_resync_completed_event | only in image nat_ha_resync_reply | only in image nat_ha_set_failover | only in image nat_ha_set_failover_reply | only in image nat_ha_set_listener | only in image nat_ha_set_listener_reply | only in image reset_session | only in file reset_session_reply | only in file sw_interface_ip6nd_ra_prefix | definition changed sw_interface_set_dpdk_hqos_pipe | only in file sw_interface_set_dpdk_hqos_pipe_reply | only in file sw_interface_set_dpdk_hqos_subport | only in file sw_interface_set_dpdk_hqos_subport_reply | only in file sw_interface_set_dpdk_hqos_tctbl | only in file sw_interface_set_dpdk_hqos_tctbl_reply | only in file sw_interface_tap_details | only in file sw_interface_tap_dump | only in file sw_interface_virtio_pci_details | only in image sw_interface_virtio_pci_dump | only in image tap_connect | only in file tap_connect_reply | only in file tap_delete | only in file tap_delete_reply | only in file tap_modify | only in file tap_modify_reply | only in file virtio_pci_create | only in image virtio_pci_create_reply | only in image virtio_pci_delete | only in image virtio_pci_delete_reply | only in image vmxnet3_create | definition changed vmxnet3_details | definition changed want_ip4_arp_events | definition changed want_ip6_nd_events | definition changed Found 90 api message signature differences ### Patches that changed API definitions | @c src/vlibmemory/memclnt.api || | ------- | ------- | | [eaec2a6d9](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=eaec2a6d9) | bapi: add options to have vpp cleanup client registration | | @c src/vpp/api/vpe.api || | ------- | ------- | | [1aaf0e343](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=1aaf0e343) | deprecate tapcli | | [f49ba0e81](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=f49ba0e81) | stats: Deprecate old stats framework | | [413f4a5b2](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=413f4a5b2) | API: Use string type instead of u8. | | @c src/vnet/interface.api || | ------- | ------- | | [3b0d7e42f](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=3b0d7e42f) | Revert "API: Cleanup APIs interface.api" | | [e63325e3c](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=e63325e3c) | API: Cleanup APIs interface.api | | [bb2c7b580](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=bb2c7b580) | Update documentation for src/vnet/interface.api sw_interface_dump | | [f49ba0e81](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=f49ba0e81) | stats: Deprecate old stats framework | | [53fffa1db](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=53fffa1db) | API: Add support for type aliases | | [5100aa9cb](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=5100aa9cb) | vnet: store hw interface speed in kbps instead of using flags | | @c src/vnet/interface_types.api || | ------- | ------- | | [3b0d7e42f](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=3b0d7e42f) | Revert "API: Cleanup APIs interface.api" | | [e63325e3c](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=e63325e3c) | API: Cleanup APIs interface.api | | [53fffa1db](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=53fffa1db) | API: Add support for type aliases | | @c src/vnet/bonding/bond.api || | ------- | ------- | | [ad9d52831](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=ad9d52831) | bonding: support custom interface IDs | | @c src/vnet/ipip/ipip.api || | ------- | ------- | | [53fffa1db](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=53fffa1db) | API: Add support for type aliases | | @c src/vnet/ipsec-gre/ipsec_gre.api || | ------- | ------- | | [e524d45ef](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=e524d45ef) | IPSEC-GRE: fixes and API update to common types. | | @c src/vnet/syslog/syslog.api || | ------- | ------- | | [b4515b4be](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b4515b4be) | Add RFC5424 syslog protocol support (VPP-1139) | | @c src/vnet/devices/tap/tapv2.api || | ------- | ------- | | [754f24b35](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=754f24b35) | tapv2: add "tap_flags" field to the TAPv2 interface API | | @c src/vnet/devices/virtio/virtio.api || | ------- | ------- | | [d6c15af33](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=d6c15af33) | virtio: Native virtio driver | | @c src/vnet/fib/fib_types.api || | ------- | ------- | | [775f73c6b](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=775f73c6b) | FIB: encode the label stack in the FIB path during table dump | | @c src/vnet/ip/ip_types.api || | ------- | ------- | | [8c8acc027](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=8c8acc027) | API: Change ip4_address and ip6_address to use type alias. | | [ffba3c377](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=ffba3c377) | MAP: Use explicit address/prefix types in API | | @c src/vnet/ip/ip.api || | ------- | ------- | | [48ae19e90](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=48ae19e90) | API: Add python2.7 support for enum flags via aenum | | [37029305c](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=37029305c) | Use IP and MAC API types for neighbors | | [7c03ed47d](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=7c03ed47d) | VOM: mroutes | | [3460b014a](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=3460b014a) | api: ip_source_check_interface_add_del api is added. | | [609e1210c](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=609e1210c) | VPP-1507: Added binary api to dump configured ip_punt_redirect | | [2af0e3a74](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=2af0e3a74) | flow-hash: Add symmetric flag for flow hashing | | [47527b24a](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=47527b24a) | IP-punt: add documentation to the API and fix IP address init | | [5bb1ecae8](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=5bb1ecae8) | IPv6: Make link-local configurable per-interface (VPP-1446) | | [75b9f45a1](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=75b9f45a1) | ip: add container proxy dump API (VPP-1364) | | @c src/vnet/ip/punt.api || | ------- | ------- | | [e88865d7b](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=e88865d7b) | VPP-1506: dump local punts and registered punt sockets | | @c src/vnet/vxlan-gbp/vxlan_gbp.api || | ------- | ------- | | [4dd4cf4f9](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=4dd4cf4f9) | GBP: fixes for l3-out routing | | [93cc3ee3b](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=93cc3ee3b) | GBP Endpoint Learning | | @c src/vnet/ethernet/ethernet_types.api || | ------- | ------- | | [8006c6aa4](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=8006c6aa4) | PAPI: Add MACAddress object wrapper for vl_api_mac_address_t | | @c src/vnet/ipsec/ipsec.api || | ------- | ------- | | [1e3aa5e21](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=1e3aa5e21) | ipsec: USE_EXTENDED_SEQ_NUM -> USE_ESN | | [1ba5bc8d8](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=1ba5bc8d8) | ipsec: add ipv6 support for ipsec tunnel interface | | [5d704aea5](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=5d704aea5) | updates now that flags are supported on the API | | [53f526b68](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=53f526b68) | TEST: IPSEC NAT-T with UDP header | | [7c44d78ef](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=7c44d78ef) | IKEv2 to plugin | | [eba31eceb](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=eba31eceb) | IPSEC: move SA counters into the stats segment | | [8d7c50200](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=8d7c50200) | IPSEC: no second lookup after tunnel encap | | [a09c1ff5b](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=a09c1ff5b) | IPSEC: SPD counters in the stats sgement | | [17dcec0b9](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=17dcec0b9) | IPSEC: API modernisation | | [4c422f9a3](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=4c422f9a3) | Add IPSec interface FIB index for TX packet | | [b4a7a7dcf](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b4a7a7dcf) | Add UDP encap flag | | [b4d305344](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b4d305344) | ipsec: infra for selecting backends | | [871bca9aa](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=871bca9aa) | VPP-1450: binary api call for dumping SPD to interface registration | | @c src/vnet/tcp/tcp.api || | ------- | ------- | | [c5df8c71c](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=c5df8c71c) | host stack: update stale copyright | | @c src/vnet/l2/l2.api || | ------- | ------- | | [192b13f96](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=192b13f96) | BVI Interface | | [5daf0c55c](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=5daf0c55c) | add default NONE flag for bd_flags | | [e26c81fc8](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=e26c81fc8) | L2 BD API to flush all IP-MAC entries in the specified BD | | [8006c6aa4](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=8006c6aa4) | PAPI: Add MACAddress object wrapper for vl_api_mac_address_t | | [93cc3ee3b](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=93cc3ee3b) | GBP Endpoint Learning | | [4d5b917b1](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=4d5b917b1) | BD ARP entry use common API types | | @c src/vnet/session/session.api || | ------- | ------- | | [6442401c2](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=6442401c2) | session: remove deprecated binary apis | | [d85de68ec](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=d85de68ec) | vcl: wait for segments with segment handle | | [fa76a76bf](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=fa76a76bf) | session: segment handle in accept/connect notifications | | [c1f5a4336](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=c1f5a4336) | session: cleanup use of api_client_index | | [c0d532d17](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=c0d532d17) | session: mark apis for deprecation | | @c src/vnet/udp/udp.api || | ------- | ------- | | [c5df8c71c](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=c5df8c71c) | host stack: update stale copyright | | @c src/plugins/cdp/cdp.api || | ------- | ------- | | [76ef6094c](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=76ef6094c) | tests: cdp plugin. Replace cdp enable cli command with API call. | | @c src/plugins/nat/nat.api || | ------- | ------- | | [8feeaff56](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=8feeaff56) | Typos. A bunch of typos I've been collecting. | | [34931eb47](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=34931eb47) | NAT44: active-passive HA (VPP-1571) | | [b686508c4](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b686508c4) | NAT44: nat44_add_del_lb_static_mapping enhancements (VPP-1514) | | @c src/plugins/map/map.api || | ------- | ------- | | [4dc5c7b90](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=4dc5c7b90) | MAP: Add optional user-supplied 'tag' field in MAPs. | | [fc7344f9b](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=fc7344f9b) | MAP: Convert from DPO to input feature. | | [f34597fc8](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=f34597fc8) | MAP: Add API support for MAP input feature. | | [5a2e278a0](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=5a2e278a0) | MAP: Add API support for setting parameters. | | [a173a7a07](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=a173a7a07) | MAP: Use bool type in map.api instead of u8. | | [ffba3c377](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=ffba3c377) | MAP: Use explicit address/prefix types in API | | @c src/plugins/gbp/gbp.api || | ------- | ------- | | [1aa35576e](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=1aa35576e) | GBP: Counters per-contract | | [8ea109e40](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=8ea109e40) | gbp: Add bd flags | | [7bd343509](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=7bd343509) | GBP: custom-dump functions | | [fa0ac2c56](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=fa0ac2c56) | GBP: contracts API fixed length of allowed ethertypes | | [5d704aea5](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=5d704aea5) | updates now that flags are supported on the API | | [4ba67723d](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=4ba67723d) | GBP: use sclass in the DP for policy | | [8da9fc659](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=8da9fc659) | GBP: learn from ARP and L2 packets | | [32f6d8e0c](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=32f6d8e0c) | GBP: per-group EP retention policy | | [879d11c25](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=879d11c25) | GBP: Sclass to src-epg conversions | | [1c17e2eca](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=1c17e2eca) | GBP: add allowed ethertypes to contracts | | [b6a479539](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b6a479539) | GBP: l3-out subnets | | [33b81da54](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=33b81da54) | vom: Add support for redirect contracts in gbp | | [13a08cc09](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=13a08cc09) | GBP: redirect contracts | | [c29c0af40](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=c29c0af40) | GBP: Endpoints with VLAN tags and birdges that don't learn | | [93cc3ee3b](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=93cc3ee3b) | GBP Endpoint Learning | | @c src/plugins/acl/acl.api || | ------- | ------- | | [bb5d22daf](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=bb5d22daf) | New api in order to get max entries of connection table is added. | | @c src/plugins/vmxnet3/vmxnet3.api || | ------- | ------- | | [ee8ba6877](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=ee8ba6877) | vmxnet3: auto bind support | | [854559d15](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=854559d15) | vmxnet3: RSS support | | [773291163](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=773291163) | vmxnet3: multiple TX queues support | | @c src/plugins/nsim/nsim.api || | ------- | ------- | | [10c5ff143](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=10c5ff143) | nsim: add packet loss simulation, docs | | @c src/plugins/igmp/igmp.api || | ------- | ------- | | [97748cae2](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=97748cae2) | IGMP: proxy device | | @c src/plugins/lb/lb.api || | ------- | ------- | | [f7f13347b](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=f7f13347b) | tests: update test_lb.py to use api call lb_conf. | | @c src/plugins/ct6/ct6.api || | ------- | ------- | | [a55df1081](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=a55df1081) | ipv6 connection tracking plugin | | @c src/plugins/ikev2/ikev2.api || | ------- | ------- | | [7c44d78ef](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=7c44d78ef) | IKEv2 to plugin | @page release_notes_19013 Release notes for VPP 19.01.3 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/1901) @page release_notes_19012 Release notes for VPP 19.01.2 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/1901) @page release_notes_19011 Release notes for VPP 19.01.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/1901) @page release_notes_1901 Release notes for VPP 19.01 More than 649 commits since the 18.10 release. ## Features ### Infrastructure - NUMA-aware, growable physical memory allocator (pmalloc) - FIB: sticky load-balance - C11 safe string handling: provide and use "safe" C string handling functions - vlib: allocate buffers on local numa, not on numa 1 - vppinfra: autodetect default hugepage size - Move RPC traffic off the shared-memory API queue - IPv6: Make link-local configurable per-interface - IGMP: improve CLI debug output - IPSec: split ipsec nodes into ip4/ip6 nodes - IPSec: infra for selecting backends - vhost-user: cleanup and performance optimizations - ethernet-input, memif improvements and optimizations - DPDK: bump to DPDK 18.11 - reassembly: harden reassembly code - stats: Deprecate old (event-based) stats framework - vlib: support Hyper-V/Azure VMBus - binary api clients: wait for vpp to start - graph dispatch trace: capture packet data and buffer metadata, output in pcap format - improve feature arc order constraint specification ### VNET & Plugins - pktgen: correctly replay a mix of single and multi-buffer packets - add wireshark dissector to extras - avf: optimizations - acl-plugin: use L2 feature arc instead of L2 classifier - acl-plugin: performance enhancement - dpdk: allow interface name to be specified from startup.conf - dpdk: blacklist PCI devices by type - dpdk: switch to in-memory mode, deprecate use of socket-mem - vnet: store hw interface speed in kbps instead of using flags - vmxnet3: enable promiscuous mode & cli enhancements - gbp: Add support for flow hash profile & l3-out subnets - map: Add API support for setting parameters. - map: Convert from DPO to input feature - nat: improve expired sessions reuse in NAT44 - nat: syslog - sessions logging - nsim: add packet loss simulation, docs - perfmon: x86_64 perf counter plugin - vnet: L2 feature arc infrastructure ### Host stack - TCP congestion control improvements - TCP Cubic congestion control algorithm - TCP fast path optimizations - Transport tx connection pacer. TCP uses it by default - Basic support for session flushing and TCP PSH segments - TCP/session api support for configuring custom local src ip/port - VCL/LDP basic support for multi-process applications - Overall code hardening, cleanup and bugfixing for tcp, session, vcl and ldp ### PAPI & Test framework - add specific API types for IP addresses, MAC address, interface index etc. - add timeout support for socket transport - add support for format/unformat functions - generic API types format/unformat support for VAT and custom dump - python3 test adjustments - make test: create virtualenv under /test/ - make test: print TEST= values for failed tests - add human-friendly annotations to log messages ### VOM - Add support for redirect contracts in gbp - deprecate TAP add ip-punt redirect dump - vxlan-gbp support ## Known issues For the full list of issues please refer to fd.io [JIRA](https://jira.fd.io). ## Issues fixed 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/1810) ## 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 | Results ------------------------------------------------------------ | ---------------- acl_plugin_get_conn_table_max_entries | only in image acl_plugin_get_conn_table_max_entries_reply | only in image app_worker_add_del | definition changed app_worker_add_del_reply | definition changed application_attach_reply | definition changed bd_ip_mac_add_del | definition changed bd_ip_mac_details | definition changed bd_ip_mac_flush | only in image bd_ip_mac_flush_reply | only in image bond_create | definition changed cli_inband | definition changed cli_inband_reply | definition changed gbp_bridge_domain_add | only in image gbp_bridge_domain_add_reply | only in image gbp_bridge_domain_del | only in image gbp_bridge_domain_del_reply | only in image gbp_bridge_domain_details | only in image gbp_bridge_domain_dump | only in image gbp_bridge_domain_dump_reply | only in image gbp_endpoint_details | definition changed gbp_endpoint_group_add | only in image gbp_endpoint_group_add_del | only in file gbp_endpoint_group_add_del_reply | only in file gbp_endpoint_group_add_reply | only in image gbp_endpoint_group_del | only in image gbp_endpoint_group_del_reply | only in image gbp_endpoint_learn_set_inactive_threshold | only in image gbp_endpoint_learn_set_inactive_threshold_reply | only in image gbp_ext_itf_add_del | only in image gbp_ext_itf_add_del_reply | only in image gbp_ext_itf_details | only in image gbp_ext_itf_dump | only in image gbp_route_domain_add | only in image gbp_route_domain_add_reply | only in image gbp_route_domain_del | only in image gbp_route_domain_del_reply | only in image gbp_route_domain_details | only in image gbp_route_domain_dump | only in image gbp_route_domain_dump_reply | only in image gbp_vxlan_tunnel_add | only in image gbp_vxlan_tunnel_add_reply | only in image gbp_vxlan_tunnel_del | only in image gbp_vxlan_tunnel_del_reply | only in image gbp_vxlan_tunnel_details | only in image gbp_vxlan_tunnel_dump | only in image igmp_proxy_device_add_del | only in image igmp_proxy_device_add_del_interface | only in image igmp_proxy_device_add_del_interface_reply | only in image igmp_proxy_device_add_del_reply | only in image ip6_mfib_details | definition changed ip_container_proxy_details | only in image ip_container_proxy_dump | only in image ip_mfib_details | definition changed ip_punt_redirect | definition changed ip_punt_redirect_details | only in image ip_punt_redirect_dump | only in image ip_source_check_interface_add_del | only in image ip_source_check_interface_add_del_reply | only in image ipip_6rd_add_tunnel_reply | definition changed ipip_6rd_del_tunnel | definition changed ipip_add_tunnel_reply | definition changed ipip_del_tunnel | definition changed ipip_tunnel_details | definition changed ipip_tunnel_dump | definition changed ipsec_backend_details | only in image ipsec_backend_dump | only in image ipsec_sa_details | definition changed ipsec_select_backend | only in image ipsec_select_backend_reply | only in image ipsec_tunnel_if_add_del | definition changed map_add_del_rule | definition changed map_add_domain | definition changed map_another_segment | definition changed map_domain_details | definition changed map_if_enable_disable | only in image map_if_enable_disable_reply | only in image map_param_add_del_pre_resolve | only in image map_param_add_del_pre_resolve_reply | only in image map_param_get | only in image map_param_get_reply | only in image map_param_set_fragmentation | only in image map_param_set_fragmentation_reply | only in image map_param_set_icmp6 | only in image map_param_set_icmp6_reply | only in image map_param_set_icmp | only in image map_param_set_icmp_reply | only in image map_param_set_reassembly | only in image map_param_set_reassembly_reply | only in image map_param_set_security_check | only in image map_param_set_security_check_reply | only in image map_param_set_tcp | only in image map_param_set_tcp_reply | only in image map_param_set_traffic_class | only in image map_param_set_traffic_class_reply | only in image map_rule_details | definition changed memclnt_delete | definition changed nat44_add_del_lb_static_mapping | definition changed nat44_lb_static_mapping_add_del_local | only in image nat44_lb_static_mapping_add_del_local_reply | only in image nat44_lb_static_mapping_details | definition changed nsim_configure | definition changed punt | only in file punt_details | only in image punt_dump | only in image punt_reply | only in file punt_socket_deregister | definition changed punt_socket_details | only in image punt_socket_dump | only in image punt_socket_register | definition changed set_ip_flow_hash | definition changed set_punt | only in image set_punt_reply | only in image show_version_reply | definition changed stats_get_poller_delay | only in file stats_get_poller_delay_reply | only in file sw_interface_bond_details | definition changed sw_interface_details | definition changed sw_interface_ip6_set_link_local_address | only in file sw_interface_ip6_set_link_local_address_reply | only in file sw_interface_tap_v2_details | definition changed syslog_get_filter | only in image syslog_get_filter_reply | only in image syslog_get_sender | only in image syslog_get_sender_reply | only in image syslog_set_filter | only in image syslog_set_filter_reply | only in image syslog_set_sender | only in image syslog_set_sender_reply | only in image tap_create_v2 | definition changed unmap_segment | definition changed vnet_bier_neighbor_counters | only in file vnet_get_summary_stats | only in file vnet_get_summary_stats_reply | only in file vnet_interface_combined_counters | only in file vnet_interface_simple_counters | only in file vnet_ip4_fib_counters | only in file vnet_ip4_mfib_counters | only in file vnet_ip4_nbr_counters | only in file vnet_ip6_fib_counters | only in file vnet_ip6_mfib_counters | only in file vnet_ip6_nbr_counters | only in file vnet_per_interface_combined_counters | only in file vnet_per_interface_simple_counters | only in file vnet_udp_encap_counters | only in file want_bier_neighbor_stats | only in file want_bier_neighbor_stats_reply | only in file want_interface_combined_stats | only in file want_interface_combined_stats_reply | only in file want_interface_simple_stats | only in file want_interface_simple_stats_reply | only in file want_ip4_fib_stats | only in file want_ip4_fib_stats_reply | only in file want_ip4_mfib_stats | only in file want_ip4_mfib_stats_reply | only in file want_ip4_nbr_stats | only in file want_ip4_nbr_stats_reply | only in file want_ip6_fib_stats | only in file want_ip6_fib_stats_reply | only in file want_ip6_mfib_stats | only in file want_ip6_mfib_stats_reply | only in file want_ip6_nbr_stats | only in file want_ip6_nbr_stats_reply | only in file want_per_interface_combined_stats | only in file want_per_interface_combined_stats_reply | only in file want_per_interface_simple_stats | only in file want_per_interface_simple_stats_reply | only in file want_stats | only in file want_stats_reply | only in file want_udp_encap_stats | only in file want_udp_encap_stats_reply | only in file Found 170 api message signature differences ### Patches that changed API definitions | @c src/vnet/interface_types.api || | ------- | ------- | | [53fffa1](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=53fffa1) | API: Add support for type aliases | | @c src/vnet/interface.api || | ------- | ------- | | [f49ba0e](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=f49ba0e) | stats: Deprecate old stats framework | | [53fffa1](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=53fffa1) | API: Add support for type aliases | | [5100aa9](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=5100aa9) | vnet: store hw interface speed in kbps instead of using flags | | @c src/vnet/syslog/syslog.api || | ------- | ------- | | [b4515b4](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b4515b4) | Add RFC5424 syslog protocol support (VPP-1139) | | @c src/vnet/fib/fib_types.api || | ------- | ------- | | [775f73c](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=775f73c) | FIB: encode the label stack in the FIB path during table dump | | @c src/vnet/ip/ip.api || | ------- | ------- | | [7c03ed4](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=7c03ed4) | VOM: mroutes | | [3460b01](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=3460b01) | api: ip_source_check_interface_add_del api is added. | | [609e121](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=609e121) | VPP-1507: Added binary api to dump configured ip_punt_redirect | | [2af0e3a](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=2af0e3a) | flow-hash: Add symmetric flag for flow hashing | | [47527b2](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=47527b2) | IP-punt: add documentation to the API and fix IP address init | | [5bb1eca](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=5bb1eca) | IPv6: Make link-local configurable per-interface (VPP-1446) | | [75b9f45](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=75b9f45) | ip: add container proxy dump API (VPP-1364) | | @c src/vnet/ip/ip_types.api || | ------- | ------- | | [8c8acc0](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=8c8acc0) | API: Change ip4_address and ip6_address to use type alias. | | [ffba3c3](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=ffba3c3) | MAP: Use explicit address/prefix types in API | | @c src/vnet/ip/punt.api || | ------- | ------- | | [e88865d](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=e88865d) | VPP-1506: dump local punts and registered punt sockets | | @c src/vnet/ipsec/ipsec.api || | ------- | ------- | | [4c422f9](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=4c422f9) | Add IPSec interface FIB index for TX packet | | [b4a7a7d](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b4a7a7d) | Add UDP encap flag | | [b4d3053](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b4d3053) | ipsec: infra for selecting backends | | [871bca9](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=871bca9) | VPP-1450: binary api call for dumping SPD to interface registration | | @c src/vnet/l2/l2.api || | ------- | ------- | | [e26c81f](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=e26c81f) | L2 BD API to flush all IP-MAC entries in the specified BD | | [8006c6a](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=8006c6a) | PAPI: Add MACAddress object wrapper for vl_api_mac_address_t | | [93cc3ee](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=93cc3ee) | GBP Endpoint Learning | | [4d5b917](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=4d5b917) | BD ARP entry use common API types | | @c src/vnet/vxlan-gbp/vxlan_gbp.api || | ------- | ------- | | [93cc3ee](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=93cc3ee) | GBP Endpoint Learning | | @c src/vnet/ipip/ipip.api || | ------- | ------- | | [53fffa1](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=53fffa1) | API: Add support for type aliases | | @c src/vnet/session/session.api || | ------- | ------- | | [d85de68](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=d85de68) | vcl: wait for segments with segment handle | | [fa76a76](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=fa76a76) | session: segment handle in accept/connect notifications | | [c1f5a43](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=c1f5a43) | session: cleanup use of api_client_index | | [c0d532d](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=c0d532d) | session: mark apis for deprecation | | @c src/vnet/ethernet/ethernet_types.api || | ------- | ------- | | [8006c6a](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=8006c6a) | PAPI: Add MACAddress object wrapper for vl_api_mac_address_t | | @c src/vnet/bonding/bond.api || | ------- | ------- | | [ad9d528](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=ad9d528) | bonding: support custom interface IDs | | @c src/vnet/devices/tap/tapv2.api || | ------- | ------- | | [754f24b](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=754f24b) | tapv2: add "tap_flags" field to the TAPv2 interface API | | @c src/vlibmemory/memclnt.api || | ------- | ------- | | [eaec2a6](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=eaec2a6) | bapi: add options to have vpp cleanup client registration | | @c src/vpp/api/vpe.api || | ------- | ------- | | [f49ba0e](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=f49ba0e) | stats: Deprecate old stats framework | | [413f4a5](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=413f4a5) | API: Use string type instead of u8. | | @c src/plugins/acl/acl.api || | ------- | ------- | | [bb5d22d](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=bb5d22d) | New api in order to get max entries of connection table is added. | | @c src/plugins/nsim/nsim.api || | ------- | ------- | | [10c5ff1](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=10c5ff1) | nsim: add packet loss simulation, docs | | @c src/plugins/gbp/gbp.api || | ------- | ------- | | [1c17e2e](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=1c17e2e) | GBP: add allowed ethertypes to contracts | | [b6a4795](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b6a4795) | GBP: l3-out subnets | | [33b81da](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=33b81da) | vom: Add support for redirect contracts in gbp | | [13a08cc](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=13a08cc) | GBP: redirect contracts | | [c29c0af](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=c29c0af) | GBP: Endpoints with VLAN tags and birdges that don't learn | | [93cc3ee](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=93cc3ee) | GBP Endpoint Learning | | @c src/plugins/nat/nat.api || | ------- | ------- | | [b686508](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=b686508) | NAT44: nat44_add_del_lb_static_mapping enhancements (VPP-1514) | | @c src/plugins/map/map.api || | ------- | ------- | | [fc7344f](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=fc7344f) | MAP: Convert from DPO to input feature. | | [f34597f](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=f34597f) | MAP: Add API support for MAP input feature. | | [5a2e278](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=5a2e278) | MAP: Add API support for setting parameters. | | [a173a7a](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=a173a7a) | MAP: Use bool type in map.api instead of u8. | | [ffba3c3](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=ffba3c3) | MAP: Use explicit address/prefix types in API | | @c src/plugins/igmp/igmp.api || | ------- | ------- | | [97748ca](https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commit;h=97748ca) | IGMP: proxy device | @page release_notes_1810 Release notes for VPP 18.10 More than 632 commits since the 18.07 release. ## Features ### Infrastructure - DPDK 18.08 integration - New Stats infrastructure (interface, error, node performance counters) - Add configurable "Doug Lea malloc" support ### VNET & Plugins - Load balancing: support per-port VIP and all-port VIP - Port NSH plugin to VPP - NAT - Configurable port range - Virtual Fragmentation Reassembly for endpoint-dependent mode - Client-IP based session affinity for load-balancing - TCP MSS clamping - Session timeout - Bug-fixing and performance optimizations ### Host stack - Support for applications with multiple workers - Support for binds from multiple app workers to same ip:port - Switched to a message queue for io and control event notifications - Support for eventfd based notifications as alternative to mutext-condvar pair - VCL refactor to support async event notifications and multiple workers - TLS async support in client for HW accleration - Performance optimizations and bug-fixing - A number of binary APIs will be deprecated in favor of using the event message queue. Details in the API section. ## Known issues For the full list of issues please refer to fd.io [JIRA](https://jira.fd.io). ## Issues fixed 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/1810) ## 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 api_versions_reply definition changed app_cut_through_registration_add
/*
* Copyright (c) 2015 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* main.c: main vector processing loop
*
* Copyright (c) 2008 Eliot Dresselhaus
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <math.h>
#include <vppinfra/format.h>
#include <vlib/vlib.h>
#include <vlib/threads.h>
#include <vppinfra/tw_timer_1t_3w_1024sl_ov.h>
#include <vlib/unix/unix.h>
/* Actually allocate a few extra slots of vector data to support
speculative vector enqueues which overflow vector data in next frame. */
#define VLIB_FRAME_SIZE_ALLOC (VLIB_FRAME_SIZE + 4)
always_inline u32
vlib_frame_bytes (u32 n_scalar_bytes, u32 n_vector_bytes)
{
u32 n_bytes;
/* Make room for vlib_frame_t plus scalar arguments. */
n_bytes = vlib_frame_vector_byte_offset (n_scalar_bytes);
/* Make room for vector arguments.
Allocate a few extra slots of vector data to support
speculative vector enqueues which overflow vector data in next frame. */
#define VLIB_FRAME_SIZE_EXTRA 4
n_bytes += (VLIB_FRAME_SIZE + VLIB_FRAME_SIZE_EXTRA) * n_vector_bytes;
/* Magic number is first 32bit number after vector data.
Used to make sure that vector data is never overrun. */
#define VLIB_FRAME_MAGIC (0xabadc0ed)
n_bytes += sizeof (u32);
/* Pad to cache line. */
n_bytes = round_pow2 (n_bytes, CLIB_CACHE_LINE_BYTES);
return n_bytes;
}
always_inline u32 *
vlib_frame_find_magic (vlib_frame_t * f, vlib_node_t * node)
{
void *p = f;
p += vlib_frame_vector_byte_offset (node->scalar_size);
p += (VLIB_FRAME_SIZE + VLIB_FRAME_SIZE_EXTRA) * node->vector_size;
return p;
}
static inline vlib_frame_size_t *
get_frame_size_info (vlib_node_main_t * nm,
u32 n_scalar_bytes, u32 n_vector_bytes)
{
#ifdef VLIB_SUPPORTS_ARBITRARY_SCALAR_SIZES
uword key = (n_scalar_bytes << 16) | n_vector_bytes;
uword *p, i;
p = hash_get (nm->frame_size_hash, key);
if (p)
i = p[0];
else
{
i = vec_len (nm->frame_sizes);
vec_validate (nm->frame_sizes, i);
hash_set (nm->frame_size_hash, key, i);
}
return vec_elt_at_index (nm->frame_sizes, i);
#else
ASSERT (vlib_frame_bytes (n_scalar_bytes, n_vector_bytes)
== (vlib_frame_bytes (0, 4)));
return vec_elt_at_index (nm->frame_sizes, 0);
#endif
}
static vlib_frame_t *
vlib_frame_alloc_to_node (vlib_main_t * vm, u32 to_node_index,
u32 frame_flags)
{
vlib_node_main_t *nm = &vm->node_main;
vlib_frame_size_t *fs;
vlib_node_t *to_node;
vlib_frame_t *f;
u32 l, n, scalar_size, vector_size;
to_node = vlib_get_node (vm, to_node_index);
scalar_size = to_node->scalar_size;
vector_size = to_node->vector_size;
fs = get_frame_size_info (nm, scalar_size, vector_size);
n = vlib_frame_bytes (scalar_size, vector_size);
if ((l = vec_len (fs->free_frames)) > 0)
{
/* Allocate from end of free list. */
f = fs->free_frames[l - 1];
_vec_len (fs->free_frames) = l - 1;
}
else
{
f = clib_mem_alloc_aligned_no_fail (n, VLIB_FRAME_ALIGN);
}
/* Poison frame when debugging. */
if (CLIB_DEBUG > 0)
clib_memset (f, 0xfe, n);
/* Insert magic number. */
{
u32 *magic;
magic = vlib_frame_find_magic (f, to_node);
*magic = VLIB_FRAME_MAGIC;
}
f->frame_flags = VLIB_FRAME_IS_ALLOCATED | frame_flags;
f->n_vectors = 0;
f->scalar_size = scalar_size;
f->vector_size = vector_size;
f->flags = 0;
fs->n_alloc_frames += 1;
return f;
}
/* Allocate a frame for from FROM_NODE to TO_NODE via TO_NEXT_INDEX.
Returns frame index. */
static vlib_frame_t *
vlib_frame_alloc (vlib_main_t * vm, vlib_node_runtime_t * from_node_runtime,
u32 to_next_index)
{
vlib_node_t *from_node;
from_node = vlib_get_node (vm, from_node_runtime->node_index);
ASSERT (to_next_index < vec_len (from_node->next_nodes));
return vlib_frame_alloc_to_node (vm, from_node->next_nodes[to_next_index],
/* frame_flags */ 0);
}
vlib_frame_t *
vlib_get_frame_to_node (vlib_main_t * vm, u32 to_node_index)
{
vlib_frame_t *f = vlib_frame_alloc_to_node (vm, to_node_index,
/* frame_flags */
VLIB_FRAME_FREE_AFTER_DISPATCH);
return vlib_get_frame (vm, f);
}
static inline void
vlib_validate_frame_indices (vlib_frame_t * f)
{
if (CLIB_DEBUG > 0)
{
int i;
u32 *from = vlib_frame_vector_args (f);
/* Check for bad buffer index values */
for (i = 0; i < f->n_vectors; i++)
{
if (from[i] == 0)
{
clib_warning ("BUG: buffer index 0 at index %d", i);
ASSERT (0);
}
else if (from[i] == 0xfefefefe)
{
clib_warning ("BUG: frame poison pattern at index %d", i);
ASSERT (0);
}
}
}
}
void
vlib_put_frame_to_node (vlib_main_t * vm, u32 to_node_index, vlib_frame_t * f)
{
vlib_pending_frame_t *p;
vlib_node_t *to_node;
if (f->n_vectors == 0)
return;
vlib_validate_frame_indices (f);
to_node = vlib_get_node (vm, to_node_index);
vec_add2 (vm->node_main.pending_frames, p, 1);
f->frame_flags |= VLIB_FRAME_PENDING;
p->frame = vlib_get_frame (vm, f);
p->node_runtime_index = to_node->runtime_index;
p->next_frame_index = VLIB_PENDING_FRAME_NO_NEXT_FRAME;
}
/* Free given frame. */
void
vlib_frame_free (vlib_main_t * vm, vlib_node_runtime_t * r, vlib_frame_t * f)
{
vlib_node_main_t *nm = &vm->node_main;
vlib_node_t *node;
vlib_frame_size_t *fs;
ASSERT (f->frame_flags & VLIB_FRAME_IS_ALLOCATED);
node = vlib_get_node (vm, r->node_index);
fs = get_frame_size_info (nm, node->scalar_size, node->vector_size);
ASSERT (f->frame_flags & VLIB_FRAME_IS_ALLOCATED);
/* No next frames may point to freed frame. */
if (CLIB_DEBUG > 0)
{
vlib_next_frame_t *nf;
vec_foreach (nf, vm->node_main.next_frames) ASSERT (nf->frame != f);
}
f->frame_flags &= ~(VLIB_FRAME_IS_ALLOCATED | VLIB_FRAME_NO_APPEND);
vec_add1 (fs->free_frames, f);
ASSERT (fs->n_alloc_frames > 0);
fs->n_alloc_frames -= 1;
}
static clib_error_t *
show_frame_stats (vlib_main_t * vm,
unformat_input_t * input, vlib_cli_command_t * cmd)
{
vlib_node_main_t *nm = &vm->node_main;
vlib_frame_size_t *fs;
vlib_cli_output (vm, "%=6s%=12s%=12s", "Size", "# Alloc", "# Free");
vec_foreach (fs, nm->frame_sizes)
{
u32 n_alloc = fs->n_alloc_frames;
u32 n_free = vec_len (fs->free_frames);
if (n_alloc + n_free > 0)
vlib_cli_output (vm, "%=6d%=12d%=12d",
fs - nm->frame_sizes, n_alloc, n_free);
}
return 0;
}
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_frame_stats_cli, static) = {
.path = "show vlib frame-allocation",
.short_help = "Show node dispatch frame statistics",
.function = show_frame_stats,
};
/* *INDENT-ON* */
/* Change ownership of enqueue rights to given next node. */
static void
vlib_next_frame_change_ownership (vlib_main_t * vm,
vlib_node_runtime_t * node_runtime,
u32 next_index)
{
vlib_node_main_t *nm = &vm->node_main;
vlib_next_frame_t *next_frame;
vlib_node_t *node, *next_node;
node = vec_elt (nm->nodes, node_runtime->node_index);
/* Only internal & input nodes are allowed to call other nodes. */
ASSERT (node->type == VLIB_NODE_TYPE_INTERNAL
|| node->type == VLIB_NODE_TYPE_INPUT
|| node->type == VLIB_NODE_TYPE_PROCESS);
ASSERT (vec_len (node->next_nodes) == node_runtime->n_next_nodes);
next_frame =
vlib_node_runtime_get_next_frame (vm, node_runtime, next_index);
next_node = vec_elt (nm->nodes, node->next_nodes[next_index]);
if (next_node->owner_node_index != VLIB_INVALID_NODE_INDEX)
{
/* Get frame from previous owner. */
vlib_next_frame_t *owner_next_frame;
vlib_next_frame_t tmp;
owner_next_frame =
vlib_node_get_next_frame (vm,
next_node->owner_node_index,
next_node->owner_next_index);
/* Swap target next frame with owner's. */
tmp = owner_next_frame[0];
owner_next_frame[0] = next_frame[0];
next_frame[0] = tmp;
/*
* If next_frame is already pending, we have to track down
* all pending frames and fix their next_frame_index fields.
*/
if (next_frame->flags & VLIB_FRAME_PENDING)
{
vlib_pending_frame_t *p;
if (next_frame->frame != NULL)
{
vec_foreach (p, nm->pending_frames)
{
if (p->frame == next_frame->frame)
{
p->next_frame_index =
next_frame - vm->node_main.next_frames;
}
}
}
}
}
else
{
/* No previous owner. Take ownership. */
next_frame->flags |= VLIB_FRAME_OWNER;
}
/* Record new owner. */
next_node->owner_node_index = node->index;
next_node->owner_next_index = next_index;
/* Now we should be owner. */
ASSERT (next_frame->flags & VLIB_FRAME_OWNER);
}
/* Make sure that magic number is still there.
Otherwise, it is likely that caller has overrun frame arguments. */
always_inline void
validate_frame_magic (vlib_main_t * vm,
vlib_frame_t * f, vlib_node_t * n, uword next_index)
{
vlib_node_t *next_node = vlib_get_node (vm, n->next_nodes[next_index]);
u32 *magic = vlib_frame_find_magic (f, next_node);
ASSERT (VLIB_FRAME_MAGIC == magic[0]);
}
vlib_frame_t *
vlib_get_next_frame_internal (vlib_main_t * vm,
vlib_node_runtime_t * node,
u32 next_index, u32 allocate_new_next_frame)
{
vlib_frame_t *f;
vlib_next_frame_t *nf;
u32 n_used;
nf = vlib_node_runtime_get_next_frame (vm, node, next_index);
/* Make sure this next frame owns right to enqueue to destination frame. */
if (PREDICT_FALSE (!(nf->flags & VLIB_FRAME_OWNER)))
vlib_next_frame_change_ownership (vm, node, next_index);
/* ??? Don't need valid flag: can use frame_index == ~0 */
if (PREDICT_FALSE (!(nf->flags & VLIB_FRAME_IS_ALLOCATED)))
{
nf->frame = vlib_frame_alloc (vm, node, next_index);
nf->flags |= VLIB_FRAME_IS_ALLOCATED;
}
f = nf->frame;
/* Has frame been removed from pending vector (e.g. finished dispatching)?
If so we can reuse frame. */
if ((nf->flags & VLIB_FRAME_PENDING)
&& !(f->frame_flags & VLIB_FRAME_PENDING))
{
nf->flags &= ~VLIB_FRAME_PENDING;
f->n_vectors = 0;
f->flags = 0;
}
/* Allocate new frame if current one is marked as no-append or
it is already full. */
n_used = f->n_vectors;
if (n_used >= VLIB_FRAME_SIZE || (allocate_new_next_frame && n_used > 0) ||
(f->frame_flags & VLIB_FRAME_NO_APPEND))
{
/* Old frame may need to be freed after dispatch, since we'll have
two redundant frames from node -> next node. */
if (!(nf->flags & VLIB_FRAME_NO_FREE_AFTER_DISPATCH))
{
vlib_frame_t *f_old = vlib_get_frame (vm, nf->frame);
f_old->frame_flags |= VLIB_FRAME_FREE_AFTER_DISPATCH;
}
/* Allocate new frame to replace full one. */
f = nf->frame = vlib_frame_alloc (vm, node, next_index);
n_used = f->n_vectors;
}
/* Should have free vectors in frame now. */
ASSERT (n_used < VLIB_FRAME_SIZE);
if (CLIB_DEBUG > 0)
{
validate_frame_magic (vm, f,
vlib_get_node (vm, node->node_index), next_index);
}
return f;
}
static void
vlib_put_next_frame_validate (vlib_main_t * vm,
vlib_node_runtime_t * rt,
u32 next_index, u32 n_vectors_left)
{
vlib_node_main_t *nm = &vm->node_main;
vlib_next_frame_t *nf;
vlib_frame_t *f;
vlib_node_runtime_t *next_rt;
vlib_node_t *next_node;
u32 n_before, n_after;
nf = vlib_node_runtime_get_next_frame (vm, rt, next_index);
f = vlib_get_frame (vm, nf->frame);
ASSERT (n_vectors_left <= VLIB_FRAME_SIZE);
vlib_validate_frame_indices (f);
n_after = VLIB_FRAME_SIZE - n_vectors_left;
n_before = f->n_vectors;
ASSERT (n_after >= n_before);
next_rt = vec_elt_at_index (nm->nodes_by_type[VLIB_NODE_TYPE_INTERNAL],
nf->node_runtime_index);
next_node = vlib_get_node (vm, next_rt->node_index);
if (n_after > 0 && next_node->validate_frame)
{
u8 *msg = next_node->validate_frame (vm, rt, f);
if (msg)
{
clib_warning ("%v", msg);
ASSERT (0);
}
vec_free (msg);
}
}
void
vlib_put_next_frame (vlib_main_t * vm,
vlib_node_runtime_t * r,
u32 next_index, u32 n_vectors_left)
{
vlib_node_main_t *nm = &vm->node_main;
vlib_next_frame_t *nf;
vlib_frame_t *f;
u32 n_vectors_in_frame;
if (CLIB_DEBUG > 0)
vlib_put_next_frame_validate (vm, r, next_index, n_vectors_left);
nf = vlib_node_runtime_get_next_frame (vm, r, next_index);
f = vlib_get_frame (vm, nf->frame);
/* Make sure that magic number is still there. Otherwise, caller
has overrun frame meta data. */
if (CLIB_DEBUG > 0)
{
vlib_node_t *node = vlib_get_node (vm, r->node_index);
validate_frame_magic (vm, f, node, next_index);
}
/* Convert # of vectors left -> number of vectors there. */
ASSERT (n_vectors_left <= VLIB_FRAME_SIZE);
n_vectors_in_frame = VLIB_FRAME_SIZE - n_vectors_left;
f->n_vectors = n_vectors_in_frame;
/* If vectors were added to frame, add to pending vector. */
if (PREDICT_TRUE (n_vectors_in_frame > 0))
{
vlib_pending_frame_t *p;
u32 v0, v1;
r->cached_next_index = next_index;
if (!(f->frame_flags & VLIB_FRAME_PENDING))
{
__attribute__ ((unused)) vlib_node_t *node;
vlib_node_t *next_node;
vlib_node_runtime_t *next_runtime;
node = vlib_get_node (vm, r->node_index);
next_node = vlib_get_next_node (vm, r->node_index, next_index);
next_runtime = vlib_node_get_runtime (vm, next_node->index);
vec_add2 (nm->pending_frames, p, 1);
p->frame = nf->frame;
p->node_runtime_index = nf->node_runtime_index;
p->next_frame_index = nf - nm->next_frames;
nf->flags |= VLIB_FRAME_PENDING;
f->frame_flags |= VLIB_FRAME_PENDING;
/*
* If we're going to dispatch this frame on another thread,
* force allocation of a new frame. Otherwise, we create
* a dangling frame reference. Each thread has its own copy of
* the next_frames vector.
*/
if (0 && r->thread_index != next_runtime->thread_index)
{
nf->frame = NULL;
nf->flags &= ~(VLIB_FRAME_PENDING | VLIB_FRAME_IS_ALLOCATED);
}
}
/* Copy trace flag from next_frame and from runtime. */
nf->flags |=
(nf->flags & VLIB_NODE_FLAG_TRACE) | (r->
flags & VLIB_NODE_FLAG_TRACE);
v0 = nf->vectors_since_last_overflow;
v1 = v0 + n_vectors_in_frame;
nf->vectors_since_last_overflow = v1;
if (PREDICT_FALSE (v1 < v0))
{
vlib_node_t *node = vlib_get_node (vm, r->node_index);
vec_elt (node->n_vectors_by_next_node, next_index) += v0;
}
}
}
/* Sync up runtime (32 bit counters) and main node stats (64 bit counters). */
never_inline void
vlib_node_runtime_sync_stats (vlib_main_t * vm,
vlib_node_runtime_t * r,
uword n_calls, uword n_vectors, uword n_clocks)
{
vlib_node_t *n = vlib_get_node (vm, r->node_index);
n->stats_total.calls += n_calls + r->calls_since_last_overflow;
n->stats_total.vectors += n_vectors + r->vectors_since_last_overflow;
n->stats_total.clocks += n_clocks + r->clocks_since_last_overflow;
n->stats_total.max_clock = r->max_clock;
n->stats_total.max_clock_n = r->max_clock_n;
r->calls_since_last_overflow = 0;
r->vectors_since_last_overflow = 0;
r->clocks_since_last_overflow = 0;
}
always_inline void __attribute__ ((unused))
vlib_process_sync_stats (vlib_main_t * vm,
vlib_process_t * p,
uword n_calls, uword n_vectors, uword n_clocks)
{
vlib_node_runtime_t *rt = &p->node_runtime;
vlib_node_t *n = vlib_get_node (vm, rt->node_index);
vlib_node_runtime_sync_stats (vm, rt, n_calls, n_vectors, n_clocks);
n->stats_total.suspends += p->n_suspends;
p->n_suspends = 0;
}
void
vlib_node_sync_stats (vlib_main_t * vm, vlib_node_t * n)
{
vlib_node_runtime_t *rt;
if (n->type == VLIB_NODE_TYPE_PROCESS)
{
/* Nothing to do for PROCESS nodes except in main thread */
if (vm != &vlib_global_main)
return;
vlib_process_t *p = vlib_get_process_from_node (vm, n);
n->stats_total.suspends += p->n_suspends;
p->n_suspends = 0;
rt = &p->node_runtime;
}
else
rt =
vec_elt_at_index (vm->node_main.nodes_by_type[n->type],
n->runtime_index);
vlib_node_runtime_sync_stats (vm, rt, 0, 0, 0);
/* Sync up runtime next frame vector counters with main node structure. */
{
vlib_next_frame_t *nf;
uword i;
for (i = 0; i < rt->n_next_nodes; i++)
{
nf = vlib_node_runtime_get_next_frame (vm, rt, i);
vec_elt (n->n_vectors_by_next_node, i) +=
nf->vectors_since_last_overflow;
nf->vectors_since_last_overflow = 0;
}
}
}
always_inline u32
vlib_node_runtime_update_stats (vlib_main_t * vm,
vlib_node_runtime_t * node,
uword n_calls,
uword n_vectors, uword n_clocks)
{
u32 ca0, ca1, v0, v1, cl0, cl1, r;
cl0 = cl1 = node->clocks_since_last_overflow;
ca0 = ca1 = node->calls_since_last_overflow;
v0 = v1 = node->vectors_since_last_overflow;
ca1 = ca0 + n_calls;
v1 = v0 + n_vectors;
cl1 = cl0 + n_clocks;
node->calls_since_last_overflow = ca1;
node->clocks_since_last_overflow = cl1;
node->vectors_since_last_overflow = v1;
node->max_clock_n = node->max_clock > n_clocks ?
node->max_clock_n : n_vectors;
node->max_clock = node->max_clock > n_clocks ? node->max_clock : n_clocks;
r = vlib_node_runtime_update_main_loop_vector_stats (vm, node, n_vectors);
if (PREDICT_FALSE (ca1 < ca0 || v1 < v0 || cl1 < cl0))
{
node->calls_since_last_overflow = ca0;
node->clocks_since_last_overflow = cl0;
node->vectors_since_last_overflow = v0;
vlib_node_runtime_sync_stats (vm, node, n_calls, n_vectors, n_clocks);
}
return r;
}
always_inline void
vlib_process_update_stats (vlib_main_t * vm,
vlib_process_t * p,
uword n_calls, uword n_vectors, uword n_clocks)
{
vlib_node_runtime_update_stats (vm, &p->node_runtime,
n_calls, n_vectors, n_clocks);
}
static clib_error_t *
vlib_cli_elog_clear (vlib_main_t * vm,
unformat_input_t * input, vlib_cli_command_t * cmd)
{
elog_reset_buffer (&vm->elog_main);
return 0;
}
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (elog_clear_cli, static) = {
.path = "event-logger clear",
.short_help = "Clear the event log",
.function = vlib_cli_elog_clear,
};
/* *INDENT-ON* */
#ifdef CLIB_UNIX
static clib_error_t *
elog_save_buffer (vlib_main_t * vm,
unformat_input_t * input, vlib_cli_command_t * cmd)
{
elog_main_t *em = &vm->elog_main;
char *file, *chroot_file;
clib_error_t *error = 0;
if (!unformat (input, "%s", &file))
{
vlib_cli_output (vm, "expected file name, got `%U'",
format_unformat_error, input);
return 0;
}
/* It's fairly hard to get "../oopsie" through unformat; just in case */
if (strstr (file, "..") || index (file, '/'))
{
vlib_cli_output (vm, "illegal characters in filename '%s'", file);
return 0;
}
chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
vec_free (file);
vlib_cli_output (vm, "Saving %wd of %wd events to %s",
elog_n_events_in_buffer (em),
elog_buffer_capacity (em), chroot_file);
vlib_worker_thread_barrier_sync (vm);
error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
vlib_worker_thread_barrier_release (vm);
vec_free (chroot_file);
return error;
}
void
elog_post_mortem_dump (void)
{
vlib_main_t *vm = &vlib_global_main;
elog_main_t *em = &vm->elog_main;
u8 *filename;
clib_error_t *error;
if (!vm->elog_post_mortem_dump)
return;
filename = format (0, "/tmp/elog_post_mortem.%d%c", getpid (), 0);
error = elog_write_file (em, (char *) filename, 1 /* flush ring */ );
if (error)
clib_error_report (error);
vec_free (filename);
}
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (elog_save_cli, static) = {
.path = "event-logger save",
.short_help = "event-logger save <filename> (saves log in /tmp/<filename>)",
.function = elog_save_buffer,
};
/* *INDENT-ON* */
static clib_error_t *
elog_stop (vlib_main_t * vm,
unformat_input_t * input, vlib_cli_command_t * cmd)
{
elog_main_t *em = &vm->elog_main;
em->n_total_events_disable_limit = em->n_total_events;
vlib_cli_output (vm, "Stopped the event logger...");
return 0;
}
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (elog_stop_cli, static) = {
.path = "event-logger stop",
.short_help = "Stop the event-logger",
.function = elog_stop,
};
/* *INDENT-ON* */
static clib_error_t *
elog_restart (vlib_main_t * vm,
unformat_input_t * input, vlib_cli_command_t * cmd)
{
elog_main_t *em = &vm->elog_main;
em->n_total_events_disable_limit = ~0;
vlib_cli_output (vm, "Restarted the event logger...");
return 0;
}
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (elog_restart_cli, static) = {
.path = "event-logger restart",
.short_help = "Restart the event-logger",
.function = elog_restart,
};
/* *INDENT-ON* */
static clib_error_t *
elog_resize (vlib_main_t * vm,
unformat_input_t * input, vlib_cli_command_t * cmd)
{
elog_main_t *em = &vm->elog_main;
u32 tmp;
/* Stop the parade */
elog_reset_buffer (&vm->elog_main);
if (unformat (input, "%d", &tmp))
{
elog_alloc (em, tmp);
em->n_total_events_disable_limit = ~0;
}
else
return clib_error_return (0, "Must specify how many events in the ring");
vlib_cli_output (vm, "Resized ring and restarted the event logger...");
return 0;
}
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (elog_resize_cli, static) = {
.path = "event-logger resize",
.short_help = "event-logger resize <nnn>",
.function = elog_resize,
};
/* *INDENT-ON* */
#endif /* CLIB_UNIX */
static void
elog_show_buffer_internal (vlib_main_t * vm, u32 n_events_to_show)
{
elog_main_t *em = &vm->elog_main;
elog_event_t *e, *es;
f64 dt;
/* Show events in VLIB time since log clock starts after VLIB clock. */
dt = (em->init_time.cpu - vm->clib_time.init_cpu_time)
* vm->clib_time.seconds_per_clock;
es = elog_peek_events (em);
vlib_cli_output (vm, "%d of %d events in buffer, logger %s", vec_len (es),
em->event_ring_size,
em->n_total_events < em->n_total_events_disable_limit ?
"running" : "stopped");
vec_foreach (e, es)
{
vlib_cli_output (vm, "%18.9f: %U",
e->time + dt, format_elog_event, em, e);
n_events_to_show--;
if (n_events_to_show == 0)
break;
}
vec_free (es);
}
static clib_error_t *
elog_show_buffer (vlib_main_t * vm,
unformat_input_t * input, vlib_cli_command_t * cmd)
{
u32 n_events_to_show;
clib_error_t *error = 0;
n_events_to_show = 250;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
if (unformat (input, "%d", &n_events_to_show))
;
else if (unformat (input, "all"))
n_events_to_show = ~0;
else
return unformat_parse_error (input);
}
elog_show_buffer_internal (vm, n_events_to_show);
return error;
}
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (elog_show_cli, static) = {
.path = "show event-logger",
.short_help = "Show event logger info",
.function = elog_show_buffer,
};
/* *INDENT-ON* */
void
vlib_gdb_show_event_log (void)
{
elog_show_buffer_internal (vlib_get_main (), (u32) ~ 0);
}
static inline void
vlib_elog_main_loop_event (vlib_main_t * vm,
u32 node_index,
u64 time, u32 n_vectors, u32 is_return)
{
vlib_main_t *evm = &vlib_global_main;
elog_main_t *em = &evm->elog_main;
int enabled = evm->elog_trace_graph_dispatch |
evm->elog_trace_graph_circuit;
if (PREDICT_FALSE (enabled && n_vectors))
{
if (PREDICT_FALSE (!elog_is_enabled (em)))
{
evm->elog_trace_graph_dispatch = 0;
evm->elog_trace_graph_circuit = 0;
return;
}
if (PREDICT_TRUE
(evm->elog_trace_graph_dispatch ||
(evm->elog_trace_graph_circuit &&
node_index == evm->elog_trace_graph_circuit_node_index)))
{
elog_track (em,
/* event type */
vec_elt_at_index (is_return
? evm->node_return_elog_event_types
: evm->node_call_elog_event_types,
node_index),
/* track */
(vm->thread_index ?
&vlib_worker_threads[vm->thread_index].elog_track
: &em->default_track),
/* data to log */ n_vectors);
}
}
}
#if VLIB_BUFFER_TRACE_TRAJECTORY > 0
void (*vlib_buffer_trace_trajectory_cb) (vlib_buffer_t * b, u32 node_index);
void (*vlib_buffer_trace_trajectory_init_cb) (vlib_buffer_t * b);
void
vlib_buffer_trace_trajectory_init (vlib_buffer_t * b)
{
if (PREDICT_TRUE (vlib_buffer_trace_trajectory_init_cb != 0))
{
(*vlib_buffer_trace_trajectory_init_cb) (b);
}
}
#endif
static inline void
add_trajectory_trace (vlib_buffer_t * b, u32 node_index)
{
#if VLIB_BUFFER_TRACE_TRAJECTORY > 0
if (PREDICT_TRUE (vlib_buffer_trace_trajectory_cb != 0))
{
(*vlib_buffer_trace_trajectory_cb) (b, node_index);
}
#endif
}
u8 *format_vnet_buffer_flags (u8 * s, va_list * args) __attribute__ ((weak));
u8 *
format_vnet_buffer_flags (u8 * s, va_list * args)
{
s = format (s, "BUG STUB %s", __FUNCTION__);
return s;
}
u8 *format_vnet_buffer_opaque (u8 * s, va_list * args) __attribute__ ((weak));
u8 *
format_vnet_buffer_opaque (u8 * s, va_list * args)
{
s = format (s, "BUG STUB %s", __FUNCTION__);
return s;
}
u8 *format_vnet_buffer_opaque2 (u8 * s, va_list * args)
__attribute__ ((weak));
u8 *
format_vnet_buffer_opaque2 (u8 * s, va_list * args)
{
s = format (s, "BUG STUB %s", __FUNCTION__);
return s;
}
static u8 *
format_buffer_metadata (u8 * s, va_list * args)
{
vlib_buffer_t *b = va_arg (*args, vlib_buffer_t *);
s = format (s, "flags: %U\n", format_vnet_buffer_flags, b);
s = format (s, "current_data: %d, current_length: %d\n",
(i32) (b->current_data), (i32) (b->current_length));
s = format
(s,
"current_config_index/punt_reason: %d, flow_id: %x, next_buffer: %x\n",
b->current_config_index, b->flow_id, b->next_buffer);
s =
format (s, "error: %d, ref_count: %d, buffer_pool_index: %d\n",
(u32) (b->error), (u32) (b->ref_count),
(u32) (b->buffer_pool_index));
s =
format (s, "trace_handle: 0x%x, len_not_first_buf: %d\n", b->trace_handle,
b->total_length_not_including_first_buffer);
return s;
}
#define A(x) vec_add1(vm->pcap_buffer, (x))
static void
dispatch_pcap_trace (vlib_main_t * vm,
vlib_node_runtime_t * node, vlib_frame_t * frame)
{
int i;
vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **bufp, *b;
pcap_main_t *pm = &vlib_global_main.dispatch_pcap_main;
vlib_trace_main_t *tm = &vm->trace_main;
u32 capture_size;
vlib_node_t *n;
i32 n_left;
f64 time_now = vlib_time_now (vm);
u32 *from;
u8 *d;
u8 string_count;
/* Input nodes don't have frames yet */
if (frame == 0 || frame->n_vectors == 0)
return;
from = vlib_frame_vector_args (frame);
vlib_get_buffers (vm, from, bufs, frame->n_vectors);
bufp = bufs;
n = vlib_get_node (vm, node->node_index);
for (i = 0; i < frame->n_vectors; i++)
{
if (PREDICT_TRUE (pm->n_packets_captured < pm->n_packets_to_capture))
{
b = bufp[i];
vec_reset_length (vm->pcap_buffer);
string_count = 0;
/* Version, flags */
A ((u8) VLIB_PCAP_MAJOR_VERSION);
A ((u8) VLIB_PCAP_MINOR_VERSION);
A (0 /* string_count */ );
A (n->protocol_hint);
/* Buffer index (big endian) */
A ((from[i] >> 24) & 0xff);
A ((from[i] >> 16) & 0xff);
A ((from[i] >> 8) & 0xff);
A ((from[i] >> 0) & 0xff);
/* Node name, NULL-terminated ASCII */
vm->pcap_buffer = format (vm->pcap_buffer, "%v%c", n->name, 0);
string_count++;
vm->pcap_buffer = format (vm->pcap_buffer, "%U%c",
format_buffer_metadata, b, 0);
string_count++;
vm->pcap_buffer = format (vm->pcap_buffer, "%U%c",
format_vnet_buffer_opaque, b, 0);
string_count++;
vm->pcap_buffer = format (vm->pcap_buffer, "%U%c",
format_vnet_buffer_opaque2, b, 0);
string_count++;
/* Is this packet traced? */
if (PREDICT_FALSE (b->flags & VLIB_BUFFER_IS_TRACED))
{
vlib_trace_header_t **h
= pool_elt_at_index (tm->trace_buffer_pool,
vlib_buffer_get_trace_index (b));
vm->pcap_buffer = format (vm->pcap_buffer, "%U%c",
format_vlib_trace, vm, h[0], 0);
string_count++;
}
/* Save the string count */
vm->pcap_buffer[2] = string_count;
/* Figure out how many bytes in the pcap trace */
capture_size = vec_len (vm->pcap_buffer) +
+vlib_buffer_length_in_chain (vm, b);
clib_spinlock_lock_if_init (&pm->lock);
n_left = clib_min (capture_size, 16384);
d = pcap_add_packet (pm, time_now, n_left, capture_size);
/* Copy the header */
clib_memcpy_fast (d, vm->pcap_buffer, vec_len (vm->pcap_buffer));
d += vec_len (vm->pcap_buffer);
n_left = clib_min
(vlib_buffer_length_in_chain (vm, b),
(16384 - vec_len (vm->pcap_buffer)));
/* Copy the packet data */
while (1)
{
u32 copy_length = clib_min ((u32) n_left, b->current_length);
clib_memcpy_fast (d, b->data + b->current_data, copy_length);
n_left -= b->current_length;
if (n_left <= 0)
break;
d += b->current_length;
ASSERT (b->flags & VLIB_BUFFER_NEXT_PRESENT);
b = vlib_get_buffer (vm, b->next_buffer);
}
clib_spinlock_unlock_if_init (&pm->lock);
}
}
}
static_always_inline u64
dispatch_node (vlib_main_t * vm,
vlib_node_runtime_t * node,
vlib_node_type_t type,
vlib_node_state_t dispatch_state,
vlib_frame_t * frame, u64 last_time_stamp)
{
uword n, v;
u64 t;
vlib_node_main_t *nm = &vm->node_main;
vlib_next_frame_t *nf;
if (CLIB_DEBUG > 0)
{
vlib_node_t *n = vlib_get_node (vm, node->node_index);
ASSERT (n->type == type);
}
/* Only non-internal nodes may be disabled. */
if (type != VLIB_NODE_TYPE_INTERNAL && node->state != dispatch_state)
{
ASSERT (type != VLIB_NODE_TYPE_INTERNAL);
return last_time_stamp;
}
if ((type == VLIB_NODE_TYPE_PRE_INPUT || type == VLIB_NODE_TYPE_INPUT)
&& dispatch_state != VLIB_NODE_STATE_INTERRUPT)
{
u32 c = node->input_main_loops_per_call;
/* Only call node when count reaches zero. */
if (c)
{
node->input_main_loops_per_call = c - 1;
return last_time_stamp;
}
}
/* Speculatively prefetch next frames. */
if (node->n_next_nodes > 0)
{
nf = vec_elt_at_index (nm->next_frames, node->next_frame_index);
CLIB_PREFETCH (nf, 4 * sizeof (nf[0]), WRITE);
}
vm->cpu_time_last_node_dispatch = last_time_stamp;
vlib_elog_main_loop_event (vm, node->node_index,
last_time_stamp, frame ? frame->n_vectors : 0,
/* is_after */ 0);
vlib_node_runtime_perf_counter (vm, node, frame, 0, last_time_stamp,
VLIB_NODE_RUNTIME_PERF_BEFORE);
/*
* Turn this on if you run into
* "bad monkey" contexts, and you want to know exactly
* which nodes they've visited... See ixge.c...
*/
if (VLIB_BUFFER_TRACE_TRAJECTORY && frame)
{
int i;
u32 *from;
from = vlib_frame_vector_args (frame);
for (i = 0; i < frame->n_vectors; i++)
{
vlib_buffer_t *b = vlib_get_buffer (vm, from[i]);
add_trajectory_trace (b, node->node_index);
}
if (PREDICT_FALSE (vm->dispatch_pcap_enable))
dispatch_pcap_trace (vm, node, frame);
n = node->function (vm, node, frame);
}
else
{
if (PREDICT_FALSE (vm->dispatch_pcap_enable))
dispatch_pcap_trace (vm, node, frame);
n = node->function (vm, node, frame);
}
t = clib_cpu_time_now ();
vlib_node_runtime_perf_counter (vm, node, frame, n, t,
VLIB_NODE_RUNTIME_PERF_AFTER);
vlib_elog_main_loop_event (vm, node->node_index, t, n, 1 /* is_after */ );
vm->main_loop_vectors_processed += n;
vm->main_loop_nodes_processed += n > 0;
v = vlib_node_runtime_update_stats (vm, node,
/* n_calls */ 1,
/* n_vectors */ n,
/* n_clocks */ t - last_time_stamp);
/* When in interrupt mode and vector rate crosses threshold switch to
polling mode. */
if (PREDICT_FALSE ((dispatch_state == VLIB_NODE_STATE_INTERRUPT)
|| (dispatch_state == VLIB_NODE_STATE_POLLING
&& (node->flags
&
VLIB_NODE_FLAG_SWITCH_FROM_INTERRUPT_TO_POLLING_MODE))))
{
/* *INDENT-OFF* */
ELOG_TYPE_DECLARE (e) =
{
.function = (char *) __FUNCTION__,
.format = "%s vector length %d, switching to %s",
.format_args = "T4i4t4",
.n_enum_strings = 2,
.enum_strings = {
"interrupt", "polling",
},
};
/* *INDENT-ON* */
struct
{
u32 node_name, vector_length, is_polling;
} *ed;
if ((dispatch_state == VLIB_NODE_STATE_INTERRUPT
&& v >= nm->polling_threshold_vector_length) &&
!(node->flags &
VLIB_NODE_FLAG_SWITCH_FROM_INTERRUPT_TO_POLLING_MODE))
{
vlib_node_t *n = vlib_get_node (vm, node->node_index);
n->state = VLIB_NODE_STATE_POLLING;
node->state = VLIB_NODE_STATE_POLLING;
node->flags &=
~VLIB_NODE_FLAG_SWITCH_FROM_POLLING_TO_INTERRUPT_MODE;
node->flags |= VLIB_NODE_FLAG_SWITCH_FROM_INTERRUPT_TO_POLLING_MODE;
nm->input_node_counts_by_state[VLIB_NODE_STATE_INTERRUPT] -= 1;
nm->input_node_counts_by_state[VLIB_NODE_STATE_POLLING] += 1;
if (PREDICT_FALSE (vlib_global_main.elog_trace_graph_dispatch))
{
vlib_worker_thread_t *w = vlib_worker_threads
+ vm->thread_index;
ed = ELOG_TRACK_DATA (&vlib_global_main.elog_main, e,
w->elog_track);
ed->node_name = n->name_elog_string;
ed->vector_length = v;
ed->is_polling = 1;
}
}
else if (dispatch_state == VLIB_NODE_STATE_POLLING
&& v <= nm->interrupt_threshold_vector_length)
{
vlib_node_t *n = vlib_get_node (vm, node->node_index);
if (node->flags &
VLIB_NODE_FLAG_SWITCH_FROM_POLLING_TO_INTERRUPT_MODE)
{
/* Switch to interrupt mode after dispatch in polling one more time.
This allows driver to re-enable interrupts. */
n->state = VLIB_NODE_STATE_INTERRUPT;
node->state = VLIB_NODE_STATE_INTERRUPT;
node->flags &=
~VLIB_NODE_FLAG_SWITCH_FROM_INTERRUPT_TO_POLLING_MODE;
nm->input_node_counts_by_state[VLIB_NODE_STATE_POLLING] -= 1;
nm->input_node_counts_by_state[VLIB_NODE_STATE_INTERRUPT] += 1;
}
else
{
vlib_worker_thread_t *w = vlib_worker_threads
+ vm->thread_index;
node->flags |=
VLIB_NODE_FLAG_SWITCH_FROM_POLLING_TO_INTERRUPT_MODE;
if (PREDICT_FALSE (vlib_global_main.elog_trace_graph_dispatch))
{
ed = ELOG_TRACK_DATA (&vlib_global_main.elog_main, e,
w->elog_track);
ed->node_name = n->name_elog_string;
ed->vector_length = v;
ed->is_polling = 0;
}
}
}
}
return t;
}
static u64
dispatch_pending_node (vlib_main_t * vm, uword pending_frame_index,
u64 last_time_stamp)
{
vlib_node_main_t *nm = &vm->node_main;
vlib_frame_t *f;
vlib_next_frame_t *nf, nf_placeholder;
vlib_node_runtime_t *n;
vlib_frame_t *restore_frame;
vlib_pending_frame_t *p;
/* See comment below about dangling references to nm->pending_frames */
p = nm->pending_frames + pending_frame_index;
n = vec_elt_at_index (nm->nodes_by_type[VLIB_NODE_TYPE_INTERNAL],
p->node_runtime_index);
f = vlib_get_frame (vm, p->frame);
if (p->next_frame_index == VLIB_PENDING_FRAME_NO_NEXT_FRAME)
{
/* No next frame: so use placeholder on stack. */
nf = &nf_placeholder;
nf->flags = f->frame_flags & VLIB_NODE_FLAG_TRACE;
nf->frame = NULL;
}
else
nf = vec_elt_at_index (nm->next_frames, p->next_frame_index);
ASSERT (f->frame_flags & VLIB_FRAME_IS_ALLOCATED);
/* Force allocation of new frame while current frame is being
dispatched. */
restore_frame = NULL;
if (nf->frame == p->frame)
{
nf->frame = NULL;
nf->flags &= ~VLIB_FRAME_IS_ALLOCATED;
if (!(n->flags & VLIB_NODE_FLAG_FRAME_NO_FREE_AFTER_DISPATCH))
restore_frame = p->frame;
}
/* Frame must be pending. */
ASSERT (f->frame_flags & VLIB_FRAME_PENDING);
ASSERT (f->n_vectors > 0);
/* Copy trace flag from next frame to node.
Trace flag indicates that at least one vector in the dispatched
frame is traced. */
n->flags &= ~VLIB_NODE_FLAG_TRACE;
n->flags |= (nf->flags & VLIB_FRAME_TRACE) ? VLIB_NODE_FLAG_TRACE : 0;
nf->flags &= ~VLIB_FRAME_TRACE;
last_time_stamp = dispatch_node (vm, n,
VLIB_NODE_TYPE_INTERNAL,
VLIB_NODE_STATE_POLLING,
f, last_time_stamp);
/* Internal node vector-rate accounting, for summary stats */
vm->internal_node_vectors += f->n_vectors;
vm->internal_node_calls++;
vm->internal_node_last_vectors_per_main_loop =
(f->n_vectors > vm->internal_node_last_vectors_per_main_loop) ?
f->n_vectors : vm->internal_node_last_vectors_per_main_loop;
f->frame_flags &= ~(VLIB_FRAME_PENDING | VLIB_FRAME_NO_APPEND);
/* Frame is ready to be used again, so restore it. */
if (restore_frame != NULL)
{
/*
* We musn't restore a frame that is flagged to be freed. This
* shouldn't happen since frames to be freed post dispatch are
* those used when the to-node frame becomes full i.e. they form a
* sort of queue of frames to a single node. If we get here then
* the to-node frame and the pending frame *were* the same, and so
* we removed the to-node frame. Therefore this frame is no
* longer part of the queue for that node and hence it cannot be
* it's overspill.
*/
ASSERT (!(f->frame_flags & VLIB_FRAME_FREE_AFTER_DISPATCH));
/*
* NB: dispatching node n can result in the creation and scheduling
* of new frames, and hence in the reallocation of nm->pending_frames.
* Recompute p, or no supper. This was broken for more than 10 years.
*/
p = nm->pending_frames + pending_frame_index;
/*
* p->next_frame_index can change during node dispatch if node
* function decides to change graph hook up.
*/
nf = vec_elt_at_index (nm->next_frames, p->next_frame_index);
nf->flags |= VLIB_FRAME_IS_ALLOCATED;
if (NULL == nf->frame)
{
/* no new frame has been assigned to this node, use the saved one */
nf->frame = restore_frame;
f->n_vectors = 0;
}
else
{
/* The node has gained a frame, implying packets from the current frame
were re-queued to this same node. we don't need the saved one
anymore */
vlib_frame_free (vm, n, f);
}
}
else
{
if (f->frame_flags & VLIB_FRAME_FREE_AFTER_DISPATCH)
{
ASSERT (!(n->flags & VLIB_NODE_FLAG_FRAME_NO_FREE_AFTER_DISPATCH));
vlib_frame_free (vm, n, f);
}
}
return last_time_stamp;
}
always_inline uword
vlib_process_stack_is_valid (vlib_process_t * p)
{
return p->stack[0] == VLIB_PROCESS_STACK_MAGIC;
}
typedef struct
{
vlib_main_t *vm;
vlib_process_t *process;
vlib_frame_t *frame;
} vlib_process_bootstrap_args_t;
/* Called in process stack. */
static uword
vlib_process_bootstrap (uword _a)
{
vlib_process_bootstrap_args_t *a;
vlib_main_t *vm;
vlib_node_runtime_t *node;
vlib_frame_t *f;
vlib_process_t *p;
uword n;
a = uword_to_pointer (_a, vlib_process_bootstrap_args_t *);
vm = a->vm;
p = a->process;
vlib_process_finish_switch_stack (vm);
f = a->frame;
node = &p->node_runtime;
n = node->function (vm, node, f);
ASSERT (vlib_process_stack_is_valid (p));
vlib_process_start_switch_stack (vm, 0);
clib_longjmp (&p->return_longjmp, n);
return n;
}
/* Called in main stack. */
static_always_inline uword
vlib_process_startup (vlib_main_t * vm, vlib_process_t * p, vlib_frame_t * f)
{
vlib_process_bootstrap_args_t a;
uword r;
a.vm = vm;
a.process = p;
a.frame = f;
r = clib_setjmp (&p->return_longjmp, VLIB_PROCESS_RETURN_LONGJMP_RETURN);
if (r == VLIB_PROCESS_RETURN_LONGJMP_RETURN)
{
vlib_process_start_switch_stack (vm, p);
r = clib_calljmp (vlib_process_bootstrap, pointer_to_uword (&a),
(void *) p->stack + (1 << p->log2_n_stack_bytes));
}
else
vlib_process_finish_switch_stack (vm);
return r;
}