Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5b052042 authored by Li Wei's avatar Li Wei Committed by David S. Miller
Browse files

ipv4: fix error handling in icmp_protocol.



Now we handle icmp errors in each transport protocol's err_handler,
for icmp protocols, that is ping_err. Since this handler only care
of those icmp errors triggered by echo request, errors triggered
by echo reply(which sent by kernel) are sliently ignored.

So wrap ping_err() with icmp_err() to deal with those icmp errors.

Signed-off-by: default avatarLi Wei <lw@cn.fujitsu.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 08dcdbf6
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -41,6 +41,7 @@ struct net;


extern void	icmp_send(struct sk_buff *skb_in,  int type, int code, __be32 info);
extern void	icmp_send(struct sk_buff *skb_in,  int type, int code, __be32 info);
extern int	icmp_rcv(struct sk_buff *skb);
extern int	icmp_rcv(struct sk_buff *skb);
extern void	icmp_err(struct sk_buff *, u32 info);
extern int	icmp_init(void);
extern int	icmp_init(void);
extern void	icmp_out_count(struct net *net, unsigned char type);
extern void	icmp_out_count(struct net *net, unsigned char type);


+1 −1
Original line number Original line Diff line number Diff line
@@ -1577,7 +1577,7 @@ static const struct net_offload udp_offload = {


static const struct net_protocol icmp_protocol = {
static const struct net_protocol icmp_protocol = {
	.handler =	icmp_rcv,
	.handler =	icmp_rcv,
	.err_handler =	ping_err,
	.err_handler =	icmp_err,
	.no_policy =	1,
	.no_policy =	1,
	.netns_ok =	1,
	.netns_ok =	1,
};
};
+23 −0
Original line number Original line Diff line number Diff line
@@ -934,6 +934,29 @@ int icmp_rcv(struct sk_buff *skb)
	goto drop;
	goto drop;
}
}


void icmp_err(struct sk_buff *skb, u32 info)
{
	struct iphdr *iph = (struct iphdr *)skb->data;
	struct icmphdr *icmph = (struct icmphdr *)(skb->data+(iph->ihl<<2));
	int type = icmp_hdr(skb)->type;
	int code = icmp_hdr(skb)->code;
	struct net *net = dev_net(skb->dev);

	/*
	 * Use ping_err to handle all icmp errors except those
	 * triggered by ICMP_ECHOREPLY which sent from kernel.
	 */
	if (icmph->type != ICMP_ECHOREPLY) {
		ping_err(skb, info);
		return;
	}

	if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED)
		ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_ICMP, 0);
	else if (type == ICMP_REDIRECT)
		ipv4_redirect(skb, net, 0, 0, IPPROTO_ICMP, 0);
}

/*
/*
 *	This table is the definition of how we handle ICMP.
 *	This table is the definition of how we handle ICMP.
 */
 */