Coverage Report

Created: 2023-03-26 07:42

/src/openvswitch/lib/odp-execute.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc.
3
 * Copyright (c) 2013 Simon Horman
4
 *
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 <config.h>
19
#include "odp-execute.h"
20
#include "odp-execute-private.h"
21
#include <sys/types.h>
22
#include <netinet/in.h>
23
#include <arpa/inet.h>
24
#include <netinet/icmp6.h>
25
#include <netinet/ip6.h>
26
#include <stdlib.h>
27
#include <string.h>
28
29
#include "coverage.h"
30
#include "dp-packet.h"
31
#include "dpif.h"
32
#include "netlink.h"
33
#include "odp-netlink.h"
34
#include "odp-util.h"
35
#include "packets.h"
36
#include "flow.h"
37
#include "unaligned.h"
38
#include "util.h"
39
#include "csum.h"
40
#include "conntrack.h"
41
#include "openvswitch/vlog.h"
42
#include "unixctl.h"
43
44
VLOG_DEFINE_THIS_MODULE(odp_execute);
45
COVERAGE_DEFINE(datapath_drop_sample_error);
46
COVERAGE_DEFINE(datapath_drop_nsh_decap_error);
47
COVERAGE_DEFINE(drop_action_of_pipeline);
48
COVERAGE_DEFINE(drop_action_bridge_not_found);
49
COVERAGE_DEFINE(drop_action_recursion_too_deep);
50
COVERAGE_DEFINE(drop_action_too_many_resubmit);
51
COVERAGE_DEFINE(drop_action_stack_too_deep);
52
COVERAGE_DEFINE(drop_action_no_recirculation_context);
53
COVERAGE_DEFINE(drop_action_recirculation_conflict);
54
COVERAGE_DEFINE(drop_action_too_many_mpls_labels);
55
COVERAGE_DEFINE(drop_action_invalid_tunnel_metadata);
56
COVERAGE_DEFINE(drop_action_unsupported_packet_type);
57
COVERAGE_DEFINE(drop_action_congestion);
58
COVERAGE_DEFINE(drop_action_forwarding_disabled);
59
60
static void
61
dp_update_drop_action_counter(enum xlate_error drop_reason,
62
                              int delta)
63
0
{
64
0
   static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
65
66
0
   switch (drop_reason) {
67
0
   case XLATE_OK:
68
0
        COVERAGE_ADD(drop_action_of_pipeline, delta);
69
0
        break;
70
0
   case XLATE_BRIDGE_NOT_FOUND:
71
0
        COVERAGE_ADD(drop_action_bridge_not_found, delta);
72
0
        break;
73
0
   case XLATE_RECURSION_TOO_DEEP:
74
0
        COVERAGE_ADD(drop_action_recursion_too_deep, delta);
75
0
        break;
76
0
   case XLATE_TOO_MANY_RESUBMITS:
77
0
        COVERAGE_ADD(drop_action_too_many_resubmit, delta);
78
0
        break;
79
0
   case XLATE_STACK_TOO_DEEP:
80
0
        COVERAGE_ADD(drop_action_stack_too_deep, delta);
81
0
        break;
82
0
   case XLATE_NO_RECIRCULATION_CONTEXT:
83
0
        COVERAGE_ADD(drop_action_no_recirculation_context, delta);
84
0
        break;
85
0
   case XLATE_RECIRCULATION_CONFLICT:
86
0
        COVERAGE_ADD(drop_action_recirculation_conflict, delta);
87
0
        break;
88
0
   case XLATE_TOO_MANY_MPLS_LABELS:
89
0
        COVERAGE_ADD(drop_action_too_many_mpls_labels, delta);
90
0
        break;
91
0
   case XLATE_INVALID_TUNNEL_METADATA:
92
0
        COVERAGE_ADD(drop_action_invalid_tunnel_metadata, delta);
93
0
        break;
94
0
   case XLATE_UNSUPPORTED_PACKET_TYPE:
95
0
        COVERAGE_ADD(drop_action_unsupported_packet_type, delta);
96
0
        break;
97
0
   case XLATE_CONGESTION_DROP:
98
0
        COVERAGE_ADD(drop_action_congestion, delta);
99
0
        break;
100
0
   case XLATE_FORWARDING_DISABLED:
101
0
        COVERAGE_ADD(drop_action_forwarding_disabled, delta);
102
0
        break;
103
0
   case XLATE_MAX:
104
0
   default:
105
0
        VLOG_ERR_RL(&rl, "Invalid Drop reason type: %d", drop_reason);
106
0
   }
107
0
}
108
109
/* Masked copy of an ethernet address. 'src' is already properly masked. */
110
static void
111
ether_addr_copy_masked(struct eth_addr *dst, const struct eth_addr src,
112
                       const struct eth_addr mask)
113
0
{
114
0
    int i;
115
116
0
    for (i = 0; i < ARRAY_SIZE(dst->be16); i++) {
117
0
        dst->be16[i] = src.be16[i] | (dst->be16[i] & ~mask.be16[i]);
118
0
    }
119
0
}
120
121
static void
122
odp_eth_set_addrs(struct dp_packet *packet, const struct ovs_key_ethernet *key,
123
                  const struct ovs_key_ethernet *mask)
124
0
{
125
0
    struct eth_header *eh = dp_packet_eth(packet);
126
127
0
    if (eh) {
128
0
        if (!mask) {
129
0
            eh->eth_src = key->eth_src;
130
0
            eh->eth_dst = key->eth_dst;
131
0
        } else {
132
0
            ether_addr_copy_masked(&eh->eth_src, key->eth_src, mask->eth_src);
133
0
            ether_addr_copy_masked(&eh->eth_dst, key->eth_dst, mask->eth_dst);
134
0
        }
135
0
    }
136
0
}
137
138
static void
139
odp_set_ipv4(struct dp_packet *packet, const struct ovs_key_ipv4 *key,
140
             const struct ovs_key_ipv4 *mask)
