FD.io VPP  v17.07-30-g839fa73
Vector Packet Processing
handoff.h
Go to the documentation of this file.
1 /*
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:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
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.
14  */
15 
16 #ifndef included_vnet_handoff_h
17 #define included_vnet_handoff_h
18 
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>
24 
25 typedef enum
26 {
34 
35 
36 static inline u64
38 {
39  u64 hash_key;
40 
41  hash_key = *((u64 *) (&ip->address_pair)) ^ ip->protocol;
42 
43  return hash_key;
44 }
45 
46 static inline u64
48 {
49  u64 hash_key;
50 
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;
55 
56  return hash_key;
57 }
58 
59 #define MPLS_BOTTOM_OF_STACK_BIT_MASK 0x00000100U
60 #define MPLS_LABEL_MASK 0xFFFFF000U
61 
62 static inline u64
64 {
65  u64 hash_key;
66  u8 ip_ver;
67 
68 
69  /* find the bottom of the MPLS label stack. */
71  clib_net_to_host_u32 (MPLS_BOTTOM_OF_STACK_BIT_MASK)))
72  {
73  goto bottom_lbl_found;
74  }
75  m++;
76 
78  clib_net_to_host_u32 (MPLS_BOTTOM_OF_STACK_BIT_MASK)))
79  {
80  goto bottom_lbl_found;
81  }
82  m++;
83 
84  if (m->label_exp_s_ttl &
85  clib_net_to_host_u32 (MPLS_BOTTOM_OF_STACK_BIT_MASK))
86  {
87  goto bottom_lbl_found;
88  }
89  m++;
90 
91  if (m->label_exp_s_ttl &
92  clib_net_to_host_u32 (MPLS_BOTTOM_OF_STACK_BIT_MASK))
93  {
94  goto bottom_lbl_found;
95  }
96  m++;
97 
98  if (m->label_exp_s_ttl &
99  clib_net_to_host_u32 (MPLS_BOTTOM_OF_STACK_BIT_MASK))
100  {
101  goto bottom_lbl_found;
102  }
103 
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);
106 
107  return hash_key;
108 
109 bottom_lbl_found:
110  m++;
111  ip_ver = (*((u8 *) m) >> 4);
112 
113  /* find out if it is IPV4 or IPV6 header */
114  if (PREDICT_TRUE (ip_ver == 4))
115  {
116  hash_key = ipv4_get_key ((ip4_header_t *) m);
117  }
118  else if (PREDICT_TRUE (ip_ver == 6))
119  {
120  hash_key = ipv6_get_key ((ip6_header_t *) m);
121  }
122  else
123  {
124  /* use the bottom label */
125  hash_key =
126  (m - 1)->label_exp_s_ttl & clib_net_to_host_u32 (MPLS_LABEL_MASK);
127  }
128 
129  return hash_key;
130 
131 }
132 
133 static inline u64
135 {
136  u64 hash_key;
137 
138  if (PREDICT_TRUE (h0->type) == clib_host_to_net_u16 (ETHERNET_TYPE_IP4))
139  {
140  ip4_header_t *ip = (ip4_header_t *) (h0 + 1);
141  hash_key =
142  (u64) (ip->src_address.as_u32 ^
143  ip->dst_address.as_u32 ^ ip->protocol);
144  }
145  else if (h0->type == clib_host_to_net_u16 (ETHERNET_TYPE_IP6))
146  {
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);
152  }
153  else if (h0->type == clib_host_to_net_u16 (ETHERNET_TYPE_MPLS))
154  {
155  hash_key = mpls_get_key ((mpls_unicast_header_t *) (h0 + 1));
156  }
157  else
158  if (PREDICT_FALSE
159  ((h0->type == clib_host_to_net_u16 (ETHERNET_TYPE_VLAN))
160  || (h0->type == clib_host_to_net_u16 (ETHERNET_TYPE_DOT1AD))))
161  {
162  ethernet_vlan_header_t *outer = (ethernet_vlan_header_t *) (h0 + 1);
163 
164  outer = (outer->type == clib_host_to_net_u16 (ETHERNET_TYPE_VLAN)) ?
165  outer + 1 : outer;
166  if (PREDICT_TRUE (outer->type) ==
167  clib_host_to_net_u16 (ETHERNET_TYPE_IP4))
168  {
169  ip4_header_t *ip = (ip4_header_t *) (outer + 1);
170  hash_key =
171  (u64) (ip->src_address.as_u32 ^
172  ip->dst_address.as_u32 ^ ip->protocol);
173  }
174  else if (outer->type == clib_host_to_net_u16 (ETHERNET_TYPE_IP6))
175  {
176  ip6_header_t *ip = (ip6_header_t *) (outer + 1);
177  hash_key =
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);
181  }
182  else if (outer->type == clib_host_to_net_u16 (ETHERNET_TYPE_MPLS))
183  {
184  hash_key = mpls_get_key ((mpls_unicast_header_t *) (outer + 1));
185  }
186  else
187  {
188  hash_key = outer->type;
189  }
190  }
191  else
192  {
193  hash_key = 0;
194  }
195 
196  return hash_key;
197 }
198 
199 static inline u64
201 {
202  u64 hash_key;
203 
204  if (PREDICT_TRUE (h0->type) == clib_host_to_net_u16 (ETHERNET_TYPE_IP4))
205  {
206  hash_key = ipv4_get_key ((ip4_header_t *) (h0 + 1));
207  }
208  else if (h0->type == clib_host_to_net_u16 (ETHERNET_TYPE_IP6))
209  {
210  hash_key = ipv6_get_key ((ip6_header_t *) (h0 + 1));
211  }
212  else if (h0->type == clib_host_to_net_u16 (ETHERNET_TYPE_MPLS))
213  {
214  hash_key = mpls_get_key ((mpls_unicast_header_t *) (h0 + 1));
215  }
216  else if ((h0->type == clib_host_to_net_u16 (ETHERNET_TYPE_VLAN)) ||
217  (h0->type == clib_host_to_net_u16 (ETHERNET_TYPE_DOT1AD)))
218  {
219  ethernet_vlan_header_t *outer = (ethernet_vlan_header_t *) (h0 + 1);
220 
221  outer = (outer->type == clib_host_to_net_u16 (ETHERNET_TYPE_VLAN)) ?
222  outer + 1 : outer;
223  if (PREDICT_TRUE (outer->type) ==
224  clib_host_to_net_u16 (ETHERNET_TYPE_IP4))
225  {
226  hash_key = ipv4_get_key ((ip4_header_t *) (outer + 1));
227  }
228  else if (outer->type == clib_host_to_net_u16 (ETHERNET_TYPE_IP6))
229  {
230  hash_key = ipv6_get_key ((ip6_header_t *) (outer + 1));
231  }
232  else if (outer->type == clib_host_to_net_u16 (ETHERNET_TYPE_MPLS))
233  {
234  hash_key = mpls_get_key ((mpls_unicast_header_t *) (outer + 1));
235  }
236  else
237  {
238  hash_key = outer->type;
239  }
240  }
241  else
242  {
243  hash_key = 0;
244  }
245 
246  return hash_key;
247 }
248 
249 #endif /* included_vnet_handoff_h */
250 
251 /*
252  * fd.io coding-style-patch-verification: ON
253  *
254  * Local Variables:
255  * eval: (c-set-style "gnu")
256  * End:
257  */
ip4_address_t src_address
Definition: ip4_packet.h:164
#define PREDICT_TRUE(x)
Definition: clib.h:98
u64 as_u64[2]
Definition: ip6_packet.h:51
ip6_address_t src_address
Definition: ip6_packet.h:341
ip4_address_t dst_address
Definition: ip4_packet.h:164
#define MPLS_LABEL_MASK
Definition: handoff.h:60
unsigned long u64
Definition: types.h:89
#define MPLS_BOTTOM_OF_STACK_BIT_MASK
Definition: handoff.h:59
ip4_address_pair_t address_pair
Definition: ip4_packet.h:166
#define PREDICT_FALSE(x)
Definition: clib.h:97
static u64 ipv4_get_key(ip4_header_t *ip)
Definition: handoff.h:37
static u64 eth_get_sym_key(ethernet_header_t *h0)
Definition: handoff.h:134
mpls_label_t label_exp_s_ttl
Definition: packet.h:31
unsigned char u8
Definition: types.h:56
handoff_dispatch_next_t
Definition: handoff.h:25
static u64 ipv6_get_key(ip6_header_t *ip)
Definition: handoff.h:47
static u64 eth_get_key(ethernet_header_t *h0)
Definition: handoff.h:200
static u64 mpls_get_key(mpls_unicast_header_t *m)
Definition: handoff.h:63
static uword rotate_left(uword x, uword i)
Definition: bitops.h:134
ip6_address_t dst_address
Definition: ip6_packet.h:341