2 * Copyright (c) 2009, 2010, 2011, 2012, 2013 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 <linux/openvswitch.h>
28 #include "unaligned.h"
32 odp_eth_set_addrs(struct ofpbuf
*packet
, const struct ovs_key_ethernet
*eth_key
)
34 struct eth_header
*eh
= packet
->l2
;
36 memcpy(eh
->eth_src
, eth_key
->eth_src
, sizeof eh
->eth_src
);
37 memcpy(eh
->eth_dst
, eth_key
->eth_dst
, sizeof eh
->eth_dst
);
41 odp_set_tunnel_action(const struct nlattr
*a
, struct flow_tnl
*tun_key
)
43 enum odp_key_fitness fitness
;
45 fitness
= odp_tun_key_from_attr(a
, tun_key
);
46 ovs_assert(fitness
!= ODP_FIT_ERROR
);
50 set_arp(struct ofpbuf
*packet
, const struct ovs_key_arp
*arp_key
)
52 struct arp_eth_header
*arp
= packet
->l3
;
54 arp
->ar_op
= arp_key
->arp_op
;
55 memcpy(arp
->ar_sha
, arp_key
->arp_sha
, ETH_ADDR_LEN
);
56 put_16aligned_be32(&arp
->ar_spa
, arp_key
->arp_sip
);
57 memcpy(arp
->ar_tha
, arp_key
->arp_tha
, ETH_ADDR_LEN
);
58 put_16aligned_be32(&arp
->ar_tpa
, arp_key
->arp_tip
);
62 odp_execute_set_action(struct ofpbuf
*packet
, const struct nlattr
*a
,
65 enum ovs_key_attr type
= nl_attr_type(a
);
66 const struct ovs_key_ipv4
*ipv4_key
;
67 const struct ovs_key_ipv6
*ipv6_key
;
68 const struct ovs_key_tcp
*tcp_key
;
69 const struct ovs_key_udp
*udp_key
;
70 const struct ovs_key_sctp
*sctp_key
;
73 case OVS_KEY_ATTR_PRIORITY
:
74 flow
->skb_priority
= nl_attr_get_u32(a
);
77 case OVS_KEY_ATTR_TUNNEL
:
78 odp_set_tunnel_action(a
, &flow
->tunnel
);
81 case OVS_KEY_ATTR_SKB_MARK
:
82 flow
->pkt_mark
= nl_attr_get_u32(a
);
85 case OVS_KEY_ATTR_ETHERNET
:
86 odp_eth_set_addrs(packet
,
87 nl_attr_get_unspec(a
, sizeof(struct ovs_key_ethernet
)));
90 case OVS_KEY_ATTR_IPV4
:
91 ipv4_key
= nl_attr_get_unspec(a
, sizeof(struct ovs_key_ipv4
));
92 packet_set_ipv4(packet
, ipv4_key
->ipv4_src
, ipv4_key
->ipv4_dst
,
93 ipv4_key
->ipv4_tos
, ipv4_key
->ipv4_ttl
);
96 case OVS_KEY_ATTR_IPV6
:
97 ipv6_key
= nl_attr_get_unspec(a
, sizeof(struct ovs_key_ipv6
));
98 packet_set_ipv6(packet
, ipv6_key
->ipv6_proto
, ipv6_key
->ipv6_src
,
99 ipv6_key
->ipv6_dst
, ipv6_key
->ipv6_tclass
,
100 ipv6_key
->ipv6_label
, ipv6_key
->ipv6_hlimit
);
103 case OVS_KEY_ATTR_TCP
:
104 tcp_key
= nl_attr_get_unspec(a
, sizeof(struct ovs_key_tcp
));
105 packet_set_tcp_port(packet
, tcp_key
->tcp_src
, tcp_key
->tcp_dst
);
108 case OVS_KEY_ATTR_UDP
:
109 udp_key
= nl_attr_get_unspec(a
, sizeof(struct ovs_key_udp
));
110 packet_set_udp_port(packet
, udp_key
->udp_src
, udp_key
->udp_dst
);
113 case OVS_KEY_ATTR_SCTP
:
114 sctp_key
= nl_attr_get_unspec(a
, sizeof(struct ovs_key_sctp
));
115 packet_set_sctp_port(packet
, sctp_key
->sctp_src
, sctp_key
->sctp_dst
);
118 case OVS_KEY_ATTR_MPLS
:
119 set_mpls_lse(packet
, nl_attr_get_be32(a
));
122 case OVS_KEY_ATTR_ARP
:
123 set_arp(packet
, nl_attr_get_unspec(a
, sizeof(struct ovs_key_arp
)));
126 case OVS_KEY_ATTR_UNSPEC
:
127 case OVS_KEY_ATTR_ENCAP
:
128 case OVS_KEY_ATTR_ETHERTYPE
:
129 case OVS_KEY_ATTR_IN_PORT
:
130 case OVS_KEY_ATTR_VLAN
:
131 case OVS_KEY_ATTR_ICMP
:
132 case OVS_KEY_ATTR_ICMPV6
:
133 case OVS_KEY_ATTR_ND
:
134 case OVS_KEY_ATTR_TCP_FLAGS
:
135 case __OVS_KEY_ATTR_MAX
:
142 odp_execute_actions__(void *dp
, struct ofpbuf
*packet
, struct flow
*key
,
143 const struct nlattr
*actions
, size_t actions_len
,
144 odp_output_cb output
, odp_userspace_cb userspace
,
148 odp_execute_sample(void *dp
, struct ofpbuf
*packet
, struct flow
*key
,
149 const struct nlattr
*action
, odp_output_cb output
,
150 odp_userspace_cb userspace
, bool more_actions
)
152 const struct nlattr
*subactions
= NULL
;
153 const struct nlattr
*a
;
156 NL_NESTED_FOR_EACH_UNSAFE (a
, left
, action
) {
157 int type
= nl_attr_type(a
);
159 switch ((enum ovs_sample_attr
) type
) {
160 case OVS_SAMPLE_ATTR_PROBABILITY
:
161 if (random_uint32() >= nl_attr_get_u32(a
)) {
166 case OVS_SAMPLE_ATTR_ACTIONS
:
170 case OVS_SAMPLE_ATTR_UNSPEC
:
171 case __OVS_SAMPLE_ATTR_MAX
:
177 odp_execute_actions__(dp
, packet
, key
, nl_attr_get(subactions
),
178 nl_attr_get_size(subactions
), output
, userspace
,
183 odp_execute_actions__(void *dp
, struct ofpbuf
*packet
, struct flow
*key
,
184 const struct nlattr
*actions
, size_t actions_len
,
185 odp_output_cb output
, odp_userspace_cb userspace
,
188 const struct nlattr
*a
;
191 NL_ATTR_FOR_EACH_UNSAFE (a
, left
, actions
, actions_len
) {
192 int type
= nl_attr_type(a
);
194 switch ((enum ovs_action_attr
) type
) {
195 case OVS_ACTION_ATTR_OUTPUT
:
197 output(dp
, packet
, key
, u32_to_odp(nl_attr_get_u32(a
)));
201 case OVS_ACTION_ATTR_USERSPACE
: {
203 /* Allow 'userspace' to steal the packet data if we do not
204 * need it any more. */
205 bool steal
= !more_actions
&& left
<= NLA_ALIGN(a
->nla_len
);
206 userspace(dp
, packet
, key
, a
, steal
);
211 case OVS_ACTION_ATTR_PUSH_VLAN
: {
212 const struct ovs_action_push_vlan
*vlan
= nl_attr_get(a
);
213 eth_push_vlan(packet
, vlan
->vlan_tci
);
217 case OVS_ACTION_ATTR_POP_VLAN
:
218 eth_pop_vlan(packet
);
221 case OVS_ACTION_ATTR_PUSH_MPLS
: {
222 const struct ovs_action_push_mpls
*mpls
= nl_attr_get(a
);
223 push_mpls(packet
, mpls
->mpls_ethertype
, mpls
->mpls_lse
);
227 case OVS_ACTION_ATTR_POP_MPLS
:
228 pop_mpls(packet
, nl_attr_get_be16(a
));
231 case OVS_ACTION_ATTR_SET
:
232 odp_execute_set_action(packet
, nl_attr_get(a
), key
);
235 case OVS_ACTION_ATTR_SAMPLE
:
236 odp_execute_sample(dp
, packet
, key
, a
, output
, userspace
,
237 more_actions
|| left
> NLA_ALIGN(a
->nla_len
));
240 case OVS_ACTION_ATTR_UNSPEC
:
241 case __OVS_ACTION_ATTR_MAX
:
248 odp_execute_actions(void *dp
, struct ofpbuf
*packet
, struct flow
*key
,
249 const struct nlattr
*actions
, size_t actions_len
,
250 odp_output_cb output
, odp_userspace_cb userspace
)
252 odp_execute_actions__(dp
, packet
, key
, actions
, actions_len
, output
,