ipprot = rcu_dereference(inet6_protos[proto]); if (ipprot && ipprot->err_handler) { if (!ipprot->err_handler(skb, opt, type, code, offset, info)) return 0;
}
return -ENOENT;
}
staticint gue6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
u8 type, u8 code, int offset, __be32 info)
{ int transport_offset = skb_transport_offset(skb); struct guehdr *guehdr;
size_t len, optlen; int ret;
len = sizeof(struct udphdr) + sizeof(struct guehdr); if (!pskb_may_pull(skb, transport_offset + len)) return -EINVAL;
guehdr = (struct guehdr *)&udp_hdr(skb)[1];
switch (guehdr->version) { case 0: /* Full GUE header present */ break; case 1: { /* Direct encasulation of IPv4 or IPv6 */
skb_set_transport_header(skb, -(int)sizeof(struct icmp6hdr));
switch (((struct iphdr *)guehdr)->version) { case 4:
ret = gue6_err_proto_handler(IPPROTO_IPIP, skb, opt,
type, code, offset, info); goto out; case 6:
ret = gue6_err_proto_handler(IPPROTO_IPV6, skb, opt,
type, code, offset, info); goto out; default:
ret = -EOPNOTSUPP; goto out;
}
} default: /* Undefined version */ return -EOPNOTSUPP;
}
if (guehdr->control) return -ENOENT;
optlen = guehdr->hlen << 2;
if (!pskb_may_pull(skb, transport_offset + len + optlen)) return -EINVAL;
guehdr = (struct guehdr *)&udp_hdr(skb)[1]; if (validate_gue_flags(guehdr, optlen)) return -EINVAL;
/* Handling exceptions for direct UDP encapsulation in GUE would lead to * recursion. Besides, this kind of encapsulation can't even be * configured currently. Discard this.
*/ if (guehdr->proto_ctype == IPPROTO_UDP ||
guehdr->proto_ctype == IPPROTO_UDPLITE) return -EOPNOTSUPP;
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.