blob: 106d17da3cb428f1910a6a1ef51188433ad392ed [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
2 * Copyright (c) 2015 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 * ip/ip4_input.c: IP v4 input node
17 *
18 * Copyright (c) 2008 Eliot Dresselhaus
19 *
20 * Permission is hereby granted, free of charge, to any person obtaining
21 * a copy of this software and associated documentation files (the
22 * "Software"), to deal in the Software without restriction, including
23 * without limitation the rights to use, copy, modify, merge, publish,
24 * distribute, sublicense, and/or sell copies of the Software, and to
25 * permit persons to whom the Software is furnished to do so, subject to
26 * the following conditions:
27 *
28 * The above copyright notice and this permission notice shall be
29 * included in all copies or substantial portions of the Software.
30 *
31 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 */
39
Neale Ranns4c7c8e52017-10-21 09:37:55 -070040#include <vnet/ip/ip4_input.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070041#include <vnet/ethernet/ethernet.h>
Neale Ranns68d48d92021-06-03 14:59:47 +000042#include <vnet/pg/pg.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070043#include <vnet/ppp/ppp.h>
44#include <vnet/hdlc/hdlc.h>
Neale Rannsc8352bc2018-08-29 10:23:58 -070045#include <vnet/util/throttle.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070046
Dave Barachd7cb1b52016-12-09 09:52:16 -050047typedef struct
48{
Ed Warnickecb9cada2015-12-08 15:45:58 -070049 u8 packet_data[64];
50} ip4_input_trace_t;
51
Dave Barachd7cb1b52016-12-09 09:52:16 -050052static u8 *
53format_ip4_input_trace (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -070054{
55 CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
56 CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
Dave Barachd7cb1b52016-12-09 09:52:16 -050057 ip4_input_trace_t *t = va_arg (*va, ip4_input_trace_t *);
Ed Warnickecb9cada2015-12-08 15:45:58 -070058
59 s = format (s, "%U",
Dave Barachd7cb1b52016-12-09 09:52:16 -050060 format_ip4_header, t->packet_data, sizeof (t->packet_data));
Ed Warnickecb9cada2015-12-08 15:45:58 -070061
62 return s;
63}
Damjan Marion3ade6b62018-05-26 18:53:34 +020064
65static_always_inline u32
66ip4_input_set_next (u32 sw_if_index, vlib_buffer_t * b, int arc_enabled)
67{
68 ip4_main_t *im = &ip4_main;
69 ip_lookup_main_t *lm = &im->lookup_main;
70 u32 next;
71 u8 arc;
72
73 ip4_header_t *ip = vlib_buffer_get_current (b);
74
75 if (PREDICT_FALSE (ip4_address_is_multicast (&ip->dst_address)))
76 {
77 next = IP4_INPUT_NEXT_LOOKUP_MULTICAST;
78 arc = lm->mcast_feature_arc_index;
79 }
80 else
81 {
82 next = IP4_INPUT_NEXT_LOOKUP;
83 arc = lm->ucast_feature_arc_index;
84 }
85
86 if (arc_enabled)
87 vnet_feature_arc_start (arc, sw_if_index, &next, b);
88
89 return next;
90}
91
92static_always_inline void
Damjan Marion067cd622018-07-11 12:47:43 +020093ip4_input_check_sw_if_index (vlib_main_t * vm,
94 vlib_simple_counter_main_t * cm, u32 sw_if_index,
Damjan Marion3ade6b62018-05-26 18:53:34 +020095 u32 * last_sw_if_index, u32 * cnt,
96 int *arc_enabled)
97{
98 ip4_main_t *im = &ip4_main;
99 ip_lookup_main_t *lm = &im->lookup_main;
100 u32 thread_index;
101 if (*last_sw_if_index == sw_if_index)
102 {
103 (*cnt)++;
104 return;
105 }
106
Damjan Marion067cd622018-07-11 12:47:43 +0200107 thread_index = vm->thread_index;
Damjan Marion3ade6b62018-05-26 18:53:34 +0200108 if (*cnt)
109 vlib_increment_simple_counter (cm, thread_index, *last_sw_if_index, *cnt);
110 *cnt = 1;
111 *last_sw_if_index = sw_if_index;
112
113 if (vnet_have_features (lm->ucast_feature_arc_index, sw_if_index) ||
114 vnet_have_features (lm->mcast_feature_arc_index, sw_if_index))
115 *arc_enabled = 1;
116 else
117 *arc_enabled = 0;
118}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700119
Ed Warnickecb9cada2015-12-08 15:45:58 -0700120/* Validate IP v4 packets and pass them either to forwarding code
121 or drop/punt exception packets. */
122always_inline uword
123ip4_input_inline (vlib_main_t * vm,
124 vlib_node_runtime_t * node,
Dave Barachd7cb1b52016-12-09 09:52:16 -0500125 vlib_frame_t * frame, int verify_checksum)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700126{
Dave Barachd7cb1b52016-12-09 09:52:16 -0500127 vnet_main_t *vnm = vnet_get_main ();
Damjan Marion3ade6b62018-05-26 18:53:34 +0200128 u32 n_left_from, *from;
Damjan Marion067cd622018-07-11 12:47:43 +0200129 u32 thread_index = vm->thread_index;
Dave Barachd7cb1b52016-12-09 09:52:16 -0500130 vlib_node_runtime_t *error_node =
131 vlib_node_get_runtime (vm, ip4_input_node.index);
132 vlib_simple_counter_main_t *cm;
Damjan Marion3ade6b62018-05-26 18:53:34 +0200133 vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
134 ip4_header_t *ip[4];
135 u16 nexts[VLIB_FRAME_SIZE], *next;
136 u32 sw_if_index[4];
137 u32 last_sw_if_index = ~0;
138 u32 cnt = 0;
139 int arc_enabled = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700140
141 from = vlib_frame_vector_args (frame);
142 n_left_from = frame->n_vectors;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700143
144 if (node->flags & VLIB_NODE_FLAG_TRACE)
145 vlib_trace_frame_buffers_only (vm, node, from, frame->n_vectors,
146 /* stride */ 1,
147 sizeof (ip4_input_trace_t));
148
149 cm = vec_elt_at_index (vnm->interface_main.sw_if_counters,
Dave Barachd7cb1b52016-12-09 09:52:16 -0500150 VNET_INTERFACE_COUNTER_IP4);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700151
Damjan Marion3ade6b62018-05-26 18:53:34 +0200152 vlib_get_buffers (vm, from, bufs, n_left_from);
153 b = bufs;
154 next = nexts;
Lijian.Zhang86b18712019-07-08 10:33:34 +0800155#if (CLIB_N_PREFETCHES >= 8)
Damjan Marion3ade6b62018-05-26 18:53:34 +0200156 while (n_left_from >= 4)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700157 {
Damjan Marion3ade6b62018-05-26 18:53:34 +0200158 u32 x = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700159
Damjan Marion3ade6b62018-05-26 18:53:34 +0200160 /* Prefetch next iteration. */
161 if (n_left_from >= 12)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700162 {
Damjan Marion3ade6b62018-05-26 18:53:34 +0200163 vlib_prefetch_buffer_header (b[8], LOAD);
164 vlib_prefetch_buffer_header (b[9], LOAD);
165 vlib_prefetch_buffer_header (b[10], LOAD);
166 vlib_prefetch_buffer_header (b[11], LOAD);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700167
Damjan Mariond30bf012018-11-18 23:48:43 +0100168 vlib_prefetch_buffer_data (b[4], LOAD);
169 vlib_prefetch_buffer_data (b[5], LOAD);
170 vlib_prefetch_buffer_data (b[6], LOAD);
171 vlib_prefetch_buffer_data (b[7], LOAD);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700172 }
173
Damjan Marion3ade6b62018-05-26 18:53:34 +0200174 vnet_buffer (b[0])->ip.adj_index[VLIB_RX] = ~0;
175 vnet_buffer (b[1])->ip.adj_index[VLIB_RX] = ~0;
176 vnet_buffer (b[2])->ip.adj_index[VLIB_RX] = ~0;
177 vnet_buffer (b[3])->ip.adj_index[VLIB_RX] = ~0;
178
179 sw_if_index[0] = vnet_buffer (b[0])->sw_if_index[VLIB_RX];
180 sw_if_index[1] = vnet_buffer (b[1])->sw_if_index[VLIB_RX];
181 sw_if_index[2] = vnet_buffer (b[2])->sw_if_index[VLIB_RX];
182 sw_if_index[3] = vnet_buffer (b[3])->sw_if_index[VLIB_RX];
183
184 x |= sw_if_index[0] ^ last_sw_if_index;
185 x |= sw_if_index[1] ^ last_sw_if_index;
186 x |= sw_if_index[2] ^ last_sw_if_index;
187 x |= sw_if_index[3] ^ last_sw_if_index;
188
189 if (PREDICT_TRUE (x == 0))
190 {
191 /* we deal with 4 more packets sharing the same sw_if_index
192 with the previous one, so we can optimize */
193 cnt += 4;
194 if (arc_enabled)
195 {
196 next[0] = ip4_input_set_next (sw_if_index[0], b[0], 1);
197 next[1] = ip4_input_set_next (sw_if_index[1], b[1], 1);
198 next[2] = ip4_input_set_next (sw_if_index[2], b[2], 1);
199 next[3] = ip4_input_set_next (sw_if_index[3], b[3], 1);
200 }
201 else
202 {
203 next[0] = ip4_input_set_next (sw_if_index[0], b[0], 0);
204 next[1] = ip4_input_set_next (sw_if_index[1], b[1], 0);
205 next[2] = ip4_input_set_next (sw_if_index[2], b[2], 0);
206 next[3] = ip4_input_set_next (sw_if_index[3], b[3], 0);
207 }
208 }
209 else
210 {
Damjan Marion067cd622018-07-11 12:47:43 +0200211 ip4_input_check_sw_if_index (vm, cm, sw_if_index[0],
212 &last_sw_if_index, &cnt, &arc_enabled);
213 ip4_input_check_sw_if_index (vm, cm, sw_if_index[1],
214 &last_sw_if_index, &cnt, &arc_enabled);
215 ip4_input_check_sw_if_index (vm, cm, sw_if_index[2],
216 &last_sw_if_index, &cnt, &arc_enabled);
217 ip4_input_check_sw_if_index (vm, cm, sw_if_index[3],
218 &last_sw_if_index, &cnt, &arc_enabled);
Damjan Marion3ade6b62018-05-26 18:53:34 +0200219
220 next[0] = ip4_input_set_next (sw_if_index[0], b[0], 1);
221 next[1] = ip4_input_set_next (sw_if_index[1], b[1], 1);
222 next[2] = ip4_input_set_next (sw_if_index[2], b[2], 1);
223 next[3] = ip4_input_set_next (sw_if_index[3], b[3], 1);
224 }
225
226 ip[0] = vlib_buffer_get_current (b[0]);
227 ip[1] = vlib_buffer_get_current (b[1]);
228 ip[2] = vlib_buffer_get_current (b[2]);
229 ip[3] = vlib_buffer_get_current (b[3]);
230
231 ip4_input_check_x4 (vm, error_node, b, ip, next, verify_checksum);
232
233 /* next */
234 b += 4;
235 next += 4;
236 n_left_from -= 4;
237 }
Lijian.Zhang86b18712019-07-08 10:33:34 +0800238#elif (CLIB_N_PREFETCHES >= 4)
239 while (n_left_from >= 2)
240 {
241 u32 x = 0;
242 u32 next0, next1;
243
244 /* Prefetch next iteration. */
245 if (n_left_from >= 6)
246 {
247 vlib_prefetch_buffer_header (b[4], LOAD);
248 vlib_prefetch_buffer_header (b[5], LOAD);
249
250 vlib_prefetch_buffer_data (b[2], LOAD);
251 vlib_prefetch_buffer_data (b[3], LOAD);
252 }
253
254 vnet_buffer (b[0])->ip.adj_index[VLIB_RX] = ~0;
255 vnet_buffer (b[1])->ip.adj_index[VLIB_RX] = ~0;
256
257 sw_if_index[0] = vnet_buffer (b[0])->sw_if_index[VLIB_RX];
258 sw_if_index[1] = vnet_buffer (b[1])->sw_if_index[VLIB_RX];
259
260 x |= sw_if_index[0] ^ last_sw_if_index;
261 x |= sw_if_index[1] ^ last_sw_if_index;
262
263 if (PREDICT_TRUE (x == 0))
264 {
265 /* we deal with 2 more packets sharing the same sw_if_index
266 with the previous one, so we can optimize */
267 cnt += 2;
268 if (arc_enabled)
269 {
270 next0 = ip4_input_set_next (sw_if_index[0], b[0], 1);
271 next1 = ip4_input_set_next (sw_if_index[1], b[1], 1);
272 }
273 else
274 {
275 next0 = ip4_input_set_next (sw_if_index[0], b[0], 0);
276 next1 = ip4_input_set_next (sw_if_index[1], b[1], 0);
277 }
278 }
279 else
280 {
281 ip4_input_check_sw_if_index (vm, cm, sw_if_index[0],
282 &last_sw_if_index, &cnt, &arc_enabled);
283 ip4_input_check_sw_if_index (vm, cm, sw_if_index[1],
284 &last_sw_if_index, &cnt, &arc_enabled);
285
286 next0 = ip4_input_set_next (sw_if_index[0], b[0], 1);
287 next1 = ip4_input_set_next (sw_if_index[1], b[1], 1);
288 }
289
290 ip[0] = vlib_buffer_get_current (b[0]);
291 ip[1] = vlib_buffer_get_current (b[1]);
292
293 ip4_input_check_x2 (vm, error_node, b[0], b[1], ip[0], ip[1],
294 &next0, &next1, verify_checksum);
295 next[0] = (u16) next0;
296 next[1] = (u16) next1;
297
298 /* next */
299 b += 2;
300 next += 2;
301 n_left_from -= 2;
302 }
303#endif
304
Damjan Marion3ade6b62018-05-26 18:53:34 +0200305 while (n_left_from)
306 {
307 u32 next0;
308 vnet_buffer (b[0])->ip.adj_index[VLIB_RX] = ~0;
309 sw_if_index[0] = vnet_buffer (b[0])->sw_if_index[VLIB_RX];
Damjan Marion067cd622018-07-11 12:47:43 +0200310 ip4_input_check_sw_if_index (vm, cm, sw_if_index[0], &last_sw_if_index,
Damjan Marion3ade6b62018-05-26 18:53:34 +0200311 &cnt, &arc_enabled);
312 next0 = ip4_input_set_next (sw_if_index[0], b[0], arc_enabled);
313 ip[0] = vlib_buffer_get_current (b[0]);
314 ip4_input_check_x1 (vm, error_node, b[0], ip[0], &next0,
315 verify_checksum);
316 next[0] = next0;
317
318 /* next */
319 b += 1;
320 next += 1;
321 n_left_from -= 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700322 }
323
Damjan Marion3ade6b62018-05-26 18:53:34 +0200324 vlib_increment_simple_counter (cm, thread_index, last_sw_if_index, cnt);
325 vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700326 return frame->n_vectors;
327}
328
Dave Barach132d51d2016-07-07 10:10:17 -0400329/** \brief IPv4 input node.
330 @node ip4-input
331
332 This is the IPv4 input node: validates ip4 header checksums,
333 verifies ip header lengths, discards pkts with expired TTLs,
334 and sends pkts to the set of ip feature nodes configured on
335 the rx interface.
336
337 @param vm vlib_main_t corresponding to the current thread
338 @param node vlib_node_runtime_t
339 @param frame vlib_frame_t whose contents should be dispatched
340
341 @par Graph mechanics: buffer metadata, next index usage
342
343 @em Uses:
Dave Barachd7cb1b52016-12-09 09:52:16 -0500344 - vnet_feature_config_main_t cm corresponding to each pkt's dst address unicast /
Dave Barach132d51d2016-07-07 10:10:17 -0400345 multicast status.
346 - <code>b->current_config_index</code> corresponding to each pkt's
Dave Barachd7cb1b52016-12-09 09:52:16 -0500347 rx sw_if_index.
Dave Barach132d51d2016-07-07 10:10:17 -0400348 - This sets the per-packet graph trajectory, ensuring that
349 each packet visits the per-interface features in order.
350
351 - <code>vnet_buffer(b)->sw_if_index[VLIB_RX]</code>
352 - Indicates the @c sw_if_index value of the interface that the
353 packet was received on.
354
355 @em Sets:
356 - <code>vnet_buffer(b)->ip.adj_index[VLIB_TX]</code>
357 - The lookup result adjacency index.
358
359 <em>Next Indices:</em>
360 - Dispatches pkts to the (first) feature node:
361 <code> vnet_get_config_data (... &next0 ...); </code>
Dave Barachd7cb1b52016-12-09 09:52:16 -0500362 or @c error-drop
Dave Barach132d51d2016-07-07 10:10:17 -0400363*/
Damjan Marion812b32d2018-05-28 21:26:47 +0200364VLIB_NODE_FN (ip4_input_node) (vlib_main_t * vm, vlib_node_runtime_t * node,
Damjan Marion3ade6b62018-05-26 18:53:34 +0200365 vlib_frame_t * frame)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700366{
367 return ip4_input_inline (vm, node, frame, /* verify_checksum */ 1);
368}
369
Damjan Marion812b32d2018-05-28 21:26:47 +0200370VLIB_NODE_FN (ip4_input_no_checksum_node) (vlib_main_t * vm,
Damjan Marion3ade6b62018-05-26 18:53:34 +0200371 vlib_node_runtime_t * node,
372 vlib_frame_t * frame)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700373{
374 return ip4_input_inline (vm, node, frame, /* verify_checksum */ 0);
375}
376
Ed Warnickecb9cada2015-12-08 15:45:58 -0700377VLIB_REGISTER_NODE (ip4_input_node) = {
Ed Warnickecb9cada2015-12-08 15:45:58 -0700378 .name = "ip4-input",
379 .vector_size = sizeof (u32),
Dave Barach7fff3d22018-11-27 16:52:59 -0500380 .protocol_hint = VLIB_NODE_PROTO_HINT_IP4,
Ed Warnickecb9cada2015-12-08 15:45:58 -0700381
382 .n_errors = IP4_N_ERROR,
Neale Rannse22a7042022-08-09 03:03:29 +0000383 .error_counters = ip4_error_counters,
Ed Warnickecb9cada2015-12-08 15:45:58 -0700384
385 .n_next_nodes = IP4_INPUT_N_NEXT,
386 .next_nodes = {
387 [IP4_INPUT_NEXT_DROP] = "error-drop",
388 [IP4_INPUT_NEXT_PUNT] = "error-punt",
Neale Rannsc667ffd2018-06-27 18:59:03 -0700389 [IP4_INPUT_NEXT_OPTIONS] = "ip4-options",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700390 [IP4_INPUT_NEXT_LOOKUP] = "ip4-lookup",
Neale Ranns32e1c012016-11-22 17:07:28 +0000391 [IP4_INPUT_NEXT_LOOKUP_MULTICAST] = "ip4-mfib-forward-lookup",
Ole Troan92eade12016-01-13 20:17:08 +0100392 [IP4_INPUT_NEXT_ICMP_ERROR] = "ip4-icmp-error",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700393 },
394
395 .format_buffer = format_ip4_header,
396 .format_trace = format_ip4_input_trace,
397};
398
Damjan Marion812b32d2018-05-28 21:26:47 +0200399VLIB_REGISTER_NODE (ip4_input_no_checksum_node) = {
Ed Warnickecb9cada2015-12-08 15:45:58 -0700400 .name = "ip4-input-no-checksum",
401 .vector_size = sizeof (u32),
402
Neale Ranns8a03e4f2018-07-17 07:15:05 -0700403 .sibling_of = "ip4-input",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700404 .format_buffer = format_ip4_header,
405 .format_trace = format_ip4_input_trace,
406};
407
Dave Barachd7cb1b52016-12-09 09:52:16 -0500408static clib_error_t *
409ip4_init (vlib_main_t * vm)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700410{
Dave Barachd7cb1b52016-12-09 09:52:16 -0500411 clib_error_t *error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700412
Dave Barachd7cb1b52016-12-09 09:52:16 -0500413 ethernet_register_input_type (vm, ETHERNET_TYPE_IP4, ip4_input_node.index);
414 ppp_register_input_protocol (vm, PPP_PROTOCOL_ip4, ip4_input_node.index);
415 hdlc_register_input_protocol (vm, HDLC_PROTOCOL_ip4, ip4_input_node.index);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700416
417 {
Damjan Marion6e363512018-08-10 22:39:11 +0200418 extern vlib_node_registration_t ip4_input_no_checksum_node;
Dave Barachd7cb1b52016-12-09 09:52:16 -0500419 pg_node_t *pn;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700420 pn = pg_get_node (ip4_input_node.index);
421 pn->unformat_edit = unformat_pg_ip4_header;
422 pn = pg_get_node (ip4_input_no_checksum_node.index);
423 pn->unformat_edit = unformat_pg_ip4_header;
424 }
425
426 if ((error = vlib_call_init_function (vm, ip4_cli_init)))
427 return error;
428
Dave Barachd7cb1b52016-12-09 09:52:16 -0500429 if ((error = vlib_call_init_function
Dave Barach6f9bca22016-04-30 10:25:32 -0400430 (vm, ip4_source_and_port_range_check_init)))
431 return error;
432
Ed Warnickecb9cada2015-12-08 15:45:58 -0700433 /* Set flow hash to something non-zero. */
434 ip4_main.flow_hash_seed = 0xdeadbeef;
435
436 /* Default TTL for packets we generate. */
437 ip4_main.host_config.ttl = 64;
438
439 return error;
440}
441
442VLIB_INIT_FUNCTION (ip4_init);
Dave Barach49433ad2018-08-08 17:59:03 -0400443
Dave Barachd7cb1b52016-12-09 09:52:16 -0500444/*
445 * fd.io coding-style-patch-verification: ON
446 *
447 * Local Variables:
448 * eval: (c-set-style "gnu")
449 * End:
450 */