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 <sys/types.h>
21 #include <netinet/in.h>
22 #include <arpa/inet.h>
23 #include <netinet/icmp6.h>
24 #include <netinet/ip6.h>
28 #include "dp-packet.h"
31 #include "odp-netlink.h"
35 #include "unaligned.h"
39 /* Masked copy of an ethernet address. 'src' is already properly masked. */
41 ether_addr_copy_masked(struct eth_addr
*dst
, const struct eth_addr src
,
42 const struct eth_addr mask
)
46 for (i
= 0; i
< ARRAY_SIZE(dst
->be16
); i
++) {
47 dst
->be16
[i
] = src
.be16
[i
] | (dst
->be16
[i
] & ~mask
.be16
[i
]);
52 odp_eth_set_addrs(struct dp_packet
*packet
, const struct ovs_key_ethernet
*key
,
53 const struct ovs_key_ethernet
*mask
)
55 struct eth_header
*eh
= dp_packet_eth(packet
);
59 eh
->eth_src
= key
->eth_src
;
60 eh
->eth_dst
= key
->eth_dst
;
62 ether_addr_copy_masked(&eh
->eth_src
, key
->eth_src
, mask
->eth_src
);
63 ether_addr_copy_masked(&eh
->eth_dst
, key
->eth_dst
, mask
->eth_dst
);
69 odp_set_ipv4(struct dp_packet
*packet
, const struct ovs_key_ipv4
*key
,
70 const struct ovs_key_ipv4
*mask
)
72 struct ip_header
*nh
= dp_packet_l3(packet
);
81 ip_src_nh
= get_16aligned_be32(&nh
->ip_src
);
82 new_ip_src
= key
->ipv4_src
| (ip_src_nh
& ~mask
->ipv4_src
);
84 if (ip_src_nh
!= new_ip_src
) {
85 packet_set_ipv4_addr(packet
, &nh
->ip_src
, new_ip_src
);
90 ip_dst_nh
= get_16aligned_be32(&nh
->ip_dst
);
91 new_ip_dst
= key
->ipv4_dst
| (ip_dst_nh
& ~mask
->ipv4_dst
);
93 if (ip_dst_nh
!= new_ip_dst
) {
94 packet_set_ipv4_addr(packet
, &nh
->ip_dst
, new_ip_dst
);
99 new_tos
= key
->ipv4_tos
| (nh
->ip_tos
& ~mask
->ipv4_tos
);
101 if (nh
->ip_tos
!= new_tos
) {
102 nh
->ip_csum
= recalc_csum16(nh
->ip_csum
,
103 htons((uint16_t) nh
->ip_tos
),
104 htons((uint16_t) new_tos
));
105 nh
->ip_tos
= new_tos
;
109 if (OVS_LIKELY(mask
->ipv4_ttl
)) {
110 new_ttl
= key
->ipv4_ttl
| (nh
->ip_ttl
& ~mask
->ipv4_ttl
);
112 if (OVS_LIKELY(nh
->ip_ttl
!= new_ttl
)) {
113 nh
->ip_csum
= recalc_csum16(nh
->ip_csum
, htons(nh
->ip_ttl
<< 8),
114 htons(new_ttl
<< 8));
115 nh
->ip_ttl
= new_ttl
;
120 static struct in6_addr
*
121 mask_ipv6_addr(const ovs_16aligned_be32
*old
, const struct in6_addr
*addr
,
122 const struct in6_addr
*mask
, struct in6_addr
*masked
)
125 for (int i
= 0; i
< 4; i
++) {
126 masked
->s6_addr32
[i
] = addr
->s6_addr32
[i
]
127 | (get_16aligned_be32(&old
[i
]) & ~mask
->s6_addr32
[i
]);
130 const uint8_t *old8
= (const uint8_t *)old
;
131 for (int i
= 0; i
< 16; i
++) {
132 masked
->s6_addr
[i
] = addr
->s6_addr
[i
] | (old8
[i
] & ~mask
->s6_addr
[i
]);
139 odp_set_ipv6(struct dp_packet
*packet
, const struct ovs_key_ipv6
*key
,
140 const struct ovs_key_ipv6
*mask
)
142 struct ovs_16aligned_ip6_hdr
*nh
= dp_packet_l3(packet
);
143 struct in6_addr sbuf
, dbuf
;
144 uint8_t old_tc
= ntohl(get_16aligned_be32(&nh
->ip6_flow
)) >> 20;
145 ovs_be32 old_fl
= get_16aligned_be32(&nh
->ip6_flow
) & htonl(0xfffff);
149 mask_ipv6_addr(nh
->ip6_src
.be32
, &key
->ipv6_src
, &mask
->ipv6_src
,
151 mask_ipv6_addr(nh
->ip6_dst
.be32
, &key
->ipv6_dst
, &mask
->ipv6_dst
,
153 key
->ipv6_tclass
| (old_tc
& ~mask
->ipv6_tclass
),
154 key
->ipv6_label
| (old_fl
& ~mask
->ipv6_label
),
155 key
->ipv6_hlimit
| (nh
->ip6_hlim
& ~mask
->ipv6_hlimit
));
159 odp_set_tcp(struct dp_packet
*packet
, const struct ovs_key_tcp
*key
,
160 const struct ovs_key_tcp
*mask
)
162 struct tcp_header
*th
= dp_packet_l4(packet
);
164 if (OVS_LIKELY(th
&& dp_packet_get_tcp_payload(packet
))) {
165 packet_set_tcp_port(packet
,
166 key
->tcp_src
| (th
->tcp_src
& ~mask
->tcp_src
),
167 key
->tcp_dst
| (th
->tcp_dst
& ~mask
->tcp_dst
));
172 odp_set_udp(struct dp_packet
*packet
, const struct ovs_key_udp
*key
,
173 const struct ovs_key_udp
*mask
)
175 struct udp_header
*uh
= dp_packet_l4(packet
);
177 if (OVS_LIKELY(uh
&& dp_packet_get_udp_payload(packet
))) {
178 packet_set_udp_port(packet
,
179 key
->udp_src
| (uh
->udp_src
& ~mask
->udp_src
),
180 key
->udp_dst
| (uh
->udp_dst
& ~mask
->udp_dst
));
185 odp_set_sctp(struct dp_packet
*packet
, const struct ovs_key_sctp
*key
,
186 const struct ovs_key_sctp
*mask
)
188 struct sctp_header
*sh
= dp_packet_l4(packet
);
190 if (OVS_LIKELY(sh
&& dp_packet_get_sctp_payload(packet
))) {
191 packet_set_sctp_port(packet
,
192 key
->sctp_src
| (sh
->sctp_src
& ~mask
->sctp_src
),
193 key
->sctp_dst
| (sh
->sctp_dst
& ~mask
->sctp_dst
));
198 odp_set_tunnel_action(const struct nlattr
*a
, struct flow_tnl
*tun_key
)
200 enum odp_key_fitness fitness
;
202 fitness
= odp_tun_key_from_attr(a
, tun_key
);
203 ovs_assert(fitness
!= ODP_FIT_ERROR
);
207 set_arp(struct dp_packet
*packet
, const struct ovs_key_arp
*key
,
208 const struct ovs_key_arp
*mask
)
210 struct arp_eth_header
*arp
= dp_packet_l3(packet
);
213 arp
->ar_op
= key
->arp_op
;
214 arp
->ar_sha
= key
->arp_sha
;
215 put_16aligned_be32(&arp
->ar_spa
, key
->arp_sip
);
216 arp
->ar_tha
= key
->arp_tha
;
217 put_16aligned_be32(&arp
->ar_tpa
, key
->arp_tip
);
219 ovs_be32 ar_spa
= get_16aligned_be32(&arp
->ar_spa
);
220 ovs_be32 ar_tpa
= get_16aligned_be32(&arp
->ar_tpa
);
222 arp
->ar_op
= key
->arp_op
| (arp
->ar_op
& ~mask
->arp_op
);
223 ether_addr_copy_masked(&arp
->ar_sha
, key
->arp_sha
, mask
->arp_sha
);
224 put_16aligned_be32(&arp
->ar_spa
,
225 key
->arp_sip
| (ar_spa
& ~mask
->arp_sip
));
226 ether_addr_copy_masked(&arp
->ar_tha
, key
->arp_tha
, mask
->arp_tha
);
227 put_16aligned_be32(&arp
->ar_tpa
,
228 key
->arp_tip
| (ar_tpa
& ~mask
->arp_tip
));
233 odp_set_nd(struct dp_packet
*packet
, const struct ovs_key_nd
*key
,
234 const struct ovs_key_nd
*mask
)
236 const struct ovs_nd_msg
*ns
= dp_packet_l4(packet
);
237 const struct ovs_nd_lla_opt
*lla_opt
= dp_packet_get_nd_payload(packet
);
239 if (OVS_LIKELY(ns
&& lla_opt
)) {
240 int bytes_remain
= dp_packet_l4_size(packet
) - sizeof(*ns
);
241 struct in6_addr tgt_buf
;
242 struct eth_addr sll_buf
= eth_addr_zero
;
243 struct eth_addr tll_buf
= eth_addr_zero
;
245 while (bytes_remain
>= ND_LLA_OPT_LEN
&& lla_opt
->len
!= 0) {
246 if (lla_opt
->type
== ND_OPT_SOURCE_LINKADDR
247 && lla_opt
->len
== 1) {
248 sll_buf
= lla_opt
->mac
;
249 ether_addr_copy_masked(&sll_buf
, key
->nd_sll
, mask
->nd_sll
);
251 /* A packet can only contain one SLL or TLL option */
253 } else if (lla_opt
->type
== ND_OPT_TARGET_LINKADDR
254 && lla_opt
->len
== 1) {
255 tll_buf
= lla_opt
->mac
;
256 ether_addr_copy_masked(&tll_buf
, key
->nd_tll
, mask
->nd_tll
);
258 /* A packet can only contain one SLL or TLL option */
262 lla_opt
+= lla_opt
->len
;
263 bytes_remain
-= lla_opt
->len
* ND_LLA_OPT_LEN
;
266 packet_set_nd(packet
,
267 mask_ipv6_addr(ns
->target
.be32
, &key
->nd_target
,
268 &mask
->nd_target
, &tgt_buf
),
274 /* Set the NSH header. Assumes the NSH header is present and matches the
275 * MD format of the key. The slow path must take case of that. */
277 odp_set_nsh(struct dp_packet
*packet
, const struct flow_nsh
*key
,
278 const struct flow_nsh
*mask
)
280 struct nsh_hdr
*nsh
= dp_packet_l3(packet
);
281 uint8_t mdtype
= nsh_md_type(nsh
);
285 nsh
->ver_flags_ttl_len
= htons(key
->flags
<< NSH_FLAGS_SHIFT
) |
286 (nsh
->ver_flags_ttl_len
& ~htons(NSH_FLAGS_MASK
));
287 path_hdr
= htonl((ntohl(key
->spi
) << NSH_SPI_SHIFT
) |
289 put_16aligned_be32(&nsh
->path_hdr
, path_hdr
);
292 for (int i
= 0; i
< 4; i
++) {
293 put_16aligned_be32(&nsh
->md1
.context
[i
], key
->context
[i
]);
298 /* No support for setting any other metadata format yet. */
302 uint8_t flags
= (ntohs(nsh
->ver_flags_ttl_len
) & NSH_FLAGS_MASK
) >>
304 flags
= key
->flags
| (flags
& ~mask
->flags
);
305 nsh
->ver_flags_ttl_len
= htons(flags
<< NSH_FLAGS_SHIFT
) |
306 (nsh
->ver_flags_ttl_len
& ~htons(NSH_FLAGS_MASK
));
308 path_hdr
= get_16aligned_be32(&nsh
->path_hdr
);
309 uint32_t spi
= (ntohl(path_hdr
) & NSH_SPI_MASK
) >> NSH_SPI_SHIFT
;
310 uint8_t si
= (ntohl(path_hdr
) & NSH_SI_MASK
) >> NSH_SI_SHIFT
;
311 uint32_t spi_mask
= ntohl(mask
->spi
);
312 if (spi_mask
== 0x00ffffff) {
313 spi_mask
= UINT32_MAX
;
315 spi
= ntohl(key
->spi
) | (spi
& ~spi_mask
);
316 si
= key
->si
| (si
& ~mask
->si
);
317 path_hdr
= htonl((spi
<< NSH_SPI_SHIFT
) | si
);
318 put_16aligned_be32(&nsh
->path_hdr
, path_hdr
);
321 for (int i
= 0; i
< 4; i
++) {
322 ovs_be32 p
= get_16aligned_be32(&nsh
->md1
.context
[i
]);
323 ovs_be32 k
= key
->context
[i
];
324 ovs_be32 m
= mask
->context
[i
];
325 put_16aligned_be32(&nsh
->md1
.context
[i
], k
| (p
& ~m
));
330 /* No support for setting any other metadata format yet. */
337 odp_execute_set_action(struct dp_packet
*packet
, const struct nlattr
*a
)
339 enum ovs_key_attr type
= nl_attr_type(a
);
340 const struct ovs_key_ipv4
*ipv4_key
;
341 const struct ovs_key_ipv6
*ipv6_key
;
342 struct pkt_metadata
*md
= &packet
->md
;
345 case OVS_KEY_ATTR_PRIORITY
:
346 md
->skb_priority
= nl_attr_get_u32(a
);
349 case OVS_KEY_ATTR_TUNNEL
:
350 odp_set_tunnel_action(a
, &md
->tunnel
);
353 case OVS_KEY_ATTR_SKB_MARK
:
354 md
->pkt_mark
= nl_attr_get_u32(a
);
357 case OVS_KEY_ATTR_ETHERNET
:
358 odp_eth_set_addrs(packet
, nl_attr_get(a
), NULL
);
361 case OVS_KEY_ATTR_NSH
: {
363 odp_nsh_key_from_attr(a
, &nsh
);
364 odp_set_nsh(packet
, &nsh
, NULL
);
368 case OVS_KEY_ATTR_IPV4
:
369 ipv4_key
= nl_attr_get_unspec(a
, sizeof(struct ovs_key_ipv4
));
370 packet_set_ipv4(packet
, ipv4_key
->ipv4_src
,
371 ipv4_key
->ipv4_dst
, ipv4_key
->ipv4_tos
,
375 case OVS_KEY_ATTR_IPV6
:
376 ipv6_key
= nl_attr_get_unspec(a
, sizeof(struct ovs_key_ipv6
));
377 packet_set_ipv6(packet
, &ipv6_key
->ipv6_src
, &ipv6_key
->ipv6_dst
,
378 ipv6_key
->ipv6_tclass
, ipv6_key
->ipv6_label
,
379 ipv6_key
->ipv6_hlimit
);
382 case OVS_KEY_ATTR_TCP
:
383 if (OVS_LIKELY(dp_packet_get_tcp_payload(packet
))) {
384 const struct ovs_key_tcp
*tcp_key
385 = nl_attr_get_unspec(a
, sizeof(struct ovs_key_tcp
));
387 packet_set_tcp_port(packet
, tcp_key
->tcp_src
,
392 case OVS_KEY_ATTR_UDP
:
393 if (OVS_LIKELY(dp_packet_get_udp_payload(packet
))) {
394 const struct ovs_key_udp
*udp_key
395 = nl_attr_get_unspec(a
, sizeof(struct ovs_key_udp
));
397 packet_set_udp_port(packet
, udp_key
->udp_src
,
402 case OVS_KEY_ATTR_SCTP
:
403 if (OVS_LIKELY(dp_packet_get_sctp_payload(packet
))) {
404 const struct ovs_key_sctp
*sctp_key
405 = nl_attr_get_unspec(a
, sizeof(struct ovs_key_sctp
));
407 packet_set_sctp_port(packet
, sctp_key
->sctp_src
,
412 case OVS_KEY_ATTR_MPLS
:
413 set_mpls_lse(packet
, nl_attr_get_be32(a
));
416 case OVS_KEY_ATTR_ARP
:
417 set_arp(packet
, nl_attr_get(a
), NULL
);
420 case OVS_KEY_ATTR_ICMP
:
421 case OVS_KEY_ATTR_ICMPV6
:
422 if (OVS_LIKELY(dp_packet_get_icmp_payload(packet
))) {
423 const struct ovs_key_icmp
*icmp_key
424 = nl_attr_get_unspec(a
, sizeof(struct ovs_key_icmp
));
426 packet_set_icmp(packet
, icmp_key
->icmp_type
, icmp_key
->icmp_code
);
430 case OVS_KEY_ATTR_ND
:
431 if (OVS_LIKELY(dp_packet_get_nd_payload(packet
))) {
432 const struct ovs_key_nd
*nd_key
433 = nl_attr_get_unspec(a
, sizeof(struct ovs_key_nd
));
434 packet_set_nd(packet
, &nd_key
->nd_target
, nd_key
->nd_sll
,
439 case OVS_KEY_ATTR_DP_HASH
:
440 md
->dp_hash
= nl_attr_get_u32(a
);
443 case OVS_KEY_ATTR_RECIRC_ID
:
444 md
->recirc_id
= nl_attr_get_u32(a
);
447 case OVS_KEY_ATTR_UNSPEC
:
448 case OVS_KEY_ATTR_PACKET_TYPE
:
449 case OVS_KEY_ATTR_ENCAP
:
450 case OVS_KEY_ATTR_ETHERTYPE
:
451 case OVS_KEY_ATTR_IN_PORT
:
452 case OVS_KEY_ATTR_VLAN
:
453 case OVS_KEY_ATTR_TCP_FLAGS
:
454 case OVS_KEY_ATTR_CT_STATE
:
455 case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4
:
456 case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6
:
457 case OVS_KEY_ATTR_CT_ZONE
:
458 case OVS_KEY_ATTR_CT_MARK
:
459 case OVS_KEY_ATTR_CT_LABELS
:
460 case __OVS_KEY_ATTR_MAX
:
466 #define get_mask(a, type) ((const type *)(const void *)(a + 1) + 1)
469 odp_execute_masked_set_action(struct dp_packet
*packet
,
470 const struct nlattr
*a
)
472 struct pkt_metadata
*md
= &packet
->md
;
473 enum ovs_key_attr type
= nl_attr_type(a
);
477 case OVS_KEY_ATTR_PRIORITY
:
478 md
->skb_priority
= nl_attr_get_u32(a
)
479 | (md
->skb_priority
& ~*get_mask(a
, uint32_t));
482 case OVS_KEY_ATTR_SKB_MARK
:
483 md
->pkt_mark
= nl_attr_get_u32(a
)
484 | (md
->pkt_mark
& ~*get_mask(a
, uint32_t));
487 case OVS_KEY_ATTR_ETHERNET
:
488 odp_eth_set_addrs(packet
, nl_attr_get(a
),
489 get_mask(a
, struct ovs_key_ethernet
));
492 case OVS_KEY_ATTR_NSH
: {
493 struct flow_nsh nsh
, nsh_mask
;
496 uint8_t data
[sizeof(struct ovs_nsh_key_base
) + NSH_CTX_HDRS_MAX_LEN
499 size_t size
= nl_attr_get_size(a
) / 2;
501 mask
.nla
.nla_type
= attr
.nla
.nla_type
= nl_attr_type(a
);
502 mask
.nla
.nla_len
= attr
.nla
.nla_len
= NLA_HDRLEN
+ size
;
503 memcpy(attr
.data
, (char *)(a
+ 1), size
);
504 memcpy(mask
.data
, (char *)(a
+ 1) + size
, size
);
506 odp_nsh_key_from_attr(&attr
.nla
, &nsh
);
507 odp_nsh_key_from_attr(&mask
.nla
, &nsh_mask
);
508 odp_set_nsh(packet
, &nsh
, &nsh_mask
);
513 case OVS_KEY_ATTR_IPV4
:
514 odp_set_ipv4(packet
, nl_attr_get(a
),
515 get_mask(a
, struct ovs_key_ipv4
));
518 case OVS_KEY_ATTR_IPV6
:
519 odp_set_ipv6(packet
, nl_attr_get(a
),
520 get_mask(a
, struct ovs_key_ipv6
));
523 case OVS_KEY_ATTR_TCP
:
524 odp_set_tcp(packet
, nl_attr_get(a
),
525 get_mask(a
, struct ovs_key_tcp
));
528 case OVS_KEY_ATTR_UDP
:
529 odp_set_udp(packet
, nl_attr_get(a
),
530 get_mask(a
, struct ovs_key_udp
));
533 case OVS_KEY_ATTR_SCTP
:
534 odp_set_sctp(packet
, nl_attr_get(a
),
535 get_mask(a
, struct ovs_key_sctp
));
538 case OVS_KEY_ATTR_MPLS
:
539 mh
= dp_packet_l2_5(packet
);
541 put_16aligned_be32(&mh
->mpls_lse
, nl_attr_get_be32(a
)
542 | (get_16aligned_be32(&mh
->mpls_lse
)
543 & ~*get_mask(a
, ovs_be32
)));
547 case OVS_KEY_ATTR_ARP
:
548 set_arp(packet
, nl_attr_get(a
),
549 get_mask(a
, struct ovs_key_arp
));
552 case OVS_KEY_ATTR_ND
:
553 odp_set_nd(packet
, nl_attr_get(a
),
554 get_mask(a
, struct ovs_key_nd
));
557 case OVS_KEY_ATTR_DP_HASH
:
558 md
->dp_hash
= nl_attr_get_u32(a
)
559 | (md
->dp_hash
& ~*get_mask(a
, uint32_t));
562 case OVS_KEY_ATTR_RECIRC_ID
:
563 md
->recirc_id
= nl_attr_get_u32(a
)
564 | (md
->recirc_id
& ~*get_mask(a
, uint32_t));
567 case OVS_KEY_ATTR_TUNNEL
: /* Masked data not supported for tunnel. */
568 case OVS_KEY_ATTR_PACKET_TYPE
:
569 case OVS_KEY_ATTR_UNSPEC
:
570 case OVS_KEY_ATTR_CT_STATE
:
571 case OVS_KEY_ATTR_CT_ZONE
:
572 case OVS_KEY_ATTR_CT_MARK
:
573 case OVS_KEY_ATTR_CT_LABELS
:
574 case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4
:
575 case OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6
:
576 case OVS_KEY_ATTR_ENCAP
:
577 case OVS_KEY_ATTR_ETHERTYPE
:
578 case OVS_KEY_ATTR_IN_PORT
:
579 case OVS_KEY_ATTR_VLAN
:
580 case OVS_KEY_ATTR_ICMP
:
581 case OVS_KEY_ATTR_ICMPV6
:
582 case OVS_KEY_ATTR_TCP_FLAGS
:
583 case __OVS_KEY_ATTR_MAX
:
590 odp_execute_sample(void *dp
, struct dp_packet
*packet
, bool steal
,
591 const struct nlattr
*action
,
592 odp_execute_cb dp_execute_action
)
594 const struct nlattr
*subactions
= NULL
;
595 const struct nlattr
*a
;
596 struct dp_packet_batch pb
;
599 NL_NESTED_FOR_EACH_UNSAFE (a
, left
, action
) {
600 int type
= nl_attr_type(a
);
602 switch ((enum ovs_sample_attr
) type
) {
603 case OVS_SAMPLE_ATTR_PROBABILITY
:
604 if (random_uint32() >= nl_attr_get_u32(a
)) {
606 dp_packet_delete(packet
);
612 case OVS_SAMPLE_ATTR_ACTIONS
:
616 case OVS_SAMPLE_ATTR_UNSPEC
:
617 case __OVS_SAMPLE_ATTR_MAX
:
624 /* The 'subactions' may modify the packet, but the modification
625 * should not propagate beyond this sample action. Make a copy
626 * the packet in case we don't own the packet, so that the
627 * 'subactions' are only applid to the clone. 'odp_execute_actions'
628 * will free the clone. */
629 packet
= dp_packet_clone(packet
);
631 dp_packet_batch_init_packet(&pb
, packet
);
632 odp_execute_actions(dp
, &pb
, true, nl_attr_get(subactions
),
633 nl_attr_get_size(subactions
), dp_execute_action
);
637 odp_execute_clone(void *dp
, struct dp_packet_batch
*batch
, bool steal
,
638 const struct nlattr
*actions
,
639 odp_execute_cb dp_execute_action
)
642 /* The 'actions' may modify the packet, but the modification
643 * should not propagate beyond this clone action. Make a copy
644 * the packet in case we don't own the packet, so that the
645 * 'actions' are only applied to the clone. 'odp_execute_actions'
646 * will free the clone. */
647 struct dp_packet_batch clone_pkt_batch
;
648 dp_packet_batch_clone(&clone_pkt_batch
, batch
);
649 dp_packet_batch_reset_cutlen(batch
);
650 odp_execute_actions(dp
, &clone_pkt_batch
, true, nl_attr_get(actions
),
651 nl_attr_get_size(actions
), dp_execute_action
);
654 odp_execute_actions(dp
, batch
, true, nl_attr_get(actions
),
655 nl_attr_get_size(actions
), dp_execute_action
);
660 requires_datapath_assistance(const struct nlattr
*a
)
662 enum ovs_action_attr type
= nl_attr_type(a
);
665 /* These only make sense in the context of a datapath. */
666 case OVS_ACTION_ATTR_OUTPUT
:
667 case OVS_ACTION_ATTR_TUNNEL_PUSH
:
668 case OVS_ACTION_ATTR_TUNNEL_POP
:
669 case OVS_ACTION_ATTR_USERSPACE
:
670 case OVS_ACTION_ATTR_RECIRC
:
671 case OVS_ACTION_ATTR_CT
:
672 case OVS_ACTION_ATTR_METER
:
675 case OVS_ACTION_ATTR_SET
:
676 case OVS_ACTION_ATTR_SET_MASKED
:
677 case OVS_ACTION_ATTR_PUSH_VLAN
:
678 case OVS_ACTION_ATTR_POP_VLAN
:
679 case OVS_ACTION_ATTR_SAMPLE
:
680 case OVS_ACTION_ATTR_HASH
:
681 case OVS_ACTION_ATTR_PUSH_MPLS
:
682 case OVS_ACTION_ATTR_POP_MPLS
:
683 case OVS_ACTION_ATTR_TRUNC
:
684 case OVS_ACTION_ATTR_PUSH_ETH
:
685 case OVS_ACTION_ATTR_POP_ETH
:
686 case OVS_ACTION_ATTR_CLONE
:
687 case OVS_ACTION_ATTR_PUSH_NSH
:
688 case OVS_ACTION_ATTR_POP_NSH
:
691 case OVS_ACTION_ATTR_UNSPEC
:
692 case __OVS_ACTION_ATTR_MAX
:
699 /* Executes all of the 'actions_len' bytes of datapath actions in 'actions' on
700 * the packets in 'batch'. If 'steal' is true, possibly modifies and
701 * definitely free the packets in 'batch', otherwise leaves 'batch' unchanged.
703 * Some actions (e.g. output actions) can only be executed by a datapath. This
704 * function implements those actions by passing the action and the packets to
705 * 'dp_execute_action' (along with 'dp'). If 'dp_execute_action' is passed a
706 * true 'may_steal' parameter then it may possibly modify and must definitely
707 * free the packets passed into it, otherwise it must leave them unchanged. */
709 odp_execute_actions(void *dp
, struct dp_packet_batch
*batch
, bool steal
,
710 const struct nlattr
*actions
, size_t actions_len
,
711 odp_execute_cb dp_execute_action
)
713 struct dp_packet
*packet
;
714 const struct nlattr
*a
;
717 NL_ATTR_FOR_EACH_UNSAFE (a
, left
, actions
, actions_len
) {
718 int type
= nl_attr_type(a
);
719 bool last_action
= (left
<= NLA_ALIGN(a
->nla_len
));
721 if (requires_datapath_assistance(a
)) {
722 if (dp_execute_action
) {
723 /* Allow 'dp_execute_action' to steal the packet data if we do
724 * not need it any more. */
725 bool may_steal
= steal
&& last_action
;
727 dp_execute_action(dp
, batch
, a
, may_steal
);
729 if (last_action
|| batch
->count
== 0) {
730 /* We do not need to free the packets.
731 * Either dp_execute_actions() has stolen them
732 * or the batch is freed due to errors. In either
733 * case we do not need to execute further actions.
741 switch ((enum ovs_action_attr
) type
) {
742 case OVS_ACTION_ATTR_HASH
: {
743 const struct ovs_action_hash
*hash_act
= nl_attr_get(a
);
745 /* Calculate a hash value directly. This might not match the
746 * value computed by the datapath, but it is much less expensive,
747 * and the current use case (bonding) does not require a strict
748 * match to work properly. */
749 if (hash_act
->hash_alg
== OVS_HASH_ALG_L4
) {
753 DP_PACKET_BATCH_FOR_EACH (packet
, batch
) {
754 /* RSS hash can be used here instead of 5tuple for
755 * performance reasons. */
756 if (dp_packet_rss_valid(packet
)) {
757 hash
= dp_packet_get_rss_hash(packet
);
758 hash
= hash_int(hash
, hash_act
->hash_basis
);
760 flow_extract(packet
, &flow
);
761 hash
= flow_hash_5tuple(&flow
, hash_act
->hash_basis
);
763 packet
->md
.dp_hash
= hash
;
766 /* Assert on unknown hash algorithm. */
772 case OVS_ACTION_ATTR_PUSH_VLAN
: {
773 const struct ovs_action_push_vlan
*vlan
= nl_attr_get(a
);
775 DP_PACKET_BATCH_FOR_EACH (packet
, batch
) {
776 eth_push_vlan(packet
, vlan
->vlan_tpid
, vlan
->vlan_tci
);
781 case OVS_ACTION_ATTR_POP_VLAN
:
782 DP_PACKET_BATCH_FOR_EACH (packet
, batch
) {
783 eth_pop_vlan(packet
);
787 case OVS_ACTION_ATTR_PUSH_MPLS
: {
788 const struct ovs_action_push_mpls
*mpls
= nl_attr_get(a
);
790 DP_PACKET_BATCH_FOR_EACH (packet
, batch
) {
791 push_mpls(packet
, mpls
->mpls_ethertype
, mpls
->mpls_lse
);
796 case OVS_ACTION_ATTR_POP_MPLS
:
797 DP_PACKET_BATCH_FOR_EACH (packet
, batch
) {
798 pop_mpls(packet
, nl_attr_get_be16(a
));
802 case OVS_ACTION_ATTR_SET
:
803 DP_PACKET_BATCH_FOR_EACH (packet
, batch
) {
804 odp_execute_set_action(packet
, nl_attr_get(a
));
808 case OVS_ACTION_ATTR_SET_MASKED
:
809 DP_PACKET_BATCH_FOR_EACH(packet
, batch
) {
810 odp_execute_masked_set_action(packet
, nl_attr_get(a
));
814 case OVS_ACTION_ATTR_SAMPLE
:
815 DP_PACKET_BATCH_FOR_EACH (packet
, batch
) {
816 odp_execute_sample(dp
, packet
, steal
&& last_action
, a
,
821 /* We do not need to free the packets. odp_execute_sample() has
827 case OVS_ACTION_ATTR_TRUNC
: {
828 const struct ovs_action_trunc
*trunc
=
829 nl_attr_get_unspec(a
, sizeof *trunc
);
832 DP_PACKET_BATCH_FOR_EACH (packet
, batch
) {
833 dp_packet_set_cutlen(packet
, trunc
->max_len
);
838 case OVS_ACTION_ATTR_CLONE
:
839 odp_execute_clone(dp
, batch
, steal
&& last_action
, a
,
842 /* We do not need to free the packets. odp_execute_clone() has
847 case OVS_ACTION_ATTR_METER
:
848 /* Not implemented yet. */
850 case OVS_ACTION_ATTR_PUSH_ETH
: {
851 const struct ovs_action_push_eth
*eth
= nl_attr_get(a
);
853 DP_PACKET_BATCH_FOR_EACH (packet
, batch
) {
854 push_eth(packet
, ð
->addresses
.eth_dst
,
855 ð
->addresses
.eth_src
);
860 case OVS_ACTION_ATTR_POP_ETH
:
861 DP_PACKET_BATCH_FOR_EACH (packet
, batch
) {
866 case OVS_ACTION_ATTR_PUSH_NSH
: {
867 uint32_t buffer
[NSH_HDR_MAX_LEN
/ 4];
868 struct nsh_hdr
*nsh_hdr
= ALIGNED_CAST(struct nsh_hdr
*, buffer
);
869 nsh_reset_ver_flags_ttl_len(nsh_hdr
);
870 odp_nsh_hdr_from_attr(nl_attr_get(a
), nsh_hdr
, NSH_HDR_MAX_LEN
);
871 DP_PACKET_BATCH_FOR_EACH (packet
, batch
) {
872 push_nsh(packet
, nsh_hdr
);
876 case OVS_ACTION_ATTR_POP_NSH
: {
878 const size_t num
= dp_packet_batch_size(batch
);
880 DP_PACKET_BATCH_REFILL_FOR_EACH (i
, num
, packet
, batch
) {
881 if (pop_nsh(packet
)) {
882 dp_packet_batch_refill(batch
, packet
, i
);
884 dp_packet_delete(packet
);
890 case OVS_ACTION_ATTR_OUTPUT
:
891 case OVS_ACTION_ATTR_TUNNEL_PUSH
:
892 case OVS_ACTION_ATTR_TUNNEL_POP
:
893 case OVS_ACTION_ATTR_USERSPACE
:
894 case OVS_ACTION_ATTR_RECIRC
:
895 case OVS_ACTION_ATTR_CT
:
896 case OVS_ACTION_ATTR_UNSPEC
:
897 case __OVS_ACTION_ATTR_MAX
:
902 dp_packet_delete_batch(batch
, steal
);