blob: 69b1e5a83d2a53cc780dedca7d8becc1796edc44 [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
40#include <vnet/ip/ip.h>
41#include <vnet/ethernet/ethernet.h>
42#include <vnet/ppp/ppp.h>
43#include <vnet/hdlc/hdlc.h>
44
Dave Barachd7cb1b52016-12-09 09:52:16 -050045typedef struct
46{
Ed Warnickecb9cada2015-12-08 15:45:58 -070047 u8 packet_data[64];
48} ip4_input_trace_t;
49
Dave Barachd7cb1b52016-12-09 09:52:16 -050050static u8 *
51format_ip4_input_trace (u8 * s, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -070052{
53 CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
54 CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
Dave Barachd7cb1b52016-12-09 09:52:16 -050055 ip4_input_trace_t *t = va_arg (*va, ip4_input_trace_t *);
Ed Warnickecb9cada2015-12-08 15:45:58 -070056
57 s = format (s, "%U",
Dave Barachd7cb1b52016-12-09 09:52:16 -050058 format_ip4_header, t->packet_data, sizeof (t->packet_data));
Ed Warnickecb9cada2015-12-08 15:45:58 -070059
60 return s;
61}
62
Dave Barachd7cb1b52016-12-09 09:52:16 -050063typedef enum
64{
Ed Warnickecb9cada2015-12-08 15:45:58 -070065 IP4_INPUT_NEXT_DROP,
66 IP4_INPUT_NEXT_PUNT,
67 IP4_INPUT_NEXT_LOOKUP,
68 IP4_INPUT_NEXT_LOOKUP_MULTICAST,
Ole Troan92eade12016-01-13 20:17:08 +010069 IP4_INPUT_NEXT_ICMP_ERROR,
Ed Warnickecb9cada2015-12-08 15:45:58 -070070 IP4_INPUT_N_NEXT,
71} ip4_input_next_t;
72
73/* Validate IP v4 packets and pass them either to forwarding code
74 or drop/punt exception packets. */
75always_inline uword
76ip4_input_inline (vlib_main_t * vm,
77 vlib_node_runtime_t * node,
Dave Barachd7cb1b52016-12-09 09:52:16 -050078 vlib_frame_t * frame, int verify_checksum)
Ed Warnickecb9cada2015-12-08 15:45:58 -070079{
Dave Barachd7cb1b52016-12-09 09:52:16 -050080 ip4_main_t *im = &ip4_main;
81 vnet_main_t *vnm = vnet_get_main ();
82 ip_lookup_main_t *lm = &im->lookup_main;
83 u32 n_left_from, *from, *to_next;
Ed Warnickecb9cada2015-12-08 15:45:58 -070084 ip4_input_next_t next_index;
Dave Barachd7cb1b52016-12-09 09:52:16 -050085 vlib_node_runtime_t *error_node =
86 vlib_node_get_runtime (vm, ip4_input_node.index);
87 vlib_simple_counter_main_t *cm;
88 u32 cpu_index = os_get_cpu_number ();
Ed Warnickecb9cada2015-12-08 15:45:58 -070089
90 from = vlib_frame_vector_args (frame);
91 n_left_from = frame->n_vectors;
92 next_index = node->cached_next_index;
93
94 if (node->flags & VLIB_NODE_FLAG_TRACE)
95 vlib_trace_frame_buffers_only (vm, node, from, frame->n_vectors,
96 /* stride */ 1,
97 sizeof (ip4_input_trace_t));
98
99 cm = vec_elt_at_index (vnm->interface_main.sw_if_counters,
Dave Barachd7cb1b52016-12-09 09:52:16 -0500100 VNET_INTERFACE_COUNTER_IP4);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700101
102 while (n_left_from > 0)
103 {
104 u32 n_left_to_next;
105
Dave Barachd7cb1b52016-12-09 09:52:16 -0500106 vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700107
108 while (n_left_from >= 4 && n_left_to_next >= 2)
109 {
Dave Barachd7cb1b52016-12-09 09:52:16 -0500110 vlib_buffer_t *p0, *p1;
111 ip4_header_t *ip0, *ip1;
Damjan Marion8b3191e2016-11-09 19:54:20 +0100112 u32 sw_if_index0, pi0, ip_len0, cur_len0, next0 = 0;
113 u32 sw_if_index1, pi1, ip_len1, cur_len1, next1 = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700114 i32 len_diff0, len_diff1;
Damjan Marion8b3191e2016-11-09 19:54:20 +0100115 u8 error0, error1, arc0, arc1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700116
117 /* Prefetch next iteration. */
118 {
Dave Barachd7cb1b52016-12-09 09:52:16 -0500119 vlib_buffer_t *p2, *p3;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700120
121 p2 = vlib_get_buffer (vm, from[2]);
122 p3 = vlib_get_buffer (vm, from[3]);
123
124 vlib_prefetch_buffer_header (p2, LOAD);
125 vlib_prefetch_buffer_header (p3, LOAD);
126
127 CLIB_PREFETCH (p2->data, sizeof (ip0[0]), LOAD);
128 CLIB_PREFETCH (p3->data, sizeof (ip1[0]), LOAD);
129 }
130
131 to_next[0] = pi0 = from[0];
132 to_next[1] = pi1 = from[1];
133 from += 2;
134 to_next += 2;
135 n_left_from -= 2;
136 n_left_to_next -= 2;
137
138 p0 = vlib_get_buffer (vm, pi0);
139 p1 = vlib_get_buffer (vm, pi1);
140
141 ip0 = vlib_buffer_get_current (p0);
142 ip1 = vlib_buffer_get_current (p1);
143
144 sw_if_index0 = vnet_buffer (p0)->sw_if_index[VLIB_RX];
145 sw_if_index1 = vnet_buffer (p1)->sw_if_index[VLIB_RX];
146
Dave Barachd7cb1b52016-12-09 09:52:16 -0500147 arc0 =
148 ip4_address_is_multicast (&ip0->dst_address) ?
149 lm->mcast_feature_arc_index : lm->ucast_feature_arc_index;
150 arc1 =
151 ip4_address_is_multicast (&ip1->dst_address) ?
152 lm->mcast_feature_arc_index : lm->ucast_feature_arc_index;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700153
154 vnet_buffer (p0)->ip.adj_index[VLIB_RX] = ~0;
155 vnet_buffer (p1)->ip.adj_index[VLIB_RX] = ~0;
156
Damjan Marion8b3191e2016-11-09 19:54:20 +0100157 vnet_feature_arc_start (arc0, sw_if_index0, &next0, p0);
158 vnet_feature_arc_start (arc1, sw_if_index1, &next1, p1);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700159
160 vlib_increment_simple_counter (cm, cpu_index, sw_if_index0, 1);
161 vlib_increment_simple_counter (cm, cpu_index, sw_if_index1, 1);
162
163 error0 = error1 = IP4_ERROR_NONE;
164
165 /* Punt packets with options. */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500166 error0 =
167 (ip0->ip_version_and_header_length & 0xf) !=
168 5 ? IP4_ERROR_OPTIONS : error0;
169 error1 =
170 (ip1->ip_version_and_header_length & 0xf) !=
171 5 ? IP4_ERROR_OPTIONS : error1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700172
173 /* Version != 4? Drop it. */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500174 error0 =
175 (ip0->ip_version_and_header_length >> 4) !=
176 4 ? IP4_ERROR_VERSION : error0;
177 error1 =
178 (ip1->ip_version_and_header_length >> 4) !=
179 4 ? IP4_ERROR_VERSION : error1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700180
181 /* Verify header checksum. */
182 if (verify_checksum)
183 {
184 ip_csum_t sum0, sum1;
185
186 ip4_partial_header_checksum_x1 (ip0, sum0);
187 ip4_partial_header_checksum_x1 (ip1, sum1);
188
Dave Barachd7cb1b52016-12-09 09:52:16 -0500189 error0 =
190 0xffff !=
191 ip_csum_fold (sum0) ? IP4_ERROR_BAD_CHECKSUM : error0;
192 error1 =
193 0xffff !=
194 ip_csum_fold (sum1) ? IP4_ERROR_BAD_CHECKSUM : error1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700195 }
196
197 /* Drop fragmentation offset 1 packets. */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500198 error0 =
199 ip4_get_fragment_offset (ip0) ==
200 1 ? IP4_ERROR_FRAGMENT_OFFSET_ONE : error0;
201 error1 =
202 ip4_get_fragment_offset (ip1) ==
203 1 ? IP4_ERROR_FRAGMENT_OFFSET_ONE : error1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700204
Chris Luke816f3e12016-06-14 16:24:47 -0400205 /* TTL < 1? Drop it. */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500206 error0 = (ip0->ttl < 1
207 && arc0 ==
208 lm->ucast_feature_arc_index) ? IP4_ERROR_TIME_EXPIRED :
209 error0;
210 error1 = (ip1->ttl < 1
211 && arc1 ==
212 lm->ucast_feature_arc_index) ? IP4_ERROR_TIME_EXPIRED :
213 error1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700214
215 /* Verify lengths. */
216 ip_len0 = clib_net_to_host_u16 (ip0->length);
217 ip_len1 = clib_net_to_host_u16 (ip1->length);
218
219 /* IP length must be at least minimal IP header. */
220 error0 = ip_len0 < sizeof (ip0[0]) ? IP4_ERROR_TOO_SHORT : error0;
221 error1 = ip_len1 < sizeof (ip1[0]) ? IP4_ERROR_TOO_SHORT : error1;
222
223 cur_len0 = vlib_buffer_length_in_chain (vm, p0);
224 cur_len1 = vlib_buffer_length_in_chain (vm, p1);
225
226 len_diff0 = cur_len0 - ip_len0;
227 len_diff1 = cur_len1 - ip_len1;
228
229 error0 = len_diff0 < 0 ? IP4_ERROR_BAD_LENGTH : error0;
230 error1 = len_diff1 < 0 ? IP4_ERROR_BAD_LENGTH : error1;
231
232 p0->error = error_node->errors[error0];
233 p1->error = error_node->errors[error1];
234
Dave Barachd7cb1b52016-12-09 09:52:16 -0500235 if (PREDICT_FALSE (error0 != IP4_ERROR_NONE))
236 {
237 if (error0 == IP4_ERROR_TIME_EXPIRED)
238 {
239 icmp4_error_set_vnet_buffer (p0, ICMP4_time_exceeded,
240 ICMP4_time_exceeded_ttl_exceeded_in_transit,
241 0);
242 next0 = IP4_INPUT_NEXT_ICMP_ERROR;
243 }
244 else
245 next0 =
246 error0 !=
247 IP4_ERROR_OPTIONS ? IP4_INPUT_NEXT_DROP :
248 IP4_INPUT_NEXT_PUNT;
249 }
250 if (PREDICT_FALSE (error1 != IP4_ERROR_NONE))
251 {
252 if (error1 == IP4_ERROR_TIME_EXPIRED)
253 {
254 icmp4_error_set_vnet_buffer (p1, ICMP4_time_exceeded,
255 ICMP4_time_exceeded_ttl_exceeded_in_transit,
256 0);
257 next1 = IP4_INPUT_NEXT_ICMP_ERROR;
258 }
259 else
260 next1 =
261 error1 !=
262 IP4_ERROR_OPTIONS ? IP4_INPUT_NEXT_DROP :
263 IP4_INPUT_NEXT_PUNT;
264 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700265
266 vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
267 to_next, n_left_to_next,
268 pi0, pi1, next0, next1);
Dave Barachd7cb1b52016-12-09 09:52:16 -0500269 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700270 while (n_left_from > 0 && n_left_to_next > 0)
271 {
Dave Barachd7cb1b52016-12-09 09:52:16 -0500272 vlib_buffer_t *p0;
273 ip4_header_t *ip0;
Damjan Marion8b3191e2016-11-09 19:54:20 +0100274 u32 sw_if_index0, pi0, ip_len0, cur_len0, next0 = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700275 i32 len_diff0;
Damjan Marion8b3191e2016-11-09 19:54:20 +0100276 u8 error0, arc0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700277
278 pi0 = from[0];
279 to_next[0] = pi0;
280 from += 1;
281 to_next += 1;
282 n_left_from -= 1;
283 n_left_to_next -= 1;
284
285 p0 = vlib_get_buffer (vm, pi0);
286 ip0 = vlib_buffer_get_current (p0);
287
288 sw_if_index0 = vnet_buffer (p0)->sw_if_index[VLIB_RX];
289
Dave Barachd7cb1b52016-12-09 09:52:16 -0500290 arc0 =
291 ip4_address_is_multicast (&ip0->dst_address) ?
292 lm->mcast_feature_arc_index : lm->ucast_feature_arc_index;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700293 vnet_buffer (p0)->ip.adj_index[VLIB_RX] = ~0;
Damjan Marion8b3191e2016-11-09 19:54:20 +0100294 vnet_feature_arc_start (arc0, sw_if_index0, &next0, p0);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700295
296 vlib_increment_simple_counter (cm, cpu_index, sw_if_index0, 1);
297
298 error0 = IP4_ERROR_NONE;
299
300 /* Punt packets with options. */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500301 error0 =
302 (ip0->ip_version_and_header_length & 0xf) !=
303 5 ? IP4_ERROR_OPTIONS : error0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700304
305 /* Version != 4? Drop it. */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500306 error0 =
307 (ip0->ip_version_and_header_length >> 4) !=
308 4 ? IP4_ERROR_VERSION : error0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700309
310 /* Verify header checksum. */
311 if (verify_checksum)
312 {
313 ip_csum_t sum0;
314
315 ip4_partial_header_checksum_x1 (ip0, sum0);
Dave Barachd7cb1b52016-12-09 09:52:16 -0500316 error0 =
317 0xffff !=
318 ip_csum_fold (sum0) ? IP4_ERROR_BAD_CHECKSUM : error0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700319 }
320
321 /* Drop fragmentation offset 1 packets. */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500322 error0 =
323 ip4_get_fragment_offset (ip0) ==
324 1 ? IP4_ERROR_FRAGMENT_OFFSET_ONE : error0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700325
Chris Luke816f3e12016-06-14 16:24:47 -0400326 /* TTL < 1? Drop it. */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500327 error0 = (ip0->ttl < 1
328 && arc0 ==
329 lm->ucast_feature_arc_index) ? IP4_ERROR_TIME_EXPIRED :
330 error0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700331
332 /* Verify lengths. */
333 ip_len0 = clib_net_to_host_u16 (ip0->length);
334
335 /* IP length must be at least minimal IP header. */
336 error0 = ip_len0 < sizeof (ip0[0]) ? IP4_ERROR_TOO_SHORT : error0;
337
338 cur_len0 = vlib_buffer_length_in_chain (vm, p0);
339 len_diff0 = cur_len0 - ip_len0;
340 error0 = len_diff0 < 0 ? IP4_ERROR_BAD_LENGTH : error0;
341
342 p0->error = error_node->errors[error0];
Dave Barachd7cb1b52016-12-09 09:52:16 -0500343 if (PREDICT_FALSE (error0 != IP4_ERROR_NONE))
344 {
345 if (error0 == IP4_ERROR_TIME_EXPIRED)
346 {
347 icmp4_error_set_vnet_buffer (p0, ICMP4_time_exceeded,
348 ICMP4_time_exceeded_ttl_exceeded_in_transit,
349 0);
350 next0 = IP4_INPUT_NEXT_ICMP_ERROR;
351 }
352 else
353 next0 =
354 error0 !=
355 IP4_ERROR_OPTIONS ? IP4_INPUT_NEXT_DROP :
356 IP4_INPUT_NEXT_PUNT;
357 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700358
359 vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
360 to_next, n_left_to_next,
361 pi0, next0);
362 }
363
364 vlib_put_next_frame (vm, node, next_index, n_left_to_next);
365 }
366
367 return frame->n_vectors;
368}
369
Dave Barach132d51d2016-07-07 10:10:17 -0400370/** \brief IPv4 input node.
371 @node ip4-input
372
373 This is the IPv4 input node: validates ip4 header checksums,
374 verifies ip header lengths, discards pkts with expired TTLs,
375 and sends pkts to the set of ip feature nodes configured on
376 the rx interface.
377
378 @param vm vlib_main_t corresponding to the current thread
379 @param node vlib_node_runtime_t
380 @param frame vlib_frame_t whose contents should be dispatched
381
382 @par Graph mechanics: buffer metadata, next index usage
383
384 @em Uses:
Dave Barachd7cb1b52016-12-09 09:52:16 -0500385 - vnet_feature_config_main_t cm corresponding to each pkt's dst address unicast /
Dave Barach132d51d2016-07-07 10:10:17 -0400386 multicast status.
387 - <code>b->current_config_index</code> corresponding to each pkt's
Dave Barachd7cb1b52016-12-09 09:52:16 -0500388 rx sw_if_index.
Dave Barach132d51d2016-07-07 10:10:17 -0400389 - This sets the per-packet graph trajectory, ensuring that
390 each packet visits the per-interface features in order.
391
392 - <code>vnet_buffer(b)->sw_if_index[VLIB_RX]</code>
393 - Indicates the @c sw_if_index value of the interface that the
394 packet was received on.
395
396 @em Sets:
397 - <code>vnet_buffer(b)->ip.adj_index[VLIB_TX]</code>
398 - The lookup result adjacency index.
399
400 <em>Next Indices:</em>
401 - Dispatches pkts to the (first) feature node:
402 <code> vnet_get_config_data (... &next0 ...); </code>
Dave Barachd7cb1b52016-12-09 09:52:16 -0500403 or @c error-drop
Dave Barach132d51d2016-07-07 10:10:17 -0400404*/
Ed Warnickecb9cada2015-12-08 15:45:58 -0700405static uword
Dave Barachd7cb1b52016-12-09 09:52:16 -0500406ip4_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700407{
408 return ip4_input_inline (vm, node, frame, /* verify_checksum */ 1);
409}
410
411static uword
412ip4_input_no_checksum (vlib_main_t * vm,
Dave Barachd7cb1b52016-12-09 09:52:16 -0500413 vlib_node_runtime_t * node, vlib_frame_t * frame)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700414{
415 return ip4_input_inline (vm, node, frame, /* verify_checksum */ 0);
416}
417
Dave Barachd7cb1b52016-12-09 09:52:16 -0500418static char *ip4_error_strings[] = {
Ed Warnickecb9cada2015-12-08 15:45:58 -0700419#define _(sym,string) string,
420 foreach_ip4_error
421#undef _
422};
423
Dave Barachd7cb1b52016-12-09 09:52:16 -0500424/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700425VLIB_REGISTER_NODE (ip4_input_node) = {
426 .function = ip4_input,
427 .name = "ip4-input",
428 .vector_size = sizeof (u32),
429
430 .n_errors = IP4_N_ERROR,
431 .error_strings = ip4_error_strings,
432
433 .n_next_nodes = IP4_INPUT_N_NEXT,
434 .next_nodes = {
435 [IP4_INPUT_NEXT_DROP] = "error-drop",
436 [IP4_INPUT_NEXT_PUNT] = "error-punt",
437 [IP4_INPUT_NEXT_LOOKUP] = "ip4-lookup",
438 [IP4_INPUT_NEXT_LOOKUP_MULTICAST] = "ip4-lookup-multicast",
Ole Troan92eade12016-01-13 20:17:08 +0100439 [IP4_INPUT_NEXT_ICMP_ERROR] = "ip4-icmp-error",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700440 },
441
442 .format_buffer = format_ip4_header,
443 .format_trace = format_ip4_input_trace,
444};
Dave Barachd7cb1b52016-12-09 09:52:16 -0500445/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700446
Dave Barachd7cb1b52016-12-09 09:52:16 -0500447VLIB_NODE_FUNCTION_MULTIARCH (ip4_input_node, ip4_input);
Damjan Marion1c80e832016-05-11 23:07:18 +0200448
Dave Barachd7cb1b52016-12-09 09:52:16 -0500449/* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700450VLIB_REGISTER_NODE (ip4_input_no_checksum_node,static) = {
451 .function = ip4_input_no_checksum,
452 .name = "ip4-input-no-checksum",
453 .vector_size = sizeof (u32),
454
455 .n_next_nodes = IP4_INPUT_N_NEXT,
456 .next_nodes = {
457 [IP4_INPUT_NEXT_DROP] = "error-drop",
458 [IP4_INPUT_NEXT_PUNT] = "error-punt",
459 [IP4_INPUT_NEXT_LOOKUP] = "ip4-lookup",
460 [IP4_INPUT_NEXT_LOOKUP_MULTICAST] = "ip4-lookup-multicast",
Ole Troan92eade12016-01-13 20:17:08 +0100461 [IP4_INPUT_NEXT_ICMP_ERROR] = "ip4-icmp-error",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700462 },
463
464 .format_buffer = format_ip4_header,
465 .format_trace = format_ip4_input_trace,
466};
Dave Barachd7cb1b52016-12-09 09:52:16 -0500467/* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700468
Dave Barachd7cb1b52016-12-09 09:52:16 -0500469VLIB_NODE_FUNCTION_MULTIARCH (ip4_input_no_checksum_node,
470 ip4_input_no_checksum);
Damjan Marion1c80e832016-05-11 23:07:18 +0200471
Dave Barachd7cb1b52016-12-09 09:52:16 -0500472static clib_error_t *
473ip4_init (vlib_main_t * vm)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700474{
Dave Barachd7cb1b52016-12-09 09:52:16 -0500475 clib_error_t *error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700476
Dave Barachd7cb1b52016-12-09 09:52:16 -0500477 ethernet_register_input_type (vm, ETHERNET_TYPE_IP4, ip4_input_node.index);
478 ppp_register_input_protocol (vm, PPP_PROTOCOL_ip4, ip4_input_node.index);
479 hdlc_register_input_protocol (vm, HDLC_PROTOCOL_ip4, ip4_input_node.index);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700480
481 {
Dave Barachd7cb1b52016-12-09 09:52:16 -0500482 pg_node_t *pn;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700483 pn = pg_get_node (ip4_input_node.index);
484 pn->unformat_edit = unformat_pg_ip4_header;
485 pn = pg_get_node (ip4_input_no_checksum_node.index);
486 pn->unformat_edit = unformat_pg_ip4_header;
487 }
488
489 if ((error = vlib_call_init_function (vm, ip4_cli_init)))
490 return error;
491
492 if ((error = vlib_call_init_function (vm, ip4_source_check_init)))
493 return error;
494
Dave Barachd7cb1b52016-12-09 09:52:16 -0500495 if ((error = vlib_call_init_function
Dave Barach6f9bca22016-04-30 10:25:32 -0400496 (vm, ip4_source_and_port_range_check_init)))
497 return error;
498
Ed Warnickecb9cada2015-12-08 15:45:58 -0700499 /* Set flow hash to something non-zero. */
500 ip4_main.flow_hash_seed = 0xdeadbeef;
501
502 /* Default TTL for packets we generate. */
503 ip4_main.host_config.ttl = 64;
504
505 return error;
506}
507
508VLIB_INIT_FUNCTION (ip4_init);
Dave Barachd7cb1b52016-12-09 09:52:16 -0500509
510/*
511 * fd.io coding-style-patch-verification: ON
512 *
513 * Local Variables:
514 * eval: (c-set-style "gnu")
515 * End:
516 */