int rpl_ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb) { if (!OVS_GSO_CB(skb)->fix_segment) return output_ipv6(skb); if (skb_is_gso(skb)) { int ret; skb = tnl_skb_gso_segment(skb, 0, false, AF_INET6); if (!skb || IS_ERR(skb)) return NET_XMIT_DROP; do { struct sk_buff *next_skb = skb->next; skb->next = NULL; ret = output_ipv6(skb); skb = next_skb; } while (skb); return ret; } else if (skb->ip_summed == CHECKSUM_PARTIAL) { int err; err = skb_checksum_help(skb); if (unlikely(err)) return NET_XMIT_DROP; } return output_ipv6(skb); }
int rpl_ip_local_out(struct sk_buff *skb) { int ret = NETDEV_TX_OK; int id = -1; if (skb_is_gso(skb)) { struct iphdr *iph; iph = ip_hdr(skb); id = ntohs(iph->id); skb = tnl_skb_gso_segment(skb, 0, false); if (!skb || IS_ERR(skb)) return 0; } else if (skb->ip_summed == CHECKSUM_PARTIAL) { int err; err = skb_checksum_help(skb); if (unlikely(err)) return 0; } while (skb) { struct sk_buff *next_skb = skb->next; struct iphdr *iph; int err; skb->next = NULL; iph = ip_hdr(skb); if (id >= 0) iph->id = htons(id++); memset(IPCB(skb), 0, sizeof(*IPCB(skb))); #undef ip_local_out err = ip_local_out(skb); if (unlikely(net_xmit_eval(err))) ret = err; skb = next_skb; } return ret; }
int rpl_ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb) { if (!OVS_GSO_CB(skb)->fix_segment) return output_ip(skb); /* This bit set can confuse some drivers on old kernel. */ skb->encapsulation = 0; if (skb_is_gso(skb)) { int ret; int id; skb = tnl_skb_gso_segment(skb, 0, false, AF_INET); if (!skb || IS_ERR(skb)) return NET_XMIT_DROP; id = ntohs(ip_hdr(skb)->id); do { struct sk_buff *next_skb = skb->next; skb->next = NULL; ip_hdr(skb)->id = htons(id++); ret = output_ip(skb); skb = next_skb; } while (skb); return ret; } else if (skb->ip_summed == CHECKSUM_PARTIAL) { int err; err = skb_checksum_help(skb); if (unlikely(err)) return NET_XMIT_DROP; } return output_ip(skb); }