141
0
{
142
0
    struct ip_header *nh = dp_packet_l3(packet);
143
0
    ovs_be32 ip_src_nh;
144
0
    ovs_be32 ip_dst_nh;
145
0
    ovs_be32 new_ip_src;
146
0
    ovs_be32 new_ip_dst;
147
0
    uint8_t new_tos;
148
0
    uint8_t new_ttl;
149
150
0
    if (mask->ipv4_src) {
151
0
        ip_src_nh = get_16aligned_be32(&nh->ip_src);
152
0
        new_ip_src = key->ipv4_src | (ip_src_nh & ~mask->ipv4_src);
153
154
0
        if (ip_src_nh != new_ip_src) {
155
0
            packet_set_ipv4_addr(packet, &nh->ip_src, new_ip_src);
156
0
        }
157
0
    }
158
159
0
    if (mask->ipv4_dst) {
160
0
        ip_dst_nh = get_16aligned_be32(&nh->ip_dst);
161
0
        new_ip_dst = key->ipv4_dst | (ip_dst_nh & ~mask->ipv4_dst);
162
163
0
        if (ip_dst_nh != new_ip_dst) {
164
0
            packet_set_ipv4_addr(packet, &nh->ip_dst, new_ip_dst);
165
0
        }
166
0
    }
167
168
0
    if (mask->ipv4_tos) {
169
0
        new_tos = key->ipv4_tos | (nh->ip_tos & ~mask->ipv4_tos);
170
171
0
        if (nh->ip_tos != new_tos) {
172
0
            nh->ip_csum = recalc_csum16(nh->ip_csum,
173
0
                                        htons((uint16_t) nh->ip_tos),
174
0
                                        htons((uint16_t) new_tos));
175
0
            nh->ip_tos = new_tos;
176
0
        }
177
0
    }
178
179
0
    if (OVS_LIKELY(mask->ipv4_ttl)) {
180
0
        new_ttl = key->ipv4_ttl | (nh->ip_ttl & ~mask->ipv4_ttl);
181
182
0
        if (OVS_LIKELY(nh->ip_ttl != new_ttl)) {
183
0
            nh->ip_csum = recalc_csum16(nh->ip_csum, htons(nh->ip_ttl << 8),
184
0
                                        htons(new_ttl << 8));
185
0
            nh->ip_ttl = new_ttl;
186
0
        }
187
0
    }
188
0
}
189
190
static struct in6_addr *
191
mask_ipv6_addr(const ovs_16aligned_be32 *old, const struct in6_addr *addr,
192
               const struct in6_addr *mask, struct in6_addr *masked)
193
0
{
194
0
#ifdef s6_addr32
195
0
    for (int i = 0; i < 4; i++) {
196
0
        masked->s6_addr32[i] = addr->s6_addr32[i]
197
0
            | (get_16aligned_be32(&old[i]) & ~mask->s6_addr32[i]);
198
0
    }
199
#else
200
    const uint8_t *old8 = (const uint8_t *)old;
201
    for (int i = 0; i < 16; i++) {
202
        masked->s6_addr[i] = addr->s6_addr[i] | (old8[i] & ~mask->s6_addr[i]);
203
    }
204
#endif
205
0
    return masked;
206
0
}
207
208
static void
209
odp_set_ipv6(struct dp_packet *packet, const struct ovs_key_ipv6 *key,
210
             const struct ovs_key_ipv6 *mask)
211
0
{
212
0
    struct ovs_16aligned_ip6_hdr *nh = dp_packet_l3(packet);
213
0
    struct in6_addr sbuf, dbuf;
214
0
    uint8_t old_tc = ntohl(get_16aligned_be32(&nh->ip6_flow)) >> 20;
215
0
    ovs_be32 old_fl = get_16aligned_be32(&nh->ip6_flow) & htonl(0xfffff);
216
217
0
    packet_set_ipv6(
218
0
        packet,
219
0
        mask_ipv6_addr(nh->ip6_src.be32, &key->ipv6_src, &mask->ipv6_src,
220
0
                       &sbuf),
221
0
        mask_ipv6_addr(nh->ip6_dst.be32, &key->ipv6_dst, &mask->ipv6_dst,
222
0
                       &dbuf),
223
0
        key->ipv6_tclass | (old_tc & ~mask->ipv6_tclass),
224
0
        key->ipv6_label | (old_fl & ~mask->ipv6_label),
225
0
        key->ipv6_hlimit | (nh->ip6_hlim & ~mask->ipv6_hlimit));
226
0
}
227
228
static void
229
odp_set_tcp(struct dp_packet *packet, const struct ovs_key_tcp *key,
230
             const struct ovs_key_tcp *mask)
231
0
{
232
0
    struct tcp_header *th = dp_packet_l4(packet);
233
234
0
    if (OVS_LIKELY(th && dp_packet_get_tcp_payload(packet))) {
235
0
        packet_set_tcp_port(packet,
236
0
                            key->tcp_src | (th->tcp_src & ~mask->tcp_src),
237
0
                            key->tcp_dst | (th->tcp_dst & ~mask->tcp_dst));
238
0
    }
239
0
}
240
241
static void
242
odp_set_udp(struct dp_packet *packet, const struct ovs_key_udp *key,
243
             const struct ovs_key_udp *mask)
244
0
{
245
0
    struct udp_header *uh = dp_packet_l4(packet);
246
247
0
    if (OVS_LIKELY(uh && dp_packet_get_udp_payload(packet))) {
248
0
        packet_set_udp_port(packet,
249
0
                            key->udp_src | (uh->udp_src & ~mask->udp_src),
250
0
                            key->udp_dst | (uh->udp_dst & ~mask->udp_dst));
251
0
    }
252
0
}
253
254
static void
255
odp_set_sctp(struct dp_packet *packet, const struct ovs_key_sctp *key,
256
             const struct ovs_key_sctp *mask)
257
0
{
258
0
    struct sctp_header *sh = dp_packet_l4(packet);
259
260
0
    if (OVS_LIKELY(sh && dp_packet_get_sctp_payload(packet))) {
261
0
        packet_set_sctp_port(packet,
262
0
                             key->sctp_src | (sh->sctp_src & ~mask->sctp_src),
263
0
                             key->sctp_dst | (sh->sctp_dst & ~mask->sctp_dst));
264
0
    }
265
0
}
266
267
static void
268
odp_set_tunnel_action(const struct nlattr *a, struct flow_tnl *tun_key)
269
0
{
270
0
    ovs_assert(odp_tun_key_from_attr(a, tun_key, NULL) != ODP_FIT_ERROR);
271
0
}
272
273
static void
274
set_arp(struct dp_packet *packet, const struct ovs_key_arp *key,
275
        const struct ovs_key_arp *mask)
276
0
{
277
0
    struct arp_eth_header *arp = dp_packet_l3(packet);
278
279
0
    if (!mask) {
280
0
        arp->ar_op = key->arp_op;
281
0
        arp->ar_sha = key->arp_sha;
282
0
        put_16aligned_be32(&arp->ar_spa, key->arp_sip);
283
0
        arp->ar_tha = key->arp_tha;
284
0
        put_16aligned_be32(&arp->ar_tpa, key->arp_tip);
285
0
    } else {
286
0
        ovs_be32 ar_spa = get_16aligned_be32(&arp->ar_spa);
287
0
        ovs_be32 ar_tpa = get_16aligned_be32(&arp->ar_tpa);
288
289
0
        arp->ar_op = key->arp_op | (arp->ar_op & ~mask->arp_op);
290
0
        ether_addr_copy_masked(&arp->ar_sha, key->arp_sha, mask->arp_sha);
291
0
        put_16aligned_be32(&arp->ar_spa,
292
0
                           key->arp_sip | (ar_spa & ~mask->arp_sip));
293
0
        ether_addr_copy_masked(&arp->ar_tha, key->arp_tha, mask->arp_tha);
294
0
        put_16aligned_be32(&arp->ar_tpa,
295
0
                           key->arp_tip | (ar_tpa & ~mask->arp_tip));
296
0
    }
297
0
}
298
299
static void
300
odp_set_nd_ext(struct dp_packet *packet, const struct ovs_key_nd_extensions
301
        *key, const struct ovs_key_nd_extensions *mask)
