Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit edc1bb0b authored by David S. Miller's avatar David S. Miller
Browse files


Pravin B Shelar says:

====================
Open vSwitch

A set of fixes for net.
First bug is related flow-table management.  Second one is in sample
action. Third is related flow stats and last one add gre-err handler for ovs.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 11ef7a89 4a46b24e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -551,6 +551,8 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,

		case OVS_ACTION_ATTR_SAMPLE:
			err = sample(dp, skb, a);
			if (unlikely(err)) /* skb already freed. */
				return err;
			break;
		}

+13 −14
Original line number Diff line number Diff line
/*
 * Copyright (c) 2007-2013 Nicira, Inc.
 * Copyright (c) 2007-2014 Nicira, Inc.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General Public
@@ -276,7 +276,7 @@ void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb)
	OVS_CB(skb)->flow = flow;
	OVS_CB(skb)->pkt_key = &key;

	ovs_flow_stats_update(OVS_CB(skb)->flow, skb);
	ovs_flow_stats_update(OVS_CB(skb)->flow, key.tp.flags, skb);
	ovs_execute_actions(dp, skb);
	stats_counter = &stats->n_hit;

@@ -889,9 +889,12 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
		}
		/* The unmasked key has to be the same for flow updates. */
		if (unlikely(!ovs_flow_cmp_unmasked_key(flow, &match))) {
			error = -EEXIST;
			flow = ovs_flow_tbl_lookup_exact(&dp->table, &match);
			if (!flow) {
				error = -ENOENT;
				goto err_unlock_ovs;
			}
		}
		/* Update actions. */
		old_acts = ovsl_dereference(flow->sf_acts);
		rcu_assign_pointer(flow->sf_acts, acts);
@@ -981,16 +984,12 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
		goto err_unlock_ovs;
	}
	/* Check that the flow exists. */
	flow = ovs_flow_tbl_lookup(&dp->table, &key);
	flow = ovs_flow_tbl_lookup_exact(&dp->table, &match);
	if (unlikely(!flow)) {
		error = -ENOENT;
		goto err_unlock_ovs;
	}
	/* The unmasked key has to be the same for flow updates. */
	if (unlikely(!ovs_flow_cmp_unmasked_key(flow, &match))) {
		error = -EEXIST;
		goto err_unlock_ovs;
	}

	/* Update actions, if present. */
	if (likely(acts)) {
		old_acts = ovsl_dereference(flow->sf_acts);
@@ -1063,8 +1062,8 @@ static int ovs_flow_cmd_get(struct sk_buff *skb, struct genl_info *info)
		goto unlock;
	}

	flow = ovs_flow_tbl_lookup(&dp->table, &key);
	if (!flow || !ovs_flow_cmp_unmasked_key(flow, &match)) {
	flow = ovs_flow_tbl_lookup_exact(&dp->table, &match);
	if (!flow) {
		err = -ENOENT;
		goto unlock;
	}
@@ -1113,8 +1112,8 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
		goto unlock;
	}

	flow = ovs_flow_tbl_lookup(&dp->table, &key);
	if (unlikely(!flow || !ovs_flow_cmp_unmasked_key(flow, &match))) {
	flow = ovs_flow_tbl_lookup_exact(&dp->table, &match);
	if (unlikely(!flow)) {
		err = -ENOENT;
		goto unlock;
	}
+2 −2
Original line number Diff line number Diff line
@@ -61,10 +61,10 @@ u64 ovs_flow_used_time(unsigned long flow_jiffies)

#define TCP_FLAGS_BE16(tp) (*(__be16 *)&tcp_flag_word(tp) & htons(0x0FFF))

void ovs_flow_stats_update(struct sw_flow *flow, struct sk_buff *skb)
void ovs_flow_stats_update(struct sw_flow *flow, __be16 tcp_flags,
			   struct sk_buff *skb)
{
	struct flow_stats *stats;
	__be16 tcp_flags = flow->key.tp.flags;
	int node = numa_node_id();

	stats = rcu_dereference(flow->stats[node]);
+3 −2
Original line number Diff line number Diff line
/*
 * Copyright (c) 2007-2013 Nicira, Inc.
 * Copyright (c) 2007-2014 Nicira, Inc.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General Public
@@ -180,7 +180,8 @@ struct arp_eth_header {
	unsigned char       ar_tip[4];		/* target IP address        */
} __packed;

void ovs_flow_stats_update(struct sw_flow *, struct sk_buff *);
void ovs_flow_stats_update(struct sw_flow *, __be16 tcp_flags,
			   struct sk_buff *);
void ovs_flow_stats_get(const struct sw_flow *, struct ovs_flow_stats *,
			unsigned long *used, __be16 *tcp_flags);
void ovs_flow_stats_clear(struct sw_flow *);
+16 −0
Original line number Diff line number Diff line
@@ -456,6 +456,22 @@ struct sw_flow *ovs_flow_tbl_lookup(struct flow_table *tbl,
	return ovs_flow_tbl_lookup_stats(tbl, key, &n_mask_hit);
}

struct sw_flow *ovs_flow_tbl_lookup_exact(struct flow_table *tbl,
					  struct sw_flow_match *match)
{
	struct table_instance *ti = rcu_dereference_ovsl(tbl->ti);
	struct sw_flow_mask *mask;
	struct sw_flow *flow;

	/* Always called under ovs-mutex. */
	list_for_each_entry(mask, &tbl->mask_list, list) {
		flow = masked_flow_lookup(ti, match->key, mask);
		if (flow && ovs_flow_cmp_unmasked_key(flow, match))  /* Found */
			return flow;
	}
	return NULL;
}

int ovs_flow_tbl_num_masks(const struct flow_table *table)
{
	struct sw_flow_mask *mask;
Loading