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;
return dp;
}
-EXPORT_SYMBOL_GPL(get_dp);
/* Must be called with genl_mutex. */
static struct flow_table *get_table_protected(struct datapath *dp)
{
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);
}
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);
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);
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. */
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,
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);
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,
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));
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();