302
0
{
303
0
    const struct ovs_nd_msg *ns = dp_packet_l4(packet);
304
0
    ovs_16aligned_be32 reserved = ns->rso_flags;
305
0
    uint8_t opt_type = ns->options[0].type;
306
307
0
    if (mask->nd_reserved) {
308
0
        put_16aligned_be32(&reserved, key->nd_reserved);
309
0
    }
310
0
    if (mask->nd_options_type) {
311
0
        opt_type = key->nd_options_type;
312
0
    }
313
0
    packet_set_nd_ext(packet, reserved, opt_type);
314
0
}
315
316
static void
317
odp_set_nd(struct dp_packet *packet, const struct ovs_key_nd *key,
318
           const struct ovs_key_nd *mask)
319
0
{
320
0
    const struct ovs_nd_msg *ns = dp_packet_l4(packet);
321
0
    const struct ovs_nd_lla_opt *lla_opt = dp_packet_get_nd_payload(packet);
322
323
0
    if (OVS_LIKELY(ns && lla_opt)) {
324
0
        int bytes_remain = dp_packet_l4_size(packet) - sizeof(*ns);
325
0
        struct in6_addr tgt_buf;
326
0
        struct eth_addr sll_buf = eth_addr_zero;
327
0
        struct eth_addr tll_buf = eth_addr_zero;
328
329
0
        while (bytes_remain >= ND_LLA_OPT_LEN && lla_opt->len != 0) {
330
0
            if (lla_opt->type == ND_OPT_SOURCE_LINKADDR
331
0
                && lla_opt->len == 1) {
332
0
                sll_buf = lla_opt->mac;
333
0
                ether_addr_copy_masked(&sll_buf, key->nd_sll, mask->nd_sll);
334
335
                /* A packet can only contain one SLL or TLL option */
336
0
                break;
337
0
            } else if (lla_opt->type == ND_OPT_TARGET_LINKADDR
338
0
                       && lla_opt->len == 1) {
339
0
                tll_buf = lla_opt->mac;
340
0
                ether_addr_copy_masked(&tll_buf, key->nd_tll, mask->nd_tll);
341
342
                /* A packet can only contain one SLL or TLL option */
343
0
                break;
344
0
            }
345
346
0
            lla_opt += lla_opt->len;
347
0
            bytes_remain -= lla_opt->len * ND_LLA_OPT_LEN;
348
0
        }
349
350
0
        packet_set_nd(packet,
351
0
                      mask_ipv6_addr(ns->target.be32, &key->nd_target,
352
0
                                     &mask->nd_target, &tgt_buf),
353
0
                      sll_buf,
354
0
                      tll_buf);
355
0
    }
356
0
}
357
358
/* Set the NSH header. Assumes the NSH header is present and matches the
359
 * MD format of the key. The slow path must take case of that. */
