# Release Notes {#release_notes} * @subpage release_notes_2001 * @subpage release_notes_1908 * @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_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/gitwe }
/*
* Copyright (c) 2018 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.
*/
/*
* ethernet_node.c: ethernet packet processing
*
* 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 <vlib/vlib.h>
#include <vnet/pg/pg.h>
#include <vnet/ethernet/ethernet.h>
#include <vnet/ethernet/p2p_ethernet.h>
#include <vnet/devices/pipe/pipe.h>
#include <vppinfra/sparse_vec.h>
#include <vnet/l2/l2_bvi.h>
#define foreach_ethernet_input_next \
_ (PUNT, "error-punt") \
_ (DROP, "error-drop") \
_ (LLC, "llc-input") \
_ (IP4_INPUT, "ip4-input") \
_ (IP4_INPUT_NCS, "ip4-input-no-checksum")
typedef enum
{
#define _(s,n) ETHERNET_INPUT_NEXT_##s,
foreach_ethernet_input_next
#undef _
ETHERNET_INPUT_N_NEXT,
} ethernet_input_next_t;
typedef struct
{
u8 packet_data[32];
u16 frame_flags;
ethernet_input_frame_t frame_data;
} ethernet_input_trace_t;
static u8 *
format_ethernet_input_trace (u8 * s, va_list * va)
{
CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
ethernet_input_trace_t *t = va_arg (*va, ethernet_input_trace_t *);
u32 indent = format_get_indent (s);
if (t->frame_flags)
{
s = format (s, "frame: flags 0x%x", t->frame_flags);
if (t->frame_flags & ETH_INPUT_FRAME_F_SINGLE_SW_IF_IDX)
s = format (s, ", hw-if-index %u, sw-if-index %u",
t->frame_data.hw_if_index, t->frame_data.sw_if_index);
s = format (s, "\n%U", format_white_space, indent);
}
s = format (s, "%U", format_ethernet_header, t->packet_data);
return s;
}
extern vlib_node_registration_t ethernet_input_node;
typedef enum
{
ETHERNET_INPUT_VARIANT_ETHERNET,
ETHERNET_INPUT_VARIANT_ETHERNET_TYPE,
ETHERNET_INPUT_VARIANT_NOT_L2,
} ethernet_input_variant_t;
// Parse the ethernet header to extract vlan tags and innermost ethertype
static_always_inline void
parse_header (ethernet_input_variant_t variant,
vlib_buffer_t * b0,
u16 * type,
u16 * orig_type,
u16 * outer_id, u16 * inner_id, u32 * match_flags)
{
u8 vlan_count;
if (variant == ETHERNET_INPUT_VARIANT_ETHERNET
|| variant == ETHERNET_INPUT_VARIANT_NOT_L2)
{
ethernet_header_t *e0;
e0 = (void *) (b0->data + b0->current_data);
vnet_buffer (b0)->l2_hdr_offset = b0->current_data;
b0->flags |= VNET_BUFFER_F_L2_HDR_OFFSET_VALID;
vlib_buffer_advance (b0, sizeof (e0[0]));
*type = clib_net_to_host_u16 (e0->type);
}
else if (variant == ETHERNET_INPUT_VARIANT_ETHERNET_TYPE)
{
// here when prior node was LLC/SNAP processing
u16 *e0;
e0 = (void *) (b0->data + b0->current_data);
vlib_buffer_advance (b0, sizeof (e0[0]));
*type = clib_net_to_host_u16 (e0[0]);
}
// save for distinguishing between dot1q and dot1ad later
*orig_type = *type;
// default the tags to 0 (used if there is no corresponding tag)
*outer_id = 0;
*inner_id = 0;
*match_flags = SUBINT_CONFIG_VALID | SUBINT_CONFIG_MATCH_0_TAG;
vlan_count = 0;
// check for vlan encaps
if (ethernet_frame_is_tagged (*type))
{
ethernet_vlan_header_t *h0;
u16 tag;
*match_flags = SUBINT_CONFIG_VALID | SUBINT_CONFIG_MATCH_1_TAG;
h0 = (void *) (b0->data + b0->current_data);
tag = clib_net_to_host_u16 (h0->priority_cfi_and_id);
*outer_id = tag & 0xfff;
if (0 == *outer_id)
*match_flags &= ~SUBINT_CONFIG_MATCH_1_TAG;
*type = clib_net_to_host_u16 (h0->type);
vlib_buffer_advance (b0, sizeof (h0[0]));
vlan_count = 1;
if (*type == ETHERNET_TYPE_VLAN)
{
// Double tagged packet
*match_flags = SUBINT_CONFIG_VALID | SUBINT_CONFIG_MATCH_2_TAG;
h0 = (void *) (b0->data + b0->current_data);
tag = clib_net_to_host_u16 (h0->priority_cfi_and_id);
*inner_id = tag & 0xfff;
*type = clib_net_to_host_u16 (h0->type);
vlib_buffer_advance (b0, sizeof (h0[0]));
vlan_count = 2;
if (*type == ETHERNET_TYPE_VLAN)
{
// More than double tagged packet
*match_flags = SUBINT_CONFIG_VALID | SUBINT_CONFIG_MATCH_3_TAG;
vlib_buffer_advance (b0, sizeof (h0[0]));
vlan_count = 3; // "unknown" number, aka, 3-or-more
}
}
}
ethernet_buffer_set_vlan_count (b0, vlan_count);
}
// Determine the subinterface for this packet, given the result of the
// vlan table lookups and vlan header parsing. Check the most specific
// matches first.
static_always_inline void
identify_subint (vnet_hw_interface_t * hi,
vlib_buffer_t * b0,
u32 match_flags,
main_intf_t * main_intf,
vlan_intf_t * vlan_intf,
qinq_intf_t * qinq_intf,
u32 * new_sw_if_index, u8 * error0, u32 * is_l2)
{
u32 matched;
matched = eth_identify_subint (hi, match_flags, main_intf, vlan_intf,
qinq_intf, new_sw_if_index, error0, is_l2);
if (matched)
{
// Perform L3 my-mac filter
// A unicast packet arriving on an L3 interface must have a dmac matching the interface mac.
// This is required for promiscuous mode, else we will forward packets we aren't supposed to.
if (!(*is_l2))
{
ethernet_header_t *e0;
e0 = (void *) (b0->data + vnet_buffer (b0)->l2_hdr_offset);
if (!(ethernet_address_cast (e0->dst_address)))
{
if (!ethernet_mac_address_equal ((u8 *) e0, hi->hw_address))
{
*error0 = ETHERNET_ERROR_L3_MAC_MISMATCH;
}
}
}
// Check for down subinterface
*error0 = (*new_sw_if_index) != ~0 ? (*error0) : ETHERNET_ERROR_DOWN;
}
}
static_always_inline void
determine_next_node (ethernet_main_t * em,
ethernet_input_variant_t variant,
u32 is_l20,
u32 type0, vlib_buffer_t * b0, u8 * error0, u8 * next0)
{
vnet_buffer (b0)->l3_hdr_offset = b0->current_data;
b0->flags |= VNET_BUFFER_F_L3_HDR_OFFSET_VALID;
if (PREDICT_FALSE (*error0 != ETHERNET_ERROR_NONE))
{
// some error occurred
*next0 = ETHERNET_INPUT_NEXT_DROP;
}
else if (is_l20)
{
// record the L2 len and reset the buffer so the L2 header is preserved
u32 eth_start = vnet_buffer (b0)->l2_hdr_offset;
vnet_buffer (b0)->l2.l2_len = b0->current_data - eth_start;
*next0 = em->l2_next;
ASSERT (vnet_buffer (b0)->l2.l2_len ==
ethernet_buffer_header_size (b0));
vlib_buffer_advance (b0, -(vnet_buffer (b0)->l2.l2_len));
// check for common IP/MPLS ethertypes
}
else if (type0 == ETHERNET_TYPE_IP4)
{
*next0 = em->l3_next.input_next_ip4;
}
else if (type0 == ETHERNET_TYPE_IP6)
{
*next0 = em->l3_next.input_next_ip6;
}
else if (type0 == ETHERNET_TYPE_MPLS)
{
*next0 = em->l3_next.input_next_mpls;
}
else if (em->redirect_l3)
{
// L3 Redirect is on, the cached common next nodes will be
// pointing to the redirect node, catch the uncommon types here
*next0 = em->redirect_l3_next;
}
else
{
// uncommon ethertype, check table
u32 i0;
i0 = sparse_vec_index (em->l3_next.input_next_by_type, type0);
*next0 = vec_elt (em->l3_next.input_next_by_type, i0);
*error0 =
i0 ==
SPARSE_VEC_INVALID_INDEX ? ETHERNET_ERROR_UNKNOWN_TYPE : *error0;
// The table is not populated with LLC values, so check that now.
// If variant is variant_ethernet then we came from LLC processing. Don't
// go back there; drop instead using by keeping the drop/bad table result.
if ((type0 < 0x600) && (variant == ETHERNET_INPUT_VARIANT_ETHERNET))
{
*next0 = ETHERNET_INPUT_NEXT_LLC;
}
}
}
/* following vector code relies on following assumptions */
STATIC_ASSERT_OFFSET_OF (vlib_buffer_t, current_data, 0);
STATIC_ASSERT_OFFSET_OF (vlib_buffer_t, current_length, 2);
STATIC_ASSERT_OFFSET_OF (vlib_buffer_t, flags, 4);
STATIC_ASSERT (STRUCT_OFFSET_OF (vnet_buffer_opaque_t, l2_hdr_offset) ==
STRUCT_OFFSET_OF (vnet_buffer_opaque_t, l3_hdr_offset) - 2,
"l3_hdr_offset must follow l2_hdr_offset");
static_always_inline void
eth_input_adv_and_flags_x4 (vlib_buffer_t ** b, int is_l3)
{
i16 adv = sizeof (ethernet_header_t);
u32 flags = VNET_BUFFER_F_L2_HDR_OFFSET_VALID |
VNET_BUFFER_F_L3_HDR_OFFSET_VALID;
#ifdef CLIB_HAVE_VEC256
/* to reduce number of small loads/stores we are loading first 64 bits
of each buffer metadata into 256-bit register so we can advance
current_data, current_length and flags.
Observed saving of this code is ~2 clocks per packet */
u64x4 r, radv;
/* vector if signed 16 bit integers used in signed vector add operation
to advnce current_data and current_length */
u32x8 flags4 = { 0, flags, 0, flags, 0, flags, 0, flags };
i16x16 adv4 = {
adv, -adv, 0, 0, adv, -adv, 0, 0,
adv, -adv, 0, 0, adv, -adv, 0, 0
};
/* load 4 x 64 bits */
r = u64x4_gather (b[0], b[1], b[2], b[3]);
/* set flags */
r |= (u64x4) flags4;
/* advance buffer */
radv = (u64x4) ((i16x16) r + adv4);
/* write 4 x 64 bits */
u64x4_scatter (is_l3 ? radv : r, b[0], b[1], b[2], b[3]);
/* use old current_data as l2_hdr_offset and new current_data as
l3_hdr_offset */
r = (u64x4) u16x16_blend (r, radv << 16, 0xaa);
/* store both l2_hdr_offset and l3_hdr_offset in single store operation */
u32x8_scatter_one ((u32x8) r, 0, &vnet_buffer (b[0])->l2_hdr_offset);
u32x8_scatter_one ((u32x8) r, 2, &vnet_buffer (b[1])->l2_hdr_offset);
u32x8_scatter_one ((u32x8) r, 4, &vnet_buffer (b[2])->l2_hdr_offset);
u32x8_scatter_one ((u32x8) r, 6, &vnet_buffer (b[3])->l2_hdr_offset);
if (is_l3)
{
ASSERT (b[0]->current_data == vnet_buffer (b[0])->l3_hdr_offset);
ASSERT (b[1]->current_data == vnet_buffer (b[1])->l3_hdr_offset);
ASSERT (b[2]->current_data == vnet_buffer (b[2])->l3_hdr_offset);
ASSERT (b[3]->current_data == vnet_buffer (b[3])->l3_hdr_offset);
ASSERT (b[0]->current_data - vnet_buffer (b[0])->l2_hdr_offset == adv);
ASSERT (b[1]->current_data - vnet_buffer (b[1])->l2_hdr_offset == adv);
ASSERT (b[2]->current_data - vnet_buffer (b[2])->l2_hdr_offset == adv);
ASSERT (b[3]->current_data - vnet_buffer (b[3])->l2_hdr_offset == adv);
}
else
{
ASSERT (b[0]->current_data == vnet_buffer (b[0])->l2_hdr_offset);
ASSERT (b[1]->current_data == vnet_buffer (b[1])->l2_hdr_offset);
ASSERT (b[2]->current_data == vnet_buffer (b[2])->l2_hdr_offset);
ASSERT (b[3]->current_data == vnet_buffer (b[3])->l2_hdr_offset);
ASSERT (b[0]->current_data - vnet_buffer (b[0])->l3_hdr_offset == -adv);
ASSERT (b[1]->current_data - vnet_buffer (b[1])->l3_hdr_offset == -adv);
ASSERT (b[2]->current_data - vnet_buffer (b[2])->l3_hdr_offset == -adv);
ASSERT (b[3]->current_data - vnet_buffer (b[3])->l3_hdr_offset == -adv);
}
#else
vnet_buffer (b[0])->l2_hdr_offset = b[0]->current_data;
vnet_buffer (b[1])->l2_hdr_offset = b[1]->current_data;
vnet_buffer (b[2])->l2_hdr_offset = b[2]->current_data;
vnet_buffer (b[3])->l2_hdr_offset = b[3]->current_data;
vnet_buffer (b[0])->l3_hdr_offset = b[0]->current_data + adv;
vnet_buffer (b[1])->l3_hdr_offset = b[1]->current_data + adv;
vnet_buffer (b[2])->l3_hdr_offset = b[2]->current_data + adv;
vnet_buffer (b[3])->l3_hdr_offset = b[3]->current_data + adv;
if (is_l3)
{
vlib_buffer_advance (b[0], adv);
vlib_buffer_advance (b[1], adv);
vlib_buffer_advance (b[2], adv);
vlib_buffer_advance (b[3], adv);
}
b[0]->flags |= flags;
b[1]->flags |= flags;
b[2]->flags |= flags;
b[3]->flags |= flags;
#endif
if (!is_l3)
{
vnet_buffer (b[0])->l2.l2_len = adv;
vnet_buffer (b[1])->l2.l2_len = adv;
vnet_buffer (b[2])->l2.l2_len = adv;
vnet_buffer (b[3])->l2.l2_len = adv;
}
}
static_always_inline void
eth_input_adv_and_flags_x1 (vlib_buffer_t ** b, int is_l3)
{
i16 adv = sizeof (ethernet_header_t);
u32 flags = VNET_BUFFER_F_L2_HDR_OFFSET_VALID |
VNET_BUFFER_F_L3_HDR_OFFSET_VALID;
vnet_buffer (b[0])->l2_hdr_offset = b[0]->current_data;
vnet_buffer (b[0])->l3_hdr_offset = b[0]->current_data + adv;
if (is_l3)
vlib_buffer_advance (b[0], adv);
b[0]->flags |= flags;
if (!is_l3)
vnet_buffer (b[0])->l2.l2_len = adv;
}
static_always_inline void
eth_input_get_etype_and_tags (vlib_buffer_t ** b, u16 * etype, u64 * tags,
u64 * dmacs, int offset, int dmac_check)
{
ethernet_header_t *e;
e = vlib_buffer_get_current (b[offset]);
#ifdef CLIB_HAVE_VEC128
u64x2 r = u64x2_load_unaligned (((u8 *) & e->type) - 6);
etype[offset] = ((u16x8) r)[3];
tags[offset] = r[1];
#else
etype[offset] = e->type;
tags[offset] = *(u64 *) (e + 1);
#endif
if (dmac_check)
dmacs[offset] = *(u64 *) e;
}
static_always_inline u16
eth_input_next_by_type (u16 etype)
{
ethernet_main_t *em = ðernet_main;
return (etype < 0x600) ? ETHERNET_INPUT_NEXT_LLC :
vec_elt (em->l3_next.input_next_by_type,
sparse_vec_index (em->l3_next.input_next_by_type, etype));
}
typedef struct
{
u64 tag, mask;
u32 sw_if_index;
u16 type, len, next;
i16 adv;
u8 err, n_tags;
u64 n_packets, n_bytes;
} eth_input_tag_lookup_t;
static_always_inline void
eth_input_update_if_counters (vlib_main_t * vm, vnet_main_t * vnm,
eth_input_tag_lookup_t * l)
{
if (l->n_packets == 0 || l->sw_if_index == ~0)
return;
if (l->adv > 0)
l->n_bytes += l->n_packets * l->len;
vlib_increment_combined_counter
(vnm->interface_main.combined_sw_if_counters +
VNET_INTERFACE_COUNTER_RX, vm->thread_index, l->sw_if_index,
l->n_packets, l->n_bytes);
}
static_always_inline void
eth_input_tag_lookup (vlib_main_t * vm, vnet_main_t * vnm,
vlib_node_runtime_t * node, vnet_hw_interface_t * hi,
u64 tag, u16 * next, vlib_buffer_t * b,
eth_input_tag_lookup_t * l, u8 dmac_bad, int is_dot1ad,
int main_is_l3, int check_dmac)
{
ethernet_main_t *em = ðernet_main;
if ((tag ^ l->tag) & l->mask)
{
main_intf_t *mif = vec_elt_at_index (em->main_intfs, hi->hw_if_index);
vlan_intf_t *vif;
qinq_intf_t *qif;
vlan_table_t *vlan_table;
qinq_table_t *qinq_table;
u16 *t = (u16 *) & tag;
u16 vlan1 = clib_net_to_host_u16 (t[0]) & 0xFFF;
u16 vlan2 = clib_net_to_host_u16 (t[2]) & 0xFFF;
u32 matched, is_l2, new_sw_if_index;
vlan_table = vec_elt_at_index (em->vlan_pool, is_dot1ad ?
mif->dot1ad_vlans : mif->dot1q_vlans);
vif = &vlan_table->vlans[vlan1];
qinq_table = vec_elt_at_index (em->qinq_pool, vif->qinqs);
qif = &qinq_table->vlans[vlan2];
l->err = ETHERNET_ERROR_NONE;
l->type = clib_net_to_host_u16 (t[1]);
if (l->type == ETHERNET_TYPE_VLAN)
{
l->type = clib_net_to_host_u16 (t[3]);
l->n_tags = 2;
matched = eth_identify_subint (hi, SUBINT_CONFIG_VALID |
SUBINT_CONFIG_MATCH_2_TAG, mif, vif,
qif, &new_sw_if_index, &l->err,
&is_l2);
}
else
{
l->n_tags = 1;
if (vlan1 == 0)
{
new_sw_if_index = hi->sw_if_index;
l->err = ETHERNET_ERROR_NONE;
matched = 1;
is_l2 = main_is_l3 == 0;
}
else
matched = eth_identify_subint (hi, SUBINT_CONFIG_VALID |
SUBINT_CONFIG_MATCH_1_TAG, mif,
vif, qif, &new_sw_if_index,
&l->err, &is_l2);
}
if (l->sw_if_index != new_sw_if_index)
{
eth_input_update_if_counters (vm, vnm, l);
l->n_packets = 0;
l->n_bytes = 0;
l->sw_if_index = new_sw_if_index;
}
l->tag = tag;
l->mask = (l->n_tags == 2) ?
clib_net_to_host_u64 (0xffffffffffffffff) :
clib_net_to_host_u64 (0xffffffff00000000);
if (matched && l->sw_if_index == ~0)
l->err = ETHERNET_ERROR_DOWN;
l->len = sizeof (ethernet_header_t) +
l->n_tags * sizeof (ethernet_vlan_header_t);
if (main_is_l3)
l->adv = is_l2 ? -(int) sizeof (ethernet_header_t) :
l->n_tags * sizeof (ethernet_vlan_header_t);
else
l->adv = is_l2 ? 0 : l->len;
if (PREDICT_FALSE (l->err != ETHERNET_ERROR_NONE))
l->next = ETHERNET_INPUT_NEXT_DROP;
else if (is_l2)
l->next = em->l2_next;
else if (l->type == ETHERNET_TYPE_IP4)
l->next = em->l3_next.input_next_ip4;
else if (l->type == ETHERNET_TYPE_IP6)
l->next = em->l3_next.input_next_ip6;
else if (l->type == ETHERNET_TYPE_MPLS)
l->next = em->l3_next.input_next_mpls;
else if (em->redirect_l3)
l->next = em->redirect_l3_next;
else
{
l->next = eth_input_next_by_type (l->type);
if (l->next == ETHERNET_INPUT_NEXT_PUNT)
l->err = ETHERNET_ERROR_UNKNOWN_TYPE;
}
}
if (check_dmac && l->adv > 0 && dmac_bad)
{
l->err = ETHERNET_ERROR_L3_MAC_MISMATCH;
next[0] = ETHERNET_INPUT_NEXT_PUNT;
}
else
next[0] = l->next;
vlib_buffer_advance (b, l->adv);
vnet_buffer (b)->l2.l2_len = l->len;
vnet_buffer (b)->l3_hdr_offset = vnet_buffer (b)->l2_hdr_offset + l->len;
if (l->err == ETHERNET_ERROR_NONE)
{
vnet_buffer (b)->sw_if_index[VLIB_RX] = l->sw_if_index;
ethernet_buffer_set_vlan_count (b, l->n_tags);
}
else
b->error = node->errors[l->err];
/* update counters */
l->n_packets += 1;
l->n_bytes += vlib_buffer_length_in_chain (vm, b);
}
static_always_inline void
eth_input_process_frame_dmac_check (vnet_hw_interface_t * hi,
u64 * dmacs, u8 * dmacs_bad,
u32 n_packets)
{
u64 mask = clib_net_to_host_u64 (0xFFFFFFFFFFFF0000);
u64 igbit = clib_net_to_host_u64 (0x0100000000000000);
u64 hwaddr = (*(u64 *) hi->hw_address) & mask;
u64 *dmac = dmacs;
u8 *dmac_bad = dmacs_bad;
i32 n_left = n_packets;
#ifdef CLIB_HAVE_VEC256
u64x4 igbit4 = u64x4_splat (igbit);
u64x4 mask4 = u64x4_splat (mask);
u64x4 hwaddr4 = u64x4_splat (hwaddr);
while (n_left > 0)
{
u64x4 r0, r1;
r0 = u64x4_load_unaligned (dmac + 0) & mask4;
r1 = u64x4_load_unaligned (dmac + 4) & mask4;
r0 = (r0 != hwaddr4) & ((r0 & igbit4) == 0);
r1 = (r1 != hwaddr4) & ((r1 & igbit4) == 0);
*(u32 *) (dmac_bad + 0) = u8x32_msb_mask ((u8x32) (r0));
*(u32 *) (dmac_bad + 4) = u8x32_msb_mask ((u8x32) (r1));
/* next */
dmac += 8;
dmac_bad += 8;
n_left -= 8;
}
#else
while (n_left > 0)
{
u64 r0, r1, r2, r3;
r0 = dmac[0] & mask;
r1 = dmac[1] & mask;
r2 = dmac[2] & mask;
r3 = dmac[3] & mask;
r0 = (r0 != hwaddr) && ((r0 & igbit) == 0);
r1 = (r1 != hwaddr) && ((r1 & igbit) == 0);
r2 = (r2 != hwaddr) && ((r2 & igbit) == 0);
r3 = (r3 != hwaddr) && ((r3 & igbit) == 0);
dmac_bad[0] = r0;
dmac_bad[1] = r1;
dmac_bad[2] = r2;
dmac_bad[3] = r3;
/* next */
dmac += 4;
dmac_bad += 4;
n_left -= 4;
}
#endif
}
/* process frame of buffers, store ethertype into array and update
buffer metadata fields depending on interface being l2 or l3 assuming that
packets are untagged. For tagged packets those fields are updated later.
Optionally store Destionation MAC address and tag data into arrays
for further processing */
STATIC_ASSERT (VLIB_FRAME_SIZE % 8 == 0,
"VLIB_FRAME_SIZE must be power of 8");
static_always_inline void
eth_input_process_frame (vlib_main_t * vm, vlib_node_runtime_t * node,
vnet_hw_interface_t * hi,
u32 * buffer_indices, u32 n_packets, int main_is_l3,
int ip4_cksum_ok, int dmac_check)
{
ethernet_main_t *em = ðernet_main;
u16 nexts[VLIB_FRAME_SIZE], *next;
u16 etypes[VLIB_FRAME_SIZE], *etype = etypes;
u64 dmacs[VLIB_FRAME_SIZE], *dmac = dmacs;
u8 dmacs_bad[VLIB_FRAME_SIZE];
u64 tags[VLIB_FRAME_SIZE], *tag = tags;
u16 slowpath_indices[VLIB_FRAME_SIZE];
u16 n_slowpath, i;
u16 next_ip4, next_ip6, next_mpls, next_l2;
u16 et_ip4 = clib_host_to_net_u16 (ETHERNET_TYPE_IP4);
u16 et_ip6 = clib_host_to_net_u16 (ETHERNET_TYPE_IP6);
u16 et_mpls = clib_host_to_net_u16 (ETHERNET_TYPE_MPLS);
u16 et_vlan = clib_host_to_net_u16 (ETHERNET_TYPE_VLAN);
u16 et_dot1ad = clib_host_to_net_u16 (ETHERNET_TYPE_DOT1AD);
i32 n_left = n_packets;
vlib_buffer_t *b[20];
u32 *from;
from = buffer_indices;
while (n_left >= 20)
{
vlib_buffer_t **ph = b + 16, **pd = b + 8;
vlib_get_buffers (vm, from, b, 4);
vlib_get_buffers (vm, from + 8, pd, 4);
vlib_get_buffers (vm, from + 16, ph, 4);
vlib_prefetch_buffer_header (ph[0], LOAD);
vlib_prefetch_buffer_data (pd[0], LOAD);
eth_input_get_etype_and_tags (b, etype, tag, dmac, 0, dmac_check);
vlib_prefetch_buffer_header (ph[1], LOAD);
vlib_prefetch_buffer_data (pd[1], LOAD);
eth_input_get_etype_and_tags (b, etype, tag, dmac, 1, dmac_check);
vlib_prefetch_buffer_header (ph[2], LOAD);
vlib_prefetch_buffer_data (pd[2], LOAD);
eth_input_get_etype_and_tags (b, etype, tag, dmac, 2, dmac_check);
vlib_prefetch_buffer_header (ph[3], LOAD);
vlib_prefetch_buffer_data (pd[3], LOAD);
eth_input_get_etype_and_tags (b, etype, tag, dmac, 3, dmac_check);
eth_input_adv_and_flags_x4 (b, main_is_l3);
/* next */
n_left -= 4;
etype += 4;
tag += 4;
dmac += 4;
from += 4;
}
while (n_left >= 4)
{
vlib_get_buffers (vm, from, b, 4);
eth_input_get_etype_and_tags (b, etype, tag, dmac, 0, dmac_check);
eth_input_get_etype_and_tags (b, etype, tag, dmac, 1, dmac_check);
eth_input_get_etype_and_tags (b, etype, tag, dmac, 2, dmac_check);
eth_input_get_etype_and_tags (b, etype, tag, dmac, 3, dmac_check);
eth_input_adv_and_flags_x4 (b, main_is_l3);
/* next */
n_left -= 4;
etype += 4;
tag += 4;
dmac += 4;
from += 4;
}
while (n_left)
{
vlib_get_buffers (vm, from, b, 1);
eth_input_get_etype_and_tags (b, etype, tag, dmac, 0, dmac_check);
eth_input_adv_and_flags_x1 (b, main_is_l3);
/* next */
n_left -= 1;
etype += 1;
tag += 1;
dmac += 4;
from += 1;
}
if (dmac_check)
eth_input_process_frame_dmac_check (hi, dmacs, dmacs_bad, n_packets);
next_ip4 = em->l3_next.input_next_ip4;
next_ip6 = em->l3_next.input_next_ip6;
next_mpls = em->l3_next.input_next_mpls;
next_l2 = em->l2_next;
if (next_ip4 == ETHERNET_INPUT_NEXT_IP4_INPUT && ip4_cksum_ok)
next_ip4 = ETHERNET_INPUT_NEXT_IP4_INPUT_NCS;
#ifdef CLIB_HAVE_VEC256
u16x16 et16_ip4 = u16x16_splat (et_ip4);
u16x16 et16_ip6 = u16x16_splat (et_ip6);
u16x16 et16_mpls = u16x16_splat (et_mpls);
u16x16 et16_vlan = u16x16_splat (et_vlan);
u16x16 et16_dot1ad = u16x16_splat (et_dot1ad);
u16x16 next16_ip4 = u16x16_splat (next_ip4);
u16x16 next16_ip6 = u16x16_splat (next_ip6);
u16x16 next16_mpls = u16x16_splat (next_mpls);
u16x16 next16_l2 = u16x16_splat (next_l2);
u16x16 zero = { 0 };
u16x16 stairs = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
#endif
etype = etypes;
n_left = n_packets;
next = nexts;
n_slowpath = 0;
i = 0;
/* fastpath - in l3 mode hadles ip4, ip6 and mpls packets, other packets
are considered as slowpath, in l2 mode all untagged packets are
considered as fastpath */
while (n_left > 0)
{
#ifdef CLIB_HAVE_VEC256
if (n_left >= 16)
{
u16x16 r = zero;
u16x16 e16 = u16x16_load_unaligned (etype);
if (main_is_l3)
{
r += (e16 == et16_ip4) & next16_ip4;
r += (e16 == et16_ip6) & next16_ip6;
r += (e16 == et16_mpls) & next16_mpls;
}
else
r = ((e16 != et16_vlan) & (e16 != et16_dot1ad)) & next16_l2;
u16x16_store_unaligned (r, next);
if (!u16x16_is_all_zero (r == zero))
{
if (u16x16_is_all_zero (r))
{
u16x16_store_unaligned (u16x16_splat (i) + stairs,
slowpath_indices + n_slowpath);
n_slowpath += 16;
}
else
{
for (int j = 0; j < 16; j++)
if (next[j] == 0)
slowpath_indices[n_slowpath++] = i + j;
}
}
etype += 16;
next += 16;
n_left -= 16;
i += 16;
continue;
}
#endif
if (main_is_l3 && etype[0] == et_ip4)
next[0] = next_ip4;
else if (main_is_l3 && etype[0] == et_ip6)
next[0] = next_ip6;
else if (main_is_l3 && etype[0] == et_mpls)
next[0] = next_mpls;
else if (main_is_l3 == 0 &&
etype[0] != et_vlan && etype[0] != et_dot1ad)
next[0] = next_l2;
else
{
next[0] = 0;
slowpath_indices[n_slowpath++] = i;
}
etype += 1;
next += 1;
n_left -= 1;
i += 1;
}
if (n_slowpath)
{
vnet_main_t *vnm = vnet_get_main ();
n_left = n_slowpath;
u16 *si = slowpath_indices;
u32 last_unknown_etype = ~0;
u32 last_unknown_next = ~0;
eth_input_tag_lookup_t dot1ad_lookup, dot1q_lookup = {
.mask = -1LL,
.tag = tags[si[0]] ^ -1LL,
.sw_if_index = ~0
};
clib_memcpy_fast (&dot1ad_lookup, &dot1q_lookup, sizeof (dot1q_lookup));
while (n_left)
{
i = si[0];
u16 etype = etypes[i];
if (etype == et_vlan)
{
vlib_buffer_t *b = vlib_get_buffer (vm, buffer_indices[i]);
eth_input_tag_lookup (vm, vnm, node, hi, tags[i], nexts + i, b,
&dot1q_lookup, dmacs_bad[i], 0,
main_is_l3, dmac_check);
}
else if (etype == et_dot1ad)
{
vlib_buffer_t *b = vlib_get_buffer (vm, buffer_indices[i]);
eth_input_tag_lookup (vm, vnm, node, hi, tags[i], nexts + i, b,
&dot1ad_lookup, dmacs_bad[i], 1,
main_is_l3, dmac_check);
}
else
{
/* untagged packet with not well known etyertype */
if (last_unknown_etype != etype)
{
last_unknown_etype = etype;
etype = clib_host_to_net_u16 (etype);
last_unknown_next = eth_input_next_by_type (etype);
}
if (dmac_check && main_is_l3 && dmacs_bad[i])
{
vlib_buffer_t *b = vlib_get_buffer (vm, buffer_indices[i]);
b->error = node->errors[ETHERNET_ERROR_L3_MAC_MISMATCH];
nexts[i] = ETHERNET_INPUT_NEXT_PUNT;
}
else
nexts[i] = last_unknown_next;
}
/* next */
n_left--;
si++;
}
eth_input_update_if_counters (vm, vnm, &dot1q_lookup);
eth_input_update_if_counters (vm, vnm, &dot1ad_lookup);
}
vlib_buffer_enqueue_to_next (vm, node, buffer_indices, nexts, n_packets);
}
static_always_inline void
eth_input_single_int (vlib_main_t * vm, vlib_node_runtime_t * node,
vnet_hw_interface_t * hi, u32 * from, u32 n_pkts,
int ip4_cksum_ok)
{
ethernet_main_t *em = ðernet_main;
ethernet_interface_t *ei;
ei = pool_elt_at_index (em->interfaces, hi->hw_instance);
main_intf_t *intf0 = vec_elt_at_index (em->main_intfs, hi->hw_if_index);
subint_config_t *subint0 = &intf0->untagged_subint;
int main_is_l3 = (subint0->flags & SUBINT_CONFIG_L2) == 0;
int promisc = (ei->flags & ETHERNET_INTERFACE_FLAG_ACCEPT_ALL) != 0;
if (main_is_l3)
{
/* main interface is L3, we dont expect tagged packets and interface
is not in promisc node, so we dont't need to check DMAC */
int is_l3 = 1;
if (promisc == 0)
eth_input_process_frame (vm, node, hi, from, n_pkts, is_l3,
ip4_cksum_ok, 0);
else
/* subinterfaces and promisc mode so DMAC check is needed */
eth_input_process_frame (vm, node, hi, from, n_pkts, is_l3,
ip4_cksum_ok, 1);
return;
}
else
{
/* untagged packets are treated as L2 */
int is_l3 = 0;
eth_input_process_frame (vm, node, hi, from, n_pkts, is_l3,
ip4_cksum_ok, 1);
return;
}
}
static_always_inline void
ethernet_input_trace (vlib_main_t * vm, vlib_node_runtime_t * node,
vlib_frame_t * from_frame)
{
u32 *from, n_left;
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
{
from = vlib_frame_vector_args (from_frame);
n_left = from_frame->n_vectors;
while (n_left)
{
ethernet_input_trace_t *t0;
vlib_buffer_t *b0 = vlib_get_buffer (vm, from[0]);
if (b0->flags & VLIB_BUFFER_IS_TRACED)
{
t0 = vlib_add_trace (vm, node, b0,
sizeof (ethernet_input_trace_t));
clib_memcpy_fast (t0->packet_data, b0->data + b0->current_data,
sizeof (t0->packet_data));
t0->frame_flags = from_frame->flags;
clib_memcpy_fast (&t0->frame_data,
vlib_frame_scalar_args (from_frame),
sizeof (ethernet_input_frame_t));
}
from += 1;
n_left -= 1;
}
}
/* rx pcap capture if enabled */
if (PREDICT_FALSE (vlib_global_main.pcap[VLIB_RX].pcap_enable))
{
u32 bi0;
from = vlib_frame_vector_args (from_frame);
n_left = from_frame->n_vectors;
while (n_left > 0)
{
vlib_buffer_t *b0;
bi0 = from[0];
from++;
b0 = vlib_get_buffer (vm, bi0);
if (vlib_global_main.pcap[VLIB_RX].pcap_sw_if_index == 0 ||
vlib_global_main.pcap[VLIB_RX].pcap_sw_if_index
== vnet_buffer (b0)->sw_if_index[VLIB_RX])
{
pcap_add_buffer (&vlib_global_main.pcap[VLIB_RX].pcap_main, vm,
bi0, 512);
}
n_left--;
}
}
}
static_always_inline void
ethernet_input_inline (vlib_main_t * vm,
vlib_node_runtime_t * node,
u32 * from, u32 n_packets,
ethernet_input_variant_t variant)
{
vnet_main_t *vnm = vnet_get_main ();
ethernet_main_t *em = ðernet_main;
vlib_node_runtime_t *error_node;
u32 n_left_from, next_index, *to_next;
u32 stats_sw_if_index, stats_n_packets, stats_n_bytes;
u32 thread_index = vm->thread_index;
u32 cached_sw_if_index = ~0;
u32 cached_is_l2 = 0; /* shut up gcc */
vnet_hw_interface_t *hi = NULL; /* used for main interface only */
vlib_buffer_t *bufs[VLIB_FRAME_SIZE];
vlib_buffer_t **b = bufs;
if (variant != ETHERNET_INPUT_VARIANT_ETHERNET)
error_node = vlib_node_get_runtime (vm, ethernet_input_node.index);
else
error_node = node;
n_left_from = n_packets;
next_index = node->cached_next_index;
stats_sw_if_index = node->runtime_data[0];
stats_n_packets = stats_n_bytes = 0;
vlib_get_buffers (vm, from, bufs, n_left_from);
while (n_left_from > 0)
{
u32 n_left_to_next;
vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
while (n_left_from >= 4 && n_left_to_next >= 2)
{
u32 bi0, bi1;
vlib_buffer_t *b0, *b1;
u8 next0, next1, error0, error1;
u16 type0, orig_type0, type1, orig_type1;
u16 outer_id0, inner_id0, outer_id1, inner_id1;
u32 match_flags0, match_flags1;
u32 old_sw_if_index0, new_sw_if_index0, len0, old_sw_if_index1,
new_sw_if_index1, len1;
vnet_hw_interface_t *hi0, *hi1;
main_intf_t *main_intf0, *main_intf1;
vlan_intf_t *vlan_intf0, *vlan_intf1;
qinq_intf_t *qinq_intf0, *qinq_intf1;
u32 is_l20, is_l21;
ethernet_header_t *e0, *e1;
/* Prefetch next iteration. */
{
vlib_prefetch_buffer_header (b[2], STORE);
vlib_prefetch_buffer_header (b[3], STORE);
CLIB_PREFETCH (b[2]->data, sizeof (ethernet_header_t), LOAD);
CLIB_PREFETCH (b[3]->data, sizeof (ethernet_header_t), LOAD);
}
bi0 = from[0];
bi1 = from[1];
to_next[0] = bi0;
to_next[1] = bi1;
from += 2;
to_next += 2;
n_left_to_next -= 2;
n_left_from -= 2;
b0 = b[0];
b1 = b[1];
b += 2;
error0 = error1 = ETHERNET_ERROR_NONE;
e0 = vlib_buffer_get_current (b0);
type0 = clib_net_to_host_u16 (e0->type);
e1 = vlib_buffer_get_current (b1);
type1 = clib_net_to_host_u16 (e1->type);
/* Set the L2 header offset for all packets */
vnet_buffer (b0)->l2_hdr_offset = b0->current_data;
vnet_buffer (b1)->l2_hdr_offset = b1->current_data;
b0->flags |= VNET_BUFFER_F_L2_HDR_OFFSET_VALID;
b1->flags |= VNET_BUFFER_F_L2_HDR_OFFSET_VALID;
/* Speed-path for the untagged case */
if (PREDICT_TRUE (variant == ETHERNET_INPUT_VARIANT_ETHERNET
&& !ethernet_frame_is_any_tagged_x2 (type0,
type1)))
{
main_intf_t *intf0;
subint_config_t *subint0;
u32 sw_if_index0, sw_if_index1;
sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_RX];
is_l20 = cached_is_l2;
/* This is probably wholly unnecessary */
if (PREDICT_FALSE (sw_if_index0 != sw_if_index1))
goto slowpath;
/* Now sw_if_index0 == sw_if_index1 */
if (PREDICT_FALSE (cached_sw_if_index != sw_if_index0))
{
cached_sw_if_index = sw_if_index0;
hi = vnet_get_sup_hw_interface (vnm, sw_if_index0);
intf0 = vec_elt_at_index (em->main_intfs, hi->hw_if_index);
subint0 = &intf0->untagged_subint;
cached_is_l2 = is_l20 = subint0->flags & SUBINT_CONFIG_L2;
}
if (PREDICT_TRUE (is_l20 != 0))
{
vnet_buffer (b0)->l3_hdr_offset =
vnet_buffer (b0)->l2_hdr_offset +
sizeof (ethernet_header_t);
vnet_buffer (b1)->l3_hdr_offset =
vnet_buffer (b1)->l2_hdr_offset +
sizeof (ethernet_header_t);
b0->flags |= VNET_BUFFER_F_L3_HDR_OFFSET_VALID;
b1->flags |= VNET_BUFFER_F_L3_HDR_OFFSET_VALID;
next0 = em->l2_next;
vnet_buffer (b0)->l2.l2_len = sizeof (ethernet_header_t);
next1 = em->l2_next;
vnet_buffer (b1)->l2.l2_len = sizeof (ethernet_header_t);
}
else
{
if (!ethernet_address_cast (e0->dst_address) &&
(hi->hw_address != 0) &&
!ethernet_mac_address_equal ((u8 *) e0, hi->hw_address))
error0 = ETHERNET_ERROR_L3_MAC_MISMATCH;
if (!ethernet_address_cast (e1->dst_address) &&
(hi->hw_address != 0) &&
!ethernet_mac_address_equal ((u8 *) e1, hi->hw_address))
error1 = ETHERNET_ERROR_L3_MAC_MISMATCH;
vlib_buffer_advance (b0, sizeof (ethernet_header_t));
determine_next_node (em, variant, 0, type0, b0,
&error0, &next0);
vlib_buffer_advance (b1, sizeof (ethernet_header_t));
determine_next_node (em, variant, 0, type1, b1,
&error1, &next1);
}
goto ship_it01;
}
/* Slow-path for the tagged case */
slowpath:
parse_header (variant,
b0,
&type0,
&orig_type0, &outer_id0, &inner_id0, &match_flags0);
parse_header (variant,
b1,
&type1,
&orig_type1, &outer_id1, &inner_id1, &match_flags1);
old_sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
old_sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_RX];
eth_vlan_table_lookups (em,
vnm,
old_sw_if_index0,
orig_type0,
outer_id0,
inner_id0,
&hi0,
&main_intf0, &vlan_intf0, &qinq_intf0);
eth_vlan_table_lookups (em,
vnm,
old_sw_if_index1,
orig_type1,
outer_id1,
inner_id1,
&hi1,
&main_intf1, &vlan_intf1, &qinq_intf1);
identify_subint (hi0,
b0,
match_flags0,
main_intf0,
vlan_intf0,
qinq_intf0, &new_sw_if_index0, &error0, &is_l20);
identify_subint (hi1,
b1,
match_flags1,
main_intf1,
vlan_intf1,
qinq_intf1, &new_sw_if_index1, &error1, &is_l21);
// Save RX sw_if_index for later nodes
vnet_buffer (b0)->sw_if_index[VLIB_RX] =
error0 !=
ETHERNET_ERROR_NONE ? old_sw_if_index0 : new_sw_if_index0;
vnet_buffer (b1)->sw_if_index[VLIB_RX] =
error1 !=
ETHERNET_ERROR_NONE ? old_sw_if_index1 : new_sw_if_index1;
// Check if there is a stat to take (valid and non-main sw_if_index for pkt 0 or pkt 1)
if (((new_sw_if_index0 != ~0)
&& (new_sw_if_index0 != old_sw_if_index0))
|| ((new_sw_if_index1 != ~0)
&& (new_sw_if_index1 != old_sw_if_index1)))
{
len0 = vlib_buffer_length_in_chain (vm, b0) + b0->current_data
- vnet_buffer (b0)->l2_hdr_offset;
len1 = vlib_buffer_length_in_chain (vm, b1) + b1->current_data
- vnet_buffer (b1)->l2_hdr_offset;
stats_n_packets += 2;
stats_n_bytes += len0 + len1;
if (PREDICT_FALSE
(!(new_sw_if_index0 == stats_sw_if_index
&& new_sw_if_index1 == stats_sw_if_index)))
{
stats_n_packets -= 2;
stats_n_bytes -= len0 + len1;
if (new_sw_if_index0 != old_sw_if_index0
&& new_sw_if_index0 != ~0)
vlib_increment_combined_counter (vnm->
interface_main.combined_sw_if_counters
+
VNET_INTERFACE_COUNTER_RX,
thread_index,
new_sw_if_index0, 1,
len0);
if (new_sw_if_index1 != old_sw_if_index1
&& new_sw_if_index1 != ~0)
vlib_increment_combined_counter (vnm->
interface_main.combined_sw_if_counters
+
VNET_INTERFACE_COUNTER_RX,
thread_index,
new_sw_if_index1, 1,
len1);
if (new_sw_if_index0 == new_sw_if_index1)
{
if (stats_n_packets > 0)
{
vlib_increment_combined_counter
(vnm->interface_main.combined_sw_if_counters
+ VNET_INTERFACE_COUNTER_RX,
thread_index,
stats_sw_if_index,
stats_n_packets, stats_n_bytes);
stats_n_packets = stats_n_bytes = 0;
}
stats_sw_if_index = new_sw_if_index0;
}
}
}
if (variant == ETHERNET_INPUT_VARIANT_NOT_L2)
is_l20 = is_l21 = 0;
determine_next_node (em, variant, is_l20, type0, b0, &error0,
&next0);
determine_next_node (em, variant, is_l21, type1, b1, &error1,
&next1);
ship_it01:
b0->error = error_node->errors[error0];
b1->error = error_node->errors[error1];
// verify speculative enqueue
vlib_validate_buffer_enqueue_x2 (vm, node, next_index, to_next,
n_left_to_next, bi0, bi1, next0,
next1);
}
while (n_left_from > 0 && n_left_to_next > 0)
{
u32 bi0;
vlib_buffer_t *b0;
u8 error0, next0;
u16 type0, orig_type0;
u16 outer_id0, inner_id0;
u32 match_flags0;
u32 old_sw_if_index0, new_sw_if_index0, len0;
vnet_hw_interface_t *hi0;
main_intf_t *main_intf0;
vlan_intf_t *vlan_intf0;
qinq_intf_t *qinq_intf0;
ethernet_header_t *e0;
u32 is_l20;
// Prefetch next iteration
if (n_left_from > 1)
{
vlib_prefetch_buffer_header (b[1], STORE);
CLIB_PREFETCH (b[1]->data, CLIB_CACHE_LINE_BYTES, LOAD);
}
bi0 = from[0];
to_next[0] = bi0;
from += 1;
to_next += 1;
n_left_from -= 1;
n_left_to_next -= 1;
b0 = b[0];
b += 1;
error0 = ETHERNET_ERROR_NONE;
e0 = vlib_buffer_get_current (b0);
type0 = clib_net_to_host_u16 (e0->type);
/* Set the L2 header offset for all packets */
vnet_buffer (b0)->l2_hdr_offset = b0->current_data;
b0->flags |= VNET_BUFFER_F_L2_HDR_OFFSET_VALID;
/* Speed-path for the untagged case */
if (PREDICT_TRUE (variant == ETHERNET_INPUT_VARIANT_ETHERNET
&& !ethernet_frame_is_tagged (type0)))
{
main_intf_t *intf0;
subint_config_t *subint0;
u32 sw_if_index0;
sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
<