#include "vlan.h"
#include "vport-internal_dev.h"
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) || \
+ 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);
EXPORT_SYMBOL(dp_ioctl_hook);
}
if (is_frag && dp->drop_frags) {
- kfree_skb(skb);
+ consume_skb(skb);
stats_counter_off = offsetof(struct dp_stats_percpu, n_frags);
goto out;
}
WARN_ON_ONCE(skb_shared(skb));
- forward_ip_summed(skb);
-
- err = vswitch_skb_checksum_setup(skb);
- if (err)
- goto err_kfree_skb;
+ forward_ip_summed(skb, true);
/* Break apart GSO packets into their component pieces. Otherwise
* userspace may try to stuff a 64kB packet into a 1500-byte MTU. */
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);
return 0;
-err_kfree_skb:
- kfree_skb(skb);
err:
local_bh_disable();
stats = per_cpu_ptr(dp->stats_percpu, smp_processor_id());
if (err)
goto err_kfree_skbs;
- kfree_skb(skb);
+ consume_skb(skb);
skb = nskb;
} while (skb);
return 0;
[ODP_ACTION_ATTR_SET_TUNNEL] = 8,
[ODP_ACTION_ATTR_SET_PRIORITY] = 4,
[ODP_ACTION_ATTR_POP_PRIORITY] = 0,
- [ODP_ACTION_ATTR_DROP_SPOOFED_ARP] = 0,
};
int type = nla_type(a);
case ODP_ACTION_ATTR_SET_TUNNEL:
case ODP_ACTION_ATTR_SET_PRIORITY:
case ODP_ACTION_ATTR_POP_PRIORITY:
- case ODP_ACTION_ATTR_DROP_SPOOFED_ARP:
/* No validation needed. */
break;
int key_len;
err = -EINVAL;
- if (!a[ODP_PACKET_ATTR_PACKET] || !a[ODP_PACKET_ATTR_ACTIONS] ||
+ if (!a[ODP_PACKET_ATTR_PACKET] || !a[ODP_PACKET_ATTR_KEY] ||
+ !a[ODP_PACKET_ATTR_ACTIONS] ||
nla_len(a[ODP_PACKET_ATTR_PACKET]) < ETH_HLEN)
goto err;
goto err_flow_put;
flow->tbl_node.hash = flow_hash(&flow->key, key_len);
+ err = flow_metadata_from_nlattrs(&flow->key.eth.in_port,
+ &flow->key.eth.tun_id,
+ a[ODP_PACKET_ATTR_KEY]);
+ if (err)
+ goto err_flow_put;
+
acts = flow_actions_alloc(a[ODP_PACKET_ATTR_ACTIONS]);
err = PTR_ERR(acts);
if (IS_ERR(acts))
static const struct nla_policy packet_policy[ODP_PACKET_ATTR_MAX + 1] = {
[ODP_PACKET_ATTR_PACKET] = { .type = NLA_UNSPEC },
+ [ODP_PACKET_ATTR_KEY] = { .type = NLA_NESTED },
[ODP_PACKET_ATTR_ACTIONS] = { .type = NLA_NESTED },
};
if (IS_ERR(reply))
goto exit_unlock;
- err = genlmsg_reply(reply, info);
+ rcu_read_unlock();
+
+ return genlmsg_reply(reply, info);
exit_unlock:
rcu_read_unlock();