360
static void
361
odp_set_nsh(struct dp_packet *packet, const struct nlattr *a, bool has_mask)
362
0
{
363
0
    struct ovs_key_nsh key, mask;
364
0
    struct nsh_hdr *nsh = dp_packet_l3(packet);
365
0
    uint8_t mdtype = nsh_md_type(nsh);
366
0
    ovs_be32 path_hdr;
367
368
0
    if (has_mask) {
369
0
        odp_nsh_key_from_attr(a, &key, &mask, NULL);
370
0
    } else {
371
0
        odp_nsh_key_from_attr(a, &key, NULL, NULL);
372
0
    }
373
374
0
    if (!has_mask) {
375
0
        nsh_set_flags_and_ttl(nsh, key.flags, key.ttl);
376
0
        put_16aligned_be32(&nsh->path_hdr, key.path_hdr);
377
0
        switch (mdtype) {
378
0
            case NSH_M_TYPE1:
379
0
                for (int i = 0; i < 4; i++) {
380
0
                    put_16aligned_be32(&nsh->md1.context[i], key.context[i]);
381
0
                }
382
0
                break;
383
0
            case NSH_M_TYPE2:
384
0
            default:
385
                /* No support for setting any other metadata format yet. */
386
0
                break;
387
0
        }
388
0
    } else {
389
0
        uint8_t flags = nsh_get_flags(nsh);
390
0
        uint8_t ttl = nsh_get_ttl(nsh);
391
392
0
        flags = key.flags | (flags & ~mask.flags);
393
0
        ttl = key.ttl | (ttl & ~mask.ttl);
394
0
        nsh_set_flags_and_ttl(nsh, flags, ttl);
395
396
0
        uint32_t spi = ntohl(nsh_get_spi(nsh));
397
0
        uint8_t si = nsh_get_si(nsh);
398
0
        uint32_t spi_mask = nsh_path_hdr_to_spi_uint32(mask.path_hdr);
399
0
        uint8_t si_mask = nsh_path_hdr_to_si(mask.path_hdr);
400
0
        if (spi_mask == 0x00ffffff) {
401
0
            spi_mask = UINT32_MAX;
402
0
        }
403
0
        spi = nsh_path_hdr_to_spi_uint32(key.path_hdr) | (spi & ~spi_mask);
404
0
        si = nsh_path_hdr_to_si(key.path_hdr) | (si & ~si_mask);
405
0
        path_hdr = nsh_get_path_hdr(nsh);
406
0
        nsh_path_hdr_set_spi(&path_hdr, htonl(spi));
407
0
        nsh_path_hdr_set_si(&path_hdr, si);
408
0
        put_16aligned_be32(&nsh->path_hdr, path_hdr);
409
0
        switch (mdtype) {
410
0
            case NSH_M_TYPE1:
411
0
                for (int i = 0; i < 4; i++) {
412
0
                    ovs_be32 p = get_16aligned_be32(&nsh->md1.context[i]);
413
0
                    ovs_be32 k = key.context[i];
414
0
                    ovs_be32 m = mask.context[i];
415
0
                    put_16aligned_be32(&nsh->md1.context[i], k | (p & ~m));
416
0
                }
417
0
                break;
418
0
            case NSH_M_TYPE2:
419
0
            default:
420
                /* No support for setting any other metadata format yet. */
421
0
                break;
422
0
        }
423
0
    }
424
0
}
425
426
static void
427
odp_execute_set_action(struct dp_packet *packet, const struct nlattr *a)
428
0
{
429
0
    enum ovs_key_attr type = nl_attr_type(a);
430
0
    const struct ovs_key_ipv4 *ipv4_key;
431
0
    const struct ovs_key_ipv6 *ipv6_key;
432
0
    struct pkt_metadata *md = &packet->md;
433
434
0
    switch (type) {
435
0
    case OVS_KEY_ATTR_PRIORITY:
436
0
        md->skb_priority = nl_attr_get_u32(a);
437
0
        break;
438
439
0
    case OVS_KEY_ATTR_TUNNEL:
440
0
        odp_set_tunnel_action(a, &md->tunnel);
441
0
        break;
442
443
0
    case OVS_KEY_ATTR_SKB_MARK:
444
0
        md->pkt_mark = nl_attr_get_u32(a);
445
0
        break;
446
447
0
    case OVS_KEY_ATTR_ETHERNET:
448
0
        odp_eth_set_addrs(packet, nl_attr_get(a), NULL);
449
0
        break;
450
451
0
    case OVS_KEY_ATTR_NSH: {
452
0
        odp_set_nsh(packet, a, false);
453
0
        break;
454
0
    }
455
456
0
    case OVS_KEY_ATTR_IPV4:
457
0
        ipv4_key = nl_attr_get_unspec(a, sizeof(struct ovs_key_ipv4));
458
0
        packet_set_ipv4(packet, ipv4_key->ipv4_src,
459
0
                        ipv4_key->ipv4_dst, ipv4_key->ipv4_tos,
460
0
                        ipv4_key->ipv4_ttl);
461
0
        break;
462
463
0
    case OVS_KEY_ATTR_IPV6:
464
0
        ipv6_key = nl_attr_get_unspec(a, sizeof(struct ovs_key_ipv6));
465
0
        packet_set_ipv6(packet, &ipv6_key->ipv6_src, &ipv6_key->ipv6_dst,
466
0
                        ipv6_key->ipv6_tclass, ipv6_key->ipv6_label,
467
0
                        ipv6_key->ipv6_hlimit);
468
0
        break;
469
470
0
    case OVS_KEY_ATTR_TCP:
471
0
        if (OVS_LIKELY(dp_packet_get_tcp_payload(packet))) {
472
0
            const struct ovs_key_tcp *tcp_key
473
0
                = nl_attr_get_unspec(a, sizeof(struct ovs_key_tcp));
474
475
0
            packet_set_tcp_port(packet, tcp_key->tcp_src,
476
0
                                tcp_key->tcp_dst);
477
0
        }
478
0
        break;
479
480
0
    case OVS_KEY_ATTR_UDP:
481
0
        if (OVS_LIKELY(dp_packet_get_udp_payload(packet))) {
482
0
            const struct ovs_key_udp *udp_key
483
0
                = nl_attr_get_unspec(a, sizeof(struct ovs_key_udp));
484
485
0
            packet_set_udp_port(packet, udp_key->udp_src,
486
0
                                udp_key->udp_dst);
487
0
        }
488
0
        break;
489
490
0
    case OVS_KEY_ATTR_SCTP:
491
0
        if (OVS_LIKELY(dp_packet_get_sctp_payload(packet))) {
492
0
            const struct ovs_key_sctp *sctp_key
493
0
                = nl_attr_get_unspec(a, sizeof(struct ovs_key_sctp));
494
495
0
            packet_set_sctp_port(packet, sctp_key->sctp_src,
496
0
                                 sctp_key->sctp_dst);
497
0
        }
498
0
        break;
499
500
0
    case OVS_KEY_ATTR_MPLS:
501
0
        set_mpls_lse(packet, nl_attr_get_be32(a));
502
0
        break;
503
504
0
    case OVS_KEY_ATTR_ARP:
505
0
        set_arp(packet, nl_attr_get(a), NULL);
506
0
        break;
507
508
0
    case OVS_KEY_ATTR_ICMP:
509
0
    case OVS_KEY_ATTR_ICMPV6:
510
0
        if (OVS_LIKELY(dp_packet_get_icmp_payload(packet))) {
511
0
            const struct ovs_key_icmp *icmp_key
512
0
                = nl_attr_get_unspec(a, sizeof(struct ovs_key_icmp));
513
514
0
            packet_set_icmp(packet, icmp_key->icmp_type, icmp_key->icmp_code);
515
0
        }
516
0
        break;
517
518
0
    case OVS_KEY_ATTR_ND:
519
0
        if (OVS_LIKELY(dp_packet_get_nd_payload(packet))) {
520
0
            const struct ovs_key_nd *nd_key
521
0
                   = nl_attr_get_unspec(a, sizeof(struct ovs_key_nd));
522
0
            packet_set_nd(packet, &nd_key->nd_target, nd_key->nd_sll,
523
0
                          nd_key->nd_tll);
524
0
        }
525
0
        break;
526
527
0
    case OVS_KEY_ATTR_ND_EXTENSIONS:
528
0
        if (OVS_LIKELY(dp_packet_get_nd_payload(packet))) {
529
0
            const struct ovs_key_nd_extensions *nd_ext_key
530
0
                 = nl_attr_get_unspec(a, sizeof(struct ovs_key_nd_extensions));
531
0
            ovs_16aligned_be32 rso_flags;
532
0
            put_16aligned_be32(&rso_flags, nd_ext_key->nd_reserved);
533
0
            packet_set_nd_ext(packet, rso_flags, nd_ext_key->nd_options_type);
534
0
        }
535
0
        break;
536
537
0
    case OVS_KEY_ATTR_DP_HASH:
538
0
        md->dp_hash = nl_attr_get_u32(a);
539
0
        break;
540
541
0
    case OVS_KEY_ATTR_RECIRC_ID:
542
0
        md->recirc_id = nl_attr_get_u32(a);
543
0
        break;
544
545
0
    case OVS_KEY_ATTR_UNSPEC:
546
0
    case OVS_KEY_ATTR_PACKET_TYPE:
547
0
    case OVS_KEY_ATTR_ENCAP:
548
0
    case OVS_KEY_ATTR_ETHERTYPE:
549
0
    case OVS_KEY_ATTR_IN_PORT:
550
0
    case OVS_KEY_ATTR_VLAN:
551
0
    case OVS_KEY_ATTR_TCP_FLAGS:
552
0
    case OVS_KEY_ATTR_CT_STATE:
553
0
    case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4:
554
0
    case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6:
555
0
    case OVS_KEY_ATTR_CT_ZONE:
556
0
    case OVS_KEY_ATTR_CT_MARK:
557
0
    case OVS_KEY_ATTR_CT_LABELS:
558
0
    case OVS_KEY_ATTR_TUNNEL_INFO:
559
0
    case __OVS_KEY_ATTR_MAX:
560
0
    default:
561
0
        OVS_NOT_REACHED();
562
0
    }
563
0
}
564
565
static void
566
odp_execute_masked_set_action(struct dp_packet *packet,
567
                              const struct nlattr *a)
