summaryrefslogtreecommitdiff
path: root/net/ipv4/ip_sockglue.c
diff options
context:
space:
mode:
authorWillem de Bruijn <willemb@google.com>2020-07-24 09:03:09 -0400
committerDavid S. Miller <davem@davemloft.net>2020-07-24 17:12:41 -0700
commit178c49d9f9a4b5ade00c93480d714708fe971e24 (patch)
tree715bff01ce3d3520801c36e1a2daf7f3a20273d5 /net/ipv4/ip_sockglue.c
parentc4e9e09f5589f9afe6b8f8c4fb078e0559bca667 (diff)
icmp: prepare rfc 4884 for ipv6
The RFC 4884 spec is largely the same between IPv4 and IPv6. Factor out the IPv4 specific parts in preparation for IPv6 support: - icmp types supported - icmp header size, and thus offset to original datagram start - datagram length field offset in icmp(6)hdr. - datagram length field word size: 4B for IPv4, 8B for IPv6. Signed-off-by: Willem de Bruijn <willemb@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/ip_sockglue.c')
-rw-r--r--net/ipv4/ip_sockglue.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 8dc027e54c5b..d2c223554ff7 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -390,6 +390,18 @@ int ip_ra_control(struct sock *sk, unsigned char on,
return 0;
}
+static void ipv4_icmp_error_rfc4884(const struct sk_buff *skb,
+ struct sock_ee_data_rfc4884 *out)
+{
+ switch (icmp_hdr(skb)->type) {
+ case ICMP_DEST_UNREACH:
+ case ICMP_TIME_EXCEEDED:
+ case ICMP_PARAMETERPROB:
+ ip_icmp_error_rfc4884(skb, out, sizeof(struct icmphdr),
+ icmp_hdr(skb)->un.reserved[1] * 4);
+ }
+}
+
void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
__be16 port, u32 info, u8 *payload)
{
@@ -413,7 +425,7 @@ void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
if (skb_pull(skb, payload - skb->data)) {
if (inet_sk(sk)->recverr_rfc4884)
- ip_icmp_error_rfc4884(skb, &serr->ee.ee_rfc4884);
+ ipv4_icmp_error_rfc4884(skb, &serr->ee.ee_rfc4884);
skb_reset_transport_header(skb);
if (sock_queue_err_skb(sk, skb) == 0)