.. | .. |
---|
223 | 223 | if (lwtunnel_xmit_redirect(dst->lwtstate)) { |
---|
224 | 224 | int res = lwtunnel_xmit(skb); |
---|
225 | 225 | |
---|
226 | | - if (res < 0 || res == LWTUNNEL_XMIT_DONE) |
---|
| 226 | + if (res != LWTUNNEL_XMIT_CONTINUE) |
---|
227 | 227 | return res; |
---|
228 | 228 | } |
---|
229 | 229 | |
---|
.. | .. |
---|
1564 | 1564 | cork->dst = NULL; |
---|
1565 | 1565 | skb_dst_set(skb, &rt->dst); |
---|
1566 | 1566 | |
---|
1567 | | - if (iph->protocol == IPPROTO_ICMP) |
---|
1568 | | - icmp_out_count(net, ((struct icmphdr *) |
---|
1569 | | - skb_transport_header(skb))->type); |
---|
| 1567 | + if (iph->protocol == IPPROTO_ICMP) { |
---|
| 1568 | + u8 icmp_type; |
---|
| 1569 | + |
---|
| 1570 | + /* For such sockets, transhdrlen is zero when do ip_append_data(), |
---|
| 1571 | + * so icmphdr does not in skb linear region and can not get icmp_type |
---|
| 1572 | + * by icmp_hdr(skb)->type. |
---|
| 1573 | + */ |
---|
| 1574 | + if (sk->sk_type == SOCK_RAW && !inet_sk(sk)->hdrincl) |
---|
| 1575 | + icmp_type = fl4->fl4_icmp_type; |
---|
| 1576 | + else |
---|
| 1577 | + icmp_type = icmp_hdr(skb)->type; |
---|
| 1578 | + icmp_out_count(net, icmp_type); |
---|
| 1579 | + } |
---|
1570 | 1580 | |
---|
1571 | 1581 | ip_cork_release(cork); |
---|
1572 | 1582 | out: |
---|