568
0
{
569
0
    struct pkt_metadata *md = &packet->md;
570
0
    enum ovs_key_attr type = nl_attr_type(a);
571
0
    struct mpls_hdr *mh;
572
573
0
    switch (type) {
574
0
    case OVS_KEY_ATTR_PRIORITY:
575
0
        md->skb_priority = nl_attr_get_u32(a)
576
0
            | (md->skb_priority & ~*odp_get_key_mask(a, uint32_t));
577
0
        break;
578
579
0
    case OVS_KEY_ATTR_SKB_MARK:
580
0
        md->pkt_mark = nl_attr_get_u32(a)
581
0
            | (md->pkt_mark & ~*odp_get_key_mask(a, uint32_t));
582
0
        break;
583
584
0
    case OVS_KEY_ATTR_ETHERNET:
585
0
        odp_eth_set_addrs(packet, nl_attr_get(a),
586
0
                          odp_get_key_mask(a, struct ovs_key_ethernet));
587
0
        break;
588
589
0
    case OVS_KEY_ATTR_NSH: {
590
0
        odp_set_nsh(packet, a, true);
591
0
        break;
592
0
    }
593
594
0
    case OVS_KEY_ATTR_IPV4:
595
0
        odp_set_ipv4(packet, nl_attr_get(a),
596
0
                     odp_get_key_mask(a, struct ovs_key_ipv4));
597
0
        break;
598
599
0
    case OVS_KEY_ATTR_IPV6:
600
0
        odp_set_ipv6(packet, nl_attr_get(a),
601
0
                     odp_get_key_mask(a, struct ovs_key_ipv6));
602
0
        break;
603
604
0
    case OVS_KEY_ATTR_TCP:
605
0
        odp_set_tcp(packet, nl_attr_get(a),
606
0
                    odp_get_key_mask(a, struct ovs_key_tcp));
607
0
        break;
608
609
0
    case OVS_KEY_ATTR_UDP:
610
0
        odp_set_udp(packet, nl_attr_get(a),
611
0
                    odp_get_key_mask(a, struct ovs_key_udp));
612
0
        break;
613
614
0
    case OVS_KEY_ATTR_SCTP:
615
0
        odp_set_sctp(packet, nl_attr_get(a),
616
0
                     odp_get_key_mask(a, struct ovs_key_sctp));
617
0
        break;
618
619
0
    case OVS_KEY_ATTR_MPLS:
620
0
        mh = dp_packet_l2_5(packet);
621
0
        if (mh) {
622
0
            put_16aligned_be32(&mh->mpls_lse, nl_attr_get_be32(a)
623
0
                               | (get_16aligned_be32(&mh->mpls_lse)
624
0
                                  & ~*odp_get_key_mask(a, ovs_be32)));
625
0
        }
626
0
        break;
627
628
0
    case OVS_KEY_ATTR_ARP:
629
0
        set_arp(packet, nl_attr_get(a),
630
0
                odp_get_key_mask(a, struct ovs_key_arp));
631
0
        break;
632
633
0
    case OVS_KEY_ATTR_ND:
634
0
        odp_set_nd(packet, nl_attr_get(a),
635
0
                   odp_get_key_mask(a, struct ovs_key_nd));
636
0
        break;
637
638
0
    case OVS_KEY_ATTR_ND_EXTENSIONS:
639
0
        odp_set_nd_ext(packet, nl_attr_get(a),
640
0
                       odp_get_key_mask(a, struct ovs_key_nd_extensions));
641
0
        break;
642
643
0
    case OVS_KEY_ATTR_DP_HASH:
644
0
        md->dp_hash = nl_attr_get_u32(a)
645
0
            | (md->dp_hash & ~*odp_get_key_mask(a, uint32_t));
646
0
        break;
647
648
0
    case OVS_KEY_ATTR_RECIRC_ID:
649
0
        md->recirc_id = nl_attr_get_u32(a)
650
0
            | (md->recirc_id & ~*odp_get_key_mask(a, uint32_t));
651
0
        break;
652
653
0
    case OVS_KEY_ATTR_TUNNEL:    /* Masked data not supported for tunnel. */
654
0
    case OVS_KEY_ATTR_PACKET_TYPE:
655
0
    case OVS_KEY_ATTR_UNSPEC:
656
0
    case OVS_KEY_ATTR_CT_STATE:
657
0
    case OVS_KEY_ATTR_CT_ZONE:
658
0
    case OVS_KEY_ATTR_CT_MARK:
659
0
    case OVS_KEY_ATTR_CT_LABELS:
660
0
    case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4:
661
0
    case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6:
662
0
    case OVS_KEY_ATTR_ENCAP:
663
0
    case OVS_KEY_ATTR_ETHERTYPE:
664
0
    case OVS_KEY_ATTR_IN_PORT:
665
0
    case OVS_KEY_ATTR_VLAN:
666
0
    case OVS_KEY_ATTR_ICMP:
667
0
    case OVS_KEY_ATTR_ICMPV6:
668
0
    case OVS_KEY_ATTR_TCP_FLAGS:
669
0
    case OVS_KEY_ATTR_TUNNEL_INFO:
670
0
    case __OVS_KEY_ATTR_MAX:
671
0
    default:
672
0
        OVS_NOT_REACHED();
673
0
    }
674
0
}
675
676
static void
677
odp_execute_sample(void *dp, struct dp_packet *packet, bool steal,
678
                   const struct nlattr *action,
679
                   odp_execute_cb dp_execute_action)
680
0
{
681
0
    const struct nlattr *subactions = NULL;
682
0
    const struct nlattr *a;
683
0
    struct dp_packet_batch pb;
684
0
    size_t left;
685
686
0
    NL_NESTED_FOR_EACH_UNSAFE (a, left, action) {
687
0
        int type = nl_attr_type(a);
688
689
0
        switch ((enum ovs_sample_attr) type) {
690
0
        case OVS_SAMPLE_ATTR_PROBABILITY:
691
0
            if (random_uint32() >= nl_attr_get_u32(a)) {
692
0
                if (steal) {
693
0
                    COVERAGE_INC(datapath_drop_sample_error);
694
0
                    dp_packet_delete(packet);
695
0
                }
696
0
                return;
697
0
            }
698
0
            break;
699
700
0
        case OVS_SAMPLE_ATTR_ACTIONS:
701
0
            subactions = a;
702
0
            break;
703
704
0
        case OVS_SAMPLE_ATTR_UNSPEC:
705
0
        case __OVS_SAMPLE_ATTR_MAX:
706
0
        default:
707
0
            OVS_NOT_REACHED();
708
0
        }
709
0
    }
710
711
0
    if (!steal) {
712
        /* The 'subactions' may modify the packet, but the modification
713
         * should not propagate beyond this sample action. Make a copy
714
         * the packet in case we don't own the packet, so that the
715
         * 'subactions' are only applid to the clone.  'odp_execute_actions'
716
         * will free the clone.  */
717
0
        packet = dp_packet_clone(packet);
718
0
    }
719
0
    dp_packet_batch_init_packet(&pb, packet);
720
0
    odp_execute_actions(dp, &pb, true, nl_attr_get(subactions),
721
0
                        nl_attr_get_size(subactions), dp_execute_action);
722
0
}
723
724
static void
725
odp_execute_clone(void *dp, struct dp_packet_batch *batch, bool steal,
726
                   const struct nlattr *actions,
727
                   odp_execute_cb dp_execute_action)
728
0
{
729
0
    if (!steal) {
730
        /* The 'actions' may modify the packet, but the modification
731
         * should not propagate beyond this clone action. Make a copy
732
         * the packet in case we don't own the packet, so that the
733
         * 'actions' are only applied to the clone.  'odp_execute_actions'
734
         * will free the clone.  */
735
0
        struct dp_packet_batch clone_pkt_batch;
736
0
        dp_packet_batch_clone(&clone_pkt_batch, batch);
737
0
        dp_packet_batch_reset_cutlen(batch);
738
0
        odp_execute_actions(dp, &clone_pkt_batch, true, nl_attr_get(actions),
739
0
                        nl_attr_get_size(actions), dp_execute_action);
740
0
    }
741
0
    else {
742
0
        odp_execute_actions(dp, batch, true, nl_attr_get(actions),
743
0
                            nl_attr_get_size(actions), dp_execute_action);
744
0
    }
745
0
}
746
747
static void
748
odp_execute_check_pkt_len(void *dp, struct dp_packet *packet, bool steal,
749
                          const struct nlattr *action,
750
                          odp_execute_cb dp_execute_action)
