Skip to content

Commit

Permalink
datapath: refactor ovs flow extract API.
Browse files Browse the repository at this point in the history
OVS flow extract is called on packet receive or packet
execute code path.  Following patch defines separate API
for extracting flow-key in packet execute code path.

Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Acked-by: Andy Zhou <azhou@nicira.com>
  • Loading branch information
Pravin B Shelar committed Aug 14, 2014
1 parent 5024d88 commit e58ba93
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 42 deletions.
3 changes: 1 addition & 2 deletions datapath/actions.c
Expand Up @@ -554,11 +554,10 @@ static int execute_recirc(struct datapath *dp, struct sk_buff *skb,
const struct nlattr *a)
{
struct sw_flow_key recirc_key;
const struct vport *p = OVS_CB(skb)->input_vport;
uint32_t hash = OVS_CB(skb)->pkt_key->ovs_flow_hash;
int err;

err = ovs_flow_extract(skb, p->port_no, &recirc_key);
err = ovs_flow_key_extract(skb, &recirc_key);
if (err) {
kfree_skb(skb);
return err;
Expand Down
8 changes: 3 additions & 5 deletions datapath/datapath.c
Expand Up @@ -293,7 +293,7 @@ void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb)
OVS_CB(skb)->input_vport = p;

/* Extract flow from 'skb' into 'key'. */
error = ovs_flow_extract(skb, p->port_no, &key);
error = ovs_flow_key_extract(skb, &key);
if (unlikely(error)) {
kfree_skb(skb);
return;
Expand Down Expand Up @@ -570,13 +570,11 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
if (IS_ERR(flow))
goto err_kfree_skb;

err = ovs_flow_extract(packet, -1, &flow->key);
err = ovs_flow_key_extract_userspace(a[OVS_PACKET_ATTR_KEY], packet,
&flow->key);
if (err)
goto err_flow_free;

err = ovs_nla_get_flow_metadata(flow, a[OVS_PACKET_ATTR_KEY]);
if (err)
goto err_flow_free;
acts = ovs_nla_alloc_flow_actions(nla_len(a[OVS_PACKET_ATTR_ACTIONS]));
err = PTR_ERR(acts);
if (IS_ERR(acts))
Expand Down
49 changes: 36 additions & 13 deletions datapath/flow.c
Expand Up @@ -16,8 +16,6 @@
* 02110-1301, USA
*/

#include "flow.h"
#include "datapath.h"
#include <linux/uaccess.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
Expand Down Expand Up @@ -45,6 +43,10 @@
#include <net/ipv6.h>
#include <net/ndisc.h>

#include "datapath.h"
#include "flow.h"
#include "flow_netlink.h"

#include "vlan.h"

u64 ovs_flow_used_time(unsigned long flow_jiffies)
Expand Down Expand Up @@ -421,10 +423,9 @@ static int parse_icmpv6(struct sk_buff *skb, struct sw_flow_key *key,
}

/**
* ovs_flow_extract - extracts a flow key from an Ethernet frame.
* key_extract - extracts a flow key from an Ethernet frame.
* @skb: sk_buff that contains the frame, with skb->data pointing to the
* Ethernet header
* @in_port: port number on which @skb was received.
* @key: output flow key
*
* The caller must ensure that skb->len >= ETH_HLEN.
Expand All @@ -443,19 +444,11 @@ static int parse_icmpv6(struct sk_buff *skb, struct sw_flow_key *key,
* of a correct length, otherwise the same as skb->network_header.
* For other key->eth.type values it is left untouched.
*/
int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key)
static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
{
int error;
struct ethhdr *eth;

memset(key, 0, sizeof(*key));

key->phy.priority = skb->priority;
if (OVS_CB(skb)->tun_key)
memcpy(&key->tun_key, OVS_CB(skb)->tun_key, sizeof(key->tun_key));
key->phy.in_port = in_port;
key->phy.skb_mark = skb->mark;

skb_reset_mac_header(skb);

/* Link layer. We are guaranteed to have at least the 14 byte Ethernet
Expand Down Expand Up @@ -613,3 +606,33 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key)

return 0;
}

int ovs_flow_key_extract(struct sk_buff *skb, struct sw_flow_key *key)
{
/* Extract metadata from packet. */

memset(key, 0, sizeof(*key));
if (OVS_CB(skb)->tun_key)
memcpy(&key->tun_key, OVS_CB(skb)->tun_key, sizeof(key->tun_key));

key->phy.priority = skb->priority;
key->phy.in_port = OVS_CB(skb)->input_vport->port_no;
key->phy.skb_mark = skb->mark;

return key_extract(skb, key);
}

int ovs_flow_key_extract_userspace(const struct nlattr *attr,
struct sk_buff *skb,
struct sw_flow_key *key)
{
int err;

memset(key, 0, sizeof(*key));
/* Extract metadata from netlink attributes. */
err = ovs_nla_get_flow_metadata(attr, key);
if (err)
return err;

return key_extract(skb, key);
}
6 changes: 5 additions & 1 deletion datapath/flow.h
Expand Up @@ -190,6 +190,10 @@ void ovs_flow_stats_get(const struct sw_flow *, struct ovs_flow_stats *,
void ovs_flow_stats_clear(struct sw_flow *);
u64 ovs_flow_used_time(unsigned long flow_jiffies);

int ovs_flow_extract(struct sk_buff *, u16 in_port, struct sw_flow_key *);
int ovs_flow_key_extract(struct sk_buff *skb, struct sw_flow_key *key);
/* Extract key from packet coming from userspace. */
int ovs_flow_key_extract_userspace(const struct nlattr *attr,
struct sk_buff *skb,
struct sw_flow_key *key);

#endif /* flow.h */
26 changes: 7 additions & 19 deletions datapath/flow_netlink.c
Expand Up @@ -853,7 +853,7 @@ int ovs_nla_get_match(struct sw_flow_match *match,

/**
* ovs_nla_get_flow_metadata - parses Netlink attributes into a flow key.
* @flow: Receives extracted in_port, priority, tun_key and skb_mark.
* @key: Receives extracted in_port, priority, tun_key and skb_mark.
* @attr: Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink attribute
* sequence.
*
Expand All @@ -862,35 +862,23 @@ int ovs_nla_get_match(struct sw_flow_match *match,
* get the metadata, that is, the parts of the flow key that cannot be
* extracted from the packet itself.
*/

int ovs_nla_get_flow_metadata(struct sw_flow *flow,
const struct nlattr *attr)
int ovs_nla_get_flow_metadata(const struct nlattr *attr,
struct sw_flow_key *key)
{
struct ovs_key_ipv4_tunnel *tun_key = &flow->key.tun_key;
const struct nlattr *a[OVS_KEY_ATTR_MAX + 1];
struct sw_flow_match match;
u64 attrs = 0;
int err;
struct sw_flow_match match;

flow->key.phy.in_port = DP_MAX_PORTS;
flow->key.phy.priority = 0;
flow->key.phy.skb_mark = 0;
flow->key.ovs_flow_hash = 0;
flow->key.recirc_id = 0;
memset(tun_key, 0, sizeof(flow->key.tun_key));

err = parse_flow_nlattrs(attr, a, &attrs);
if (err)
return -EINVAL;

memset(&match, 0, sizeof(match));
match.key = &flow->key;
match.key = key;

err = metadata_from_nlattrs(&match, &attrs, a, false);
if (err)
return err;

return 0;
key->phy.in_port = DP_MAX_PORTS;
return metadata_from_nlattrs(&match, &attrs, a, false);
}

int ovs_nla_put_flow(const struct sw_flow_key *swkey,
Expand Down
4 changes: 2 additions & 2 deletions datapath/flow_netlink.h
Expand Up @@ -42,8 +42,8 @@ void ovs_match_init(struct sw_flow_match *match,

int ovs_nla_put_flow(const struct sw_flow_key *,
const struct sw_flow_key *, struct sk_buff *);
int ovs_nla_get_flow_metadata(struct sw_flow *flow,
const struct nlattr *attr);
int ovs_nla_get_flow_metadata(const struct nlattr *, struct sw_flow_key *);

int ovs_nla_get_match(struct sw_flow_match *match,
const struct nlattr *,
const struct nlattr *);
Expand Down

0 comments on commit e58ba93

Please sign in to comment.