diff options
Diffstat (limited to 'src')
55 files changed, 940 insertions, 686 deletions
diff --git a/src/plugins/cnat/cnat_node_vip.c b/src/plugins/cnat/cnat_node_vip.c index 5c1e0e44abe..bbce5f3bd15 100644 --- a/src/plugins/cnat/cnat_node_vip.c +++ b/src/plugins/cnat/cnat_node_vip.c @@ -22,6 +22,9 @@ #include <vnet/dpo/load_balance.h> #include <vnet/dpo/load_balance_map.h> +#include <vnet/ip/ip4_inlines.h> +#include <vnet/ip/ip6_inlines.h> + typedef struct cnat_translation_trace_t_ { cnat_session_t session; diff --git a/src/plugins/cnat/cnat_types.h b/src/plugins/cnat/cnat_types.h index 16d985f03a8..b1b5b2d2336 100644 --- a/src/plugins/cnat/cnat_types.h +++ b/src/plugins/cnat/cnat_types.h @@ -21,6 +21,7 @@ #include <vnet/fib/fib_source.h> #include <vnet/ip/ip_types.h> #include <vnet/ip/ip.h> +#include <vnet/util/throttle.h> /* only in the default table for v4 and v6 */ #define CNAT_FIB_TABLE 0 diff --git a/src/plugins/gbp/gbp_itf.c b/src/plugins/gbp/gbp_itf.c index a9e9225ae72..6a4a19733df 100644 --- a/src/plugins/gbp/gbp_itf.c +++ b/src/plugins/gbp/gbp_itf.c @@ -17,6 +17,8 @@ #include <plugins/gbp/gbp_bridge_domain.h> #include <plugins/gbp/gbp_route_domain.h> +#include <vnet/ip/ip.h> + #define foreach_gbp_itf_mode \ _(L2, "l2") \ _(L3, "L3") diff --git a/src/plugins/gbp/gbp_itf.h b/src/plugins/gbp/gbp_itf.h index b0c7ed91865..23a09b2a9ff 100644 --- a/src/plugins/gbp/gbp_itf.h +++ b/src/plugins/gbp/gbp_itf.h @@ -18,6 +18,7 @@ #include <vnet/l2/l2_input.h> #include <vnet/l2/l2_output.h> +#include <vnet/dpo/dpo.h> #define foreach_gdb_l3_feature \ diff --git a/src/plugins/gbp/gbp_learn.h b/src/plugins/gbp/gbp_learn.h index a000905e63a..b4f3ae0a23d 100644 --- a/src/plugins/gbp/gbp_learn.h +++ b/src/plugins/gbp/gbp_learn.h @@ -18,6 +18,8 @@ #include <plugins/gbp/gbp.h> +#include <vnet/util/throttle.h> + /** * The maximum learning rate per-hashed EP */ diff --git a/src/plugins/ioam/ip6/ioam_cache_node.c b/src/plugins/ioam/ip6/ioam_cache_node.c index 9c2b4697d8c..6a5465b86aa 100644 --- a/src/plugins/ioam/ip6/ioam_cache_node.c +++ b/src/plugins/ioam/ip6/ioam_cache_node.c @@ -46,6 +46,7 @@ #include <ioam/ip6/ioam_cache.h> #include <vnet/ip/ip6_hop_by_hop.h> #include <vnet/ip/ip6_hop_by_hop_packet.h> +#include <vnet/ip/ip6_inlines.h> typedef struct { diff --git a/src/plugins/ioam/ip6/ioam_cache_tunnel_select_node.c b/src/plugins/ioam/ip6/ioam_cache_tunnel_select_node.c index 633a9becabc..d2c7f20a778 100644 --- a/src/plugins/ioam/ip6/ioam_cache_tunnel_select_node.c +++ b/src/plugins/ioam/ip6/ioam_cache_tunnel_select_node.c @@ -46,6 +46,7 @@ #include <ioam/ip6/ioam_cache.h> #include <vnet/ip/ip6_hop_by_hop.h> #include <vnet/ip/ip6_hop_by_hop_packet.h> +#include <vnet/ip/ip6_inlines.h> typedef struct { diff --git a/src/plugins/l2e/l2e.c b/src/plugins/l2e/l2e.c index 791c3f67cb6..4c6eac50446 100644 --- a/src/plugins/l2e/l2e.c +++ b/src/plugins/l2e/l2e.c @@ -19,6 +19,7 @@ #include <plugins/l2e/l2e.h> #include <vnet/l2/l2_input.h> #include <vnet/l2/feat_bitmap.h> +#include <vnet/ip/ip.h> l2_emulation_main_t l2_emulation_main; diff --git a/src/plugins/lisp/lisp-cp/lisp_cp_test.c b/src/plugins/lisp/lisp-cp/lisp_cp_test.c index faffb738c04..c0284d301a7 100644 --- a/src/plugins/lisp/lisp-cp/lisp_cp_test.c +++ b/src/plugins/lisp/lisp-cp/lisp_cp_test.c @@ -20,6 +20,7 @@ #include <vnet/ip/ip_format_fns.h> #include <vnet/ethernet/ethernet_format_fns.h> +#include <vnet/ethernet/mac_address.h> #include <lisp/lisp-cp/lisp_types.h> /* define message IDs */ diff --git a/src/plugins/lisp/lisp-cp/one_test.c b/src/plugins/lisp/lisp-cp/one_test.c index 42554576fa0..6966122b2b5 100644 --- a/src/plugins/lisp/lisp-cp/one_test.c +++ b/src/plugins/lisp/lisp-cp/one_test.c @@ -20,6 +20,7 @@ #include <vnet/ip/ip_format_fns.h> #include <vnet/ethernet/ethernet_format_fns.h> +#include <vnet/ethernet/mac_address.h> #include <lisp/lisp-cp/lisp_types.h> /* define message IDs */ diff --git a/src/plugins/lisp/lisp-cp/packets.c b/src/plugins/lisp/lisp-cp/packets.c index 95f95cdb68a..8e2386e72bd 100644 --- a/src/plugins/lisp/lisp-cp/packets.c +++ b/src/plugins/lisp/lisp-cp/packets.c @@ -16,6 +16,8 @@ #include <lisp/lisp-cp/packets.h> #include <lisp/lisp-cp/lisp_cp_messages.h> #include <vnet/udp/udp_packet.h> +#include <vnet/ip/ip4_inlines.h> +#include <vnet/ip/ip6_inlines.h> /* Returns IP ID for the packet */ /* static u16 ip_id = 0; diff --git a/src/plugins/lisp/lisp-gpe/lisp_gpe_test.c b/src/plugins/lisp/lisp-gpe/lisp_gpe_test.c index 39f99492268..54f7713162a 100644 --- a/src/plugins/lisp/lisp-gpe/lisp_gpe_test.c +++ b/src/plugins/lisp/lisp-gpe/lisp_gpe_test.c @@ -20,6 +20,7 @@ #include <vnet/ip/ip_format_fns.h> #include <vnet/ethernet/ethernet_format_fns.h> +#include <vnet/ethernet/mac_address.h> #include <lisp/lisp-cp/lisp_types.h> /* define message IDs */ diff --git a/src/plugins/nat/nat.c b/src/plugins/nat/nat.c index eaecd9658ec..cb0e346c8fc 100644 --- a/src/plugins/nat/nat.c +++ b/src/plugins/nat/nat.c @@ -32,6 +32,7 @@ #include <vnet/ip/reass/ip4_sv_reass.h> #include <vppinfra/bihash_16_8.h> #include <nat/nat44/ed_inlines.h> +#include <vnet/ip/ip_table.h> #include <vpp/app/version.h> diff --git a/src/vnet/CMakeLists.txt b/src/vnet/CMakeLists.txt index 021e8604077..9f4dbb085d3 100644 --- a/src/vnet/CMakeLists.txt +++ b/src/vnet/CMakeLists.txt @@ -406,6 +406,7 @@ list(APPEND VNET_SOURCES ip/reass/ip6_sv_reass.c ip/ip_api.c ip/ip_checksum.c + ip/ip_container_proxy.c ip/ip_frag.c ip/ip.c ip/ip_interface.c @@ -444,14 +445,18 @@ list(APPEND VNET_HEADERS ip/ip4_error.h ip/ip4.h ip/ip4_mtrie.h + ip/ip4_inlines.h ip/ip4_packet.h ip/ip46_address.h ip/ip6_error.h ip/ip6.h ip/ip6_hop_by_hop.h ip/ip6_hop_by_hop_packet.h + ip/ip6_inlines.h ip/ip6_packet.h ip/ip.h + ip/ip_container_proxy.h + ip/ip_flow_hash.h ip/ip_table.h ip/ip_interface.h ip/ip_packet.h diff --git a/src/vnet/adj/adj_midchain.c b/src/vnet/adj/adj_midchain.c index 49ac24aa49c..15fef866c1b 100644 --- a/src/vnet/adj/adj_midchain.c +++ b/src/vnet/adj/adj_midchain.c @@ -23,6 +23,8 @@ #include <vnet/dpo/load_balance.h> #include <vnet/fib/fib_walk.h> #include <vnet/fib/fib_entry.h> +#include <vnet/ip/ip4_inlines.h> +#include <vnet/ip/ip6_inlines.h> /** * @brief Trace data for packets traversing the midchain tx node diff --git a/src/vnet/bier/bier_imp_node.c b/src/vnet/bier/bier_imp_node.c index 8b203258cf5..fc75cb2fca3 100644 --- a/src/vnet/bier/bier_imp_node.c +++ b/src/vnet/bier/bier_imp_node.c @@ -15,7 +15,8 @@ #include <vnet/bier/bier_imp.h> #include <vnet/bier/bier_hdr_inlines.h> -#include <vnet/ip/ip.h> +#include <vnet/ip/ip4_inlines.h> +#include <vnet/ip/ip6_inlines.h> /** * @brief A struct to hold tracing information for the BIER imposition diff --git a/src/vnet/classify/classify_api.c b/src/vnet/classify/classify_api.c index 03d04298c7a..b0750e95124 100644 --- a/src/vnet/classify/classify_api.c +++ b/src/vnet/classify/classify_api.c @@ -28,6 +28,8 @@ #include <vnet/classify/policer_classify.h> #include <vnet/classify/flow_classify.h> #include <vnet/l2/l2_classify.h> +#include <vnet/ip/ip6.h> +#include <vnet/ip/ip4.h> #include <vnet/vnet_msg_enum.h> diff --git a/src/vnet/devices/virtio/vhost_user.c b/src/vnet/devices/virtio/vhost_user.c index 5b42a272658..cf149f8b4db 100644 --- a/src/vnet/devices/virtio/vhost_user.c +++ b/src/vnet/devices/virtio/vhost_user.c @@ -33,8 +33,6 @@ #include <vlib/vlib.h> #include <vlib/unix/unix.h> -#include <vnet/ip/ip.h> - #include <vnet/ethernet/ethernet.h> #include <vnet/devices/devices.h> #include <vnet/feature/feature.h> diff --git a/src/vnet/devices/virtio/vhost_user_input.c b/src/vnet/devices/virtio/vhost_user_input.c index 001ef075985..da4937b733c 100644 --- a/src/vnet/devices/virtio/vhost_user_input.c +++ b/src/vnet/devices/virtio/vhost_user_input.c @@ -33,11 +33,10 @@ #include <vlib/vlib.h> #include <vlib/unix/unix.h> -#include <vnet/ip/ip.h> - #include <vnet/ethernet/ethernet.h> #include <vnet/devices/devices.h> #include <vnet/feature/feature.h> +#include <vnet/udp/udp_packet.h> #include <vnet/devices/virtio/vhost_user.h> #include <vnet/devices/virtio/vhost_user_inline.h> diff --git a/src/vnet/devices/virtio/vhost_user_output.c b/src/vnet/devices/virtio/vhost_user_output.c index 1f3813dd134..85ac0a3c295 100644 --- a/src/vnet/devices/virtio/vhost_user_output.c +++ b/src/vnet/devices/virtio/vhost_user_output.c @@ -34,8 +34,6 @@ #include <vlib/vlib.h> #include <vlib/unix/unix.h> -#include <vnet/ip/ip.h> - #include <vnet/ethernet/ethernet.h> #include <vnet/devices/devices.h> #include <vnet/feature/feature.h> diff --git a/src/vnet/devices/virtio/virtio_api.c b/src/vnet/devices/virtio/virtio_api.c index d9931046083..bd72284fd78 100644 --- a/src/vnet/devices/virtio/virtio_api.c +++ b/src/vnet/devices/virtio/virtio_api.c @@ -22,7 +22,6 @@ #include <vnet/interface.h> #include <vnet/api_errno.h> -#include <vnet/ip/ip.h> #include <vnet/devices/virtio/virtio.h> #include <vnet/devices/virtio/pci.h> #include <vlib/pci/pci_types_api.h> diff --git a/src/vnet/dpo/l3_proxy_dpo.h b/src/vnet/dpo/l3_proxy_dpo.h index 3a578e29924..e36edfc2ce2 100644 --- a/src/vnet/dpo/l3_proxy_dpo.h +++ b/src/vnet/dpo/l3_proxy_dpo.h @@ -22,7 +22,6 @@ #define __L3_PROXY_DPO_H__ #include <vnet/dpo/dpo.h> -#include <vnet/ip/ip6.h> typedef struct l3_proxy_dpo_t_ { diff --git a/src/vnet/dpo/load_balance.c b/src/vnet/dpo/load_balance.c index c029341f147..c0c440c25f2 100644 --- a/src/vnet/dpo/load_balance.c +++ b/src/vnet/dpo/load_balance.c @@ -13,7 +13,6 @@ * limitations under the License. */ -#include <vnet/ip/lookup.h> #include <vnet/dpo/load_balance.h> #include <vnet/dpo/load_balance_map.h> #include <vnet/dpo/drop_dpo.h> @@ -23,6 +22,8 @@ #include <vnet/fib/fib_urpf_list.h> #include <vnet/bier/bier_fwd.h> #include <vnet/fib/mpls_fib.h> +#include <vnet/ip/ip4_inlines.h> +#include <vnet/ip/ip6_inlines.h> /* * distribution error tolerance for load-balancing diff --git a/src/vnet/dpo/receive_dpo.h b/src/vnet/dpo/receive_dpo.h index 9459fbcc279..e329cdfb6f2 100644 --- a/src/vnet/dpo/receive_dpo.h +++ b/src/vnet/dpo/receive_dpo.h @@ -21,7 +21,7 @@ #define __RECEIVE_DPO_H__ #include <vnet/dpo/dpo.h> -#include <vnet/ip/ip6.h> +#include <vnet/ip/ip46_address.h> typedef struct receive_dpo_t_ { diff --git a/src/vnet/fib/fib_types.h b/src/vnet/fib/fib_types.h index f5e53038c2d..832092c5679 100644 --- a/src/vnet/fib/fib_types.h +++ b/src/vnet/fib/fib_types.h @@ -17,7 +17,6 @@ #define __FIB_TYPES_H__ #include <stdbool.h> -#include <vlib/vlib.h> #include <vnet/ip/ip46_address.h> #include <vnet/mpls/packet.h> #include <vnet/dpo/dpo.h> diff --git a/src/vnet/ip-neighbor/ip4_neighbor.c b/src/vnet/ip-neighbor/ip4_neighbor.c index 2a9e2675a78..7c0cbdcb2a2 100644 --- a/src/vnet/ip-neighbor/ip4_neighbor.c +++ b/src/vnet/ip-neighbor/ip4_neighbor.c @@ -39,6 +39,10 @@ #include <vnet/ip-neighbor/ip4_neighbor.h> #include <vnet/ethernet/ethernet.h> +#include <vnet/util/throttle.h> + +/** ARP throttling */ +static throttle_t arp_throttle; void ip4_neighbor_probe_dst (const ip_adjacency_t * adj, const ip4_address_t * dst) @@ -128,7 +132,7 @@ ip4_arp_inline (vlib_main_t * vm, if (node->flags & VLIB_NODE_FLAG_TRACE) ip4_forward_next_trace (vm, node, frame, VLIB_TX); - seed = throttle_seed (&im->arp_throttle, thread_index, vlib_time_now (vm)); + seed = throttle_seed (&arp_throttle, thread_index, vlib_time_now (vm)); from = vlib_frame_vector_args (frame); n_left_from = frame->n_vectors; @@ -186,7 +190,7 @@ ip4_arp_inline (vlib_main_t * vm, r0 = (u64) resolve0.data_u32 << 32; r0 |= sw_if_index0; - if (throttle_check (&im->arp_throttle, thread_index, r0, seed)) + if (throttle_check (&arp_throttle, thread_index, r0, seed)) { p0->error = node->errors[IP4_ARP_ERROR_THROTTLED]; continue; @@ -310,6 +314,20 @@ arp_notrace_init (vlib_main_t * vm) VLIB_INIT_FUNCTION (arp_notrace_init); +static clib_error_t * +ip4_neighbor_main_loop_enter (vlib_main_t * vm) +{ + vlib_thread_main_t *tm = &vlib_thread_main; + u32 n_vlib_mains = tm->n_vlib_mains; + + throttle_init (&arp_throttle, n_vlib_mains, 1e-3); + + return (NULL); +} + +VLIB_MAIN_LOOP_ENTER_FUNCTION (ip4_neighbor_main_loop_enter); + + /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vnet/ip-neighbor/ip6_neighbor.c b/src/vnet/ip-neighbor/ip6_neighbor.c index 325db8c6277..ca67d85778d 100644 --- a/src/vnet/ip-neighbor/ip6_neighbor.c +++ b/src/vnet/ip-neighbor/ip6_neighbor.c @@ -16,6 +16,10 @@ */ #include <vnet/ip-neighbor/ip6_neighbor.h> +#include <vnet/util/throttle.h> + +/** ND throttling */ +static throttle_t nd_throttle; void ip6_neighbor_probe_dst (const ip_adjacency_t * adj, const ip6_address_t * dst) @@ -121,7 +125,6 @@ ip6_discover_neighbor_inline (vlib_main_t * vm, vlib_frame_t * frame, int is_glean) { vnet_main_t *vnm = vnet_get_main (); - ip6_main_t *im = &ip6_main; u32 *from, *to_next_drop; uword n_left_from, n_left_to_next_drop; u64 seed; @@ -130,7 +133,7 @@ ip6_discover_neighbor_inline (vlib_main_t * vm, if (node->flags & VLIB_NODE_FLAG_TRACE) ip6_forward_next_trace (vm, node, frame, VLIB_TX); - seed = throttle_seed (&im->nd_throttle, thread_index, vlib_time_now (vm)); + seed = throttle_seed (&nd_throttle, thread_index, vlib_time_now (vm)); from = vlib_frame_vector_args (frame); n_left_from = frame->n_vectors; @@ -173,7 +176,7 @@ ip6_discover_neighbor_inline (vlib_main_t * vm, /* combine the address and interface for a hash */ r0 = ip6_address_hash_to_u64 (&ip0->dst_address) ^ sw_if_index0; - drop0 = throttle_check (&im->nd_throttle, thread_index, r0, seed); + drop0 = throttle_check (&nd_throttle, thread_index, r0, seed); from += 1; n_left_from -= 1; @@ -329,6 +332,18 @@ ip6_neighbor_init (vlib_main_t * vm) VLIB_INIT_FUNCTION (ip6_neighbor_init); +static clib_error_t * +ip6_nd_main_loop_enter (vlib_main_t * vm) +{ + vlib_thread_main_t *tm = &vlib_thread_main; + + throttle_init (&nd_throttle, tm->n_vlib_mains, 1e-3); + + return 0; +} + +VLIB_MAIN_LOOP_ENTER_FUNCTION (ip6_nd_main_loop_enter); + /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vnet/ip/icmp6.h b/src/vnet/ip/icmp6.h index 628d225eac4..7a5eef5df18 100644 --- a/src/vnet/ip/icmp6.h +++ b/src/vnet/ip/icmp6.h @@ -15,6 +15,8 @@ #ifndef included_vnet_icmp6_h #define included_vnet_icmp6_h +#include <vnet/ip/icmp46_packet.h> + #define foreach_icmp6_error \ _ (NONE, "valid packets") \ _ (UNKNOWN_TYPE, "unknown type") \ diff --git a/src/vnet/ip/ip4.h b/src/vnet/ip/ip4.h index cb78bfbe356..22de22f227a 100644 --- a/src/vnet/ip/ip4.h +++ b/src/vnet/ip/ip4.h @@ -41,12 +41,13 @@ #define included_ip_ip4_h #include <vnet/ip/ip4_packet.h> +#include <vnet/ip/ip_flow_hash.h> + #include <vnet/ip/lookup.h> #include <vnet/ip/ip_interface.h> #include <vnet/buffer.h> #include <vnet/feature/feature.h> #include <vnet/ip/icmp46_packet.h> -#include <vnet/util/throttle.h> typedef struct ip4_mfib_t { @@ -163,10 +164,6 @@ typedef struct ip4_main_t u8 pad[2]; } host_config; - - /** ARP throttling */ - throttle_t arp_throttle; - } ip4_main_t; #define ARP_THROTTLE_BITS (512) @@ -295,56 +292,6 @@ void ip4_punt_redirect_add_paths (u32 rx_sw_if_index, void ip4_punt_redirect_del (u32 rx_sw_if_index); -/* Compute flow hash. We'll use it to select which adjacency to use for this - flow. And other things. */ -always_inline u32 -ip4_compute_flow_hash (const ip4_header_t * ip, - flow_hash_config_t flow_hash_config) -{ - tcp_header_t *tcp = (void *) (ip + 1); - u32 a, b, c, t1, t2; - uword is_tcp_udp = (ip->protocol == IP_PROTOCOL_TCP - || ip->protocol == IP_PROTOCOL_UDP); - - t1 = (flow_hash_config & IP_FLOW_HASH_SRC_ADDR) - ? ip->src_address.data_u32 : 0; - t2 = (flow_hash_config & IP_FLOW_HASH_DST_ADDR) - ? ip->dst_address.data_u32 : 0; - - a = (flow_hash_config & IP_FLOW_HASH_REVERSE_SRC_DST) ? t2 : t1; - b = (flow_hash_config & IP_FLOW_HASH_REVERSE_SRC_DST) ? t1 : t2; - - t1 = is_tcp_udp ? tcp->src : 0; - t2 = is_tcp_udp ? tcp->dst : 0; - - t1 = (flow_hash_config & IP_FLOW_HASH_SRC_PORT) ? t1 : 0; - t2 = (flow_hash_config & IP_FLOW_HASH_DST_PORT) ? t2 : 0; - - if (flow_hash_config & IP_FLOW_HASH_SYMMETRIC) - { - if (b < a) - { - c = a; - a = b; - b = c; - } - if (t2 < t1) - { - t2 += t1; - t1 = t2 - t1; - t2 = t2 - t1; - } - } - - b ^= (flow_hash_config & IP_FLOW_HASH_PROTO) ? ip->protocol : 0; - c = (flow_hash_config & IP_FLOW_HASH_REVERSE_SRC_DST) ? - (t1 << 16) | t2 : (t2 << 16) | t1; - - hash_v3_mix32 (a, b, c); - hash_v3_finalize32 (a, b, c); - - return c; -} void ip4_forward_next_trace (vlib_main_t * vm, @@ -356,66 +303,6 @@ u8 *format_ip4_forward_next_trace (u8 * s, va_list * args); u32 ip4_tcp_udp_validate_checksum (vlib_main_t * vm, vlib_buffer_t * p0); -#define IP_DF 0x4000 /* don't fragment */ - -always_inline void * -vlib_buffer_push_ip4_custom (vlib_main_t * vm, vlib_buffer_t * b, - ip4_address_t * src, ip4_address_t * dst, - int proto, u8 csum_offload, u8 is_df) -{ - ip4_header_t *ih; - - /* make some room */ - ih = vlib_buffer_push_uninit (b, sizeof (ip4_header_t)); - - ih->ip_version_and_header_length = 0x45; - ih->tos = 0; - ih->length = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b)); - - /* No fragments */ - ih->flags_and_fragment_offset = is_df ? clib_host_to_net_u16 (IP_DF) : 0; - ih->ttl = 255; - ih->protocol = proto; - ih->src_address.as_u32 = src->as_u32; - ih->dst_address.as_u32 = dst->as_u32; - - vnet_buffer (b)->l3_hdr_offset = (u8 *) ih - b->data; - b->flags |= VNET_BUFFER_F_IS_IP4 | VNET_BUFFER_F_L3_HDR_OFFSET_VALID; - - /* Offload ip4 header checksum generation */ - if (csum_offload) - { - ih->checksum = 0; - b->flags |= VNET_BUFFER_F_OFFLOAD_IP_CKSUM; - } - else - ih->checksum = ip4_header_checksum (ih); - - return ih; -} - -/** - * Push IPv4 header to buffer - * - * This does not support fragmentation. - * - * @param vm - vlib_main - * @param b - buffer to write the header to - * @param src - source IP - * @param dst - destination IP - * @param prot - payload proto - * - * @return - pointer to start of IP header - */ -always_inline void * -vlib_buffer_push_ip4 (vlib_main_t * vm, vlib_buffer_t * b, - ip4_address_t * src, ip4_address_t * dst, int proto, - u8 csum_offload) -{ - return vlib_buffer_push_ip4_custom (vm, b, src, dst, proto, csum_offload, - 1 /* is_df */ ); -} - always_inline u32 vlib_buffer_get_ip4_fib_index (vlib_buffer_t * b) { @@ -425,6 +312,7 @@ vlib_buffer_get_ip4_fib_index (vlib_buffer_t * b) return (fib_index == (u32) ~ 0) ? vec_elt (ip4_main.fib_index_by_sw_if_index, sw_if_index) : fib_index; } + #endif /* included_ip_ip4_h */ /* diff --git a/src/vnet/ip/ip4_forward.h b/src/vnet/ip/ip4_forward.h index 1750ac67eab..8779d2ded6b 100644 --- a/src/vnet/ip/ip4_forward.h +++ b/src/vnet/ip/ip4_forward.h @@ -43,6 +43,7 @@ #include <vppinfra/cache.h> #include <vnet/fib/ip4_fib.h> #include <vnet/dpo/load_balance_map.h> +#include <vnet/ip/ip4_inlines.h> /** * @file diff --git a/src/vnet/ip/ip4_inlines.h b/src/vnet/ip/ip4_inlines.h new file mode 100644 index 00000000000..bdb82af0034 --- /dev/null +++ b/src/vnet/ip/ip4_inlines.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2015 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * ip/ip4.h: ip4 main include file + * + * 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. + */ + +#ifndef included_ip_ip4_inlines_h +#define included_ip_ip4_inlines_h + +#include <vnet/ip/ip_flow_hash.h> +#include <vnet/ip/ip4_packet.h> + +#define IP_DF 0x4000 /* don't fragment */ + +/* Compute flow hash. We'll use it to select which adjacency to use for this + flow. And other things. */ +always_inline u32 +ip4_compute_flow_hash (const ip4_header_t * ip, + flow_hash_config_t flow_hash_config) +{ + tcp_header_t *tcp = (void *) (ip + 1); + u32 a, b, c, t1, t2; + uword is_tcp_udp = (ip->protocol == IP_PROTOCOL_TCP + || ip->protocol == IP_PROTOCOL_UDP); + + t1 = (flow_hash_config & IP_FLOW_HASH_SRC_ADDR) + ? ip->src_address.data_u32 : 0; + t2 = (flow_hash_config & IP_FLOW_HASH_DST_ADDR) + ? ip->dst_address.data_u32 : 0; + + a = (flow_hash_config & IP_FLOW_HASH_REVERSE_SRC_DST) ? t2 : t1; + b = (flow_hash_config & IP_FLOW_HASH_REVERSE_SRC_DST) ? t1 : t2; + + t1 = is_tcp_udp ? tcp->src : 0; + t2 = is_tcp_udp ? tcp->dst : 0; + + t1 = (flow_hash_config & IP_FLOW_HASH_SRC_PORT) ? t1 : 0; + t2 = (flow_hash_config & IP_FLOW_HASH_DST_PORT) ? t2 : 0; + + if (flow_hash_config & IP_FLOW_HASH_SYMMETRIC) + { + if (b < a) + { + c = a; + a = b; + b = c; + } + if (t2 < t1) + { + t2 += t1; + t1 = t2 - t1; + t2 = t2 - t1; + } + } + + b ^= (flow_hash_config & IP_FLOW_HASH_PROTO) ? ip->protocol : 0; + c = (flow_hash_config & IP_FLOW_HASH_REVERSE_SRC_DST) ? + (t1 << 16) | t2 : (t2 << 16) | t1; + + hash_v3_mix32 (a, b, c); + hash_v3_finalize32 (a, b, c); + + return c; +} + +always_inline void * +vlib_buffer_push_ip4_custom (vlib_main_t * vm, vlib_buffer_t * b, + ip4_address_t * src, ip4_address_t * dst, + int proto, u8 csum_offload, u8 is_df) +{ + ip4_header_t *ih; + + /* make some room */ + ih = vlib_buffer_push_uninit (b, sizeof (ip4_header_t)); + + ih->ip_version_and_header_length = 0x45; + ih->tos = 0; + ih->length = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b)); + + /* No fragments */ + ih->flags_and_fragment_offset = is_df ? clib_host_to_net_u16 (IP_DF) : 0; + ih->ttl = 255; + ih->protocol = proto; + ih->src_address.as_u32 = src->as_u32; + ih->dst_address.as_u32 = dst->as_u32; + + vnet_buffer (b)->l3_hdr_offset = (u8 *) ih - b->data; + b->flags |= VNET_BUFFER_F_IS_IP4 | VNET_BUFFER_F_L3_HDR_OFFSET_VALID; + + /* Offload ip4 header checksum generation */ + if (csum_offload) + { + ih->checksum = 0; + b->flags |= VNET_BUFFER_F_OFFLOAD_IP_CKSUM; + } + else + ih->checksum = ip4_header_checksum (ih); + + return ih; +} + +/** + * Push IPv4 header to buffer + * + * This does not support fragmentation. + * + * @param vm - vlib_main + * @param b - buffer to write the header to + * @param src - source IP + * @param dst - destination IP + * @param prot - payload proto + * + * @return - pointer to start of IP header + */ +always_inline void * +vlib_buffer_push_ip4 (vlib_main_t * vm, vlib_buffer_t * b, + ip4_address_t * src, ip4_address_t * dst, int proto, + u8 csum_offload) +{ + return vlib_buffer_push_ip4_custom (vm, b, src, dst, proto, csum_offload, + 1 /* is_df */ ); +} + +#endif /* included_ip_ip4_inlines_h */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/src/vnet/ip/ip4_input.c b/src/vnet/ip/ip4_input.c index 4d48db8f567..bf8e05c1bab 100644 --- a/src/vnet/ip/ip4_input.c +++ b/src/vnet/ip/ip4_input.c @@ -451,20 +451,6 @@ ip4_init (vlib_main_t * vm) VLIB_INIT_FUNCTION (ip4_init); -static clib_error_t * -ip4_main_loop_enter (vlib_main_t * vm) -{ - ip4_main_t *im = &ip4_main; - vlib_thread_main_t *tm = &vlib_thread_main; - u32 n_vlib_mains = tm->n_vlib_mains; - - throttle_init (&im->arp_throttle, n_vlib_mains, 1e-3); - - return (NULL); -} - -VLIB_MAIN_LOOP_ENTER_FUNCTION (ip4_main_loop_enter); - /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vnet/ip/ip6.h b/src/vnet/ip/ip6.h index fcb18031a06..a0fa3b49280 100644 --- a/src/vnet/ip/ip6.h +++ b/src/vnet/ip/ip6.h @@ -40,17 +40,16 @@ #ifndef included_ip_ip6_h #define included_ip_ip6_h +#include <stdbool.h> + #include <vlib/buffer.h> -#include <vnet/ethernet/packet.h> -#include <vnet/ethernet/mac_address.h> + #include <vnet/ip/ip6_packet.h> #include <vnet/ip/ip46_address.h> #include <vnet/ip/ip6_hop_by_hop_packet.h> #include <vnet/ip/lookup.h> #include <vnet/ip/ip_interface.h> -#include <stdbool.h> -#include <vnet/util/radix.h> -#include <vnet/util/throttle.h> +#include <vnet/ip/ip_flow_hash.h> typedef struct { @@ -164,9 +163,6 @@ typedef struct ip6_main_t /* HBH processing enabled? */ u8 hbh_enabled; - - /** ND throttling */ - throttle_t nd_throttle; } ip6_main_t; #define ND_THROTTLE_BITS 512 @@ -304,153 +300,6 @@ int vnet_set_ip6_classify_intfc (vlib_main_t * vm, u32 sw_if_index, u32 table_index); extern vlib_node_registration_t ip6_lookup_node; -/* Compute flow hash. We'll use it to select which Sponge to use for this - flow. And other things. */ -always_inline u32 -ip6_compute_flow_hash (const ip6_header_t * ip, - flow_hash_config_t flow_hash_config) -{ - tcp_header_t *tcp; - u64 a, b, c; - u64 t1, t2; - uword is_tcp_udp = 0; - u8 protocol = ip->protocol; - - if (PREDICT_TRUE - ((ip->protocol == IP_PROTOCOL_TCP) - || (ip->protocol == IP_PROTOCOL_UDP))) - { - is_tcp_udp = 1; - tcp = (void *) (ip + 1); - } - else if (ip->protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS) - { - ip6_hop_by_hop_header_t *hbh = (ip6_hop_by_hop_header_t *) (ip + 1); - if ((hbh->protocol == IP_PROTOCOL_TCP) || - (hbh->protocol == IP_PROTOCOL_UDP)) - { - is_tcp_udp = 1; - tcp = (tcp_header_t *) ((u8 *) hbh + ((hbh->length + 1) << 3)); - } - protocol = hbh->protocol; - } - - t1 = (ip->src_address.as_u64[0] ^ ip->src_address.as_u64[1]); - t1 = (flow_hash_config & IP_FLOW_HASH_SRC_ADDR) ? t1 : 0; - - t2 = (ip->dst_address.as_u64[0] ^ ip->dst_address.as_u64[1]); - t2 = (flow_hash_config & IP_FLOW_HASH_DST_ADDR) ? t2 : 0; - - a = (flow_hash_config & IP_FLOW_HASH_REVERSE_SRC_DST) ? t2 : t1; - b = (flow_hash_config & IP_FLOW_HASH_REVERSE_SRC_DST) ? t1 : t2; - - t1 = is_tcp_udp ? tcp->src : 0; - t2 = is_tcp_udp ? tcp->dst : 0; - - t1 = (flow_hash_config & IP_FLOW_HASH_SRC_PORT) ? t1 : 0; - t2 = (flow_hash_config & IP_FLOW_HASH_DST_PORT) ? t2 : 0; - - if (flow_hash_config & IP_FLOW_HASH_SYMMETRIC) - { - if (b < a) - { - c = a; - a = b; - b = c; - } - if (t2 < t1) - { - t2 += t1; - t1 = t2 - t1; - t2 = t2 - t1; - } - } - - b ^= (flow_hash_config & IP_FLOW_HASH_PROTO) ? protocol : 0; - c = (flow_hash_config & IP_FLOW_HASH_REVERSE_SRC_DST) ? - ((t1 << 16) | t2) : ((t2 << 16) | t1); - - hash_mix64 (a, b, c); - return (u32) c; -} - -/* ip6_locate_header - * - * This function is to search for the header specified by the protocol number - * in find_hdr_type. - * This is used to locate a specific IPv6 extension header - * or to find transport layer header. - * 1. If the find_hdr_type < 0 then it finds and returns the protocol number and - * offset stored in *offset of the transport or ESP header in the chain if - * found. - * 2. If a header with find_hdr_type > 0 protocol number is found then the - * offset is stored in *offset and protocol number of the header is - * returned. - * 3. If find_hdr_type is not found or packet is malformed or - * it is a non-first fragment -1 is returned. - */ -always_inline int -ip6_locate_header (vlib_buffer_t * p0, - ip6_header_t * ip0, int find_hdr_type, u32 * offset) -{ - u8 next_proto = ip0->protocol; - u8 *next_header; - u8 done = 0; - u32 cur_offset; - u8 *temp_nxthdr = 0; - u32 exthdr_len = 0; - - next_header = ip6_next_header (ip0); - cur_offset = sizeof (ip6_header_t); - while (1) - { - done = (next_proto == find_hdr_type); - if (PREDICT_FALSE - (next_header >= - (u8 *) vlib_buffer_get_current (p0) + p0->current_length)) - { - //A malicious packet could set an extension header with a too big size - return (-1); - } - if (done) - break; - if ((!ip6_ext_hdr (next_proto)) || next_proto == IP_PROTOCOL_IP6_NONXT) - { - if (find_hdr_type < 0) - break; - return -1; - } - if (next_proto == IP_PROTOCOL_IPV6_FRAGMENTATION) - { - ip6_frag_hdr_t *frag_hdr = (ip6_frag_hdr_t *) next_header; - u16 frag_off = ip6_frag_hdr_offset (frag_hdr); - /* Non first fragment return -1 */ - if (frag_off) - return (-1); - exthdr_len = sizeof (ip6_frag_hdr_t); - temp_nxthdr = next_header + exthdr_len; - } - else if (next_proto == IP_PROTOCOL_IPSEC_AH) - { - exthdr_len = - ip6_ext_authhdr_len (((ip6_ext_header_t *) next_header)); - temp_nxthdr = next_header + exthdr_len; - } - else - { - exthdr_len = - ip6_ext_header_len (((ip6_ext_header_t *) next_header)); - temp_nxthdr = next_header + exthdr_len; - } - next_proto = ((ip6_ext_header_t *) next_header)->next_hdr; - next_header = temp_nxthdr; - cur_offset += exthdr_len; - } - - *offset = cur_offset; - return (next_proto); -} - u8 *format_ip6_hop_by_hop_ext_hdr (u8 * s, va_list * args); /* * Hop-by-Hop handling @@ -475,70 +324,6 @@ int ip6_hbh_register_option (u8 option, int ip6_hbh_unregister_option (u8 option); void ip6_hbh_set_next_override (uword next); -/** - * Push IPv6 header to buffer - * - * @param vm - vlib_main - * @param b - buffer to write the header to - * @param src - source IP - * @param dst - destination IP - * @param prot - payload proto - * @param flow_label - flow label - * - * @return - pointer to start of IP header - */ -always_inline void * -vlib_buffer_push_ip6_custom (vlib_main_t * vm, vlib_buffer_t * b, - ip6_address_t * src, ip6_address_t * dst, - int proto, u32 flow_label) -{ - ip6_header_t *ip6h; - u16 payload_length; - - /* make some room */ - ip6h = vlib_buffer_push_uninit (b, sizeof (ip6_header_t)); - ASSERT (flow_label < 1 << 20); - ip6h->ip_version_traffic_class_and_flow_label = - clib_host_to_net_u32 ((0x6 << 28) | flow_label); - - /* calculate ip6 payload length */ - payload_length = vlib_buffer_length_in_chain (vm, b); - payload_length -= sizeof (*ip6h); - - ip6h->payload_length = clib_host_to_net_u16 (payload_length); - - ip6h->hop_limit = 0xff; - ip6h->protocol = proto; - clib_memcpy_fast (ip6h->src_address.as_u8, src->as_u8, - sizeof (ip6h->src_address)); - clib_memcpy_fast (ip6h->dst_address.as_u8, dst->as_u8, - sizeof (ip6h->src_address)); - vnet_buffer (b)->l3_hdr_offset = (u8 *) ip6h - b->data; - b->flags |= VNET_BUFFER_F_IS_IP6 | VNET_BUFFER_F_L3_HDR_OFFSET_VALID; - - return ip6h; -} - -/** - * Push IPv6 header to buffer - * - * @param vm - vlib_main - * @param b - buffer to write the header to - * @param src - source IP - * @param dst - destination IP - * @param prot - payload proto - * - * @return - pointer to start of IP header - */ -always_inline void * -vlib_buffer_push_ip6 (vlib_main_t * vm, vlib_buffer_t * b, - ip6_address_t * src, ip6_address_t * dst, int proto) -{ - return vlib_buffer_push_ip6_custom (vm, b, src, dst, proto, - 0 /* flow label */ ); - -} - always_inline u32 vlib_buffer_get_ip6_fib_index (vlib_buffer_t * b) { diff --git a/src/vnet/ip/ip6_forward.h b/src/vnet/ip/ip6_forward.h index 7f6eb0c1184..8e5dd256ceb 100644 --- a/src/vnet/ip/ip6_forward.h +++ b/src/vnet/ip/ip6_forward.h @@ -42,6 +42,7 @@ #include <vnet/fib/ip6_fib.h> #include <vnet/dpo/load_balance_map.h> +#include <vnet/ip/ip6_inlines.h> /** * @file diff --git a/src/vnet/ip/ip6_inlines.h b/src/vnet/ip/ip6_inlines.h new file mode 100644 index 00000000000..ae7b7a1761b --- /dev/null +++ b/src/vnet/ip/ip6_inlines.h @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2016 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. + */ +/* + * ip/ip6.h: ip6 main include file + * + * 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. + */ + +#ifndef included_ip_ip6_inlines_h +#define included_ip_ip6_inlines_h + +#include <vnet/ip/ip6_packet.h> +#include <vnet/ip/ip6_hop_by_hop_packet.h> + +/* Compute flow hash. We'll use it to select which Sponge to use for this + flow. And other things. */ +always_inline u32 +ip6_compute_flow_hash (const ip6_header_t * ip, + flow_hash_config_t flow_hash_config) +{ + tcp_header_t *tcp; + u64 a, b, c; + u64 t1, t2; + uword is_tcp_udp = 0; + u8 protocol = ip->protocol; + + if (PREDICT_TRUE + ((ip->protocol == IP_PROTOCOL_TCP) + || (ip->protocol == IP_PROTOCOL_UDP))) + { + is_tcp_udp = 1; + tcp = (void *) (ip + 1); + } + else if (ip->protocol == IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS) + { + ip6_hop_by_hop_header_t *hbh = (ip6_hop_by_hop_header_t *) (ip + 1); + if ((hbh->protocol == IP_PROTOCOL_TCP) || + (hbh->protocol == IP_PROTOCOL_UDP)) + { + is_tcp_udp = 1; + tcp = (tcp_header_t *) ((u8 *) hbh + ((hbh->length + 1) << 3)); + } + protocol = hbh->protocol; + } + + t1 = (ip->src_address.as_u64[0] ^ ip->src_address.as_u64[1]); + t1 = (flow_hash_config & IP_FLOW_HASH_SRC_ADDR) ? t1 : 0; + + t2 = (ip->dst_address.as_u64[0] ^ ip->dst_address.as_u64[1]); + t2 = (flow_hash_config & IP_FLOW_HASH_DST_ADDR) ? t2 : 0; + + a = (flow_hash_config & IP_FLOW_HASH_REVERSE_SRC_DST) ? t2 : t1; + b = (flow_hash_config & IP_FLOW_HASH_REVERSE_SRC_DST) ? t1 : t2; + + t1 = is_tcp_udp ? tcp->src : 0; + t2 = is_tcp_udp ? tcp->dst : 0; + + t1 = (flow_hash_config & IP_FLOW_HASH_SRC_PORT) ? t1 : 0; + t2 = (flow_hash_config & IP_FLOW_HASH_DST_PORT) ? t2 : 0; + + if (flow_hash_config & IP_FLOW_HASH_SYMMETRIC) + { + if (b < a) + { + c = a; + a = b; + b = c; + } + if (t2 < t1) + { + t2 += t1; + t1 = t2 - t1; + t2 = t2 - t1; + } + } + + b ^= (flow_hash_config & IP_FLOW_HASH_PROTO) ? protocol : 0; + c = (flow_hash_config & IP_FLOW_HASH_REVERSE_SRC_DST) ? + ((t1 << 16) | t2) : ((t2 << 16) | t1); + + hash_mix64 (a, b, c); + return (u32) c; +} + +/* ip6_locate_header + * + * This function is to search for the header specified by the protocol number + * in find_hdr_type. + * This is used to locate a specific IPv6 extension header + * or to find transport layer header. + * 1. If the find_hdr_type < 0 then it finds and returns the protocol number and + * offset stored in *offset of the transport or ESP header in the chain if + * found. + * 2. If a header with find_hdr_type > 0 protocol number is found then the + * offset is stored in *offset and protocol number of the header is + * returned. + * 3. If find_hdr_type is not found or packet is malformed or + * it is a non-first fragment -1 is returned. + */ +always_inline int +ip6_locate_header (vlib_buffer_t * p0, + ip6_header_t * ip0, int find_hdr_type, u32 * offset) +{ + u8 next_proto = ip0->protocol; + u8 *next_header; + u8 done = 0; + u32 cur_offset; + u8 *temp_nxthdr = 0; + u32 exthdr_len = 0; + + next_header = ip6_next_header (ip0); + cur_offset = sizeof (ip6_header_t); + while (1) + { + done = (next_proto == find_hdr_type); + if (PREDICT_FALSE + (next_header >= + (u8 *) vlib_buffer_get_current (p0) + p0->current_length)) + { + //A malicious packet could set an extension header with a too big size + return (-1); + } + if (done) + break; + if ((!ip6_ext_hdr (next_proto)) || next_proto == IP_PROTOCOL_IP6_NONXT) + { + if (find_hdr_type < 0) + break; + return -1; + } + if (next_proto == IP_PROTOCOL_IPV6_FRAGMENTATION) + { + ip6_frag_hdr_t *frag_hdr = (ip6_frag_hdr_t *) next_header; + u16 frag_off = ip6_frag_hdr_offset (frag_hdr); + /* Non first fragment return -1 */ + if (frag_off) + return (-1); + exthdr_len = sizeof (ip6_frag_hdr_t); + temp_nxthdr = next_header + exthdr_len; + } + else if (next_proto == IP_PROTOCOL_IPSEC_AH) + { + exthdr_len = + ip6_ext_authhdr_len (((ip6_ext_header_t *) next_header)); + temp_nxthdr = next_header + exthdr_len; + } + else + { + exthdr_len = + ip6_ext_header_len (((ip6_ext_header_t *) next_header)); + temp_nxthdr = next_header + exthdr_len; + } + next_proto = ((ip6_ext_header_t *) next_header)->next_hdr; + next_header = temp_nxthdr; + cur_offset += exthdr_len; + } + + *offset = cur_offset; + return (next_proto); +} + + +/** + * Push IPv6 header to buffer + * + * @param vm - vlib_main + * @param b - buffer to write the header to + * @param src - source IP + * @param dst - destination IP + * @param prot - payload proto + * @param flow_label - flow label + * + * @return - pointer to start of IP header + */ +always_inline void * +vlib_buffer_push_ip6_custom (vlib_main_t * vm, vlib_buffer_t * b, + ip6_address_t * src, ip6_address_t * dst, + int proto, u32 flow_label) +{ + ip6_header_t *ip6h; + u16 payload_length; + + /* make some room */ + ip6h = vlib_buffer_push_uninit (b, sizeof (ip6_header_t)); + ASSERT (flow_label < 1 << 20); + ip6h->ip_version_traffic_class_and_flow_label = + clib_host_to_net_u32 ((0x6 << 28) | flow_label); + + /* calculate ip6 payload length */ + payload_length = vlib_buffer_length_in_chain (vm, b); + payload_length -= sizeof (*ip6h); + + ip6h->payload_length = clib_host_to_net_u16 (payload_length); + + ip6h->hop_limit = 0xff; + ip6h->protocol = proto; + clib_memcpy_fast (ip6h->src_address.as_u8, src->as_u8, + sizeof (ip6h->src_address)); + clib_memcpy_fast (ip6h->dst_address.as_u8, dst->as_u8, + sizeof (ip6h->src_address)); + vnet_buffer (b)->l3_hdr_offset = (u8 *) ip6h - b->data; + b->flags |= VNET_BUFFER_F_IS_IP6 | VNET_BUFFER_F_L3_HDR_OFFSET_VALID; + + return ip6h; +} + +/** + * Push IPv6 header to buffer + * + * @param vm - vlib_main + * @param b - buffer to write the header to + * @param src - source IP + * @param dst - destination IP + * @param prot - payload proto + * + * @return - pointer to start of IP header + */ +always_inline void * +vlib_buffer_push_ip6 (vlib_main_t * vm, vlib_buffer_t * b, + ip6_address_t * src, ip6_address_t * dst, int proto) +{ + return vlib_buffer_push_ip6_custom (vm, b, src, dst, proto, + 0 /* flow label */ ); + +} + +#endif /* included_ip_ip6_h */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/src/vnet/ip/ip6_input.c b/src/vnet/ip/ip6_input.c index ebcfd5a9f05..65d39ebc54d 100644 --- a/src/vnet/ip/ip6_input.c +++ b/src/vnet/ip/ip6_input.c @@ -280,19 +280,6 @@ ip6_init (vlib_main_t * vm) VLIB_INIT_FUNCTION (ip6_init); -static clib_error_t * -ip6_main_loop_enter (vlib_main_t * vm) -{ - ip6_main_t *im = &ip6_main; - vlib_thread_main_t *tm = &vlib_thread_main; - - throttle_init (&im->nd_throttle, tm->n_vlib_mains, 1e-3); - - return 0; -} - -VLIB_MAIN_LOOP_ENTER_FUNCTION (ip6_main_loop_enter); - /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vnet/ip/ip_api.c b/src/vnet/ip/ip_api.c index 448b36c6acc..3bdb53cd9ff 100644 --- a/src/vnet/ip/ip_api.c +++ b/src/vnet/ip/ip_api.c @@ -45,6 +45,7 @@ #include <vnet/ip/reass/ip6_sv_reass.h> #include <vnet/ip/reass/ip6_full_reass.h> #include <vnet/ip/ip_table.h> +#include <vnet/ip/ip_container_proxy.h> #include <vnet/vnet_msg_enum.h> diff --git a/src/vnet/ip/ip_container_proxy.c b/src/vnet/ip/ip_container_proxy.c new file mode 100644 index 00000000000..e90be8b45d3 --- /dev/null +++ b/src/vnet/ip/ip_container_proxy.c @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2015 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * ip/ip_lookup.c: ip4/6 adjacency and lookup table management + * + * 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 <vnet/ip/ip_container_proxy.h> +#include <vnet/ip/format.h> +#include <vnet/fib/fib_table.h> +#include <vnet/dpo/l3_proxy_dpo.h> +#include <vnet/dpo/load_balance.h> + +clib_error_t * +vnet_ip_container_proxy_add_del (vnet_ip_container_proxy_args_t * args) +{ + u32 fib_index; + + if (!vnet_sw_interface_is_api_valid (vnet_get_main (), args->sw_if_index)) + return clib_error_return_code (0, VNET_API_ERROR_INVALID_INTERFACE, 0, + "invalid sw_if_index"); + + fib_index = fib_table_get_table_id_for_sw_if_index (args->prefix.fp_proto, + args->sw_if_index); + if (args->is_add) + { + dpo_id_t proxy_dpo = DPO_INVALID; + l3_proxy_dpo_add_or_lock (fib_proto_to_dpo (args->prefix.fp_proto), + args->sw_if_index, &proxy_dpo); + fib_table_entry_special_dpo_add (fib_index, + &args->prefix, + FIB_SOURCE_PROXY, + FIB_ENTRY_FLAG_EXCLUSIVE, &proxy_dpo); + dpo_reset (&proxy_dpo); + } + else + { + fib_table_entry_special_remove (fib_index, &args->prefix, + FIB_SOURCE_PROXY); + } + return 0; +} + +u8 +ip_container_proxy_is_set (fib_prefix_t * pfx, u32 sw_if_index) +{ + u32 fib_index; + fib_node_index_t fei; + const dpo_id_t *dpo; + l3_proxy_dpo_t *l3p; + load_balance_t *lb0; + + fib_index = fib_table_get_table_id_for_sw_if_index (pfx->fp_proto, + sw_if_index); + if (fib_index == ~0) + return 0; + + fei = fib_table_lookup_exact_match (fib_index, pfx); + if (fei == FIB_NODE_INDEX_INVALID) + return 0; + + dpo = fib_entry_contribute_ip_forwarding (fei); + lb0 = load_balance_get (dpo->dpoi_index); + dpo = load_balance_get_bucket_i (lb0, 0); + if (dpo->dpoi_type != DPO_L3_PROXY) + return 0; + + l3p = l3_proxy_dpo_get (dpo->dpoi_index); + return (l3p->l3p_sw_if_index == sw_if_index); +} + +typedef struct ip_container_proxy_walk_ctx_t_ +{ + ip_container_proxy_cb_t cb; + void *ctx; +} ip_container_proxy_walk_ctx_t; + +static fib_table_walk_rc_t +ip_container_proxy_fib_table_walk (fib_node_index_t fei, void *arg) +{ + ip_container_proxy_walk_ctx_t *ctx = arg; + const fib_prefix_t *pfx; + const dpo_id_t *dpo; + load_balance_t *lb; + l3_proxy_dpo_t *l3p; + + pfx = fib_entry_get_prefix (fei); + if (fib_entry_is_sourced (fei, FIB_SOURCE_PROXY)) + { + dpo = fib_entry_contribute_ip_forwarding (fei); + lb = load_balance_get (dpo->dpoi_index); + dpo = load_balance_get_bucket_i (lb, 0); + l3p = l3_proxy_dpo_get (dpo->dpoi_index); + ctx->cb (pfx, l3p->l3p_sw_if_index, ctx->ctx); + } + + return FIB_TABLE_WALK_CONTINUE; +} + +void +ip_container_proxy_walk (ip_container_proxy_cb_t cb, void *ctx) +{ + fib_table_t *fib_table; + ip_container_proxy_walk_ctx_t wctx = { + .cb = cb, + .ctx = ctx, + }; + + /* *INDENT-OFF* */ + pool_foreach (fib_table, ip4_main.fibs, + ({ + fib_table_walk(fib_table->ft_index, + FIB_PROTOCOL_IP4, + ip_container_proxy_fib_table_walk, + &wctx); + })); + pool_foreach (fib_table, ip6_main.fibs, + ({ + fib_table_walk(fib_table->ft_index, + FIB_PROTOCOL_IP6, + ip_container_proxy_fib_table_walk, + &wctx); + })); + /* *INDENT-ON* */ +} + +clib_error_t * +ip_container_cmd (vlib_main_t * vm, + unformat_input_t * main_input, vlib_cli_command_t * cmd) +{ + unformat_input_t _line_input, *line_input = &_line_input; + fib_prefix_t pfx; + u32 is_del, addr_set = 0; + vnet_main_t *vnm; + u32 sw_if_index; + + vnm = vnet_get_main (); + is_del = 0; + sw_if_index = ~0; + clib_memset (&pfx, 0, sizeof (pfx)); + + /* Get a line of input. */ + if (!unformat_user (main_input, unformat_line_input, line_input)) + return 0; + + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "%U", unformat_ip4_address, &pfx.fp_addr.ip4)) + { + pfx.fp_proto = FIB_PROTOCOL_IP4; + pfx.fp_len = 32; + addr_set = 1; + } + else if (unformat (line_input, "%U", + unformat_ip6_address, &pfx.fp_addr.ip6)) + { + pfx.fp_proto = FIB_PROTOCOL_IP6; + pfx.fp_len = 128; + addr_set = 1; + } + else if (unformat (line_input, "%U", + unformat_vnet_sw_interface, vnm, &sw_if_index)) + ; + else if (unformat (line_input, "del")) + is_del = 1; + else + { + unformat_free (line_input); + return (clib_error_return (0, "unknown input '%U'", + format_unformat_error, line_input)); + } + } + + if (~0 == sw_if_index || !addr_set) + { + unformat_free (line_input); + vlib_cli_output (vm, "interface and address must be set"); + return 0; + } + + vnet_ip_container_proxy_args_t args = { + .prefix = pfx, + .sw_if_index = sw_if_index, + .is_add = !is_del, + }; + vnet_ip_container_proxy_add_del (&args); + unformat_free (line_input); + return (NULL); +} + +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (ip_container_command_node, static) = { + .path = "ip container", + .function = ip_container_cmd, + .short_help = "ip container <address> <interface>", + .is_mp_safe = 1, +}; +/* *INDENT-ON* */ + +clib_error_t * +show_ip_container_cmd_fn (vlib_main_t * vm, unformat_input_t * main_input, + vlib_cli_command_t * cmd) +{ + unformat_input_t _line_input, *line_input = &_line_input; + vnet_main_t *vnm = vnet_get_main (); + fib_prefix_t pfx; + u32 sw_if_index = ~0; + u8 has_proxy; + + if (!unformat_user (main_input, unformat_line_input, line_input)) + return 0; + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "%U", unformat_ip4_address, &pfx.fp_addr.ip4)) + { + pfx.fp_proto = FIB_PROTOCOL_IP4; + pfx.fp_len = 32; + } + else if (unformat (line_input, "%U", + unformat_ip6_address, &pfx.fp_addr.ip6)) + { + pfx.fp_proto = FIB_PROTOCOL_IP6; + pfx.fp_len = 128; + } + else if (unformat (line_input, "%U", + unformat_vnet_sw_interface, vnm, &sw_if_index)) + ; + else + { + unformat_free (line_input); + return (clib_error_return (0, "unknown input '%U'", + format_unformat_error, line_input)); + } + } + + if (~0 == sw_if_index) + { + unformat_free (line_input); + vlib_cli_output (vm, "no interface"); + return (clib_error_return (0, "no interface")); + } + + has_proxy = ip_container_proxy_is_set (&pfx, sw_if_index); + vlib_cli_output (vm, "ip container proxy is: %s", has_proxy ? "on" : "off"); + + unformat_free (line_input); + return 0; +} + +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (show_ip_container_command, static) = { + .path = "show ip container", + .function = show_ip_container_cmd_fn, + .short_help = "show ip container <address> <interface>", + .is_mp_safe = 1, +}; +/* *INDENT-ON* */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/src/vnet/ip/ip_container_proxy.h b/src/vnet/ip/ip_container_proxy.h new file mode 100644 index 00000000000..4aee56c80e8 --- /dev/null +++ b/src/vnet/ip/ip_container_proxy.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef included_ip_container_proxy_h +#define included_ip_container_proxy_h + +#include <vnet/fib/fib_types.h> + +typedef struct _vnet_ip_container_proxy_args +{ + fib_prefix_t prefix; + u32 sw_if_index; + u8 is_add; +} vnet_ip_container_proxy_args_t; + +clib_error_t *vnet_ip_container_proxy_add_del (vnet_ip_container_proxy_args_t + * args); + +typedef int (*ip_container_proxy_cb_t) (const fib_prefix_t * pfx, + u32 sw_if_index, void *ctx); +void ip_container_proxy_walk (ip_container_proxy_cb_t cb, void *ctx); + +#endif + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/src/vnet/ip/ip_flow_hash.h b/src/vnet/ip/ip_flow_hash.h new file mode 100644 index 00000000000..04777320f38 --- /dev/null +++ b/src/vnet/ip/ip_flow_hash.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2019 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. + */ + +#ifndef __IP_FLOW_HASH_H__ +#define __IP_FLOW_HASH_H__ + +/** Flow hash configuration */ +#define IP_FLOW_HASH_SRC_ADDR (1<<0) +#define IP_FLOW_HASH_DST_ADDR (1<<1) +#define IP_FLOW_HASH_PROTO (1<<2) +#define IP_FLOW_HASH_SRC_PORT (1<<3) +#define IP_FLOW_HASH_DST_PORT (1<<4) +#define IP_FLOW_HASH_REVERSE_SRC_DST (1<<5) +#define IP_FLOW_HASH_SYMMETRIC (1<<6) + +/** Default: 5-tuple without the "reverse" bit */ +#define IP_FLOW_HASH_DEFAULT (0x1F) + +#define foreach_flow_hash_bit \ +_(src, IP_FLOW_HASH_SRC_ADDR) \ +_(dst, IP_FLOW_HASH_DST_ADDR) \ +_(sport, IP_FLOW_HASH_SRC_PORT) \ +_(dport, IP_FLOW_HASH_DST_PORT) \ +_(proto, IP_FLOW_HASH_PROTO) \ +_(reverse, IP_FLOW_HASH_REVERSE_SRC_DST) \ +_(symmetric, IP_FLOW_HASH_SYMMETRIC) + +/** + * A flow hash configuration is a mask of the flow hash options + */ +typedef u32 flow_hash_config_t; + +#endif /* __IP_TYPES_H__ */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/src/vnet/ip/ip_table.h b/src/vnet/ip/ip_table.h index 1f75c15be26..dfdd27ab573 100644 --- a/src/vnet/ip/ip_table.h +++ b/src/vnet/ip/ip_table.h @@ -16,14 +16,7 @@ #ifndef included_ip_table_h #define included_ip_table_h -#include <vlib/vlib.h> - -/* ip table add delete callback */ -typedef struct _vnet_ip_table_function_list_elt -{ - struct _vnet_ip_table_function_list_elt *next_ip_table_function; - clib_error_t *(*fp) (struct vnet_main_t * vnm, u32 table_id, u32 flags); -} _vnet_ip_table_function_list_elt_t; +#include <vnet/vnet.h> typedef enum vnet_ip_table_function_priority_t_ { diff --git a/src/vnet/ip/lookup.c b/src/vnet/ip/lookup.c index 63bd281a325..b356b278e01 100644 --- a/src/vnet/ip/lookup.c +++ b/src/vnet/ip/lookup.c @@ -49,7 +49,6 @@ #include <vnet/dpo/punt_dpo.h> #include <vnet/dpo/receive_dpo.h> #include <vnet/dpo/ip_null_dpo.h> -#include <vnet/dpo/l3_proxy_dpo.h> /** * @file @@ -899,251 +898,6 @@ VLIB_CLI_COMMAND (ip_mroute_command, static) = }; /* *INDENT-ON* */ -clib_error_t * -vnet_ip_container_proxy_add_del (vnet_ip_container_proxy_args_t * args) -{ - u32 fib_index; - - if (!vnet_sw_interface_is_api_valid (vnet_get_main (), args->sw_if_index)) - return clib_error_return_code (0, VNET_API_ERROR_INVALID_INTERFACE, 0, - "invalid sw_if_index"); - - fib_index = fib_table_get_table_id_for_sw_if_index (args->prefix.fp_proto, - args->sw_if_index); - if (args->is_add) - { - dpo_id_t proxy_dpo = DPO_INVALID; - l3_proxy_dpo_add_or_lock (fib_proto_to_dpo (args->prefix.fp_proto), - args->sw_if_index, &proxy_dpo); - fib_table_entry_special_dpo_add (fib_index, - &args->prefix, - FIB_SOURCE_PROXY, - FIB_ENTRY_FLAG_EXCLUSIVE, &proxy_dpo); - dpo_reset (&proxy_dpo); - } - else - { - fib_table_entry_special_remove (fib_index, &args->prefix, - FIB_SOURCE_PROXY); - } - return 0; -} - -u8 -ip_container_proxy_is_set (fib_prefix_t * pfx, u32 sw_if_index) -{ - u32 fib_index; - fib_node_index_t fei; - const dpo_id_t *dpo; - l3_proxy_dpo_t *l3p; - load_balance_t *lb0; - - fib_index = fib_table_get_table_id_for_sw_if_index (pfx->fp_proto, - sw_if_index); - if (fib_index == ~0) - return 0; - - fei = fib_table_lookup_exact_match (fib_index, pfx); - if (fei == FIB_NODE_INDEX_INVALID) - return 0; - - dpo = fib_entry_contribute_ip_forwarding (fei); - lb0 = load_balance_get (dpo->dpoi_index); - dpo = load_balance_get_bucket_i (lb0, 0); - if (dpo->dpoi_type != DPO_L3_PROXY) - return 0; - - l3p = l3_proxy_dpo_get (dpo->dpoi_index); - return (l3p->l3p_sw_if_index == sw_if_index); -} - -typedef struct ip_container_proxy_walk_ctx_t_ -{ - ip_container_proxy_cb_t cb; - void *ctx; -} ip_container_proxy_walk_ctx_t; - -static fib_table_walk_rc_t -ip_container_proxy_fib_table_walk (fib_node_index_t fei, void *arg) -{ - ip_container_proxy_walk_ctx_t *ctx = arg; - const fib_prefix_t *pfx; - const dpo_id_t *dpo; - load_balance_t *lb; - l3_proxy_dpo_t *l3p; - - pfx = fib_entry_get_prefix (fei); - if (fib_entry_is_sourced (fei, FIB_SOURCE_PROXY)) - { - dpo = fib_entry_contribute_ip_forwarding (fei); - lb = load_balance_get (dpo->dpoi_index); - dpo = load_balance_get_bucket_i (lb, 0); - l3p = l3_proxy_dpo_get (dpo->dpoi_index); - ctx->cb (pfx, l3p->l3p_sw_if_index, ctx->ctx); - } - - return FIB_TABLE_WALK_CONTINUE; -} - -void -ip_container_proxy_walk (ip_container_proxy_cb_t cb, void *ctx) -{ - fib_table_t *fib_table; - ip_container_proxy_walk_ctx_t wctx = { - .cb = cb, - .ctx = ctx, - }; - - /* *INDENT-OFF* */ - pool_foreach (fib_table, ip4_main.fibs, - ({ - fib_table_walk(fib_table->ft_index, - FIB_PROTOCOL_IP4, - ip_container_proxy_fib_table_walk, - &wctx); - })); - pool_foreach (fib_table, ip6_main.fibs, - ({ - fib_table_walk(fib_table->ft_index, - FIB_PROTOCOL_IP6, - ip_container_proxy_fib_table_walk, - &wctx); - })); - /* *INDENT-ON* */ -} - -clib_error_t * -ip_container_cmd (vlib_main_t * vm, - unformat_input_t * main_input, vlib_cli_command_t * cmd) -{ - unformat_input_t _line_input, *line_input = &_line_input; - fib_prefix_t pfx; - u32 is_del, addr_set = 0; - vnet_main_t *vnm; - u32 sw_if_index; - - vnm = vnet_get_main (); - is_del = 0; - sw_if_index = ~0; - clib_memset (&pfx, 0, sizeof (pfx)); - - /* Get a line of input. */ - if (!unformat_user (main_input, unformat_line_input, line_input)) - return 0; - - while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) - { - if (unformat (line_input, "%U", unformat_ip4_address, &pfx.fp_addr.ip4)) - { - pfx.fp_proto = FIB_PROTOCOL_IP4; - pfx.fp_len = 32; - addr_set = 1; - } - else if (unformat (line_input, "%U", - unformat_ip6_address, &pfx.fp_addr.ip6)) - { - pfx.fp_proto = FIB_PROTOCOL_IP6; - pfx.fp_len = 128; - addr_set = 1; - } - else if (unformat (line_input, "%U", - unformat_vnet_sw_interface, vnm, &sw_if_index)) - ; - else if (unformat (line_input, "del")) - is_del = 1; - else - { - unformat_free (line_input); - return (clib_error_return (0, "unknown input '%U'", - format_unformat_error, line_input)); - } - } - - if (~0 == sw_if_index || !addr_set) - { - unformat_free (line_input); - vlib_cli_output (vm, "interface and address must be set"); - return 0; - } - - vnet_ip_container_proxy_args_t args = { - .prefix = pfx, - .sw_if_index = sw_if_index, - .is_add = !is_del, - }; - vnet_ip_container_proxy_add_del (&args); - unformat_free (line_input); - return (NULL); -} - -/* *INDENT-OFF* */ -VLIB_CLI_COMMAND (ip_container_command_node, static) = { - .path = "ip container", - .function = ip_container_cmd, - .short_help = "ip container <address> <interface>", - .is_mp_safe = 1, -}; -/* *INDENT-ON* */ - -clib_error_t * -show_ip_container_cmd_fn (vlib_main_t * vm, unformat_input_t * main_input, - vlib_cli_command_t * cmd) -{ - unformat_input_t _line_input, *line_input = &_line_input; - vnet_main_t *vnm = vnet_get_main (); - fib_prefix_t pfx; - u32 sw_if_index = ~0; - u8 has_proxy; - - if (!unformat_user (main_input, unformat_line_input, line_input)) - return 0; - while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) - { - if (unformat (line_input, "%U", unformat_ip4_address, &pfx.fp_addr.ip4)) - { - pfx.fp_proto = FIB_PROTOCOL_IP4; - pfx.fp_len = 32; - } - else if (unformat (line_input, "%U", - unformat_ip6_address, &pfx.fp_addr.ip6)) - { - pfx.fp_proto = FIB_PROTOCOL_IP6; - pfx.fp_len = 128; - } - else if (unformat (line_input, "%U", - unformat_vnet_sw_interface, vnm, &sw_if_index)) - ; - else - { - unformat_free (line_input); - return (clib_error_return (0, "unknown input '%U'", - format_unformat_error, line_input)); - } - } - - if (~0 == sw_if_index) - { - unformat_free (line_input); - vlib_cli_output (vm, "no interface"); - return (clib_error_return (0, "no interface")); - } - - has_proxy = ip_container_proxy_is_set (&pfx, sw_if_index); - vlib_cli_output (vm, "ip container proxy is: %s", has_proxy ? "on" : "off"); - - unformat_free (line_input); - return 0; -} - -/* *INDENT-OFF* */ -VLIB_CLI_COMMAND (show_ip_container_command, static) = { - .path = "show ip container", - .function = show_ip_container_cmd_fn, - .short_help = "show ip container <address> <interface>", - .is_mp_safe = 1, -}; -/* *INDENT-ON* */ - /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vnet/ip/lookup.h b/src/vnet/ip/lookup.h index 49ed0bbd3ef..48ba468d7c2 100644 --- a/src/vnet/ip/lookup.h +++ b/src/vnet/ip/lookup.h @@ -48,40 +48,16 @@ #ifndef included_ip_lookup_h #define included_ip_lookup_h -#include <vnet/vnet.h> +//#include <vnet/vnet.h> +#include <vlib/vlib.h> #include <vlib/buffer.h> #include <vnet/ip/ip4_packet.h> #include <vnet/ip/ip6_packet.h> +#include <vnet/ip/ip_types.h> #include <vnet/fib/fib_node.h> #include <vnet/adj/adj.h> #include <vnet/dpo/dpo.h> -#include <vnet/feature/feature.h> - -/** Flow hash configuration */ -#define IP_FLOW_HASH_SRC_ADDR (1<<0) -#define IP_FLOW_HASH_DST_ADDR (1<<1) -#define IP_FLOW_HASH_PROTO (1<<2) -#define IP_FLOW_HASH_SRC_PORT (1<<3) -#define IP_FLOW_HASH_DST_PORT (1<<4) -#define IP_FLOW_HASH_REVERSE_SRC_DST (1<<5) -#define IP_FLOW_HASH_SYMMETRIC (1<<6) - -/** Default: 5-tuple without the "reverse" bit */ -#define IP_FLOW_HASH_DEFAULT (0x1F) - -#define foreach_flow_hash_bit \ -_(src, IP_FLOW_HASH_SRC_ADDR) \ -_(dst, IP_FLOW_HASH_DST_ADDR) \ -_(sport, IP_FLOW_HASH_SRC_PORT) \ -_(dport, IP_FLOW_HASH_DST_PORT) \ -_(proto, IP_FLOW_HASH_PROTO) \ -_(reverse, IP_FLOW_HASH_REVERSE_SRC_DST) \ -_(symmetric, IP_FLOW_HASH_SYMMETRIC) - -/** - * A flow hash configuration is a mask of the flow hash options - */ -typedef u32 flow_hash_config_t; +///#include <vnet/feature/feature.h> /* An all zeros address */ extern const ip46_address_t zero_addr; @@ -202,20 +178,6 @@ ip_lookup_set_buffer_fib_index (u32 * fib_index_by_sw_if_index, /* *INDENT-ON* */ } -typedef struct _vnet_ip_container_proxy_args -{ - fib_prefix_t prefix; - u32 sw_if_index; - u8 is_add; -} vnet_ip_container_proxy_args_t; - -clib_error_t *vnet_ip_container_proxy_add_del (vnet_ip_container_proxy_args_t - * args); - -typedef int (*ip_container_proxy_cb_t) (const fib_prefix_t * pfx, - u32 sw_if_index, void *ctx); -void ip_container_proxy_walk (ip_container_proxy_cb_t cb, void *ctx); - void ip_lookup_init (ip_lookup_main_t * lm, u32 ip_lookup_node_index); #endif /* included_ip_lookup_h */ diff --git a/src/vnet/ip/vtep.h b/src/vnet/ip/vtep.h index 345b6db1f9b..0fdc4c5a346 100644 --- a/src/vnet/ip/vtep.h +++ b/src/vnet/ip/vtep.h @@ -18,8 +18,7 @@ #include <vppinfra/hash.h> #include <vnet/ip/ip.h> -#include <vnet/ip/ip4.h> -#include <vnet/ip/ip6.h> +#include <vnet/ip/ip46_address.h> /** * @brief Tunnel endpoint key (IPv4) diff --git a/src/vnet/ipsec/ipsec_itf.c b/src/vnet/ipsec/ipsec_itf.c index ff06a579f2e..8fbb1c42ed6 100644 --- a/src/vnet/ipsec/ipsec_itf.c +++ b/src/vnet/ipsec/ipsec_itf.c @@ -20,6 +20,7 @@ #include <vnet/ipsec/ipsec_tun.h> #include <vnet/ipsec/ipsec.h> #include <vnet/adj/adj_midchain.h> +#include <vnet/ethernet/mac_address.h> /* bitmap of Allocated IPSEC_ITF instances */ static uword *ipsec_itf_instances; diff --git a/src/vnet/l2/l2_arp_term.c b/src/vnet/l2/l2_arp_term.c index fd21bc433e5..3fcd9c1c83d 100644 --- a/src/vnet/l2/l2_arp_term.c +++ b/src/vnet/l2/l2_arp_term.c @@ -22,6 +22,10 @@ #include <vnet/l2/feat_bitmap.h> #include <vnet/ip/ip4_packet.h> +#include <vnet/ip/ip6_packet.h> +#include <vnet/ip/icmp6.h> +#include <vnet/ip/ip6.h> +#include <vnet/ip/format.h> #include <vnet/ethernet/arp_packet.h> static const u8 vrrp_prefix[] = { 0x00, 0x00, 0x5E, 0x00, 0x01 }; diff --git a/src/vnet/l2/l2_input.h b/src/vnet/l2/l2_input.h index 9a59d3521d0..96a0a1afa86 100644 --- a/src/vnet/l2/l2_input.h +++ b/src/vnet/l2/l2_input.h @@ -18,12 +18,15 @@ #ifndef included_vnet_l2_input_h #define included_vnet_l2_input_h +#include <stdbool.h> + #include <vlib/vlib.h> #include <vnet/vnet.h> #include <vnet/l2/l2_bd.h> #include <vnet/ethernet/ethernet.h> #include <vnet/ethernet/packet.h> -#include <vnet/ip/ip.h> +#include <vnet/ip/ip4_inlines.h> +#include <vnet/ip/ip6_inlines.h> /* l2 connection type */ typedef enum l2_input_flags_t_ diff --git a/src/vnet/l2/l2_input_node.c b/src/vnet/l2/l2_input_node.c index 972529ad92a..59a437e1b3f 100644 --- a/src/vnet/l2/l2_input_node.c +++ b/src/vnet/l2/l2_input_node.c @@ -20,9 +20,8 @@ #include <vnet/pg/pg.h> #include <vnet/ethernet/ethernet.h> #include <vnet/ethernet/packet.h> -#include <vnet/ip/ip_packet.h> -#include <vnet/ip/ip4_packet.h> -#include <vnet/ip/ip6_packet.h> +#include <vnet/ip/ip4.h> +#include <vnet/ip/ip6.h> #include <vnet/fib/fib_node.h> #include <vnet/ethernet/arp_packet.h> #include <vlib/cli.h> diff --git a/src/vnet/mfib/mfib_itf.c b/src/vnet/mfib/mfib_itf.c index decf7650c94..3e734c8a85f 100644 --- a/src/vnet/mfib/mfib_itf.c +++ b/src/vnet/mfib/mfib_itf.c @@ -18,6 +18,7 @@ #include <vnet/mfib/mfib_itf.h> #include <vnet/mfib/mfib_signal.h> #include <vnet/fib/fib_path.h> +#include <vnet/ethernet/mac_address.h> mfib_itf_t *mfib_itf_pool; diff --git a/src/vnet/mpls/mpls_lookup.h b/src/vnet/mpls/mpls_lookup.h index 17f9468f0ac..5b88be17d8f 100644 --- a/src/vnet/mpls/mpls_lookup.h +++ b/src/vnet/mpls/mpls_lookup.h @@ -19,6 +19,8 @@ #include <vnet/mpls/mpls.h> #include <vnet/ip/ip.h> #include <vnet/bier/bier_fwd.h> +#include <vnet/ip/ip4_inlines.h> +#include <vnet/ip/ip6_inlines.h> /** * The arc/edge from the MPLS lookup node to the MPLS replicate node diff --git a/src/vnet/srv6/sr_policy_rewrite.c b/src/vnet/srv6/sr_policy_rewrite.c index 814fd6266ec..7c4f757f36b 100644 --- a/src/vnet/srv6/sr_policy_rewrite.c +++ b/src/vnet/srv6/sr_policy_rewrite.c @@ -41,9 +41,9 @@ #include <vlib/vlib.h> #include <vnet/vnet.h> #include <vnet/srv6/sr.h> -#include <vnet/ip/ip.h> +#include <vnet/ip/ip4_inlines.h> +#include <vnet/ip/ip6_inlines.h> #include <vnet/srv6/sr_packet.h> -#include <vnet/ip/ip6_packet.h> #include <vnet/fib/ip6_fib.h> #include <vnet/dpo/dpo.h> #include <vnet/dpo/replicate_dpo.h> diff --git a/src/vnet/tcp/tcp_output.c b/src/vnet/tcp/tcp_output.c index b40cdbeded3..13432283677 100644 --- a/src/vnet/tcp/tcp_output.c +++ b/src/vnet/tcp/tcp_output.c @@ -16,6 +16,8 @@ #include <vnet/tcp/tcp.h> #include <vnet/tcp/tcp_inlines.h> #include <math.h> +#include <vnet/ip/ip4_inlines.h> +#include <vnet/ip/ip6_inlines.h> typedef enum _tcp_output_next { diff --git a/src/vnet/udp/udp.c b/src/vnet/udp/udp.c index 99fa2aa00d0..1d05e02b2ab 100644 --- a/src/vnet/udp/udp.c +++ b/src/vnet/udp/udp.c @@ -16,7 +16,8 @@ #include <vnet/udp/udp.h> #include <vnet/session/session.h> #include <vnet/dpo/load_balance.h> -#include <vnet/fib/ip4_fib.h> +#include <vnet/ip/ip4_inlines.h> +#include <vnet/ip/ip6_inlines.h> #include <vppinfra/sparse_vec.h> udp_main_t udp_main; diff --git a/src/vnet/udp/udp.h b/src/vnet/udp/udp.h index 8f4b2f109ff..1494b33a8c3 100644 --- a/src/vnet/udp/udp.h +++ b/src/vnet/udp/udp.h @@ -19,8 +19,6 @@ #include <vnet/udp/udp_inlines.h> #include <vnet/udp/udp_local.h> #include <vnet/udp/udp_packet.h> -#include <vnet/ip/ip.h> -#include <vnet/ip/ip4.h> #include <vnet/ip/ip4_packet.h> #include <vnet/ip/format.h> diff --git a/src/vnet/vnet.h b/src/vnet/vnet.h index 14da23f66ce..be680a77f98 100644 --- a/src/vnet/vnet.h +++ b/src/vnet/vnet.h @@ -49,7 +49,13 @@ #include <vnet/config.h> #include <vnet/interface.h> #include <vnet/api_errno.h> -#include <vnet/ip/ip_table.h> + +/* ip table add delete callback */ +typedef struct _vnet_ip_table_function_list_elt +{ + struct _vnet_ip_table_function_list_elt *next_ip_table_function; + clib_error_t *(*fp) (struct vnet_main_t * vnm, u32 table_id, u32 flags); +} _vnet_ip_table_function_list_elt_t; typedef struct vnet_main_t { |