#include "gso.h"
-static __be16 skb_network_protocol(struct sk_buff *skb)
+static __be16 __skb_network_protocol(struct sk_buff *skb)
{
__be16 type = skb->protocol;
int vlan_depth = ETH_HLEN;
struct sk_buff *skb1 = skb;
struct sk_buff *segs;
__be16 proto = skb->protocol;
+ char cb[sizeof(skb->cb)];
/* setup whole inner packet to get protocol. */
__skb_pull(skb, mac_offset);
- skb->protocol = skb_network_protocol(skb);
+ skb->protocol = __skb_network_protocol(skb);
/* setup l3 packet to gso, to get around segmentation bug on older kernel.*/
__skb_pull(skb, (pkt_hlen - mac_offset));
skb_reset_network_header(skb);
skb_reset_transport_header(skb);
+ /* From 3.9 kernel skb->cb is used by skb gso. Therefore
+ * make copy of it to restore it back. */
+ memcpy(cb, skb->cb, sizeof(cb));
+
segs = __skb_gso_segment(skb, 0, tx_path);
if (!segs || IS_ERR(segs))
goto free;
skb->mac_len = 0;
memcpy(ip_hdr(skb), iph, pkt_hlen);
+ memcpy(skb->cb, cb, sizeof(cb));
if (OVS_GSO_CB(skb)->fix_segment)
OVS_GSO_CB(skb)->fix_segment(skb);
int rpl_ip_local_out(struct sk_buff *skb)
{
int ret = NETDEV_TX_OK;
- int id;
+ int id = -1;
if (skb_is_gso(skb)) {
struct iphdr *iph;
err = skb_checksum_help(skb);
if (unlikely(err))
return 0;
- id = -1;
}
while (skb) {