struct ovs_frag_data {
unsigned long dst;
struct vport *vport;
- struct ovs_skb_cb cb;
+ struct ovs_gso_cb cb;
__be16 inner_protocol;
__u16 vlan_tci;
__be16 vlan_proto;
u8 l2_data[MAX_L2_LEN];
};
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
static DEFINE_PER_CPU(struct ovs_frag_data, ovs_frag_data_storage);
+#endif
#define DEFERRED_ACTION_FIFO_SIZE 10
struct action_fifo {
return 0;
}
-#if LINUX_VERSION_CODE > KERNEL_VERSION(3,9,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
static int ovs_vport_output(OVS_VPORT_OUTPUT_PARAMS)
{
struct ovs_frag_data *data = get_pcpu_ptr(ovs_frag_data_storage);
}
__skb_dst_copy(skb, data->dst);
- *OVS_CB(skb) = data->cb;
+ *OVS_GSO_CB(skb) = data->cb;
ovs_skb_set_inner_protocol(skb, data->inner_protocol);
skb->vlan_tci = data->vlan_tci;
skb->vlan_proto = data->vlan_proto;
data = get_pcpu_ptr(ovs_frag_data_storage);
data->dst = (unsigned long) skb_dst(skb);
data->vport = vport;
- data->cb = *OVS_CB(skb);
+ data->cb = *OVS_GSO_CB(skb);
data->inner_protocol = ovs_skb_get_inner_protocol(skb);
data->vlan_tci = skb->vlan_tci;
data->vlan_proto = skb->vlan_proto;
{
if (skb_network_offset(skb) > MAX_L2_LEN) {
OVS_NLERR(1, "L2 header too long to fragment");
- return;
+ goto err;
}
if (ethertype == htons(ETH_P_IP)) {
struct rt6_info ovs_rt;
if (!v6ops) {
- kfree_skb(skb);
- return;
+ goto err;
}
prepare_frag(vport, skb);
WARN_ONCE(1, "Failed fragment ->%s: eth=%04x, MRU=%d, MTU=%d.",
ovs_vport_name(vport), ntohs(ethertype), mru,
vport->dev->mtu);
- kfree_skb(skb);
+ goto err;
}
+
+ return;
+err:
+ kfree_skb(skb);
}
-#else /* <= 3.9 */
+#else /* < 3.10 */
static void ovs_fragment(struct vport *vport, struct sk_buff *skb, u16 mru,
__be16 ethertype)
{
case OVS_KEY_ATTR_CT_STATE:
case OVS_KEY_ATTR_CT_ZONE:
case OVS_KEY_ATTR_CT_MARK:
- case OVS_KEY_ATTR_CT_LABEL:
+ case OVS_KEY_ATTR_CT_LABELS:
err = -EINVAL;
break;
}
break;
case OVS_ACTION_ATTR_CT:
+ if (!is_flow_key_valid(key)) {
+ err = ovs_flow_key_update(skb, key);
+ if (err)
+ return err;
+ }
+
err = ovs_ct_execute(ovs_dp_get_net(dp), skb, key,
nla_data(a));
/* Hide stolen IP fragments from user space. */
- if (err == -EINPROGRESS)
- return 0;
+ if (err)
+ return err == -EINPROGRESS ? 0 : err;
break;
}