X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=inline;f=datapath%2Fdatapath.c;h=9f415ac5c3ce90062126220ebb26f46f527ca59a;hb=35f7605b3f40ebe49e4a1ad2555ef89ba48433b5;hp=6e97c345b288472a8af1714f18a5c3830ba58929;hpb=18fdbe16de40062c63f9119a6beef17602f4b233;p=openvswitch diff --git a/datapath/datapath.c b/datapath/datapath.c index 6e97c345..9f415ac5 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, 2009 Nicira Networks. + * Copyright (c) 2007, 2008, 2009, 2010 Nicira Networks. * Distributed under the terms of the GNU GPL version 2. * * Significant portions of this file may be copied from parts of the Linux @@ -81,7 +81,7 @@ struct datapath *get_dp(int dp_idx) } EXPORT_SYMBOL_GPL(get_dp); -struct datapath *get_dp_locked(int dp_idx) +static struct datapath *get_dp_locked(int dp_idx) { struct datapath *dp; @@ -176,7 +176,7 @@ static void release_dp(struct kobject *kobj) kfree(dp); } -struct kobj_type dp_ktype = { +static struct kobj_type dp_ktype = { .release = release_dp }; @@ -232,7 +232,7 @@ static int create_dp(int dp_idx, const char __user *devnamep) if (!dp->table) goto err_free_dp; - /* Setup our datapath device */ + /* Set up our datapath device. */ dp_dev = dp_dev_create(dp, devname, ODPP_LOCAL); err = PTR_ERR(dp_dev); if (IS_ERR(dp_dev)) @@ -325,7 +325,7 @@ static void release_nbp(struct kobject *kobj) kfree(p); } -struct kobj_type brport_ktype = { +static struct kobj_type brport_ktype = { #ifdef CONFIG_SYSFS .sysfs_ops = &brport_sysfs_ops, #endif @@ -349,6 +349,7 @@ static int new_nbp(struct datapath *dp, struct net_device *dev, int port_no) p->port_no = port_no; p->dp = dp; p->dev = dev; + atomic_set(&p->sflow_pool, 0); if (!is_dp_dev(dev)) rcu_assign_pointer(dev->br_port, p); else { @@ -421,7 +422,7 @@ got_port_no: dp_sysfs_add_if(dp->ports[port_no]); - err = __put_user(port_no, &port.port); + err = __put_user(port_no, &portp->port); out_put: dev_put(dev); @@ -574,7 +575,7 @@ static int dp_frame_hook(struct net_bridge_port *p, struct sk_buff **pskb) #error #endif -#if defined(CONFIG_XEN) && LINUX_VERSION_CODE == KERNEL_VERSION(2,6,18) +#if defined(CONFIG_XEN) && defined(HAVE_PROTO_DATA_VALID) /* This code is copied verbatim from net/dev/core.c in Xen's * linux-2.6.18-92.1.10.el5.xs5.0.0.394.644. We can't call those functions * directly because they aren't exported. */ @@ -621,9 +622,7 @@ int vswitch_skb_checksum_setup(struct sk_buff *skb) out: return -EPROTO; } -#else -int vswitch_skb_checksum_setup(struct sk_buff *skb) { return 0; } -#endif /* CONFIG_XEN && linux == 2.6.18 */ +#endif /* CONFIG_XEN && HAVE_PROTO_DATA_VALID */ /* Append each packet in 'skb' list to 'queue'. There will be only one packet * unless we broke up a GSO packet. */ @@ -715,8 +714,7 @@ dp_output_control(struct datapath *dp, struct sk_buff *skb, int queue_no, int err; WARN_ON_ONCE(skb_shared(skb)); - BUG_ON(queue_no != _ODPL_MISS_NR && queue_no != _ODPL_ACTION_NR); - + BUG_ON(queue_no != _ODPL_MISS_NR && queue_no != _ODPL_ACTION_NR && queue_no != _ODPL_SFLOW_NR); queue = &dp->queues[queue_no]; err = -ENOBUFS; if (skb_queue_len(queue) >= DP_MAX_QUEUE_LEN) @@ -1021,7 +1019,7 @@ static int del_flow(struct datapath *dp, struct odp_flow __user *ufp) * we get completely accurate stats, but that blows our performance, * badly. */ dp->n_flows--; - error = answer_query(flow, uf.flags, ufp); + error = answer_query(flow, 0, ufp); flow_deferred_free(flow); error: @@ -1046,7 +1044,7 @@ static int query_flows(struct datapath *dp, const struct odp_flowvec *flowvec) if (!flow) error = __put_user(ENOENT, &ufp->stats.error); else - error = answer_query(flow, 0, ufp); + error = answer_query(flow, uf.flags, ufp); if (error) return -EFAULT; } @@ -1167,9 +1165,9 @@ static int do_execute(struct datapath *dp, const struct odp_execute *executep) skb_reset_mac_header(skb); eth = eth_hdr(skb); - /* Normally, setting the skb 'protocol' field would be handled by a - * call to eth_type_trans(), but it assumes there's a sending - * device, which we may not have. */ + /* Normally, setting the skb 'protocol' field would be handled by a + * call to eth_type_trans(), but it assumes there's a sending + * device, which we may not have. */ if (ntohs(eth->h_proto) >= 1536) skb->protocol = eth->h_proto; else @@ -1393,6 +1391,7 @@ static long openvswitch_ioctl(struct file *f, unsigned int cmd, int dp_idx = iminor(f->f_dentry->d_inode); struct datapath *dp; int drop_frags, listeners, port_no; + unsigned int sflow_probability; int err; /* Handle commands with special locking requirements up front. */ @@ -1456,6 +1455,16 @@ static long openvswitch_ioctl(struct file *f, unsigned int cmd, set_listen_mask(f, listeners); break; + case ODP_GET_SFLOW_PROBABILITY: + err = put_user(dp->sflow_probability, (unsigned int __user *)argp); + break; + + case ODP_SET_SFLOW_PROBABILITY: + err = get_user(sflow_probability, (unsigned int __user *)argp); + if (!err) + dp->sflow_probability = sflow_probability; + break; + case ODP_PORT_QUERY: err = query_port(dp, (struct odp_port __user *)argp); break;