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
diff --git a/src/vnet/ip/icmp6.h b/src/vnet/ip/icmp6.h
index 628d225..7a5eef5 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 cb78bfb..22de22f 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 @@
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_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 @@
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 @@
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 1750ac6..8779d2d 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 0000000..bdb82af
--- /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 4d48db8..bf8e05c 100644
--- a/src/vnet/ip/ip4_input.c
+++ b/src/vnet/ip/ip4_input.c
@@ -451,20 +451,6 @@
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 fcb1803..a0fa3b4 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 @@
/* HBH processing enabled? */
u8 hbh_enabled;
-
- /** ND throttling */
- throttle_t nd_throttle;
} ip6_main_t;
#define ND_THROTTLE_BITS 512
@@ -304,153 +300,6 @@
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_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 7f6eb0c..8e5dd25 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 0000000..ae7b7a1
--- /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 ebcfd5a..65d39eb 100644
--- a/src/vnet/ip/ip6_input.c
+++ b/src/vnet/ip/ip6_input.c
@@ -280,19 +280,6 @@
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 448b36c..3bdb53c 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 0000000..e90be8b
--- /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 0000000..4aee56c
--- /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 0000000..0477732
--- /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 1f75c15..dfdd27a 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 63bd281..b356b27 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 @@
};
/* *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 49ed0bb..48ba468 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 @@
/* *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 345b6db..0fdc4c5 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)