diff options
author | Simon Horman <horms@verge.net.au> | 2013-05-29 15:06:38 +0900 |
---|---|---|
committer | Ben Pfaff <blp@nicira.com> | 2013-05-29 13:13:34 -0700 |
commit | f094af7b17631ce688595d7cf70235a3eed9798c (patch) | |
tree | 1b4a72755325f3f65e514a0956a4b790ae34a99d /lib/dpif-netdev.c | |
parent | 81a114e557229fc4f0ced228626ff6f6e632ce6f (diff) |
odp-execute: New module for executing datapath actions.
This moves generic action execution code out of lib/dpif-netedev.c
and into a new file, lib/odp-execute.c.
This is in preparation for using odp_execute_actions()
in lib/odp-util.c to handle recirculation/
Signed-off-by: Simon Horman <horms@verge.net.au>
Signed-off-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'lib/dpif-netdev.c')
-rw-r--r-- | lib/dpif-netdev.c | 171 |
1 files changed, 8 insertions, 163 deletions
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index a4ac23f1..bd00f184 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -42,6 +42,7 @@ #include "netdev.h" #include "netdev-vport.h" #include "netlink.h" +#include "odp-execute.h" #include "odp-util.h" #include "ofp-print.h" #include "ofpbuf.h" @@ -1095,18 +1096,9 @@ dpif_netdev_wait(struct dpif *dpif) } static void -dp_netdev_set_dl(struct ofpbuf *packet, const struct ovs_key_ethernet *eth_key) -{ - struct eth_header *eh = packet->l2; - - memcpy(eh->eth_src, eth_key->eth_src, sizeof eh->eth_src); - memcpy(eh->eth_dst, eth_key->eth_dst, sizeof eh->eth_dst); -} - -static void -dp_netdev_output_port(struct dp_netdev *dp, struct ofpbuf *packet, - uint32_t out_port) +dp_netdev_output_port(void *dp_, struct ofpbuf *packet, uint32_t out_port) { + struct dp_netdev *dp = dp_; struct dp_netdev_port *p = dp->ports[out_port]; if (p) { netdev_send(p->netdev, packet); @@ -1163,168 +1155,21 @@ dp_netdev_output_userspace(struct dp_netdev *dp, const struct ofpbuf *packet, } static void -dp_netdev_sample(struct dp_netdev *dp, - struct ofpbuf *packet, struct flow *key, - const struct nlattr *action) -{ - const struct nlattr *subactions = NULL; - const struct nlattr *a; - size_t left; - - NL_NESTED_FOR_EACH_UNSAFE (a, left, action) { - int type = nl_attr_type(a); - - switch ((enum ovs_sample_attr) type) { - case OVS_SAMPLE_ATTR_PROBABILITY: - if (random_uint32() >= nl_attr_get_u32(a)) { - return; - } - break; - - case OVS_SAMPLE_ATTR_ACTIONS: - subactions = a; - break; - - case OVS_SAMPLE_ATTR_UNSPEC: - case __OVS_SAMPLE_ATTR_MAX: - default: - NOT_REACHED(); - } - } - - dp_netdev_execute_actions(dp, packet, key, nl_attr_get(subactions), - nl_attr_get_size(subactions)); -} - -static void -dp_netdev_action_userspace(struct dp_netdev *dp, - struct ofpbuf *packet, const struct flow *key, - const struct nlattr *userdata) +dp_netdev_action_userspace(void *dp, struct ofpbuf *packet, + const struct flow *key, + const struct nlattr *userdata) { dp_netdev_output_userspace(dp, packet, DPIF_UC_ACTION, key, userdata); } static void -execute_set_action(struct ofpbuf *packet, const struct nlattr *a) -{ - enum ovs_key_attr type = nl_attr_type(a); - const struct ovs_key_ipv4 *ipv4_key; - const struct ovs_key_ipv6 *ipv6_key; - const struct ovs_key_tcp *tcp_key; - const struct ovs_key_udp *udp_key; - - switch (type) { - case OVS_KEY_ATTR_PRIORITY: - case OVS_KEY_ATTR_SKB_MARK: - case OVS_KEY_ATTR_TUNNEL: - /* not implemented */ - break; - - case OVS_KEY_ATTR_ETHERNET: - dp_netdev_set_dl(packet, - nl_attr_get_unspec(a, sizeof(struct ovs_key_ethernet))); - break; - - case OVS_KEY_ATTR_IPV4: - ipv4_key = nl_attr_get_unspec(a, sizeof(struct ovs_key_ipv4)); - packet_set_ipv4(packet, ipv4_key->ipv4_src, ipv4_key->ipv4_dst, - ipv4_key->ipv4_tos, ipv4_key->ipv4_ttl); - break; - - case OVS_KEY_ATTR_IPV6: - ipv6_key = nl_attr_get_unspec(a, sizeof(struct ovs_key_ipv6)); - packet_set_ipv6(packet, ipv6_key->ipv6_proto, ipv6_key->ipv6_src, - ipv6_key->ipv6_dst, ipv6_key->ipv6_tclass, - ipv6_key->ipv6_label, ipv6_key->ipv6_hlimit); - break; - - case OVS_KEY_ATTR_TCP: - tcp_key = nl_attr_get_unspec(a, sizeof(struct ovs_key_tcp)); - packet_set_tcp_port(packet, tcp_key->tcp_src, tcp_key->tcp_dst); - break; - - case OVS_KEY_ATTR_UDP: - udp_key = nl_attr_get_unspec(a, sizeof(struct ovs_key_udp)); - packet_set_udp_port(packet, udp_key->udp_src, udp_key->udp_dst); - break; - - case OVS_KEY_ATTR_MPLS: - set_mpls_lse(packet, nl_attr_get_be32(a)); - break; - - case OVS_KEY_ATTR_UNSPEC: - case OVS_KEY_ATTR_ENCAP: - case OVS_KEY_ATTR_ETHERTYPE: - case OVS_KEY_ATTR_IN_PORT: - case OVS_KEY_ATTR_VLAN: - case OVS_KEY_ATTR_ICMP: - case OVS_KEY_ATTR_ICMPV6: - case OVS_KEY_ATTR_ARP: - case OVS_KEY_ATTR_ND: - case __OVS_KEY_ATTR_MAX: - default: - NOT_REACHED(); - } -} - -static void dp_netdev_execute_actions(struct dp_netdev *dp, struct ofpbuf *packet, struct flow *key, const struct nlattr *actions, size_t actions_len) { - const struct nlattr *a; - unsigned int left; - - NL_ATTR_FOR_EACH_UNSAFE (a, left, actions, actions_len) { - int type = nl_attr_type(a); - - switch ((enum ovs_action_attr) type) { - case OVS_ACTION_ATTR_OUTPUT: - dp_netdev_output_port(dp, packet, nl_attr_get_u32(a)); - break; - - case OVS_ACTION_ATTR_USERSPACE: { - const struct nlattr *userdata; - - userdata = nl_attr_find_nested(a, OVS_USERSPACE_ATTR_USERDATA); - dp_netdev_action_userspace(dp, packet, key, userdata); - break; - } - - case OVS_ACTION_ATTR_PUSH_VLAN: { - const struct ovs_action_push_vlan *vlan = nl_attr_get(a); - eth_push_vlan(packet, vlan->vlan_tci); - break; - } - - case OVS_ACTION_ATTR_POP_VLAN: - eth_pop_vlan(packet); - break; - - case OVS_ACTION_ATTR_PUSH_MPLS: { - const struct ovs_action_push_mpls *mpls = nl_attr_get(a); - push_mpls(packet, mpls->mpls_ethertype, mpls->mpls_lse); - break; - } - - case OVS_ACTION_ATTR_POP_MPLS: - pop_mpls(packet, nl_attr_get_be16(a)); - break; - - case OVS_ACTION_ATTR_SET: - execute_set_action(packet, nl_attr_get(a)); - break; - - case OVS_ACTION_ATTR_SAMPLE: - dp_netdev_sample(dp, packet, key, a); - break; - - case OVS_ACTION_ATTR_UNSPEC: - case __OVS_ACTION_ATTR_MAX: - NOT_REACHED(); - } - } + odp_execute_actions(dp, packet, key, actions, actions_len, + dp_netdev_output_port, dp_netdev_action_userspace); } const struct dpif_class dpif_netdev_class = { |