blob: 3a20d512f6056a6bbc16255e11c342eb5a796949 [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
2 * ipsec_output.c : IPSec output node
3 *
4 * Copyright (c) 2015 Cisco and/or its affiliates.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#include <vnet/vnet.h>
19#include <vnet/api_errno.h>
20#include <vnet/ip/ip.h>
21
22#include <vnet/ipsec/ipsec.h>
23
Damjan Mariona9a951f2017-01-16 22:06:10 +010024#if WITH_LIBSSL > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -070025
Ed Warnickecb9cada2015-12-08 15:45:58 -070026#define foreach_ipsec_output_error \
27 _(RX_PKTS, "IPSec pkts received") \
28 _(POLICY_DISCARD, "IPSec policy discard") \
29 _(POLICY_NO_MATCH, "IPSec policy (no match)") \
30 _(POLICY_PROTECT, "IPSec policy protect") \
31 _(POLICY_BYPASS, "IPSec policy bypass") \
32 _(ENCAPS_FAILED, "IPSec encapsulation failed")
33
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070034typedef enum
35{
Ed Warnickecb9cada2015-12-08 15:45:58 -070036#define _(sym,str) IPSEC_OUTPUT_ERROR_##sym,
37 foreach_ipsec_output_error
38#undef _
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070039 IPSEC_DECAP_N_ERROR,
Ed Warnickecb9cada2015-12-08 15:45:58 -070040} ipsec_output_error_t;
41
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070042static char *ipsec_output_error_strings[] = {
Ed Warnickecb9cada2015-12-08 15:45:58 -070043#define _(sym,string) string,
44 foreach_ipsec_output_error
45#undef _
46};
47
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070048typedef struct
49{
Ed Warnickecb9cada2015-12-08 15:45:58 -070050 u32 spd_id;
51} ipsec_output_trace_t;
52
53/* packet trace format function */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070054static u8 *
55format_ipsec_output_trace (u8 * s, va_list * args)
Ed Warnickecb9cada2015-12-08 15:45:58 -070056{
57 CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
58 CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070059 ipsec_output_trace_t *t = va_arg (*args, ipsec_output_trace_t *);
Ed Warnickecb9cada2015-12-08 15:45:58 -070060
61 if (t->spd_id != ~0)
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070062 {
63 s = format (s, "spd %u ", t->spd_id);
64 }
Ed Warnickecb9cada2015-12-08 15:45:58 -070065 else
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070066 {
67 s = format (s, "no spd");
68 }
Ed Warnickecb9cada2015-12-08 15:45:58 -070069 return s;
70}
71
Ed Warnickecb9cada2015-12-08 15:45:58 -070072always_inline ipsec_policy_t *
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070073ipsec_output_policy_match (ipsec_spd_t * spd, u8 pr, u32 la, u32 ra, u16 lp,
74 u16 rp)
Ed Warnickecb9cada2015-12-08 15:45:58 -070075{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070076 ipsec_policy_t *p;
77 u32 *i;
Ed Warnickecb9cada2015-12-08 15:45:58 -070078
Damjan Marion3f54b182016-08-16 11:27:02 +020079 if (!spd)
80 return 0;
81
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070082 vec_foreach (i, spd->ipv4_outbound_policies)
83 {
84 p = pool_elt_at_index (spd->policies, *i);
85 if (PREDICT_FALSE (p->protocol && (p->protocol != pr)))
86 continue;
Ed Warnickecb9cada2015-12-08 15:45:58 -070087
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070088 if (ra < clib_net_to_host_u32 (p->raddr.start.ip4.as_u32))
89 continue;
Ed Warnickecb9cada2015-12-08 15:45:58 -070090
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070091 if (ra > clib_net_to_host_u32 (p->raddr.stop.ip4.as_u32))
92 continue;
Ed Warnickecb9cada2015-12-08 15:45:58 -070093
Radu Nicolaude412ce2018-03-12 13:52:41 +000094 if (la < clib_net_to_host_u32 (p->laddr.start.ip4.as_u32))
95 continue;
96
97 if (la > clib_net_to_host_u32 (p->laddr.stop.ip4.as_u32))
98 continue;
99
Marco Varlese191a5942017-10-30 18:17:21 +0100100 if (PREDICT_FALSE
101 ((pr != IP_PROTOCOL_TCP) && (pr != IP_PROTOCOL_UDP)
102 && (pr != IP_PROTOCOL_SCTP)))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700103 return p;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700104
105 if (lp < p->lport.start)
106 continue;
107
108 if (lp > p->lport.stop)
109 continue;
110
111 if (rp < p->rport.start)
112 continue;
113
114 if (rp > p->rport.stop)
115 continue;
116
117 return p;
118 }
119 return 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700120}
121
122always_inline uword
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700123ip6_addr_match_range (ip6_address_t * a, ip6_address_t * la,
124 ip6_address_t * ua)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700125{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700126 if ((memcmp (a->as_u64, la->as_u64, 2 * sizeof (u64)) >= 0) &&
127 (memcmp (a->as_u64, ua->as_u64, 2 * sizeof (u64)) <= 0))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700128 return 1;
129 return 0;
130}
131
132always_inline ipsec_policy_t *
Klement Sekerabe5a5dd2018-10-09 16:05:48 +0200133ipsec6_output_policy_match (ipsec_spd_t * spd,
134 ip6_address_t * la,
135 ip6_address_t * ra, u16 lp, u16 rp, u8 pr)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700136{
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700137 ipsec_policy_t *p;
138 u32 *i;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700139
Damjan Marion3f54b182016-08-16 11:27:02 +0200140 if (!spd)
141 return 0;
142
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700143 vec_foreach (i, spd->ipv6_outbound_policies)
144 {
145 p = pool_elt_at_index (spd->policies, *i);
146 if (PREDICT_FALSE (p->protocol && (p->protocol != pr)))
147 continue;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700148
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700149 if (!ip6_addr_match_range (ra, &p->raddr.start.ip6, &p->raddr.stop.ip6))
150 continue;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700151
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700152 if (!ip6_addr_match_range (la, &p->laddr.start.ip6, &p->laddr.stop.ip6))
153 continue;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700154
Marco Varlese191a5942017-10-30 18:17:21 +0100155 if (PREDICT_FALSE
156 ((pr != IP_PROTOCOL_TCP) && (pr != IP_PROTOCOL_UDP)
157 && (pr != IP_PROTOCOL_SCTP)))
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700158 return p;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700159
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700160 if (lp < p->lport.start)
161 continue;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700162
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700163 if (lp > p->lport.stop)
164 continue;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700165
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700166 if (rp < p->rport.start)
167 continue;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700168
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700169 if (rp > p->rport.stop)
170 continue;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700171
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700172 return p;
173 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700174
175 return 0;
176}
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700177
Matus Fabian08a6f012016-11-15 06:08:51 -0800178static inline uword
179ipsec_output_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
180 vlib_frame_t * from_frame, int is_ipv6)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700181{
182 ipsec_main_t *im = &ipsec_main;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700183
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700184 u32 *from, *to_next = 0;
185 u32 n_left_from, sw_if_index0, last_sw_if_index = (u32) ~ 0;
186 u32 next_node_index = (u32) ~ 0, last_next_node_index = (u32) ~ 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700187 vlib_frame_t *f = 0;
188 u32 spd_index0 = ~0;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700189 ipsec_spd_t *spd0 = 0;
Klement Sekera31da2e32018-06-24 22:49:55 +0200190 int bogus;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700191 u64 nc_protect = 0, nc_bypass = 0, nc_discard = 0, nc_nomatch = 0;
192
193 from = vlib_frame_vector_args (from_frame);
194 n_left_from = from_frame->n_vectors;
195
196 while (n_left_from > 0)
197 {
198 u32 bi0;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700199 vlib_buffer_t *b0;
200 ipsec_policy_t *p0;
201 ip4_header_t *ip0;
202 ip6_header_t *ip6_0 = 0;
203 udp_header_t *udp0;
Florin Corasfb28e9a2016-09-06 15:18:21 +0200204 u32 iph_offset = 0;
Klement Sekera31da2e32018-06-24 22:49:55 +0200205 tcp_header_t *tcp0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700206
207 bi0 = from[0];
208 b0 = vlib_get_buffer (vm, bi0);
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700209 sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_TX];
Florin Corasfb28e9a2016-09-06 15:18:21 +0200210 iph_offset = vnet_buffer (b0)->ip.save_rewrite_length;
211 ip0 = (ip4_header_t *) ((u8 *) vlib_buffer_get_current (b0)
212 + iph_offset);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700213
Ed Warnickecb9cada2015-12-08 15:45:58 -0700214 /* lookup for SPD only if sw_if_index is changed */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700215 if (PREDICT_FALSE (last_sw_if_index != sw_if_index0))
216 {
217 uword *p = hash_get (im->spd_index_by_sw_if_index, sw_if_index0);
218 ASSERT (p);
219 spd_index0 = p[0];
220 spd0 = pool_elt_at_index (im->spds, spd_index0);
221 last_sw_if_index = sw_if_index0;
222 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700223
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700224 if (is_ipv6)
225 {
Matus Fabian08a6f012016-11-15 06:08:51 -0800226 ip6_0 = (ip6_header_t *) ((u8 *) vlib_buffer_get_current (b0)
227 + iph_offset);
228
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700229 udp0 = ip6_next_header (ip6_0);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700230#if 0
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700231 clib_warning
232 ("packet received from %U port %u to %U port %u spd_id %u",
233 format_ip6_address, &ip6_0->src_address,
234 clib_net_to_host_u16 (udp0->src_port), format_ip6_address,
235 &ip6_0->dst_address, clib_net_to_host_u16 (udp0->dst_port),
236 spd0->id);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700237#endif
238
Klement Sekerabe5a5dd2018-10-09 16:05:48 +0200239 p0 = ipsec6_output_policy_match (spd0,
240 &ip6_0->src_address,
241 &ip6_0->dst_address,
242 clib_net_to_host_u16
243 (udp0->src_port),
244 clib_net_to_host_u16
245 (udp0->dst_port), ip6_0->protocol);
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700246 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700247 else
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700248 {
249 udp0 = (udp_header_t *) ((u8 *) ip0 + ip4_header_bytes (ip0));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700250
251#if 0
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700252 clib_warning ("packet received from %U to %U port %u",
253 format_ip4_address, ip0->src_address.as_u8,
254 format_ip4_address, ip0->dst_address.as_u8,
255 clib_net_to_host_u16 (udp0->dst_port));
256 clib_warning ("sw_if_index0 %u spd_index0 %u spd_id %u",
257 sw_if_index0, spd_index0, spd0->id);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700258#endif
259
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700260 p0 = ipsec_output_policy_match (spd0, ip0->protocol,
Ed Warnicke853e7202016-08-12 11:42:26 -0700261 clib_net_to_host_u32
262 (ip0->src_address.as_u32),
263 clib_net_to_host_u32
264 (ip0->dst_address.as_u32),
265 clib_net_to_host_u16
266 (udp0->src_port),
267 clib_net_to_host_u16
268 (udp0->dst_port));
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700269 }
Klement Sekera31da2e32018-06-24 22:49:55 +0200270 tcp0 = (void *) udp0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700271
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700272 if (PREDICT_TRUE (p0 != NULL))
273 {
274 if (p0->policy == IPSEC_POLICY_ACTION_PROTECT)
275 {
“mukeshyadav1984”430ac932017-11-23 02:39:33 -0800276 ipsec_sa_t *sa = 0;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700277 nc_protect++;
Radu Nicolaude412ce2018-03-12 13:52:41 +0000278 sa = pool_elt_at_index (im->sad, p0->sa_index);
“mukeshyadav1984”430ac932017-11-23 02:39:33 -0800279 if (sa->protocol == IPSEC_PROTOCOL_ESP)
Klement Sekerabe5a5dd2018-10-09 16:05:48 +0200280 if (is_ipv6)
281 next_node_index = im->esp6_encrypt_node_index;
282 else
283 next_node_index = im->esp4_encrypt_node_index;
284 else if (is_ipv6)
285 next_node_index = im->ah6_encrypt_node_index;
“mukeshyadav1984”430ac932017-11-23 02:39:33 -0800286 else
Klement Sekerabe5a5dd2018-10-09 16:05:48 +0200287 next_node_index = im->ah4_encrypt_node_index;
Damjan Marion9c6ae5f2016-11-15 23:20:01 +0100288 vnet_buffer (b0)->ipsec.sad_index = p0->sa_index;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700289 p0->counter.packets++;
290 if (is_ipv6)
291 {
292 p0->counter.bytes +=
293 clib_net_to_host_u16 (ip6_0->payload_length);
294 p0->counter.bytes += sizeof (ip6_header_t);
Klement Sekera31da2e32018-06-24 22:49:55 +0200295 if (PREDICT_FALSE
296 (b0->flags & VNET_BUFFER_F_OFFLOAD_TCP_CKSUM))
297 {
298 tcp0->checksum =
299 ip6_tcp_udp_icmp_compute_checksum (vm, b0, ip6_0,
300 &bogus);
301 b0->flags &= ~VNET_BUFFER_F_OFFLOAD_TCP_CKSUM;
302 }
303 if (PREDICT_FALSE
304 (b0->flags & VNET_BUFFER_F_OFFLOAD_UDP_CKSUM))
305 {
306 udp0->checksum =
307 ip6_tcp_udp_icmp_compute_checksum (vm, b0, ip6_0,
308 &bogus);
309 b0->flags &= ~VNET_BUFFER_F_OFFLOAD_UDP_CKSUM;
310 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700311 }
312 else
313 {
314 p0->counter.bytes += clib_net_to_host_u16 (ip0->length);
Klement Sekera31da2e32018-06-24 22:49:55 +0200315 if (b0->flags & VNET_BUFFER_F_OFFLOAD_IP_CKSUM)
316 {
317 ip0->checksum = ip4_header_checksum (ip0);
318 b0->flags &= ~VNET_BUFFER_F_OFFLOAD_IP_CKSUM;
319 }
320 if (PREDICT_FALSE
321 (b0->flags & VNET_BUFFER_F_OFFLOAD_TCP_CKSUM))
322 {
323 tcp0->checksum =
324 ip4_tcp_udp_compute_checksum (vm, b0, ip0);
325 b0->flags &= ~VNET_BUFFER_F_OFFLOAD_TCP_CKSUM;
326 }
327 if (PREDICT_FALSE
328 (b0->flags & VNET_BUFFER_F_OFFLOAD_UDP_CKSUM))
329 {
330 udp0->checksum =
331 ip4_tcp_udp_compute_checksum (vm, b0, ip0);
332 b0->flags &= ~VNET_BUFFER_F_OFFLOAD_UDP_CKSUM;
333 }
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700334 }
Klement Sekera31da2e32018-06-24 22:49:55 +0200335 vlib_buffer_advance (b0, iph_offset);
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700336 }
337 else if (p0->policy == IPSEC_POLICY_ACTION_BYPASS)
338 {
339 nc_bypass++;
Matus Fabian08a6f012016-11-15 06:08:51 -0800340 next_node_index = get_next_output_feature_node_index (b0, node);
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700341 p0->counter.packets++;
342 if (is_ipv6)
343 {
344 p0->counter.bytes +=
345 clib_net_to_host_u16 (ip6_0->payload_length);
346 p0->counter.bytes += sizeof (ip6_header_t);
347 }
348 else
349 {
350 p0->counter.bytes += clib_net_to_host_u16 (ip0->length);
351 }
352 }
353 else
354 {
355 nc_discard++;
356 p0->counter.packets++;
357 if (is_ipv6)
358 {
359 p0->counter.bytes +=
360 clib_net_to_host_u16 (ip6_0->payload_length);
361 p0->counter.bytes += sizeof (ip6_header_t);
362 }
363 else
364 {
365 p0->counter.bytes += clib_net_to_host_u16 (ip0->length);
366 }
367 next_node_index = im->error_drop_node_index;
368 }
369 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700370 else
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700371 {
372 nc_nomatch++;
373 next_node_index = im->error_drop_node_index;
374 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700375
Ed Warnickecb9cada2015-12-08 15:45:58 -0700376 from += 1;
377 n_left_from -= 1;
378
Damjan Marion3f54b182016-08-16 11:27:02 +0200379 if (PREDICT_FALSE ((last_next_node_index != next_node_index) || f == 0))
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700380 {
381 /* if this is not 1st frame */
382 if (f)
383 vlib_put_frame_to_node (vm, last_next_node_index, f);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700384
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700385 last_next_node_index = next_node_index;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700386
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700387 f = vlib_get_frame_to_node (vm, next_node_index);
388 to_next = vlib_frame_vector_args (f);
389 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700390
391 to_next[0] = bi0;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700392 to_next += 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700393 f->n_vectors++;
394
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700395 if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
396 {
397 ipsec_output_trace_t *tr =
398 vlib_add_trace (vm, node, b0, sizeof (*tr));
399 if (spd0)
400 tr->spd_id = spd0->id;
401 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700402 }
403
404 vlib_put_frame_to_node (vm, next_node_index, f);
Matus Fabian08a6f012016-11-15 06:08:51 -0800405 vlib_node_increment_counter (vm, node->node_index,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700406 IPSEC_OUTPUT_ERROR_POLICY_PROTECT, nc_protect);
Matus Fabian08a6f012016-11-15 06:08:51 -0800407 vlib_node_increment_counter (vm, node->node_index,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700408 IPSEC_OUTPUT_ERROR_POLICY_BYPASS, nc_bypass);
Matus Fabian08a6f012016-11-15 06:08:51 -0800409 vlib_node_increment_counter (vm, node->node_index,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700410 IPSEC_OUTPUT_ERROR_POLICY_DISCARD, nc_discard);
Matus Fabian08a6f012016-11-15 06:08:51 -0800411 vlib_node_increment_counter (vm, node->node_index,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700412 IPSEC_OUTPUT_ERROR_POLICY_NO_MATCH,
413 nc_nomatch);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700414 return from_frame->n_vectors;
415}
416
Matus Fabian08a6f012016-11-15 06:08:51 -0800417static uword
Klement Sekerabe5a5dd2018-10-09 16:05:48 +0200418ipsec4_output_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
419 vlib_frame_t * frame)
Matus Fabian08a6f012016-11-15 06:08:51 -0800420{
421 return ipsec_output_inline (vm, node, frame, 0);
422}
423
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700424/* *INDENT-OFF* */
Klement Sekerabe5a5dd2018-10-09 16:05:48 +0200425VLIB_REGISTER_NODE (ipsec4_output_node,static) = {
426 .function = ipsec4_output_node_fn,
427 .name = "ipsec4-output",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700428 .vector_size = sizeof (u32),
429 .format_trace = format_ipsec_output_trace,
430 .type = VLIB_NODE_TYPE_INTERNAL,
431
432 .n_errors = ARRAY_LEN(ipsec_output_error_strings),
433 .error_strings = ipsec_output_error_strings,
434
435 .n_next_nodes = IPSEC_OUTPUT_N_NEXT,
436 .next_nodes = {
437#define _(s,n) [IPSEC_OUTPUT_NEXT_##s] = n,
Ed Warnickecb9cada2015-12-08 15:45:58 -0700438 foreach_ipsec_output_next
439#undef _
440 },
441};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700442/* *INDENT-ON* */
Damjan Marione936bbe2016-02-25 23:17:38 +0100443
Klement Sekerabe5a5dd2018-10-09 16:05:48 +0200444VLIB_NODE_FUNCTION_MULTIARCH (ipsec4_output_node, ipsec4_output_node_fn);
445
446static uword
447ipsec6_output_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
448 vlib_frame_t * frame)
Matus Fabian08a6f012016-11-15 06:08:51 -0800449{
450 return ipsec_output_inline (vm, node, frame, 1);
451}
452
453/* *INDENT-OFF* */
Klement Sekerabe5a5dd2018-10-09 16:05:48 +0200454VLIB_REGISTER_NODE (ipsec6_output_node,static) = {
455 .function = ipsec6_output_node_fn,
456 .name = "ipsec6-output",
Matus Fabian08a6f012016-11-15 06:08:51 -0800457 .vector_size = sizeof (u32),
458 .format_trace = format_ipsec_output_trace,
459 .type = VLIB_NODE_TYPE_INTERNAL,
460
461 .n_errors = ARRAY_LEN(ipsec_output_error_strings),
462 .error_strings = ipsec_output_error_strings,
463
464 .n_next_nodes = IPSEC_OUTPUT_N_NEXT,
465 .next_nodes = {
466#define _(s,n) [IPSEC_OUTPUT_NEXT_##s] = n,
467 foreach_ipsec_output_next
468#undef _
469 },
470};
471/* *INDENT-ON* */
472
Klement Sekerabe5a5dd2018-10-09 16:05:48 +0200473VLIB_NODE_FUNCTION_MULTIARCH (ipsec6_output_node, ipsec6_output_node_fn);
Damjan Marione936bbe2016-02-25 23:17:38 +0100474#else /* IPSEC > 1 */
475
476/* Dummy ipsec output node, in case when IPSec is disabled */
477
478static uword
479ipsec_output_node_fn (vlib_main_t * vm,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700480 vlib_node_runtime_t * node, vlib_frame_t * frame)
Damjan Marione936bbe2016-02-25 23:17:38 +0100481{
482 clib_warning ("IPSec disabled");
483 return 0;
484}
485
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700486/* *INDENT-OFF* */
Klement Sekerabe5a5dd2018-10-09 16:05:48 +0200487VLIB_REGISTER_NODE (ipsec4_output_node) = {
Damjan Marione936bbe2016-02-25 23:17:38 +0100488 .vector_size = sizeof (u32),
489 .function = ipsec_output_node_fn,
Klement Sekerabe5a5dd2018-10-09 16:05:48 +0200490 .name = "ipsec4-output",
Matus Fabian08a6f012016-11-15 06:08:51 -0800491};
492
Klement Sekerabe5a5dd2018-10-09 16:05:48 +0200493VLIB_REGISTER_NODE (ipsec6_output_node) = {
Matus Fabian08a6f012016-11-15 06:08:51 -0800494 .vector_size = sizeof (u32),
495 .function = ipsec_output_node_fn,
Klement Sekerabe5a5dd2018-10-09 16:05:48 +0200496 .name = "ipsec6-output",
Damjan Marione936bbe2016-02-25 23:17:38 +0100497};
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700498/* *INDENT-ON* */
Damjan Marione936bbe2016-02-25 23:17:38 +0100499#endif
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700500
501/*
502 * fd.io coding-style-patch-verification: ON
503 *
504 * Local Variables:
505 * eval: (c-set-style "gnu")
506 * End:
507 */