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