751
0
{
752
0
    static const struct nl_policy ovs_cpl_policy[] = {
753
0
        [OVS_CHECK_PKT_LEN_ATTR_PKT_LEN] = { .type = NL_A_U16 },
754
0
        [OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER] = { .type = NL_A_NESTED },
755
0
        [OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL]
756
0
            = { .type = NL_A_NESTED },
757
0
    };
758
0
    struct nlattr *attrs[ARRAY_SIZE(ovs_cpl_policy)];
759
760
0
    if (!nl_parse_nested(action, ovs_cpl_policy, attrs, ARRAY_SIZE(attrs))) {
761
0
        OVS_NOT_REACHED();
762
0
    }
763
764
0
    const struct nlattr *a;
765
0
    struct dp_packet_batch pb;
766
0
    uint32_t size = dp_packet_get_send_len(packet)
767
0
                    - dp_packet_l2_pad_size(packet);
768
769
0
    a = attrs[OVS_CHECK_PKT_LEN_ATTR_PKT_LEN];
770
0
    if (size > nl_attr_get_u16(a)) {
771
0
        a = attrs[OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER];
772
0
    } else {
773
0
        a = attrs[OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL];
774
0
    }
775
776
0
    if (!steal) {
777
        /* The 'subactions' may modify the packet, but the modification
778
         * should not propagate beyond this action. Make a copy
779
         * the packet in case we don't own the packet, so that the
780
         * 'subactions' are only applid to check_pkt_len. 'odp_execute_actions'
781
         * will free the clone.  */
782
0
        packet = dp_packet_clone(packet);
783
0
    }
784
    /* If nl_attr_get(a) is NULL, the packet will be freed by
785
     * odp_execute_actions. */
786
0
    dp_packet_batch_init_packet(&pb, packet);
787
0
    odp_execute_actions(dp, &pb, true, nl_attr_get(a), nl_attr_get_size(a),
788
0
                        dp_execute_action);
789
0
}
790
791
static bool
792
requires_datapath_assistance(const struct nlattr *a)
793
0
{
794
0
    enum ovs_action_attr type = nl_attr_type(a);
795
796
0
    switch (type) {
797
        /* These only make sense in the context of a datapath. */
798
0
    case OVS_ACTION_ATTR_OUTPUT:
799
0
    case OVS_ACTION_ATTR_LB_OUTPUT:
800
0
    case OVS_ACTION_ATTR_TUNNEL_PUSH:
801
0
    case OVS_ACTION_ATTR_TUNNEL_POP:
802
0
    case OVS_ACTION_ATTR_USERSPACE:
803
0
    case OVS_ACTION_ATTR_RECIRC:
804
0
    case OVS_ACTION_ATTR_CT:
805
0
    case OVS_ACTION_ATTR_METER:
806
0
        return true;
807
808
0
    case OVS_ACTION_ATTR_SET:
809
0
    case OVS_ACTION_ATTR_SET_MASKED:
810
0
    case OVS_ACTION_ATTR_PUSH_VLAN:
811
0
    case OVS_ACTION_ATTR_POP_VLAN:
812
0
    case OVS_ACTION_ATTR_SAMPLE:
813
0
    case OVS_ACTION_ATTR_HASH:
814
0
    case OVS_ACTION_ATTR_PUSH_MPLS:
815
0
    case OVS_ACTION_ATTR_POP_MPLS:
816
0
    case OVS_ACTION_ATTR_TRUNC:
817
0
    case OVS_ACTION_ATTR_PUSH_ETH:
818
0
    case OVS_ACTION_ATTR_POP_ETH:
819
0
    case OVS_ACTION_ATTR_CLONE:
820
0
    case OVS_ACTION_ATTR_PUSH_NSH:
821
0
    case OVS_ACTION_ATTR_POP_NSH:
822
0
    case OVS_ACTION_ATTR_CT_CLEAR:
823
0
    case OVS_ACTION_ATTR_CHECK_PKT_LEN:
824
0
    case OVS_ACTION_ATTR_ADD_MPLS:
825
0
    case OVS_ACTION_ATTR_DROP:
826
0
        return false;
827
828
0
    case OVS_ACTION_ATTR_UNSPEC:
829
0
    case __OVS_ACTION_ATTR_MAX:
830
0
        OVS_NOT_REACHED();
831
0
    }
832
833
0
    return false;
834
0
}
835
836
static void
837
action_pop_vlan(struct dp_packet_batch *batch,
838
                const struct nlattr *a OVS_UNUSED)
839
0
{
840
0
    struct dp_packet *packet;
841
842
0
    DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
843
0
        eth_pop_vlan(packet);
844
0
    }
845
0
}
846
847
static void
848
action_push_vlan(struct dp_packet_batch *batch, const struct nlattr *a)
849
0
{
850
0
    struct dp_packet *packet;
851
0
    const struct ovs_action_push_vlan *vlan = nl_attr_get(a);
852
853
0
    DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
854
0
        eth_push_vlan(packet, vlan->vlan_tpid, vlan->vlan_tci);
855
0
    }
856
0
}
857
858
static void
859
action_set_masked(struct dp_packet_batch *batch, const struct nlattr *a)
860
0
{
861
0
    const struct nlattr *key = nl_attr_get(a);
862
0
    struct dp_packet *packet;
863
864
0
    DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
865
0
        odp_execute_masked_set_action(packet, key);
866
0
    }
867
0
}
868
869
/* Implementation of the scalar actions impl init function. Build up the
870
 * array of func ptrs here. */
871
int
872
odp_action_scalar_init(struct odp_execute_action_impl *self)
873
0
{
874
    /* Set function pointers for actions that can be applied directly, these
875
     * are identified by OVS_ACTION_ATTR_*. */
876
0
    self->funcs[OVS_ACTION_ATTR_POP_VLAN] = action_pop_vlan;
877
0
    self->funcs[OVS_ACTION_ATTR_PUSH_VLAN] = action_push_vlan;
878
0
    self->funcs[OVS_ACTION_ATTR_SET_MASKED] = action_set_masked;
879
880
0
    return 0;
881
0
}
882
883
/* The active function pointers on the datapath. ISA optimized implementations
884
 * are enabled by plugging them into this static arary, which is consulted when
885
 * applying actions on the datapath. */
886
static ATOMIC(struct odp_execute_action_impl *) actions_active_impl;
887
888
static int
889
odp_actions_impl_set(const char *name)
890
0
{
891
0
    struct odp_execute_action_impl *active;
892
0
    active = odp_execute_action_set(name);
893
0
    if (!active) {
894
0
        VLOG_ERR("Failed setting action implementation to %s", name);
895
0
        return 1;
896
0
    }
897
898
0
    atomic_store_relaxed(&actions_active_impl, active);
899
0
    return 0;
900
0
}
901
902
static void
903
action_impl_set(struct unixctl_conn *conn, int argc OVS_UNUSED,
904
                const char *argv[], void *aux OVS_UNUSED)
