2 * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc.
3 * Copyright (c) 2013 Simon Horman
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include "odp-execute.h"
20 #include <arpa/inet.h>
21 #include <netinet/in.h>
22 #include <netinet/icmp6.h>
23 #include <netinet/ip6.h>
27 #include "dp-packet.h"
30 #include "odp-netlink.h"
34 #include "unaligned.h"
38 /* Masked copy of an ethernet address. 'src' is already properly masked. */
40 ether_addr_copy_masked(struct eth_addr
*dst
, const struct eth_addr src
,
41 const struct eth_addr mask
)
45 for (i
= 0; i
< ARRAY_SIZE(dst
->be16
); i
++) {
46 dst
->be16
[i
] = src
.be16
[i
] | (dst
->be16
[i
] & ~mask
.be16
[i
]);
51 odp_eth_set_addrs(struct dp_packet
*packet
, const struct ovs_key_ethernet
*key
,
52 const struct ovs_key_ethernet
*mask
)
54 struct eth_header
*eh
= dp_packet_eth(packet
);
58 eh
->eth_src
= key
->eth_src
;
59 eh
->eth_dst
= key
->eth_dst
;
61 ether_addr_copy_masked(&eh
->eth_src
, key
->eth_src
, mask
->eth_src
);
62 ether_addr_copy_masked(&eh
->eth_dst
, key
->eth_dst
, mask
->eth_dst
);
68 odp_set_ipv4(struct dp_packet
*packet
, const struct ovs_key_ipv4
*key
,
69 const struct ovs_key_ipv4
*mask
)
71 struct ip_header
*nh
= dp_packet_l3(packet
);
80 ip_src_nh
= get_16aligned_be32(&nh
->ip_src
);
81 new_ip_src
= key
->ipv4_src
| (ip_src_nh
& ~mask
->ipv4_src
);
83 if (ip_src_nh
!= new_ip_src
) {
84 packet_set_ipv4_addr(packet
, &nh
->ip_src
, new_ip_src
);
89 ip_dst_nh
= get_16aligned_be32(&nh
->ip_dst
);
90 new_ip_dst
= key
->ipv4_dst
| (ip_dst_nh
& ~mask
->ipv4_dst
);
92 if (ip_dst_nh
!= new_ip_dst
) {
93 packet_set_ipv4_addr(packet
, &nh
->ip_dst
, new_ip_dst
);
98 new_tos
= key
->ipv4_tos
| (nh
->ip_tos
& ~mask
->ipv4_tos
);
100 if (nh
->ip_tos
!= new_tos
) {
101 nh
->ip_csum
= recalc_csum16(nh
->ip_csum
,
102 htons((uint16_t) nh
->ip_tos
),
103 htons((uint16_t) new_tos
));
104 nh
->ip_tos
= new_tos
;
108 if (OVS_LIKELY(mask
->ipv4_ttl
)) {
109 new_ttl
= key
->ipv4_ttl
| (nh
->ip_ttl
& ~mask
->ipv4_ttl
);
111 if (OVS_LIKELY(nh
->ip_ttl
!= new_ttl
)) {
112 nh
->ip_csum
= recalc_csum16(nh
->ip_csum
, htons(nh
->ip_ttl
<< 8),
113 htons(new_ttl
<< 8));
114 nh
->ip_ttl
= new_ttl
;
119 static struct in6_addr
*
120 mask_ipv6_addr(const ovs_16aligned_be32
*old
, const struct in6_addr
*addr
,
121 const struct in6_addr
*mask
, struct in6_addr
*masked
)
124 for (int i
= 0; i
< 4; i
++) {
125 masked
->s6_addr32
[i
] = addr
->s6_addr32
[i
]
126 | (get_16aligned_be32(&old
[i
]) & ~mask
->s6_addr32
[i
]);
129 const uint8_t *old8
= (const uint8_t *)old
;
130 for (int i
= 0; i
< 16; i
++) {
131 masked
->s6_addr
[i
] = addr
->s6_addr
[i
] | (old8
[i
] & ~mask
->s6_addr
[i
]);
138 odp_set_ipv6(struct dp_packet
*packet
, const struct ovs_key_ipv6
*key
,
139 const struct ovs_key_ipv6
*mask
)
141 struct ovs_16aligned_ip6_hdr
*nh
= dp_packet_l3(packet
);
142 struct in6_addr sbuf
, dbuf
;
143 uint8_t old_tc
= ntohl(get_16aligned_be32(&nh
->ip6_flow
)) >> 20;
144 ovs_be32 old_fl
= get_16aligned_be32(&nh
->ip6_flow
) & htonl(0xfffff);
148 mask_ipv6_addr(nh
->ip6_src
.be32
, &key
->ipv6_src
, &mask
->ipv6_src
,
150 mask_ipv6_addr(nh
->ip6_dst
.be32
, &key
->ipv6_dst
, &mask
->ipv6_dst
,
152 key
->ipv6_tclass
| (old_tc
& ~mask
->ipv6_tclass
),
153 key
->ipv6_label
| (old_fl
& ~mask
->ipv6_label
),
154 key
->ipv6_hlimit
| (nh
->ip6_hlim
& ~mask
->ipv6_hlimit
));
158 odp_set_tcp(struct dp_packet
*packet
, const struct ovs_key_tcp
*key
,
159 const struct ovs_key_tcp
*mask
)
161 struct tcp_header
*th
= dp_packet_l4(packet
);
163 if (OVS_LIKELY(th
&& dp_packet_get_tcp_payload(packet
))) {
164 packet_set_tcp_port(packet
,
165 key
->tcp_src
| (th
->tcp_src
& ~mask
->tcp_src
),
166 key
->tcp_dst
| (th
->tcp_dst
& ~mask
->tcp_dst
));
171 odp_set_udp(struct dp_packet
*packet
, const struct ovs_key_udp
*key
,
172 const struct ovs_key_udp
*mask
)
174 struct udp_header
*uh
= dp_packet_l4(packet
);
176 if (OVS_LIKELY(uh
&& dp_packet_get_udp_payload(packet
))) {
177 packet_set_udp_port(packet
,
178 key
->udp_src
| (uh
->udp_src
& ~mask
->udp_src
),
179 key
->udp_dst
| (uh
->udp_dst
& ~mask
->udp_dst
));
184 odp_set_sctp(struct dp_packet
*packet
, const struct ovs_key_sctp
*key
,
185 const struct ovs_key_sctp
*mask
)
187 struct sctp_header
*sh
= dp_packet_l4(packet
);
189 if (OVS_LIKELY(sh
&& dp_packet_get_sctp_payload(packet
))) {
190 packet_set_sctp_port(packet
,
191 key
->sctp_src
| (sh
->sctp_src
& ~mask
->sctp_src
),
192 key
->sctp_dst
| (sh
->sctp_dst
& ~mask
->sctp_dst
));
197 odp_set_tunnel_action(const struct nlattr
*a
, struct flow_tnl
*tun_key
)
199 enum odp_key_fitness fitness
;
201 fitness
= odp_tun_key_from_attr(a
, tun_key
);
202 ovs_assert(fitness
!= ODP_FIT_ERROR
);
206 set_arp(struct dp_packet
*packet
, const struct ovs_key_arp
*key
,
207 const struct ovs_key_arp
*mask
)
209 struct arp_eth_header
*arp
= dp_packet_l3(packet
);
212 arp
->ar_op
= key
->arp_op
;
213 arp
->ar_sha
= key
->arp_sha
;
214 put_16aligned_be32(&arp
->ar_spa
, key
->arp_sip
);
215 arp
->ar_tha
= key
->arp_tha
;
216 put_16aligned_be32(&arp
->ar_tpa
, key
->arp_tip
);
218 ovs_be32 ar_spa
= get_16aligned_be32(&arp
->ar_spa
);
219 ovs_be32 ar_tpa
= get_16aligned_be32(&arp
->ar_tpa
);
221 arp
->ar_op
= key
->arp_op
| (arp
->ar_op
& ~mask
->arp_op
);
222 ether_addr_copy_masked(&arp
->ar_sha
, key
->arp_sha
, mask
->arp_sha
);
223 put_16aligned_be32(&arp
->ar_spa
,
224 key
->arp_sip
| (ar_spa
& ~mask
->arp_sip
));
225 ether_addr_copy_masked(&arp
->ar_tha
, key
->arp_tha
, mask
->arp_tha
);
226 put_16aligned_be32(&arp
->ar_tpa
,
227 key
->arp_tip
| (ar_tpa
& ~mask
->arp_tip
));
232 odp_set_nd(struct dp_packet
*packet
, const struct ovs_key_nd
*key
,
233 const struct ovs_key_nd
*mask
)
235 const struct ovs_nd_msg
*ns
= dp_packet_l4(packet
);
236 const struct ovs_nd_lla_opt
*lla_opt
= dp_packet_get_nd_payload(packet
);
238 if (OVS_LIKELY(ns
&& lla_opt
)) {
239 int bytes_remain
= dp_packet_l4_size(packet
) - sizeof(*ns
);
240 struct in6_addr tgt_buf
;
241 struct eth_addr sll_buf
= eth_addr_zero
;
242 struct eth_addr tll_buf
= eth_addr_zero
;
244 while (bytes_remain
>= ND_LLA_OPT_LEN
&& lla_opt
->len
!= 0) {
245 if (lla_opt
->type
== ND_OPT_SOURCE_LINKADDR
246 && lla_opt
->len
== 1) {
247 sll_buf
= lla_opt
->mac
;
248 ether_addr_copy_masked(&sll_buf
, key
->nd_sll
, mask
->nd_sll
);
250 /* A packet can only contain one SLL or TLL option */
252 } else if (lla_opt
->type
== ND_OPT_TARGET_LINKADDR
253 && lla_opt
->len
== 1) {
254 tll_buf
= lla_opt
->mac
;
255 ether_addr_copy_masked(&tll_buf
, key
->nd_tll
, mask
->nd_tll
);
257 /* A packet can only contain one SLL or TLL option */
261 lla_opt
+= lla_opt
->len
;
262 bytes_remain
-= lla_opt
->len
* ND_LLA_OPT_LEN
;
265 packet_set_nd(packet
,
266 mask_ipv6_addr(ns
->target
.be32
, &key
->nd_target
,
267 &mask
->nd_target
, &tgt_buf
),
273 /* Set the NSH header. Assumes the NSH header is present and matches the
274 * MD format of the key. The slow path must take case of that. */
276 odp_set_nsh(struct dp_packet
*packet
, const struct ovs_key_nsh
*key
,
277 const struct ovs_key_nsh
*mask
)
279 struct nsh_hdr
*nsh
= dp_packet_l3(packet
);
280 uint8_t mdtype
= nsh_md_type(nsh
);
283 nsh
->ver_flags_ttl_len
= htons(key
->flags
<< NSH_FLAGS_SHIFT
) |
284 (nsh
->ver_flags_ttl_len
& ~htons(NSH_FLAGS_MASK
));
285 put_16aligned_be32(&nsh
->path_hdr
, key
->path_hdr
);
288 for (int i
= 0; i
< 4; i
++) {
289 put_16aligned_be32(&nsh
->md1
.c
[i
], key
->c
[i
]);
294 /* No support for setting any other metadata format yet. */
298 uint8_t flags
= (ntohs(nsh
->ver_flags_ttl_len
) & NSH_FLAGS_MASK
) >>
300 flags
= key
->flags
| (flags
& ~mask
->flags
);
301 nsh
->ver_flags_ttl_len
= htons(flags
<< NSH_FLAGS_SHIFT
) |
302 (nsh
->ver_flags_ttl_len
& ~htons(NSH_FLAGS_MASK
));
304 ovs_be32 path_hdr
= get_16aligned_be32(&nsh
->path_hdr
);
305 path_hdr
= key
->path_hdr
| (path_hdr
& ~mask
->path_hdr
);
306 put_16aligned_be32(&nsh
->path_hdr
, path_hdr
);
309 for (int i
= 0; i
< 4; i
++) {
310 ovs_be32 p
= get_16aligned_be32(&nsh
->md1
.c
[i
]);
311 ovs_be32 k
= key
->c
[i
];
312 ovs_be32 m
= mask
->c
[i
];
313 put_16aligned_be32(&nsh
->md1
.c
[i
], k
| (p
& ~m
));
318 /* No support for setting any other metadata format yet. */
325 odp_execute_set_action(struct dp_packet
*packet
, const struct nlattr
*a
)
327 enum ovs_key_attr type
= nl_attr_type(a
);
328 const struct ovs_key_ipv4
*ipv4_key
;
329 const struct ovs_key_ipv6
*ipv6_key
;
330 struct pkt_metadata
*md
= &packet
->md
;
333 case OVS_KEY_ATTR_PRIORITY
:
334 md
->skb_priority
= nl_attr_get_u32(a
);
337 case OVS_KEY_ATTR_TUNNEL
:
338 odp_set_tunnel_action(a
, &md
->tunnel
);
341 case OVS_KEY_ATTR_SKB_MARK
:
342 md
->pkt_mark
= nl_attr_get_u32(a
);
345 case OVS_KEY_ATTR_ETHERNET
:
346 odp_eth_set_addrs(packet
, nl_attr_get(a
), NULL
);
349 case OVS_KEY_ATTR_NSH
:
350 odp_set_nsh(packet
, nl_attr_get(a
), NULL
);
353 case OVS_KEY_ATTR_IPV4
:
354 ipv4_key
= nl_attr_get_unspec(a
, sizeof(struct ovs_key_ipv4
));
355 packet_set_ipv4(packet
, ipv4_key
->ipv4_src
,
356 ipv4_key
->ipv4_dst
, ipv4_key
->ipv4_tos
,
360 case OVS_KEY_ATTR_IPV6
:
361 ipv6_key
= nl_attr_get_unspec(a
, sizeof(struct ovs_key_ipv6
));
362 packet_set_ipv6(packet
, &ipv6_key
->ipv6_src
, &ipv6_key
->ipv6_dst
,
363 ipv6_key
->ipv6_tclass
, ipv6_key
->ipv6_label
,
364 ipv6_key
->ipv6_hlimit
);
367 case OVS_KEY_ATTR_TCP
:
368 if (OVS_LIKELY(dp_packet_get_tcp_payload(packet
))) {
369 const struct ovs_key_tcp
*tcp_key
370 = nl_attr_get_unspec(a
, sizeof(struct ovs_key_tcp
));
372 packet_set_tcp_port(packet
, tcp_key
->tcp_src
,
377 case OVS_KEY_ATTR_UDP
:
378 if (OVS_LIKELY(dp_packet_get_udp_payload(packet
))) {
379 const struct ovs_key_udp
*udp_key
380 = nl_attr_get_unspec(a
, sizeof(struct ovs_key_udp
));
382 packet_set_udp_port(packet
, udp_key
->udp_src
,
387 case OVS_KEY_ATTR_SCTP
:
388 if (OVS_LIKELY(dp_packet_get_sctp_payload(packet
))) {
389 const struct ovs_key_sctp
*sctp_key
390 = nl_attr_get_unspec(a
, sizeof(struct ovs_key_sctp
));
392 packet_set_sctp_port(packet
, sctp_key
->sctp_src
,
397 case OVS_KEY_ATTR_MPLS
:
398 set_mpls_lse(packet
, nl_attr_get_be32(a
));
401 case OVS_KEY_ATTR_ARP
:
402 set_arp(packet
, nl_attr_get(a
), NULL
);
405 case OVS_KEY_ATTR_ICMP
:
406 case OVS_KEY_ATTR_ICMPV6
:
407 if (OVS_LIKELY(dp_packet_get_icmp_payload(packet
))) {
408 const struct ovs_key_icmp
*icmp_key
409 = nl_attr_get_unspec(a
, sizeof(struct ovs_key_icmp
));
411 packet_set_icmp(packet
, icmp_key
->icmp_type
, icmp_key
->icmp_code
);
415 case OVS_KEY_ATTR_ND
:
416 if (OVS_LIKELY(dp_packet_get_nd_payload(packet
))) {
417 const struct ovs_key_nd
*nd_key
418 = nl_attr_get_unspec(a
, sizeof(struct ovs_key_nd
));
419 packet_set_nd(packet
, &nd_key
->nd_target
, nd_key
->nd_sll
,
424 case OVS_KEY_ATTR_DP_HASH
:
425 md
->dp_hash
= nl_attr_get_u32(a
);
428 case OVS_KEY_ATTR_RECIRC_ID
:
429 md
->recirc_id
= nl_attr_get_u32(a
);
432 case OVS_KEY_ATTR_UNSPEC
:
433 case OVS_KEY_ATTR_PACKET_TYPE
:
434 case OVS_KEY_ATTR_ENCAP
:
435 case OVS_KEY_ATTR_ETHERTYPE
:
436 case OVS_KEY_ATTR_IN_PORT
:
437 case OVS_KEY_ATTR_VLAN
:
438 case OVS_KEY_ATTR_TCP_FLAGS
:
439 case OVS_KEY_ATTR_CT_STATE
:
440 case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4
:
441 case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6
:
442 case OVS_KEY_ATTR_CT_ZONE
:
443 case OVS_KEY_ATTR_CT_MARK
:
444 case OVS_KEY_ATTR_CT_LABELS
:
445 case __OVS_KEY_ATTR_MAX
:
451 #define get_mask(a, type) ((const type *)(const void *)(a + 1) + 1)
454 odp_execute_masked_set_action(struct dp_packet
*packet
,
455 const struct nlattr
*a
)
457 struct pkt_metadata
*md
= &packet
->md
;
458 enum ovs_key_attr type
= nl_attr_type(a
);
462 case OVS_KEY_ATTR_PRIORITY
:
463 md
->skb_priority
= nl_attr_get_u32(a
)
464 | (md
->skb_priority
& ~*get_mask(a
, uint32_t));
467 case OVS_KEY_ATTR_SKB_MARK
:
468 md
->pkt_mark
= nl_attr_get_u32(a
)
469 | (md
->pkt_mark
& ~*get_mask(a
, uint32_t));
472 case OVS_KEY_ATTR_ETHERNET
:
473 odp_eth_set_addrs(packet
, nl_attr_get(a
),
474 get_mask(a
, struct ovs_key_ethernet
));
477 case OVS_KEY_ATTR_NSH
:
478 odp_set_nsh(packet
, nl_attr_get(a
),
479 get_mask(a
, struct ovs_key_nsh
));
482 case OVS_KEY_ATTR_IPV4
:
483 odp_set_ipv4(packet
, nl_attr_get(a
),
484 get_mask(a
, struct ovs_key_ipv4
));
487 case OVS_KEY_ATTR_IPV6
:
488 odp_set_ipv6(packet
, nl_attr_get(a
),
489 get_mask(a
, struct ovs_key_ipv6
));
492 case OVS_KEY_ATTR_TCP
:
493 odp_set_tcp(packet
, nl_attr_get(a
),
494 get_mask(a
, struct ovs_key_tcp
));
497 case OVS_KEY_ATTR_UDP
:
498 odp_set_udp(packet
, nl_attr_get(a
),
499 get_mask(a
, struct ovs_key_udp
));
502 case OVS_KEY_ATTR_SCTP
:
503 odp_set_sctp(packet
, nl_attr_get(a
),
504 get_mask(a
, struct ovs_key_sctp
));
507 case OVS_KEY_ATTR_MPLS
:
508 mh
= dp_packet_l2_5(packet
);
510 put_16aligned_be32(&mh
->mpls_lse
, nl_attr_get_be32(a
)
511 | (get_16aligned_be32(&mh
->mpls_lse
)
512 & ~*get_mask(a
, ovs_be32
)));
516 case OVS_KEY_ATTR_ARP
:
517 set_arp(packet
, nl_attr_get(a
),
518 get_mask(a
, struct ovs_key_arp
));
521 case OVS_KEY_ATTR_ND
:
522 odp_set_nd(packet
, nl_attr_get(a
),
523 get_mask(a
, struct ovs_key_nd
));
526 case OVS_KEY_ATTR_DP_HASH
:
527 md
->dp_hash
= nl_attr_get_u32(a
)
528 | (md
->dp_hash
& ~*get_mask(a
, uint32_t));
531 case OVS_KEY_ATTR_RECIRC_ID
:
532 md
->recirc_id
= nl_attr_get_u32(a
)
533 | (md
->recirc_id
& ~*get_mask(a
, uint32_t));
536 case OVS_KEY_ATTR_TUNNEL
: /* Masked data not supported for tunnel. */
537 case OVS_KEY_ATTR_PACKET_TYPE
:
538 case OVS_KEY_ATTR_UNSPEC
:
539 case OVS_KEY_ATTR_CT_STATE
:
540 case OVS_KEY_ATTR_CT_ZONE
:
541 case OVS_KEY_ATTR_CT_MARK
:
542 case OVS_KEY_ATTR_CT_LABELS
:
543 case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4
:
544 case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6
:
545 case OVS_KEY_ATTR_ENCAP
:
546 case OVS_KEY_ATTR_ETHERTYPE
:
547 case OVS_KEY_ATTR_IN_PORT
:
548 case OVS_KEY_ATTR_VLAN
:
549 case OVS_KEY_ATTR_ICMP
:
550 case OVS_KEY_ATTR_ICMPV6
:
551 case OVS_KEY_ATTR_TCP_FLAGS
:
552 case __OVS_KEY_ATTR_MAX
:
559 odp_execute_sample(void *dp
, struct dp_packet
*packet
, bool steal
,
560 const struct nlattr
*action
,
561 odp_execute_cb dp_execute_action
)
563 const struct nlattr
*subactions
= NULL
;
564 const struct nlattr
*a
;
565 struct dp_packet_batch pb
;
568 NL_NESTED_FOR_EACH_UNSAFE (a
, left
, action
) {
569 int type
= nl_attr_type(a
);
571 switch ((enum ovs_sample_attr
) type
) {
572 case OVS_SAMPLE_ATTR_PROBABILITY
:
573 if (random_uint32() >= nl_attr_get_u32(a
)) {
575 dp_packet_delete(packet
);
581 case OVS_SAMPLE_ATTR_ACTIONS
:
585 case OVS_SAMPLE_ATTR_UNSPEC
:
586 case __OVS_SAMPLE_ATTR_MAX
:
593 /* The 'subactions' may modify the packet, but the modification
594 * should not propagate beyond this sample action. Make a copy
595 * the packet in case we don't own the packet, so that the
596 * 'subactions' are only applid to the clone. 'odp_execute_actions'
597 * will free the clone. */
598 packet
= dp_packet_clone(packet
);
600 dp_packet_batch_init_packet(&pb
, packet
);
601 odp_execute_actions(dp
, &pb
, true, nl_attr_get(subactions
),
602 nl_attr_get_size(subactions
), dp_execute_action
);
606 odp_execute_clone(void *dp
, struct dp_packet_batch
*batch
, bool steal
,
607 const struct nlattr
*actions
,
608 odp_execute_cb dp_execute_action
)
611 /* The 'actions' may modify the packet, but the modification
612 * should not propagate beyond this clone action. Make a copy
613 * the packet in case we don't own the packet, so that the
614 * 'actions' are only applied to the clone. 'odp_execute_actions'
615 * will free the clone. */
616 struct dp_packet_batch clone_pkt_batch
;
617 dp_packet_batch_clone(&clone_pkt_batch
, batch
);
618 dp_packet_batch_reset_cutlen(batch
);
619 odp_execute_actions(dp
, &clone_pkt_batch
, true, nl_attr_get(actions
),
620 nl_attr_get_size(actions
), dp_execute_action
);
623 odp_execute_actions(dp
, batch
, true, nl_attr_get(actions
),
624 nl_attr_get_size(actions
), dp_execute_action
);
629 requires_datapath_assistance(const struct nlattr
*a
)
631 enum ovs_action_attr type
= nl_attr_type(a
);
634 /* These only make sense in the context of a datapath. */
635 case OVS_ACTION_ATTR_OUTPUT
:
636 case OVS_ACTION_ATTR_TUNNEL_PUSH
:
637 case OVS_ACTION_ATTR_TUNNEL_POP
:
638 case OVS_ACTION_ATTR_USERSPACE
:
639 case OVS_ACTION_ATTR_RECIRC
:
640 case OVS_ACTION_ATTR_CT
:
641 case OVS_ACTION_ATTR_METER
:
644 case OVS_ACTION_ATTR_SET
:
645 case OVS_ACTION_ATTR_SET_MASKED
:
646 case OVS_ACTION_ATTR_PUSH_VLAN
:
647 case OVS_ACTION_ATTR_POP_VLAN
:
648 case OVS_ACTION_ATTR_SAMPLE
:
649 case OVS_ACTION_ATTR_HASH
:
650 case OVS_ACTION_ATTR_PUSH_MPLS
:
651 case OVS_ACTION_ATTR_POP_MPLS
:
652 case OVS_ACTION_ATTR_TRUNC
:
653 case OVS_ACTION_ATTR_PUSH_ETH
:
654 case OVS_ACTION_ATTR_POP_ETH
:
655 case OVS_ACTION_ATTR_CLONE
:
656 case OVS_ACTION_ATTR_ENCAP_NSH
:
657 case OVS_ACTION_ATTR_DECAP_NSH
:
660 case OVS_ACTION_ATTR_UNSPEC
:
661 case __OVS_ACTION_ATTR_MAX
:
668 /* Executes all of the 'actions_len' bytes of datapath actions in 'actions' on
669 * the packets in 'batch'. If 'steal' is true, possibly modifies and
670 * definitely free the packets in 'batch', otherwise leaves 'batch' unchanged.
672 * Some actions (e.g. output actions) can only be executed by a datapath. This
673 * function implements those actions by passing the action and the packets to
674 * 'dp_execute_action' (along with 'dp'). If 'dp_execute_action' is passed a
675 * true 'may_steal' parameter then it may possibly modify and must definitely
676 * free the packets passed into it, otherwise it must leave them unchanged. */
678 odp_execute_actions(void *dp
, struct dp_packet_batch
*batch
, bool steal
,
679 const struct nlattr
*actions
, size_t actions_len
,
680 odp_execute_cb dp_execute_action
)
682 struct dp_packet
*packet
;
683 const struct nlattr
*a
;
686 NL_ATTR_FOR_EACH_UNSAFE (a
, left
, actions
, actions_len
) {
687 int type
= nl_attr_type(a
);
688 bool last_action
= (left
<= NLA_ALIGN(a
->nla_len
));
690 if (requires_datapath_assistance(a
)) {
691 if (dp_execute_action
) {
692 /* Allow 'dp_execute_action' to steal the packet data if we do
693 * not need it any more. */
694 bool may_steal
= steal
&& last_action
;
696 dp_execute_action(dp
, batch
, a
, may_steal
);
698 if (last_action
|| batch
->count
== 0) {
699 /* We do not need to free the packets.
700 * Either dp_execute_actions() has stolen them
701 * or the batch is freed due to errors. In either
702 * case we do not need to execute further actions.
710 switch ((enum ovs_action_attr
) type
) {
711 case OVS_ACTION_ATTR_HASH
: {
712 const struct ovs_action_hash
*hash_act
= nl_attr_get(a
);
714 /* Calculate a hash value directly. This might not match the
715 * value computed by the datapath, but it is much less expensive,
716 * and the current use case (bonding) does not require a strict
717 * match to work properly. */
718 if (hash_act
->hash_alg
== OVS_HASH_ALG_L4
) {
722 DP_PACKET_BATCH_FOR_EACH (packet
, batch
) {
723 /* RSS hash can be used here instead of 5tuple for
724 * performance reasons. */
725 if (dp_packet_rss_valid(packet
)) {
726 hash
= dp_packet_get_rss_hash(packet
);
727 hash
= hash_int(hash
, hash_act
->hash_basis
);
729 flow_extract(packet
, &flow
);
730 hash
= flow_hash_5tuple(&flow
, hash_act
->hash_basis
);
732 packet
->md
.dp_hash
= hash
;
735 /* Assert on unknown hash algorithm. */
741 case OVS_ACTION_ATTR_PUSH_VLAN
: {
742 const struct ovs_action_push_vlan
*vlan
= nl_attr_get(a
);
744 DP_PACKET_BATCH_FOR_EACH (packet
, batch
) {
745 eth_push_vlan(packet
, vlan
->vlan_tpid
, vlan
->vlan_tci
);
750 case OVS_ACTION_ATTR_POP_VLAN
:
751 DP_PACKET_BATCH_FOR_EACH (packet
, batch
) {
752 eth_pop_vlan(packet
);
756 case OVS_ACTION_ATTR_PUSH_MPLS
: {
757 const struct ovs_action_push_mpls
*mpls
= nl_attr_get(a
);
759 DP_PACKET_BATCH_FOR_EACH (packet
, batch
) {
760 push_mpls(packet
, mpls
->mpls_ethertype
, mpls
->mpls_lse
);
765 case OVS_ACTION_ATTR_POP_MPLS
:
766 DP_PACKET_BATCH_FOR_EACH (packet
, batch
) {
767 pop_mpls(packet
, nl_attr_get_be16(a
));
771 case OVS_ACTION_ATTR_SET
:
772 DP_PACKET_BATCH_FOR_EACH (packet
, batch
) {
773 odp_execute_set_action(packet
, nl_attr_get(a
));
777 case OVS_ACTION_ATTR_SET_MASKED
:
778 DP_PACKET_BATCH_FOR_EACH(packet
, batch
) {
779 odp_execute_masked_set_action(packet
, nl_attr_get(a
));
783 case OVS_ACTION_ATTR_SAMPLE
:
784 DP_PACKET_BATCH_FOR_EACH (packet
, batch
) {
785 odp_execute_sample(dp
, packet
, steal
&& last_action
, a
,
790 /* We do not need to free the packets. odp_execute_sample() has
796 case OVS_ACTION_ATTR_TRUNC
: {
797 const struct ovs_action_trunc
*trunc
=
798 nl_attr_get_unspec(a
, sizeof *trunc
);
801 DP_PACKET_BATCH_FOR_EACH (packet
, batch
) {
802 dp_packet_set_cutlen(packet
, trunc
->max_len
);
807 case OVS_ACTION_ATTR_CLONE
:
808 odp_execute_clone(dp
, batch
, steal
&& last_action
, a
,
811 /* We do not need to free the packets. odp_execute_clone() has
816 case OVS_ACTION_ATTR_METER
:
817 /* Not implemented yet. */
819 case OVS_ACTION_ATTR_PUSH_ETH
: {
820 const struct ovs_action_push_eth
*eth
= nl_attr_get(a
);
822 DP_PACKET_BATCH_FOR_EACH (packet
, batch
) {
823 push_eth(packet
, ð
->addresses
.eth_dst
,
824 ð
->addresses
.eth_src
);
829 case OVS_ACTION_ATTR_POP_ETH
:
830 DP_PACKET_BATCH_FOR_EACH (packet
, batch
) {
835 case OVS_ACTION_ATTR_ENCAP_NSH
: {
836 const struct ovs_action_encap_nsh
*enc_nsh
= nl_attr_get(a
);
837 DP_PACKET_BATCH_FOR_EACH (packet
, batch
) {
838 encap_nsh(packet
, enc_nsh
);
842 case OVS_ACTION_ATTR_DECAP_NSH
: {
844 const size_t num
= dp_packet_batch_size(batch
);
846 DP_PACKET_BATCH_REFILL_FOR_EACH (i
, num
, packet
, batch
) {
847 if (decap_nsh(packet
)) {
848 dp_packet_batch_refill(batch
, packet
, i
);
850 dp_packet_delete(packet
);
856 case OVS_ACTION_ATTR_OUTPUT
:
857 case OVS_ACTION_ATTR_TUNNEL_PUSH
:
858 case OVS_ACTION_ATTR_TUNNEL_POP
:
859 case OVS_ACTION_ATTR_USERSPACE
:
860 case OVS_ACTION_ATTR_RECIRC
:
861 case OVS_ACTION_ATTR_CT
:
862 case OVS_ACTION_ATTR_UNSPEC
:
863 case __OVS_ACTION_ATTR_MAX
:
868 dp_packet_delete_batch(batch
, steal
);