X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Finterface.h;h=f0cb540f979bb42869d3359b623a9cfb059cc9c4;hb=7c2a3357f32ae02bcc20cdad6d87beda39f71d31;hp=d5497f5cc91a81baec30fdc7dd9d21af8f1c1a6f;hpb=e3bbf5b565132515800dc4e7a137875d9865a5a6;p=vpp.git diff --git a/src/vnet/interface.h b/src/vnet/interface.h index d5497f5cc91..f0cb540f979 100644 --- a/src/vnet/interface.h +++ b/src/vnet/interface.h @@ -43,6 +43,8 @@ #include #include #include +#include +#include struct vnet_main_t; struct vnet_hw_interface_t; @@ -51,13 +53,13 @@ union ip46_address_t_; typedef enum { - VNET_HW_INTERFACE_RX_MODE_UNKNOWN, - VNET_HW_INTERFACE_RX_MODE_POLLING, - VNET_HW_INTERFACE_RX_MODE_INTERRUPT, - VNET_HW_INTERFACE_RX_MODE_ADAPTIVE, - VNET_HW_INTERFACE_RX_MODE_DEFAULT, - VNET_HW_INTERFACE_NUM_RX_MODES, -} vnet_hw_interface_rx_mode; + VNET_HW_IF_RX_MODE_UNKNOWN, + VNET_HW_IF_RX_MODE_POLLING, + VNET_HW_IF_RX_MODE_INTERRUPT, + VNET_HW_IF_RX_MODE_ADAPTIVE, + VNET_HW_IF_RX_MODE_DEFAULT, + VNET_HW_IF_NUM_RX_MODES, +} vnet_hw_if_rx_mode; /* Interface up/down callback. */ typedef clib_error_t *(vnet_interface_function_t) @@ -68,21 +70,34 @@ typedef clib_error_t *(vnet_subif_add_del_function_t) (struct vnet_main_t * vnm, u32 if_index, struct vnet_sw_interface_t * template, int is_add); +/* Interface set mtu callback. */ +typedef clib_error_t *(vnet_interface_set_max_frame_size_function_t) ( + struct vnet_main_t *vnm, struct vnet_hw_interface_t *hi, u32 mtu); + /* Interface set mac address callback. */ typedef clib_error_t *(vnet_interface_set_mac_address_function_t) (struct vnet_hw_interface_t * hi, const u8 * old_address, const u8 * new_address); +/* Interface add/del additional mac address callback */ +typedef clib_error_t *(vnet_interface_add_del_mac_address_function_t) + (struct vnet_hw_interface_t * hi, const u8 * address, u8 is_add); + /* Interface set rx mode callback. */ typedef clib_error_t *(vnet_interface_set_rx_mode_function_t) (struct vnet_main_t * vnm, u32 if_index, u32 queue_id, - vnet_hw_interface_rx_mode mode); + vnet_hw_if_rx_mode mode); /* Interface set l2 mode callback. */ typedef clib_error_t *(vnet_interface_set_l2_mode_function_t) (struct vnet_main_t * vnm, struct vnet_hw_interface_t * hi, i32 l2_if_adjust); +/* Interface to set rss queues of the interface */ +typedef clib_error_t *(vnet_interface_rss_queues_set_t) + (struct vnet_main_t * vnm, struct vnet_hw_interface_t * hi, + clib_bitmap_t * bitmap); + typedef enum { VNET_FLOW_DEV_OP_ADD_FLOW, @@ -169,6 +184,8 @@ static __clib_unused void * __clib_unused_##f = f; _VNET_INTERFACE_FUNCTION_DECL(f,sw_interface_mtu_change) #define VNET_SW_INTERFACE_ADD_DEL_FUNCTION(f) \ _VNET_INTERFACE_FUNCTION_DECL(f,sw_interface_add_del) +#define VNET_SW_INTERFACE_ADD_DEL_FUNCTION_PRIO(f,p) \ + _VNET_INTERFACE_FUNCTION_DECL_PRIO(f,sw_interface_add_del,p) #define VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION(f) \ _VNET_INTERFACE_FUNCTION_DECL(f,sw_interface_admin_up_down) #define VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION_PRIO(f,p) \ @@ -217,6 +234,7 @@ typedef struct _vnet_device_class /* Error strings indexed by error code for this node. */ char **tx_function_error_strings; + vlib_error_desc_t *tx_function_error_counters; /* Number of error codes used by this node. */ u32 tx_function_n_errors; @@ -265,8 +283,17 @@ typedef struct _vnet_device_class /* Function to set mac address. */ vnet_interface_set_mac_address_function_t *mac_addr_change_function; + + /* Function to add/delete additional MAC addresses */ + vnet_interface_add_del_mac_address_function_t *mac_addr_add_del_function; + + /* Interface to set rss queues of the interface */ + vnet_interface_rss_queues_set_t *set_rss_queues_function; + } vnet_device_class_t; +u32 vnet_register_device_class (vlib_main_t *, vnet_device_class_t *); + #ifndef CLIB_MARCH_VARIANT #define VNET_DEVICE_CLASS(x,...) \ __VA_ARGS__ vnet_device_class_t x; \ @@ -294,23 +321,25 @@ __VA_ARGS__ vnet_device_class_t x static __clib_unused vnet_device_class_t __clib_unused_##x #endif -#define VNET_DEVICE_CLASS_TX_FN(devclass) \ -uword CLIB_MARCH_SFX (devclass##_tx_fn)(); \ -static vlib_node_fn_registration_t \ - CLIB_MARCH_SFX(devclass##_tx_fn_registration) = \ - { .function = &CLIB_MARCH_SFX (devclass##_tx_fn), }; \ - \ -static void __clib_constructor \ -CLIB_MARCH_SFX (devclass##_tx_fn_multiarch_register) (void) \ -{ \ - extern vnet_device_class_t devclass; \ - vlib_node_fn_registration_t *r; \ - r = &CLIB_MARCH_SFX (devclass##_tx_fn_registration); \ - r->priority = CLIB_MARCH_FN_PRIORITY(); \ - r->next_registration = devclass.tx_fn_registrations; \ - devclass.tx_fn_registrations = r; \ -} \ -uword CLIB_CPU_OPTIMIZED CLIB_MARCH_SFX (devclass##_tx_fn) +#define VNET_DEVICE_CLASS_TX_FN(devclass) \ + uword CLIB_MARCH_SFX (devclass##_tx_fn) ( \ + vlib_main_t *, vlib_node_runtime_t *, vlib_frame_t *); \ + static vlib_node_fn_registration_t CLIB_MARCH_SFX ( \ + devclass##_tx_fn_registration) = { \ + .function = &CLIB_MARCH_SFX (devclass##_tx_fn), \ + }; \ + \ + static void __clib_constructor CLIB_MARCH_SFX ( \ + devclass##_tx_fn_multiarch_register) (void) \ + { \ + extern vnet_device_class_t devclass; \ + vlib_node_fn_registration_t *r; \ + r = &CLIB_MARCH_SFX (devclass##_tx_fn_registration); \ + r->march_variant = CLIB_MARCH_SFX (CLIB_MARCH_VARIANT_TYPE); \ + r->next_registration = devclass.tx_fn_registrations; \ + devclass.tx_fn_registrations = r; \ + } \ + uword CLIB_MARCH_SFX (devclass##_tx_fn) /** * Link Type: A description of the protocol of packets on the link. @@ -345,11 +374,17 @@ typedef enum vnet_link_t_ _link <= VNET_LINK_NSH; \ _link++) +#define FOR_EACH_VNET_IP_LINK(_link) \ + for (_link = VNET_LINK_IP4; \ + _link <= VNET_LINK_IP6; \ + _link++) + /** - * @brief Number of link types. Not part of the enum so it does not have to be included in - * switch statements + * @brief Number of link types. Not part of the enum so it does not have to be + * included in switch statements */ #define VNET_LINK_NUM (VNET_LINK_NSH+1) +#define VNET_N_LINKS VNET_LINK_NUM /** * @brief Convert a link to to an Ethertype @@ -365,6 +400,10 @@ typedef enum vnet_hw_interface_class_flags_t_ * @brief a point 2 point interface */ VNET_HW_INTERFACE_CLASS_FLAG_P2P = (1 << 0), + /** + * @brief a non-broadcast multiple access interface + */ + VNET_HW_INTERFACE_CLASS_FLAG_NBMA = (1 << 1), } vnet_hw_interface_class_flags_t; /* Layer-2 (e.g. Ethernet) interface class. */ @@ -379,6 +418,9 @@ typedef struct _vnet_hw_interface_class /* Flags */ vnet_hw_interface_class_flags_t flags; + /* tx hash type for interfaces of this hw class */ + vnet_hash_fn_type_t tx_hash_fn_type; + /* Function to call when hardware interface is added/deleted. */ vnet_interface_function_t *interface_add_del_function; @@ -391,6 +433,12 @@ typedef struct _vnet_hw_interface_class /* Function to call when link MAC changes. */ vnet_interface_set_mac_address_function_t *mac_addr_change_function; + /* Function to add/delete additional MAC addresses */ + vnet_interface_add_del_mac_address_function_t *mac_addr_add_del_function; + + /* Function to set max frame size. */ + vnet_interface_set_max_frame_size_function_t *set_max_frame_size; + /* Format function to display interface name. */ format_function_t *format_interface_name; @@ -435,7 +483,7 @@ typedef struct _vnet_hw_interface_class } vnet_hw_interface_class_t; /** - * @brief Return a complete, zero-length (aka dummy) rewrite + * @brief Return a complete, zero-length (aka placeholder) rewrite */ extern u8 *default_build_rewrite (struct vnet_main_t *vnm, u32 sw_if_index, @@ -477,15 +525,64 @@ typedef enum vnet_hw_interface_flags_t_ VNET_HW_INTERFACE_FLAG_HALF_DUPLEX = (1 << 1), VNET_HW_INTERFACE_FLAG_FULL_DUPLEX = (1 << 2), - /* rx mode flags */ - VNET_HW_INTERFACE_FLAG_SUPPORTS_INT_MODE = (1 << 16), + /* non-broadcast multiple access */ + VNET_HW_INTERFACE_FLAG_NBMA = (1 << 19), +} vnet_hw_interface_flags_t; - /* tx checksum offload */ - VNET_HW_INTERFACE_FLAG_SUPPORTS_TX_L4_CKSUM_OFFLOAD = (1 << 17), +#define foreach_vnet_hw_if_caps \ + _ (0, TX_IP4_CKSUM, "ip4-csum-tx") \ + _ (1, TX_TCP_CKSUM, "tcp-csum-tx") \ + _ (2, TX_UDP_CKSUM, "udp-csum-tx") \ + _ (3, TX_IP4_OUTER_CKSUM, "outer-ip4-csum-tx") \ + _ (4, TX_UDP_OUTER_CKSUM, "outer-udp-csum-tx") \ + _ (5, RX_IP4_CKSUM, "ip4-csum-rx") \ + _ (6, RX_TCP_CKSUM, "tcp-csum-rx") \ + _ (7, RX_UDP_CKSUM, "udp-csum-rx") \ + _ (8, RX_IP4_OUTER_CKSUM, "outer-ip4-csum-rx") \ + _ (9, RX_UDP_OUTER_CKSUM, "outer-udp-csum-rx") \ + _ (10, TCP_GSO, "tcp-tso") \ + _ (11, UDP_GSO, "udp-gso") \ + _ (12, VXLAN_TNL_GSO, "vxlan-tnl-gso") \ + _ (13, IPIP_TNL_GSO, "ipip-tnl-gso") \ + _ (14, GENEVE_TNL_GSO, "geneve-tnl-gso") \ + _ (15, GRE_TNL_GSO, "gre-tnl-gso") \ + _ (16, UDP_TNL_GSO, "udp-tnl-gso") \ + _ (17, IP_TNL_GSO, "ip-tnl-gso") \ + _ (18, TCP_LRO, "tcp-lro") \ + _ (30, INT_MODE, "int-mode") \ + _ (31, MAC_FILTER, "mac-filter") + +typedef enum vnet_hw_if_caps_t_ +{ + VNET_HW_INTERFACE_CAP_NONE, +#define _(bit, sfx, str) VNET_HW_IF_CAP_##sfx = (1 << (bit)), + foreach_vnet_hw_if_caps +#undef _ - /* gso */ - VNET_HW_INTERFACE_FLAG_SUPPORTS_GSO = (1 << 18), -} vnet_hw_interface_flags_t; +} vnet_hw_if_caps_t; + +#define VNET_HW_IF_CAP_L4_TX_CKSUM \ + (VNET_HW_IF_CAP_TX_TCP_CKSUM | VNET_HW_IF_CAP_TX_UDP_CKSUM) + +#define VNET_HW_IF_CAP_TX_CKSUM \ + (VNET_HW_IF_CAP_TX_IP4_CKSUM | VNET_HW_IF_CAP_TX_TCP_CKSUM | \ + VNET_HW_IF_CAP_TX_UDP_CKSUM) + +#define VNET_HW_IF_CAP_TX_OUTER_CKSUM \ + (VNET_HW_IF_CAP_TX_IP4_OUTER_CKSUM | VNET_HW_IF_CAP_TX_UDP_OUTER_CKSUM) + +#define VNET_HW_IF_CAP_TX_CKSUM_MASK \ + (VNET_HW_IF_CAP_TX_CKSUM | VNET_HW_IF_CAP_TX_OUTER_CKSUM) + +#define VNET_HW_IF_CAP_L4_RX_CKSUM \ + (VNET_HW_IF_CAP_RX_TCP_CKSUM | VNET_HW_IF_CAP_RX_UDP_CKSUM) + +#define VNET_HW_IF_CAP_RX_CKSUM \ + (VNET_HW_IF_CAP_RX_IP4_CKSUM | VNET_HW_IF_CAP_RX_TCP_CKSUM | \ + VNET_HW_IF_CAP_RX_UDP_CKSUM) + +#define VNET_HW_IF_CAP_TNL_GSO_MASK \ + VNET_HW_IF_CAP_VXLAN_TNL_GSO | VNET_HW_IF_CAP_IPIP_TNL_GSO #define VNET_HW_INTERFACE_FLAG_DUPLEX_SHIFT 1 #define VNET_HW_INTERFACE_FLAG_SPEED_SHIFT 3 @@ -493,19 +590,74 @@ typedef enum vnet_hw_interface_flags_t_ (VNET_HW_INTERFACE_FLAG_HALF_DUPLEX | \ VNET_HW_INTERFACE_FLAG_FULL_DUPLEX) +typedef struct +{ + /* hw interface index */ + u32 hw_if_index; + + /* device instance */ + u32 dev_instance; + + /* index of thread pollling this queue */ + u32 thread_index; + + /* file index of queue interrupt line */ + u32 file_index; + + /* hardware queue identifier */ + u32 queue_id; + + /* mode */ + vnet_hw_if_rx_mode mode : 8; +#define VNET_HW_IF_RXQ_THREAD_ANY ~0 +#define VNET_HW_IF_RXQ_NO_RX_INTERRUPT ~0 +} vnet_hw_if_rx_queue_t; + +typedef struct +{ + u8 shared_queue : 1; + /* hw interface index */ + u32 hw_if_index; + + /* hardware queue identifier */ + u32 queue_id; + + /* bitmap of threads which use this queue */ + clib_bitmap_t *threads; +} vnet_hw_if_tx_queue_t; + +typedef enum +{ + VNET_HW_IF_TX_FRAME_HINT_NOT_CHAINED = (1 << 0), + VNET_HW_IF_TX_FRAME_HINT_NO_GSO = (1 << 1), + VNET_HW_IF_TX_FRAME_HINT_NO_CKSUM_OFFLOAD = (1 << 2), +} vnet_hw_if_tx_frame_hint_t; + +typedef struct +{ + u8 shared_queue : 1; + vnet_hw_if_tx_frame_hint_t hints : 16; + u32 queue_id; +} vnet_hw_if_tx_frame_t; + +typedef struct +{ + CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); + vnet_hw_if_tx_frame_t *frame; + u32 *lookup_table; + u32 n_queues; +} vnet_hw_if_output_node_runtime_t; + /* Hardware-interface. This corresponds to a physical wire that packets flow over. */ typedef struct vnet_hw_interface_t { - /* Interface name. */ - u8 *name; - + CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); /* flags */ vnet_hw_interface_flags_t flags; - - /* link speed in kbps */ - u32 link_speed; + /* capabilities flags */ + vnet_hw_if_caps_t caps; /* Hardware address as vector. Zero (e.g. zero-length vector) if no address for this class (e.g. PPP). */ @@ -515,6 +667,9 @@ typedef struct vnet_hw_interface_t /* NAME.{output,tx} nodes for this interface. */ u32 output_node_index, tx_node_index; + /* interface-output-arc-end node next index for tx node */ + u32 if_out_arc_end_node_next_index; + /* (dev_class, dev_instance) uniquely identifies hw interface. */ u32 dev_class_index; u32 dev_instance; @@ -529,30 +684,42 @@ typedef struct vnet_hw_interface_t /* Software index for this hardware interface. */ u32 sw_if_index; + /* per thread output-node runtimes */ + vnet_hw_if_output_node_runtime_t *output_node_thread_runtimes; + + CLIB_CACHE_LINE_ALIGN_MARK (cacheline1); + + /* Interface name. */ + u8 *name; + + /* link speed in kbps */ + u32 link_speed; + /* Next index in interface-output node for this interface used by node function vnet_per_buffer_interface_output() */ u32 output_node_next_index; + /* called when hw interface is using transmit side packet steering */ + vnet_hash_fn_t hf; + /* Maximum transmit rate for this interface in bits/sec. */ f64 max_rate_bits_per_sec; - /* Smallest packet size supported by this interface. */ - u32 min_supported_packet_bytes; - - /* Largest packet size supported by this interface. */ - u32 max_supported_packet_bytes; - /* Smallest packet size for this interface. */ - u32 min_packet_bytes; + u32 min_frame_size; + + /* Largest frame size for this interface. */ + u32 max_frame_size; - /* Largest packet size for this interface. */ - u32 max_packet_bytes; + /* Layer 2 overhead */ + u16 frame_overhead; /* Hash table mapping sub interface id to sw_if_index. */ uword *sub_interface_sw_if_index_by_id; - /* Count of number of L2 subinterfaces */ + /* Count of number of L2 and L3 subinterfaces */ u32 l2_if_count; + u32 l3_if_count; /* Bonded interface info - 0 - not a bonded interface nor a slave @@ -565,22 +732,42 @@ typedef struct vnet_hw_interface_t /* Input node */ u32 input_node_index; - /* input node cpu index by queue */ - u32 *input_node_thread_index_by_queue; + vnet_hw_if_rx_mode default_rx_mode; - /* vnet_hw_interface_rx_mode by queue */ - u8 *rx_mode_by_queue; - vnet_hw_interface_rx_mode default_rx_mode; + /* rx queues */ + u32 *rx_queue_indices; - /* device input device_and_queue runtime index */ - uword *dq_runtime_index_by_queue; + /* tx queues */ + u32 *tx_queue_indices; /* numa node that hardware device connects to */ u8 numa_node; - u8 padding[3]; + /* rss queues bitmap */ + clib_bitmap_t *rss_queues; + + /* trace */ + i32 n_trace; + + u32 trace_classify_table_index; } vnet_hw_interface_t; +STATIC_ASSERT_OFFSET_OF (vnet_hw_interface_t, cacheline1, + CLIB_CACHE_LINE_BYTES); + +typedef struct +{ + u32 dev_instance; + u32 queue_id; +} vnet_hw_if_rxq_poll_vector_t; + +typedef struct +{ + vnet_hw_if_rxq_poll_vector_t *rxq_vector_int; + vnet_hw_if_rxq_poll_vector_t *rxq_vector_poll; + void *rxq_interrupts; +} vnet_hw_if_rx_node_runtime_t; + extern vnet_device_class_t vnet_local_interface_device_class; typedef enum @@ -675,7 +862,7 @@ typedef enum vnet_sw_interface_flags_t_ VNET_SW_INTERFACE_FLAG_UNNUMBERED = (1 << 3), - VNET_SW_INTERFACE_FLAG_BOND_SLAVE = (1 << 4), + __VNET_SW_INTERFACE_FLAG_UNUSED2 = (1 << 4), /* Interface does not appear in CLI/API */ VNET_SW_INTERFACE_FLAG_HIDDEN = (1 << 5), @@ -809,11 +996,22 @@ typedef struct u32 *split_buffers; } vnet_interface_per_thread_data_t; +typedef u8 *(*vnet_buffer_opquae_formatter_t) (const vlib_buffer_t * b, + u8 * s); + typedef struct { /* Hardware interfaces. */ vnet_hw_interface_t *hw_interfaces; + /* Hardware interface RX queues */ + vnet_hw_if_rx_queue_t *hw_if_rx_queues; + uword *rxq_index_by_hw_if_index_and_queue_id; + + /* Hardware interface TX queues */ + vnet_hw_if_tx_queue_t *hw_if_tx_queues; + uword *txq_index_by_hw_if_index_and_queue_id; + /* Hash table mapping HW interface name to index. */ uword *hw_interface_by_name; @@ -833,52 +1031,79 @@ typedef struct /* Software interface counters both simple and combined packet and byte counters. */ - volatile u32 *sw_if_counter_lock; + clib_spinlock_t sw_if_counter_lock; vlib_simple_counter_main_t *sw_if_counters; vlib_combined_counter_main_t *combined_sw_if_counters; vnet_hw_interface_nodes_t *deleted_hw_interface_nodes; - /* pcap drop tracing */ - int drop_pcap_enable; - pcap_main_t pcap_main; - u8 *pcap_filename; - u32 pcap_sw_if_index; - u32 pcap_pkts_to_capture; + /* + * pcap drop tracing + * Only the drop filter hash lives here. See ../src/vlib/main.h for + * the rest of the variables. + */ uword *pcap_drop_filter_hash; + /* Buffer metadata format helper functions */ + vnet_buffer_opquae_formatter_t *buffer_opaque_format_helpers; + vnet_buffer_opquae_formatter_t *buffer_opaque2_format_helpers; + /* per-thread data */ vnet_interface_per_thread_data_t *per_thread_data; - /* enable GSO processing in packet path if this count is > 0 */ - u32 gso_interface_count; - /* feature_arc_index */ u8 output_feature_arc_index; + + /* fast lookup tables */ + u32 *hw_if_index_by_sw_if_index; + u16 *if_out_arc_end_next_index_by_sw_if_index; } vnet_interface_main_t; static inline void vnet_interface_counter_lock (vnet_interface_main_t * im) { if (im->sw_if_counter_lock) - while (clib_atomic_test_and_set (im->sw_if_counter_lock)) - /* zzzz */ ; + clib_spinlock_lock (&im->sw_if_counter_lock); } static inline void vnet_interface_counter_unlock (vnet_interface_main_t * im) { if (im->sw_if_counter_lock) - clib_atomic_release (im->sw_if_counter_lock); + clib_spinlock_unlock (&im->sw_if_counter_lock); } void vnet_pcap_drop_trace_filter_add_del (u32 error_index, int is_add); int vnet_interface_name_renumber (u32 sw_if_index, u32 new_show_dev_instance); -uword vnet_interface_output_node (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame); +void vnet_register_format_buffer_opaque_helper + (vnet_buffer_opquae_formatter_t fn); + +void vnet_register_format_buffer_opaque2_helper + (vnet_buffer_opquae_formatter_t fn); + +typedef struct +{ + u8 *filename; + int enable; + int status; + u32 packets_to_capture; + u32 max_bytes_per_pkt; + u8 rx_enable; + u8 tx_enable; + u8 drop_enable; + u8 preallocate_data; + u8 free_data; + u32 sw_if_index; + int filter; + vlib_error_t drop_err; +} vnet_pcap_dispatch_trace_args_t; + +int vnet_pcap_dispatch_trace_configure (vnet_pcap_dispatch_trace_args_t *); + +extern vlib_node_registration_t vnet_interface_output_node; +extern vlib_node_registration_t vnet_interface_output_arc_end_node; #endif /* included_vnet_interface_h */