2 * Copyright (c) 2016 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
16 #ifndef included_vnet_handoff_h
17 #define included_vnet_handoff_h
19 #include <vlib/vlib.h>
20 #include <vnet/ethernet/ethernet.h>
21 #include <vnet/ip/ip4_packet.h>
22 #include <vnet/ip/ip6_packet.h>
23 #include <vnet/mpls/packet.h>
27 HANDOFF_DISPATCH_NEXT_IP4_INPUT,
28 HANDOFF_DISPATCH_NEXT_IP6_INPUT,
29 HANDOFF_DISPATCH_NEXT_MPLS_INPUT,
30 HANDOFF_DISPATCH_NEXT_ETHERNET_INPUT,
31 HANDOFF_DISPATCH_NEXT_DROP,
32 HANDOFF_DISPATCH_N_NEXT,
33 } handoff_dispatch_next_t;
37 ipv4_get_key (ip4_header_t * ip)
41 hash_key = *((u64 *) (&ip->address_pair)) ^ ip->protocol;
47 ipv6_get_key (ip6_header_t * ip)
51 hash_key = ip->src_address.as_u64[0] ^
52 rotate_left (ip->src_address.as_u64[1], 13) ^
53 rotate_left (ip->dst_address.as_u64[0], 26) ^
54 rotate_left (ip->dst_address.as_u64[1], 39) ^ ip->protocol;
59 #define MPLS_BOTTOM_OF_STACK_BIT_MASK 0x00000100U
60 #define MPLS_LABEL_MASK 0xFFFFF000U
63 mpls_get_key (mpls_unicast_header_t * m)
69 /* find the bottom of the MPLS label stack. */
70 if (PREDICT_TRUE (m->label_exp_s_ttl &
71 clib_net_to_host_u32 (MPLS_BOTTOM_OF_STACK_BIT_MASK)))
73 goto bottom_lbl_found;
77 if (PREDICT_TRUE (m->label_exp_s_ttl &
78 clib_net_to_host_u32 (MPLS_BOTTOM_OF_STACK_BIT_MASK)))
80 goto bottom_lbl_found;
84 if (m->label_exp_s_ttl &
85 clib_net_to_host_u32 (MPLS_BOTTOM_OF_STACK_BIT_MASK))
87 goto bottom_lbl_found;
91 if (m->label_exp_s_ttl &
92 clib_net_to_host_u32 (MPLS_BOTTOM_OF_STACK_BIT_MASK))
94 goto bottom_lbl_found;
98 if (m->label_exp_s_ttl &
99 clib_net_to_host_u32 (MPLS_BOTTOM_OF_STACK_BIT_MASK))
101 goto bottom_lbl_found;
104 /* the bottom label was not found - use the last label */
105 hash_key = m->label_exp_s_ttl & clib_net_to_host_u32 (MPLS_LABEL_MASK);
111 ip_ver = (*((u8 *) m) >> 4);
113 /* find out if it is IPV4 or IPV6 header */
114 if (PREDICT_TRUE (ip_ver == 4))
116 hash_key = ipv4_get_key ((ip4_header_t *) m);
118 else if (PREDICT_TRUE (ip_ver == 6))
120 hash_key = ipv6_get_key ((ip6_header_t *) m);
124 /* use the bottom label */
126 (m - 1)->label_exp_s_ttl & clib_net_to_host_u32 (MPLS_LABEL_MASK);
134 eth_get_sym_key (ethernet_header_t * h0)
138 if (PREDICT_TRUE (h0->type) == clib_host_to_net_u16 (ETHERNET_TYPE_IP4))
140 ip4_header_t *ip = (ip4_header_t *) (h0 + 1);
142 (u64) (ip->src_address.as_u32 ^
143 ip->dst_address.as_u32 ^ ip->protocol);
145 else if (h0->type == clib_host_to_net_u16 (ETHERNET_TYPE_IP6))
147 ip6_header_t *ip = (ip6_header_t *) (h0 + 1);
148 hash_key = (u64) (ip->src_address.as_u64[0] ^
149 ip->src_address.as_u64[1] ^
150 ip->dst_address.as_u64[0] ^
151 ip->dst_address.as_u64[1] ^ ip->protocol);
153 else if (h0->type == clib_host_to_net_u16 (ETHERNET_TYPE_MPLS))
155 hash_key = mpls_get_key ((mpls_unicast_header_t *) (h0 + 1));
159 ((h0->type == clib_host_to_net_u16 (ETHERNET_TYPE_VLAN))
160 || (h0->type == clib_host_to_net_u16 (ETHERNET_TYPE_DOT1AD))))
162 ethernet_vlan_header_t *outer = (ethernet_vlan_header_t *) (h0 + 1);
164 outer = (outer->type == clib_host_to_net_u16 (ETHERNET_TYPE_VLAN)) ?
166 if (PREDICT_TRUE (outer->type) ==
167 clib_host_to_net_u16 (ETHERNET_TYPE_IP4))
169 ip4_header_t *ip = (ip4_header_t *) (outer + 1);
171 (u64) (ip->src_address.as_u32 ^
172 ip->dst_address.as_u32 ^ ip->protocol);
174 else if (outer->type == clib_host_to_net_u16 (ETHERNET_TYPE_IP6))
176 ip6_header_t *ip = (ip6_header_t *) (outer + 1);
178 (u64) (ip->src_address.as_u64[0] ^ ip->src_address.as_u64[1] ^
179 ip->dst_address.as_u64[0] ^
180 ip->dst_address.as_u64[1] ^ ip->protocol);
182 else if (outer->type == clib_host_to_net_u16 (ETHERNET_TYPE_MPLS))
184 hash_key = mpls_get_key ((mpls_unicast_header_t *) (outer + 1));
188 hash_key = outer->type;
200 eth_get_key (ethernet_header_t * h0)
204 if (PREDICT_TRUE (h0->type) == clib_host_to_net_u16 (ETHERNET_TYPE_IP4))
206 hash_key = ipv4_get_key ((ip4_header_t *) (h0 + 1));
208 else if (h0->type == clib_host_to_net_u16 (ETHERNET_TYPE_IP6))
210 hash_key = ipv6_get_key ((ip6_header_t *) (h0 + 1));
212 else if (h0->type == clib_host_to_net_u16 (ETHERNET_TYPE_MPLS))
214 hash_key = mpls_get_key ((mpls_unicast_header_t *) (h0 + 1));
216 else if ((h0->type == clib_host_to_net_u16 (ETHERNET_TYPE_VLAN)) ||
217 (h0->type == clib_host_to_net_u16 (ETHERNET_TYPE_DOT1AD)))
219 ethernet_vlan_header_t *outer = (ethernet_vlan_header_t *) (h0 + 1);
221 outer = (outer->type == clib_host_to_net_u16 (ETHERNET_TYPE_VLAN)) ?
223 if (PREDICT_TRUE (outer->type) ==
224 clib_host_to_net_u16 (ETHERNET_TYPE_IP4))
226 hash_key = ipv4_get_key ((ip4_header_t *) (outer + 1));
228 else if (outer->type == clib_host_to_net_u16 (ETHERNET_TYPE_IP6))
230 hash_key = ipv6_get_key ((ip6_header_t *) (outer + 1));
232 else if (outer->type == clib_host_to_net_u16 (ETHERNET_TYPE_MPLS))
234 hash_key = mpls_get_key ((mpls_unicast_header_t *) (outer + 1));
238 hash_key = outer->type;
249 #endif /* included_vnet_handoff_h */
252 * fd.io coding-style-patch-verification: ON
255 * eval: (c-set-style "gnu")