X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=datapath%2Fdatapath.c;h=1ea5d1e9a7c2d850cf989b34c6a5f3e7b53d25ac;hb=6161d3fd928edf7016abae60f549a135a2f83f09;hp=2d67657da8fd64b40d5cdbb02cf4aaed61ce9741;hpb=fea393b1d6b2729a784b898dbdd48d30d42e3ff7;p=openvswitch diff --git a/datapath/datapath.c b/datapath/datapath.c index 2d67657d..1ea5d1e9 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -1,13 +1,21 @@ /* - * Copyright (c) 2007, 2008, 2009, 2010, 2011 Nicira Networks. - * Distributed under the terms of the GNU GPL version 2. + * Copyright (c) 2007-2011 Nicira Networks. * - * Significant portions of this file may be copied from parts of the Linux - * kernel, by Linus Torvalds and others. + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA */ -/* Functions for managing the dp interface/device. */ - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include @@ -87,7 +95,7 @@ static int queue_userspace_packet(int dp_ifindex, struct sk_buff *, const struct dp_upcall_info *); /* Must be called with rcu_read_lock, genl_mutex, or RTNL lock. */ -struct datapath *get_dp(int dp_ifindex) +static struct datapath *get_dp(int dp_ifindex) { struct datapath *dp = NULL; struct net_device *dev; @@ -103,7 +111,6 @@ struct datapath *get_dp(int dp_ifindex) return dp; } -EXPORT_SYMBOL_GPL(get_dp); /* Must be called with genl_mutex. */ static struct flow_table *get_table_protected(struct datapath *dp) @@ -241,7 +248,7 @@ static void destroy_dp_rcu(struct rcu_head *rcu) { struct datapath *dp = container_of(rcu, struct datapath, rcu); - flow_tbl_destroy(dp->table); + flow_tbl_destroy((__force struct flow_table *)dp->table); free_percpu(dp->stats_percpu); kobject_put(&dp->ifobj); } @@ -430,17 +437,28 @@ static int queue_userspace_packet(int dp_ifindex, struct sk_buff *skb, const struct dp_upcall_info *upcall_info) { struct ovs_header *upcall; + struct sk_buff *nskb = NULL; struct sk_buff *user_skb; /* to be queued to userspace */ struct nlattr *nla; unsigned int len; int err; - err = vlan_deaccel_tag(skb); - if (unlikely(err)) - return err; + if (vlan_tx_tag_present(skb)) { + nskb = skb_clone(skb, GFP_ATOMIC); + if (!nskb) + return -ENOMEM; + + err = vlan_deaccel_tag(nskb); + if (err) + return err; - if (nla_attr_size(skb->len) > USHRT_MAX) - return -EFBIG; + skb = nskb; + } + + if (nla_attr_size(skb->len) > USHRT_MAX) { + err = -EFBIG; + goto out; + } len = sizeof(struct ovs_header); len += nla_total_size(skb->len); @@ -449,8 +467,10 @@ static int queue_userspace_packet(int dp_ifindex, struct sk_buff *skb, len += nla_total_size(8); user_skb = genlmsg_new(len, GFP_ATOMIC); - if (!user_skb) - return -ENOMEM; + if (!user_skb) { + err = -ENOMEM; + goto out; + } upcall = genlmsg_put(user_skb, 0, 0, &dp_packet_genl_family, 0, upcall_info->cmd); @@ -468,7 +488,11 @@ static int queue_userspace_packet(int dp_ifindex, struct sk_buff *skb, skb_copy_and_csum_dev(skb, nla_data(nla)); - return genlmsg_unicast(&init_net, user_skb, upcall_info->pid); + err = genlmsg_unicast(&init_net, user_skb, upcall_info->pid); + +out: + kfree_skb(nskb); + return err; } /* Called with genl_mutex. */ @@ -657,7 +681,7 @@ static int validate_actions(const struct nlattr *attr, vlan = nla_data(a); if (vlan->vlan_tpid != htons(ETH_P_8021Q)) return -EINVAL; - if (vlan->vlan_tci & htons(VLAN_TAG_PRESENT)) + if (!(vlan->vlan_tci & htons(VLAN_TAG_PRESENT))) return -EINVAL; break; @@ -1254,7 +1278,7 @@ static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb, u32 pid, u32 seq, u32 flags, u8 cmd) { struct ovs_header *ovs_header; - struct nlattr *nla; + struct ovs_dp_stats dp_stats; int err; ovs_header = genlmsg_put(skb, pid, seq, &dp_datapath_genl_family, @@ -1270,10 +1294,8 @@ static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb, if (err) goto nla_put_failure; - nla = nla_reserve(skb, OVS_DP_ATTR_STATS, sizeof(struct ovs_dp_stats)); - if (!nla) - goto nla_put_failure; - get_dp_stats(dp, nla_data(nla)); + get_dp_stats(dp, &dp_stats); + NLA_PUT(skb, OVS_DP_ATTR_STATS, sizeof(struct ovs_dp_stats), &dp_stats); return genlmsg_end(skb, ovs_header); @@ -1597,7 +1619,7 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, u32 pid, u32 seq, u32 flags, u8 cmd) { struct ovs_header *ovs_header; - struct nlattr *nla; + struct ovs_vport_stats vport_stats; int err; ovs_header = genlmsg_put(skb, pid, seq, &dp_vport_genl_family, @@ -1612,12 +1634,9 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, NLA_PUT_STRING(skb, OVS_VPORT_ATTR_NAME, vport->ops->get_name(vport)); NLA_PUT_U32(skb, OVS_VPORT_ATTR_UPCALL_PID, vport->upcall_pid); - nla = nla_reserve(skb, OVS_VPORT_ATTR_STATS, - sizeof(struct ovs_vport_stats)); - if (!nla) - goto nla_put_failure; - - vport_get_stats(vport, nla_data(nla)); + vport_get_stats(vport, &vport_stats); + NLA_PUT(skb, OVS_VPORT_ATTR_STATS, sizeof(struct ovs_vport_stats), + &vport_stats); NLA_PUT(skb, OVS_VPORT_ATTR_ADDRESS, ETH_ALEN, vport->ops->get_addr(vport)); @@ -2032,7 +2051,7 @@ static int __init dp_init(void) BUILD_BUG_ON(sizeof(struct ovs_skb_cb) > sizeof(dummy_skb->cb)); - pr_info("Open vSwitch %s, built "__DATE__" "__TIME__"\n", + pr_info("Open vSwitch switching datapath %s, built "__DATE__" "__TIME__"\n", VERSION BUILDNR); err = tnl_init();