/* Set up inner headers if we are offloading inner checksum */ if (skb->ip_summed == CHECKSUM_PARTIAL) {
skb_reset_inner_headers(skb);
skb->encapsulation = 1;
}
if (gso_partial && skb_is_gso(skb)) { unsignedint partial_adj;
/* Adjust checksum to account for the fact that * the partial checksum is based on actual size * whereas headers should be based on MSS size.
*/
partial_adj = skb->len + skb_headroom(skb) -
SKB_GSO_CB(skb)->data_offset -
skb_shinfo(skb)->gso_size;
*pcsum = ~csum_fold((__force __wsum)htonl(partial_adj));
} else {
*pcsum = 0;
}
off = skb_gro_offset(skb);
hlen = off + sizeof(*greh);
greh = skb_gro_header(skb, hlen, off); if (unlikely(!greh)) goto out;
/* Only support version 0 and K (key), C (csum) flags. Note that * although the support for the S (seq#) flag can be added easily * for GRO, this is problematic for GSO hence can not be enabled * here because a GRO pkt may end up in the forwarding path, thus * requiring GSO support to break it up correctly.
*/ if ((greh->flags & ~(GRE_KEY|GRE_CSUM)) != 0) goto out;
/* We can only support GRE_CSUM if we can track the location of * the GRE header. In the case of FOU/GUE we cannot because the * outer UDP header displaces the GRE header leaving us in a state * of limbo.
*/ if ((greh->flags & GRE_CSUM) && NAPI_GRO_CB(skb)->is_fou) goto out;
type = greh->protocol;
ptype = gro_find_receive_by_type(type); if (!ptype) goto out;
grehlen = GRE_HEADER_SECTION;
if (greh->flags & GRE_KEY)
grehlen += GRE_HEADER_SECTION;
if (greh->flags & GRE_CSUM)
grehlen += GRE_HEADER_SECTION;
hlen = off + grehlen; if (!skb_gro_may_pull(skb, hlen)) {
greh = skb_gro_header_slow(skb, hlen, off); if (unlikely(!greh)) goto out;
}
/* Don't bother verifying checksum if we're going to flush anyway. */ if ((greh->flags & GRE_CSUM) && !NAPI_GRO_CB(skb)->flush) { if (skb_gro_checksum_simple_validate(skb)) goto out;
/* The following checks are needed to ensure only pkts * from the same tunnel are considered for aggregation. * The criteria for "the same tunnel" includes: * 1) same version (we only support version 0 here) * 2) same protocol (we only support ETH_P_IP for now) * 3) same set of flags * 4) same key if the key field is present.
*/
greh2 = (struct gre_base_hdr *)(p->data + off);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.