905
0
{
906
0
    struct ds reply = DS_EMPTY_INITIALIZER;
907
908
0
    int err = odp_actions_impl_set(argv[1]);
909
0
    if (err) {
910
0
        ds_put_format(&reply,
911
0
                      "Error: unknown action implementation, %s, specified!",
912
0
                      argv[1]);
913
0
        unixctl_command_reply_error(conn, ds_cstr(&reply));
914
0
    } else {
915
0
        ds_put_format(&reply, "Action implementation set to %s.", argv[1]);
916
0
        unixctl_command_reply(conn, ds_cstr(&reply));
917
0
    }
918
919
0
    ds_destroy(&reply);
920
0
}
921
922
static void
923
action_impl_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
924
                const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
925
0
{
926
0
    struct ds reply = DS_EMPTY_INITIALIZER;
927
928
0
    odp_execute_action_get_info(&reply);
929
0
    unixctl_command_reply(conn, ds_cstr(&reply));
930
0
    ds_destroy(&reply);
931
0
}
932
933
static void
934
odp_execute_unixctl_init(void)
935
0
{
936
0
    unixctl_command_register("odp-execute/action-impl-set", "name",
937
0
                             1, 1, action_impl_set,
938
0
                             NULL);
939
0
    unixctl_command_register("odp-execute/action-impl-show", "",
940
0
                             0, 0, action_impl_show,
941
0
                             NULL);
942
0
}
943
944
void
945
odp_execute_init(void)
946
0
{
947
0
    static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
948
0
    if (ovsthread_once_start(&once)) {
949
0
        odp_execute_action_init();
950
#ifdef ACTIONS_AUTOVALIDATOR_DEFAULT
951
        odp_actions_impl_set("autovalidator");
952
#else
953
0
        odp_actions_impl_set("scalar");
954
0
#endif
955
0
        odp_execute_unixctl_init();
956
0
        ovsthread_once_done(&once);
957
0
    }
958
0
}
959
960
/* Executes all of the 'actions_len' bytes of datapath actions in 'actions' on
961
 * the packets in 'batch'.  If 'steal' is true, possibly modifies and
962
 * definitely free the packets in 'batch', otherwise leaves 'batch' unchanged.
963
 *
964
 * Some actions (e.g. output actions) can only be executed by a datapath.  This
965
 * function implements those actions by passing the action and the packets to
966
 * 'dp_execute_action' (along with 'dp').  If 'dp_execute_action' is passed a
967
 * true 'steal' parameter then it must definitely free the packets passed into
968
 * it.  The packet can be modified whether 'steal' is false or true.  If a
969
 * packet is removed from the batch, then the fate of the packet is determined
970
 * by the code that does this removal, irrespective of the value of 'steal'.
971
 * Otherwise, if the packet is not removed from the batch and 'steal' is false
972
 * then the packet could either be cloned or not. */
973
void
974
odp_execute_actions(void *dp, struct dp_packet_batch *batch, bool steal,
975
                    const struct nlattr *actions, size_t actions_len,
976
                    odp_execute_cb dp_execute_action)
977
0
{
978
0
    struct dp_packet *packet;
979
0
    const struct nlattr *a;
980
0
    unsigned int left;
981
982
0
    NL_ATTR_FOR_EACH_UNSAFE (a, left, actions, actions_len) {
983
0
        int type = nl_attr_type(a);
984
0
        enum ovs_action_attr attr_type = (enum ovs_action_attr) type;
985
0
        bool last_action = (left <= NLA_ALIGN(a->nla_len));
986
987
0
        if (requires_datapath_assistance(a)) {
988
0
            if (dp_execute_action) {
989
                /* Allow 'dp_execute_action' to steal the packet data if we do
990
                 * not need it any more. */
991
0
                bool should_steal = steal && last_action;
992
993
0
                dp_execute_action(dp, batch, a, should_steal);
994
995
0
                if (last_action || dp_packet_batch_is_empty(batch)) {
996
                    /* We do not need to free the packets.
997
                     * Either dp_execute_actions() has stolen them
998
                     * or the batch is freed due to errors. In either
999
                     * case we do not need to execute further actions.
1000
                     */
1001
0
                    return;
1002
0
                }
1003
0
            }
1004
0
            continue;
1005
0
        }
1006
1007
        /* If type is set in the active actions implementation, call the
1008
         * function-pointer and continue to the next action. */
1009
0
        if (attr_type <= OVS_ACTION_ATTR_MAX) {
1010
            /* Read the action implementation pointer atomically to avoid
1011
             * non-atomic read causing corruption if being written by another
1012
             * thread simultaneously. */
1013
0
            struct odp_execute_action_impl *actions_impl;
1014
0
            atomic_read_relaxed(&actions_active_impl, &actions_impl);
1015
1016
0
            if (actions_impl && actions_impl->funcs[attr_type]) {
1017
0
                actions_impl->funcs[attr_type](batch, a);
1018
0
                continue;
1019
0
            }
1020
0
        }
1021
1022
        /* If the action was not handled by the active function pointers above,
1023
         * process them by switching on the type below. */
1024
1025
0
        switch (attr_type) {
1026
0
        case OVS_ACTION_ATTR_HASH: {
1027
0
            const struct ovs_action_hash *hash_act = nl_attr_get(a);
1028
1029
            /* Calculate a hash value directly. This might not match the
1030
             * value computed by the datapath, but it is much less expensive,
1031
             * and the current use case (bonding) does not require a strict
1032
             * match to work properly. */
1033
0
            switch (hash_act->hash_alg) {
1034
0
            case OVS_HASH_ALG_L4: {
1035
0
                struct flow flow;
1036
0
                uint32_t hash;
1037
1038
0
                DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
1039
                    /* RSS hash can be used here instead of 5tuple for
1040
                     * performance reasons. */
1041
0
                    if (dp_packet_rss_valid(packet)) {
1042
0
                        hash = dp_packet_get_rss_hash(packet);
1043
0
                        hash = hash_int(hash, hash_act->hash_basis);
1044
0
                    } else {
1045
0
                        flow_extract(packet, &flow);
1046
0
                        hash = flow_hash_5tuple(&flow, hash_act->hash_basis);
1047
0
                    }
1048
0
                    packet->md.dp_hash = hash;
1049
0
                }
1050
0
                break;
1051
0
            }
1052
0
            case OVS_HASH_ALG_SYM_L4: {
1053
0
                struct flow flow;
1054
0
                uint32_t hash;
1055
1056
0
                DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
1057
0
                    flow_extract(packet, &flow);
1058
0
                    hash = flow_hash_symmetric_l3l4(&flow,
1059
0
                                                    hash_act->hash_basis,
1060
0
                                                    false);
1061
0
                    packet->md.dp_hash = hash;
1062
0
                }
1063
0
                break;
1064
0
            }
1065
0
            default:
1066
                /* Assert on unknown hash algorithm.  */
1067
0
                OVS_NOT_REACHED();
1068
0
            }
1069
0
            break;
1070
0
        }
1071
1072
0
        case OVS_ACTION_ATTR_PUSH_MPLS: {
1073
0
            const struct ovs_action_push_mpls *mpls = nl_attr_get(a);
1074
1075
0
            DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
1076
0
                push_mpls(packet, mpls->mpls_ethertype, mpls->mpls_lse);
1077
0
            }
1078
0
            break;
1079
0
         }
