summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeale Ranns <neale.ranns@cisco.com>2020-10-26 13:00:06 +0000
committerDamjan Marion <dmarion@me.com>2020-10-28 16:55:35 +0000
commite4031131ccddd7c4eb683b36f1a97a65dcff008a (patch)
treeef469ab6a2188bd3ce7ab0daacb0d9ef14fca632
parent224a3c03d9aa34259ac3816c0039f2776d6da5ef (diff)
misc: Break the big IP header files to improve compile time
Type: refactor Signed-off-by: Neale Ranns <neale.ranns@cisco.com> Change-Id: Id1801519638a9b97175847d7ed58824fb83433d6
-rw-r--r--src/plugins/cnat/cnat_node_vip.c3
-rw-r--r--src/plugins/cnat/cnat_types.h1
-rw-r--r--src/plugins/gbp/gbp_itf.c2
-rw-r--r--src/plugins/gbp/gbp_itf.h1
-rw-r--r--src/plugins/gbp/gbp_learn.h2
-rw-r--r--src/plugins/ioam/ip6/ioam_cache_node.c1
-rw-r--r--src/plugins/ioam/ip6/ioam_cache_tunnel_select_node.c1
-rw-r--r--src/plugins/l2e/l2e.c1
-rw-r--r--src/plugins/lisp/lisp-cp/lisp_cp_test.c1
-rw-r--r--src/plugins/lisp/lisp-cp/one_test.c1
-rw-r--r--src/plugins/lisp/lisp-cp/packets.c2
-rw-r--r--src/plugins/lisp/lisp-gpe/lisp_gpe_test.c1
-rw-r--r--src/plugins/nat/nat.c1
-rw-r--r--src/vnet/CMakeLists.txt5
-rw-r--r--src/vnet/adj/adj_midchain.c2
-rw-r--r--src/vnet/bier/bier_imp_node.c3
-rw-r--r--src/vnet/classify/classify_api.c2
-rw-r--r--src/vnet/devices/virtio/vhost_user.c2
-rw-r--r--src/vnet/devices/virtio/vhost_user_input.c3
-rw-r--r--src/vnet/devices/virtio/vhost_user_output.c2
-rw-r--r--src/vnet/devices/virtio/virtio_api.c1
-rw-r--r--src/vnet/dpo/l3_proxy_dpo.h1
-rw-r--r--src/vnet/dpo/load_balance.c3
-rw-r--r--src/vnet/dpo/receive_dpo.h2
-rw-r--r--src/vnet/fib/fib_types.h1
-rw-r--r--src/vnet/ip-neighbor/ip4_neighbor.c22
-rw-r--r--src/vnet/ip-neighbor/ip6_neighbor.c21
-rw-r--r--src/vnet/ip/icmp6.h2
-rw-r--r--src/vnet/ip/ip4.h118
-rw-r--r--src/vnet/ip/ip4_forward.h1
-rw-r--r--src/vnet/ip/ip4_inlines.h165
-rw-r--r--src/vnet/ip/ip4_input.c14
-rw-r--r--src/vnet/ip/ip6.h223
-rw-r--r--src/vnet/ip/ip6_forward.h1
-rw-r--r--src/vnet/ip/ip6_inlines.h266
-rw-r--r--src/vnet/ip/ip6_input.c13
-rw-r--r--src/vnet/ip/ip_api.c1
-rw-r--r--src/vnet/ip/ip_container_proxy.c297
-rw-r--r--src/vnet/ip/ip_container_proxy.h43
-rw-r--r--src/vnet/ip/ip_flow_hash.h53
-rw-r--r--src/vnet/ip/ip_table.h9
-rw-r--r--src/vnet/ip/lookup.c246
-rw-r--r--src/vnet/ip/lookup.h46
-rw-r--r--src/vnet/ip/vtep.h3
-rw-r--r--src/vnet/ipsec/ipsec_itf.c1
-rw-r--r--src/vnet/l2/l2_arp_term.c4
-rw-r--r--src/vnet/l2/l2_input.h5
-rw-r--r--src/vnet/l2/l2_input_node.c5
-rw-r--r--src/vnet/mfib/mfib_itf.c1
-rw-r--r--src/vnet/mpls/mpls_lookup.h2
-rw-r--r--src/vnet/srv6/sr_policy_rewrite.c4
-rw-r--r--src/vnet/tcp/tcp_output.c2
-rw-r--r--src/vnet/udp/udp.c3
-rw-r--r--src/vnet/udp/udp.h2
-rw-r--r--src/vnet/vnet.h8
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
{