X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=datapath%2Fdatapath.c;h=b19123975ad1cca2fec2a958a734e3e048fb2840;hb=0c58c0c4da31b554e88be581cca39d314ded9b6b;hp=566aeed6e5dc3d10cc62d2512f1f03cd6035d4b4;hpb=c3729ee42dc25a8240cee6c0041b7db3e4070414;p=openvswitch diff --git a/datapath/datapath.c b/datapath/datapath.c index 566aeed6..b1912397 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -54,8 +54,8 @@ #include "vport-internal_dev.h" #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) || \ - LINUX_VERSION_CODE > KERNEL_VERSION(2,6,39) -#error Kernels before 2.6.18 or after 2.6.39 are not supported by this version of Open vSwitch. + LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0) +#error Kernels before 2.6.18 or after 3.0 are not supported by this version of Open vSwitch. #endif int (*dp_ioctl_hook)(struct net_device *dev, struct ifreq *rq, int cmd); @@ -84,7 +84,7 @@ EXPORT_SYMBOL(dp_ioctl_hook); static LIST_HEAD(dps); static struct vport *new_vport(const struct vport_parms *); -static int queue_control_packets(struct datapath *, struct sk_buff *, +static int queue_userspace_packets(struct datapath *, struct sk_buff *, const struct dp_upcall_info *); /* Must be called with rcu_read_lock, genl_mutex, or RTNL lock. */ @@ -289,7 +289,7 @@ void dp_process_received_packet(struct vport *p, struct sk_buff *skb) } if (is_frag && dp->drop_frags) { - kfree_skb(skb); + consume_skb(skb); stats_counter_off = offsetof(struct dp_stats_percpu, n_frags); goto out; } @@ -406,15 +406,16 @@ int dp_upcall(struct datapath *dp, struct sk_buff *skb, const struct dp_upcall_i if (skb_is_gso(skb)) { struct sk_buff *nskb = skb_gso_segment(skb, NETIF_F_SG | NETIF_F_HW_CSUM); - kfree_skb(skb); - skb = nskb; - if (IS_ERR(skb)) { - err = PTR_ERR(skb); + if (IS_ERR(nskb)) { + kfree_skb(skb); + err = PTR_ERR(nskb); goto err; } + consume_skb(skb); + skb = nskb; } - err = queue_control_packets(dp, skb, upcall_info); + err = queue_userspace_packets(dp, skb, upcall_info); if (err) goto err; @@ -437,7 +438,7 @@ err: * 'upcall_info'. There will be only one packet unless we broke up a GSO * packet. */ -static int queue_control_packets(struct datapath *dp, struct sk_buff *skb, +static int queue_userspace_packets(struct datapath *dp, struct sk_buff *skb, const struct dp_upcall_info *upcall_info) { u32 group = packet_mc_group(dp, upcall_info->cmd); @@ -506,7 +507,7 @@ static int queue_control_packets(struct datapath *dp, struct sk_buff *skb, if (err) goto err_kfree_skbs; - kfree_skb(skb); + consume_skb(skb); skb = nskb; } while (skb); return 0; @@ -551,7 +552,7 @@ static int validate_actions(const struct nlattr *attr) nla_for_each_nested(a, attr, rem) { static const u32 action_lens[ODP_ACTION_ATTR_MAX + 1] = { [ODP_ACTION_ATTR_OUTPUT] = 4, - [ODP_ACTION_ATTR_CONTROLLER] = 8, + [ODP_ACTION_ATTR_USERSPACE] = 8, [ODP_ACTION_ATTR_SET_DL_TCI] = 2, [ODP_ACTION_ATTR_STRIP_VLAN] = 0, [ODP_ACTION_ATTR_SET_DL_SRC] = ETH_ALEN, @@ -574,7 +575,7 @@ static int validate_actions(const struct nlattr *attr) case ODP_ACTION_ATTR_UNSPEC: return -EINVAL; - case ODP_ACTION_ATTR_CONTROLLER: + case ODP_ACTION_ATTR_USERSPACE: case ODP_ACTION_ATTR_STRIP_VLAN: case ODP_ACTION_ATTR_SET_DL_SRC: case ODP_ACTION_ATTR_SET_DL_DST: @@ -628,11 +629,13 @@ static int expand_table(struct datapath *dp) struct tbl *new_table; new_table = tbl_expand(old_table); - if (IS_ERR(new_table)) - return PTR_ERR(new_table); - - rcu_assign_pointer(dp->table, new_table); - tbl_deferred_destroy(old_table, NULL); + if (IS_ERR(new_table)) { + if (PTR_ERR(new_table) != -ENOSPC) + return PTR_ERR(new_table); + } else { + rcu_assign_pointer(dp->table, new_table); + tbl_deferred_destroy(old_table, NULL); + } return 0; } @@ -744,6 +747,9 @@ static struct genl_ops dp_packet_genl_ops[] = { static void get_dp_stats(struct datapath *dp, struct odp_stats *stats) { int i; + struct tbl *table = get_table_protected(dp); + + stats->n_flows = tbl_count(table); stats->n_frags = stats->n_hit = stats->n_missed = stats->n_lost = 0; for_each_possible_cpu(i) {