1080
1081
0
        case OVS_ACTION_ATTR_POP_MPLS:
1082
0
            DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
1083
0
                pop_mpls(packet, nl_attr_get_be16(a));
1084
0
            }
1085
0
            break;
1086
1087
0
        case OVS_ACTION_ATTR_SET:
1088
0
            DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
1089
0
                odp_execute_set_action(packet, nl_attr_get(a));
1090
0
            }
1091
0
            break;
1092
1093
0
        case OVS_ACTION_ATTR_SAMPLE:
1094
0
            DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
1095
0
                odp_execute_sample(dp, packet, steal && last_action, a,
1096
0
                                   dp_execute_action);
1097
0
            }
1098
1099
0
            if (last_action) {
1100
                /* We do not need to free the packets. odp_execute_sample() has
1101
                 * stolen them*/
1102
0
                return;
1103
0
            }
1104
0
            break;
1105
1106
0
        case OVS_ACTION_ATTR_TRUNC: {
1107
0
            const struct ovs_action_trunc *trunc =
1108
0
                        nl_attr_get_unspec(a, sizeof *trunc);
1109
1110
0
            batch->trunc = true;
1111
0
            DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
1112
0
                dp_packet_set_cutlen(packet, trunc->max_len);
1113
0
            }
1114
0
            break;
1115
0
        }
1116
1117
0
        case OVS_ACTION_ATTR_CLONE:
1118
0
            odp_execute_clone(dp, batch, steal && last_action, a,
1119
0
                                                dp_execute_action);
1120
0
            if (last_action) {
1121
                /* We do not need to free the packets. odp_execute_clone() has
1122
                 * stolen them.  */
1123
0
                return;
1124
0
            }
1125
0
            break;
1126
0
        case OVS_ACTION_ATTR_METER:
1127
            /* Not implemented yet. */
1128
0
            break;
1129
0
        case OVS_ACTION_ATTR_PUSH_ETH: {
1130
0
            const struct ovs_action_push_eth *eth = nl_attr_get(a);
1131
1132
0
            DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
1133
0
                push_eth(packet, &eth->addresses.eth_dst,
1134
0
                         &eth->addresses.eth_src);
1135
0
            }
1136
0
            break;
1137
0
        }
1138
1139
0
        case OVS_ACTION_ATTR_POP_ETH:
1140
0
            DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
1141
0
                pop_eth(packet);
1142
0
            }
1143
0
            break;
1144
1145
0
        case OVS_ACTION_ATTR_PUSH_NSH: {
1146
0
            uint32_t buffer[NSH_HDR_MAX_LEN / 4];
1147
0
            struct nsh_hdr *nsh_hdr = ALIGNED_CAST(struct nsh_hdr *, buffer);
1148
0
            nsh_reset_ver_flags_ttl_len(nsh_hdr);
1149
0
            odp_nsh_hdr_from_attr(nl_attr_get(a), nsh_hdr, NSH_HDR_MAX_LEN);
1150
0
            DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
1151
0
                push_nsh(packet, nsh_hdr);
1152
0
            }
1153
0
            break;
1154
0
        }
1155
0
        case OVS_ACTION_ATTR_POP_NSH: {
1156
0
            size_t i;
1157
0
            const size_t num = dp_packet_batch_size(batch);
1158
1159
0
            DP_PACKET_BATCH_REFILL_FOR_EACH (i, num, packet, batch) {
1160
0
                if (pop_nsh(packet)) {
1161
0
                    dp_packet_batch_refill(batch, packet, i);
1162
0
                } else {
1163
0
                    COVERAGE_INC(datapath_drop_nsh_decap_error);
1164
0
                    dp_packet_delete(packet);
1165
0
                }
1166
0
            }
1167
0
            break;
1168
0
        }
1169
0
        case OVS_ACTION_ATTR_CT_CLEAR:
1170
0
            DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
1171
0
                conntrack_clear(packet);
1172
0
            }
1173
0
            break;
1174
1175
0
        case OVS_ACTION_ATTR_CHECK_PKT_LEN:
1176
0
            DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
1177
0
                odp_execute_check_pkt_len(dp, packet, steal && last_action, a,
1178
0
                                          dp_execute_action);
1179
0
            }
1180
1181
0
            if (last_action) {
1182
                /* We do not need to free the packets.
1183
                 * odp_execute_check_pkt_len() has stolen them. */
1184
0
                return;
1185
0
            }
1186
0
            break;
1187
1188
0
        case OVS_ACTION_ATTR_ADD_MPLS: {
1189
0
            const struct ovs_action_add_mpls *mpls = nl_attr_get(a);
1190
0
            bool l3_flag =  mpls->tun_flags & OVS_MPLS_L3_TUNNEL_FLAG_MASK;
1191
1192
0
            DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
1193
0
                add_mpls(packet, mpls->mpls_ethertype, mpls->mpls_lse,
1194
0
                         l3_flag);
1195
0
            }
1196
0
            break;
1197
0
        }
1198
1199
0
        case OVS_ACTION_ATTR_DROP:{
1200
0
            const enum xlate_error *drop_reason = nl_attr_get(a);
1201
1202
0
            dp_update_drop_action_counter(*drop_reason,
1203
0
                                          dp_packet_batch_size(batch));
1204
0
            dp_packet_delete_batch(batch, steal);
1205
0
            return;
1206
0
        }
1207
0
        case OVS_ACTION_ATTR_OUTPUT:
1208
0
        case OVS_ACTION_ATTR_LB_OUTPUT:
1209
0
        case OVS_ACTION_ATTR_TUNNEL_PUSH:
1210
0
        case OVS_ACTION_ATTR_TUNNEL_POP:
1211
0
        case OVS_ACTION_ATTR_USERSPACE:
1212
0
        case OVS_ACTION_ATTR_RECIRC:
1213
0
        case OVS_ACTION_ATTR_CT:
1214
0
        case OVS_ACTION_ATTR_UNSPEC:
1215
0
        case __OVS_ACTION_ATTR_MAX:
1216
        /* The following actions are handled by the scalar implementation. */
1217
0
        case OVS_ACTION_ATTR_POP_VLAN:
1218
0
        case OVS_ACTION_ATTR_PUSH_VLAN:
1219
0
        case OVS_ACTION_ATTR_SET_MASKED:
1220
0
            OVS_NOT_REACHED();
1221
0
        }
1222
1223
        /* Do not add any generic processing here, as it won't be executed when
1224
         * an ISA-specific action implementation exists. */
1225
0
    }
1226
1227
0
    dp_packet_delete_batch(batch, steal);
1228
0
}