if (xo && (xo->flags & XFRM_GRO)) { /* The full l2 header needs to be preserved so that re-injecting the packet at l2 *workscorrectlyinthepresenceofvlantags.
*/
skb_mac_header_rebuild_full(skb, xo->orig_mac_len);
skb_reset_network_header(skb);
skb_reset_transport_header(skb); return0;
}
encap_type = READ_ONCE(up->encap_type); /* if this is not encapsulated socket, then just return now */ if (!encap_type) return1;
/* If this is a paged skb, make sure we pull up
* whatever data we need to look at. */
len = skb->len - sizeof(struct udphdr); if (!pskb_may_pull(skb, sizeof(struct udphdr) + min(len, 8))) return1;
/* Now we can get the pointers */
uh = udp_hdr(skb);
udpdata = (__u8 *)uh + sizeof(struct udphdr);
udpdata32 = (__be32 *)udpdata;
switch (encap_type) { default: case UDP_ENCAP_ESPINUDP: /* Check if this is a keepalive packet. If so, eat it. */ if (len == 1 && udpdata[0] == 0xff) { return -EINVAL;
} elseif (len > sizeof(struct ip_esp_hdr) && udpdata32[0] != 0) { /* ESP Packet without Non-ESP header */
len = sizeof(struct udphdr);
} else /* Must be an IKE packet.. pass it through */ return1; break;
}
/* At this point we are sure that this is an ESPinUDP packet, *soweneedtoremove'len'bytesfromthepacket(theUDP *headerandoptionalESPmarkerbytes)andthenmodifythe *protocoltoESP,andthencallintothetransformreceiver.
*/ if (skb_unclone(skb, GFP_ATOMIC)) return -EINVAL;
/* Now we can update and verify the packet length... */
ip6h = ipv6_hdr(skb);
ip6h->payload_len = htons(ntohs(ip6h->payload_len) - len); if (skb->len < ip6hlen + len) { /* packet is too small!?! */ return -EINVAL;
}
/* pull the data buffer up to the ESP header and set the *transportheadertopointtoESP.KeepUDPonthestack *forlater.
*/ if (pull) {
__skb_pull(skb, len);
skb_reset_transport_header(skb);
} else {
skb_set_transport_header(skb, len);
}
/* process ESP */ return0;
}
/* If it's a keepalive packet, then just eat it. *Ifit'sanencapsulatedpacket,thenpassittothe *IPsecxfrminput. *Returns0ifskbpassedtoxfrmorwasdropped. *Returns>0ifskbshouldbepassedtoUDP. *Returns<0ifskbshouldberesubmitted(-retisprotocol)
*/ int xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
{ int ret;
if (skb->protocol == htons(ETH_P_IP)) return xfrm4_udp_encap_rcv(sk, skb);
ret = __xfrm6_udp_encap_rcv(sk, skb, true); if (!ret) return xfrm6_rcv_encap(skb, IPPROTO_ESP, 0,
udp_sk(sk)->encap_type);
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.