/* Index into FIB vector. */
u32 index;
-
- /* flow hash configuration */
- flow_hash_config_t flow_hash_config;
} ip6_fib_t;
typedef struct ip6_mfib_t
uword function_opaque;
} ip6_add_del_interface_address_callback_t;
+typedef void (ip6_table_bind_function_t)
+ (struct ip6_main_t * im,
+ uword opaque, u32 sw_if_index, u32 new_fib_index, u32 old_fib_index);
+
+typedef struct
+{
+ ip6_table_bind_function_t *function;
+ uword function_opaque;
+} ip6_table_bind_callback_t;
+
/**
* Enumeration of the FIB table instance types
*/
/* Pool of FIBs. */
struct fib_table_t_ *fibs;
+ /* Pool of V6 FIBs. */
+ ip6_fib_t *v6_fibs;
+
/** Vector of MFIBs. */
struct mfib_table_t_ *mfibs;
ip6_add_del_interface_address_callback_t
* add_del_interface_address_callbacks;
+ /** Functions to call when interface to table biding changes. */
+ ip6_table_bind_callback_t *table_bind_callbacks;
+
/* Template used to generate IP6 neighbor solicitation packets. */
vlib_packet_template_t discover_neighbor_packet_template;
extern vlib_node_registration_t ip6_glean_node;
extern vlib_node_registration_t ip6_midchain_node;
-extern vlib_node_registration_t ip6_icmp_neighbor_discovery_event_node;
-
-/* ipv6 neighbor discovery - timer/event types */
-typedef enum
-{
- ICMP6_ND_EVENT_INIT,
-} ip6_icmp_neighbor_discovery_event_type_t;
-
-typedef union
-{
- u32 add_del_swindex;
- struct
- {
- u32 up_down_swindex;
- u32 fib_index;
- } up_down_event;
-} ip6_icmp_neighbor_discovery_event_data_t;
-
always_inline uword
ip6_destination_matches_route (const ip6_main_t * im,
const ip6_address_t * key,
clib_error_t *ip6_probe_neighbor (vlib_main_t * vm, ip6_address_t * dst,
u32 sw_if_index);
-clib_error_t *ip6_set_neighbor_limit (u32 neighbor_limit);
-
uword
ip6_udp_register_listener (vlib_main_t * vm,
u16 dst_port, u32 next_node_index);
void ip6_ethernet_update_adjacency (vnet_main_t * vnm,
u32 sw_if_index, u32 ai);
-int
-vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm,
- u32 sw_if_index,
- ip6_address_t * a,
- u8 * link_layer_address,
- uword n_bytes_link_layer_address,
- int is_static);
-int
-vnet_unset_ip6_ethernet_neighbor (vlib_main_t * vm,
- u32 sw_if_index,
- ip6_address_t * a,
- u8 * link_layer_address,
- uword n_bytes_link_layer_address);
void
ip6_link_local_address_from_ethernet_mac_address (ip6_address_t * ip,
int vnet_set_ip6_flow_hash (u32 table_id,
flow_hash_config_t flow_hash_config);
-int
-ip6_neighbor_ra_config (vlib_main_t * vm, u32 sw_if_index,
- u8 suppress, u8 managed, u8 other,
- u8 ll_option, u8 send_unicast, u8 cease,
- u8 use_lifetime, u32 lifetime,
- u32 initial_count, u32 initial_interval,
- u32 max_interval, u32 min_interval, u8 is_no);
-
-int
-ip6_neighbor_ra_prefix (vlib_main_t * vm, u32 sw_if_index,
- ip6_address_t * prefix_addr, u8 prefix_len,
- u8 use_default, u32 val_lifetime, u32 pref_lifetime,
- u8 no_advertise, u8 off_link, u8 no_autoconfig,
- u8 no_onlink, u8 is_no);
-
-
clib_error_t *enable_ip6_interface (vlib_main_t * vm, u32 sw_if_index);
clib_error_t *disable_ip6_interface (vlib_main_t * vm, u32 sw_if_index);
u32 sw_if_index,
ip6_address_t * address);
-void vnet_register_ip6_neighbor_resolution_event (vnet_main_t * vnm,
- void *address_arg,
- uword node_index,
- uword type_opaque,
- uword data);
-
int vnet_add_del_ip6_nd_change_event (vnet_main_t * vnm,
void *data_callback,
u32 pid,
vlib_node_runtime_t * node,
vlib_buffer_t * p0,
ethernet_header_t * eth,
- ip6_header_t * ip,
- u32 sw_if_index, u16 bd_index, u8 shg);
+ ip6_header_t * ip, u32 sw_if_index, u16 bd_index);
+
+void send_ip6_na (vlib_main_t * vm, vnet_hw_interface_t * hi);
u8 *format_ip6_forward_next_trace (u8 * s, va_list * args);
ip6_compute_flow_hash (const ip6_header_t * ip,
flow_hash_config_t flow_hash_config)
{
- tcp_header_t *tcp = (void *) (ip + 1);
+ tcp_header_t *tcp;
u64 a, b, c;
u64 t1, t2;
- uword is_tcp_udp = (ip->protocol == IP_PROTOCOL_TCP
- || ip->protocol == IP_PROTOCOL_UDP);
+ 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;
a = (flow_hash_config & IP_FLOW_HASH_REVERSE_SRC_DST) ? t2 : t1;
b = (flow_hash_config & IP_FLOW_HASH_REVERSE_SRC_DST) ? t1 : t2;
- b ^= (flow_hash_config & IP_FLOW_HASH_PROTO) ? ip->protocol : 0;
+ b ^= (flow_hash_config & IP_FLOW_HASH_PROTO) ? protocol : 0;
t1 = is_tcp_udp ? tcp->src : 0;
t2 = is_tcp_udp ? tcp->dst : 0;
sizeof (ip6h->src_address));
clib_memcpy (ip6h->dst_address.as_u8, dst->as_u8,
sizeof (ip6h->src_address));
+ b->flags |= VNET_BUFFER_F_IS_IP6;
return ip6h;
}