|
@@ -484,17 +484,25 @@ static void esp4_err(struct sk_buff *skb, u32 info)
|
|
|
struct ip_esp_hdr *esph = (struct ip_esp_hdr *)(skb->data+(iph->ihl<<2));
|
|
|
struct xfrm_state *x;
|
|
|
|
|
|
- if (icmp_hdr(skb)->type != ICMP_DEST_UNREACH ||
|
|
|
- icmp_hdr(skb)->code != ICMP_FRAG_NEEDED)
|
|
|
+ switch (icmp_hdr(skb)->type) {
|
|
|
+ case ICMP_DEST_UNREACH:
|
|
|
+ if (icmp_hdr(skb)->code != ICMP_FRAG_NEEDED)
|
|
|
+ return;
|
|
|
+ case ICMP_REDIRECT:
|
|
|
+ break;
|
|
|
+ default:
|
|
|
return;
|
|
|
+ }
|
|
|
|
|
|
x = xfrm_state_lookup(net, skb->mark, (const xfrm_address_t *)&iph->daddr,
|
|
|
esph->spi, IPPROTO_ESP, AF_INET);
|
|
|
if (!x)
|
|
|
return;
|
|
|
- NETDEBUG(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%08x\n",
|
|
|
- ntohl(esph->spi), ntohl(iph->daddr));
|
|
|
- ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_ESP, 0);
|
|
|
+
|
|
|
+ if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH)
|
|
|
+ ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_ESP, 0);
|
|
|
+ else
|
|
|
+ ipv4_redirect(skb, net, 0, 0, IPPROTO_ESP, 0);
|
|
|
xfrm_state_put(x);
|
|
|
}
|
|
|
|