X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=datapath%2Fdatapath.c;h=1ea5d1e9a7c2d850cf989b34c6a5f3e7b53d25ac;hb=6161d3fd928edf7016abae60f549a135a2f83f09;hp=317c404a908dbd131cff38db928763638e5c5164;hpb=a9a29d22d8f485bb90bb49ae9ddff8c3c1ab04f5;p=openvswitch diff --git a/datapath/datapath.c b/datapath/datapath.c index 317c404a..1ea5d1e9 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -95,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; @@ -111,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) @@ -249,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); } @@ -438,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); @@ -457,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); @@ -476,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. */ @@ -1262,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, @@ -1278,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); @@ -1605,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, @@ -1620,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)); @@ -2040,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();