Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
55be7a9c
Commit
55be7a9c
authored
Jul 11, 2012
by
David S. Miller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ipv4: Add redirect support to all protocol icmp error handlers.
Signed-off-by:
David S. Miller
<
davem@davemloft.net
>
parent
b42597e2
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
110 additions
and
16 deletions
+110
-16
net/dccp/ipv4.c
net/dccp/ipv4.c
+11
-0
net/ipv4/ah4.c
net/ipv4/ah4.c
+13
-5
net/ipv4/esp4.c
net/ipv4/esp4.c
+13
-5
net/ipv4/ip_gre.c
net/ipv4/ip_gre.c
+8
-1
net/ipv4/ipcomp.c
net/ipv4/ipcomp.c
+13
-5
net/ipv4/ipip.c
net/ipv4/ipip.c
+9
-0
net/ipv4/ping.c
net/ipv4/ping.c
+1
-0
net/ipv4/raw.c
net/ipv4/raw.c
+2
-0
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_ipv4.c
+11
-0
net/ipv4/udp.c
net/ipv4/udp.c
+3
-0
net/ipv4/xfrm4_policy.c
net/ipv4/xfrm4_policy.c
+10
-0
net/sctp/input.c
net/sctp/input.c
+16
-0
No files found.
net/dccp/ipv4.c
View file @
55be7a9c
...
...
@@ -195,6 +195,14 @@ static inline void dccp_do_pmtu_discovery(struct sock *sk,
}
/* else let the usual retransmit timer handle it */
}
static
void
dccp_do_redirect
(
struct
sk_buff
*
skb
,
struct
sock
*
sk
)
{
struct
dst_entry
*
dst
=
__sk_dst_check
(
sk
,
0
);
if
(
dst
&&
dst
->
ops
->
redirect
)
dst
->
ops
->
redirect
(
dst
,
skb
);
}
/*
* This routine is called by the ICMP module when it gets some sort of error
* condition. If err < 0 then the socket should be closed and the error
...
...
@@ -259,6 +267,9 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
}
switch
(
type
)
{
case
ICMP_REDIRECT
:
dccp_do_redirect
(
skb
,
sk
);
goto
out
;
case
ICMP_SOURCE_QUENCH
:
/* Just silently ignore these. */
goto
out
;
...
...
net/ipv4/ah4.c
View file @
55be7a9c
...
...
@@ -398,17 +398,25 @@ static void ah4_err(struct sk_buff *skb, u32 info)
struct
ip_auth_hdr
*
ah
=
(
struct
ip_auth_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
,
ah
->
spi
,
IPPROTO_AH
,
AF_INET
);
if
(
!
x
)
return
;
pr_debug
(
"pmtu discovery on SA AH/%08x/%08x
\n
"
,
ntohl
(
ah
->
spi
),
ntohl
(
iph
->
daddr
));
ipv4_update_pmtu
(
skb
,
net
,
info
,
0
,
0
,
IPPROTO_AH
,
0
);
if
(
icmp_hdr
(
skb
)
->
type
==
ICMP_DEST_UNREACH
)
ipv4_update_pmtu
(
skb
,
net
,
info
,
0
,
0
,
IPPROTO_AH
,
0
);
else
ipv4_redirect
(
skb
,
net
,
0
,
0
,
IPPROTO_AH
,
0
);
xfrm_state_put
(
x
);
}
...
...
net/ipv4/esp4.c
View file @
55be7a9c
...
...
@@ -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
);
}
...
...
net/ipv4/ip_gre.c
View file @
55be7a9c
...
...
@@ -528,6 +528,9 @@ static void ipgre_err(struct sk_buff *skb, u32 info)
if
(
code
!=
ICMP_EXC_TTL
)
return
;
break
;
case
ICMP_REDIRECT
:
break
;
}
rcu_read_lock
();
...
...
@@ -543,7 +546,11 @@ static void ipgre_err(struct sk_buff *skb, u32 info)
t
->
parms
.
link
,
0
,
IPPROTO_GRE
,
0
);
goto
out
;
}
if
(
type
==
ICMP_REDIRECT
)
{
ipv4_redirect
(
skb
,
dev_net
(
skb
->
dev
),
t
->
parms
.
link
,
0
,
IPPROTO_GRE
,
0
);
goto
out
;
}
if
(
t
->
parms
.
iph
.
daddr
==
0
||
ipv4_is_multicast
(
t
->
parms
.
iph
.
daddr
))
goto
out
;
...
...
net/ipv4/ipcomp.c
View file @
55be7a9c
...
...
@@ -31,18 +31,26 @@ static void ipcomp4_err(struct sk_buff *skb, u32 info)
struct
ip_comp_hdr
*
ipch
=
(
struct
ip_comp_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
;
}
spi
=
htonl
(
ntohs
(
ipch
->
cpi
));
x
=
xfrm_state_lookup
(
net
,
skb
->
mark
,
(
const
xfrm_address_t
*
)
&
iph
->
daddr
,
spi
,
IPPROTO_COMP
,
AF_INET
);
if
(
!
x
)
return
;
NETDEBUG
(
KERN_DEBUG
"pmtu discovery on SA IPCOMP/%08x/%pI4
\n
"
,
spi
,
&
iph
->
daddr
);
ipv4_update_pmtu
(
skb
,
net
,
info
,
0
,
0
,
IPPROTO_COMP
,
0
);
if
(
icmp_hdr
(
skb
)
->
type
==
ICMP_DEST_UNREACH
)
ipv4_update_pmtu
(
skb
,
net
,
info
,
0
,
0
,
IPPROTO_COMP
,
0
);
else
ipv4_redirect
(
skb
,
net
,
0
,
0
,
IPPROTO_COMP
,
0
);
xfrm_state_put
(
x
);
}
...
...
net/ipv4/ipip.c
View file @
55be7a9c
...
...
@@ -360,6 +360,8 @@ static int ipip_err(struct sk_buff *skb, u32 info)
if
(
code
!=
ICMP_EXC_TTL
)
return
0
;
break
;
case
ICMP_REDIRECT
:
break
;
}
err
=
-
ENOENT
;
...
...
@@ -376,6 +378,13 @@ static int ipip_err(struct sk_buff *skb, u32 info)
goto
out
;
}
if
(
type
==
ICMP_REDIRECT
)
{
ipv4_redirect
(
skb
,
dev_net
(
skb
->
dev
),
t
->
dev
->
ifindex
,
0
,
IPPROTO_IPIP
,
0
);
err
=
0
;
goto
out
;
}
if
(
t
->
parms
.
iph
.
daddr
==
0
)
goto
out
;
...
...
net/ipv4/ping.c
View file @
55be7a9c
...
...
@@ -387,6 +387,7 @@ void ping_err(struct sk_buff *skb, u32 info)
break
;
case
ICMP_REDIRECT
:
/* See ICMP_SOURCE_QUENCH */
ipv4_sk_redirect
(
skb
,
sk
);
err
=
EREMOTEIO
;
break
;
}
...
...
net/ipv4/raw.c
View file @
55be7a9c
...
...
@@ -218,6 +218,8 @@ static void raw_err(struct sock *sk, struct sk_buff *skb, u32 info)
if
(
type
==
ICMP_DEST_UNREACH
&&
code
==
ICMP_FRAG_NEEDED
)
ipv4_sk_update_pmtu
(
skb
,
sk
,
info
);
else
if
(
type
==
ICMP_REDIRECT
)
ipv4_sk_redirect
(
skb
,
sk
);
/* Report error on raw socket, if:
1. User requested ip_recverr.
...
...
net/ipv4/tcp_ipv4.c
View file @
55be7a9c
...
...
@@ -321,6 +321,14 @@ static void do_pmtu_discovery(struct sock *sk, const struct iphdr *iph, u32 mtu)
}
/* else let the usual retransmit timer handle it */
}
static
void
do_redirect
(
struct
sk_buff
*
skb
,
struct
sock
*
sk
)
{
struct
dst_entry
*
dst
=
__sk_dst_check
(
sk
,
0
);
if
(
dst
&&
dst
->
ops
->
redirect
)
dst
->
ops
->
redirect
(
dst
,
skb
);
}
/*
* This routine is called by the ICMP module when it gets some
* sort of error condition. If err < 0 then the socket should
...
...
@@ -394,6 +402,9 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
}
switch
(
type
)
{
case
ICMP_REDIRECT
:
do_redirect
(
icmp_skb
,
sk
);
goto
out
;
case
ICMP_SOURCE_QUENCH
:
/* Just silently ignore these. */
goto
out
;
...
...
net/ipv4/udp.c
View file @
55be7a9c
...
...
@@ -630,6 +630,9 @@ void __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable)
err
=
icmp_err_convert
[
code
].
errno
;
}
break
;
case
ICMP_REDIRECT
:
ipv4_sk_redirect
(
skb
,
sk
);
break
;
}
/*
...
...
net/ipv4/xfrm4_policy.c
View file @
55be7a9c
...
...
@@ -202,6 +202,15 @@ static void xfrm4_update_pmtu(struct dst_entry *dst, u32 mtu)
path
->
ops
->
update_pmtu
(
path
,
mtu
);
}
static
void
xfrm4_redirect
(
struct
dst_entry
*
dst
,
struct
sk_buff
*
skb
)
{
struct
xfrm_dst
*
xdst
=
(
struct
xfrm_dst
*
)
dst
;
struct
dst_entry
*
path
=
xdst
->
route
;
if
(
path
->
ops
->
redirect
)
path
->
ops
->
redirect
(
path
,
skb
);
}
static
void
xfrm4_dst_destroy
(
struct
dst_entry
*
dst
)
{
struct
xfrm_dst
*
xdst
=
(
struct
xfrm_dst
*
)
dst
;
...
...
@@ -225,6 +234,7 @@ static struct dst_ops xfrm4_dst_ops = {
.
protocol
=
cpu_to_be16
(
ETH_P_IP
),
.
gc
=
xfrm4_garbage_collect
,
.
update_pmtu
=
xfrm4_update_pmtu
,
.
redirect
=
xfrm4_redirect
,
.
cow_metrics
=
dst_cow_metrics_generic
,
.
destroy
=
xfrm4_dst_destroy
,
.
ifdown
=
xfrm4_dst_ifdown
,
...
...
net/sctp/input.c
View file @
55be7a9c
...
...
@@ -423,6 +423,18 @@ void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc,
sctp_retransmit
(
&
asoc
->
outqueue
,
t
,
SCTP_RTXR_PMTUD
);
}
static
void
sctp_icmp_redirect
(
struct
sock
*
sk
,
struct
sctp_transport
*
t
,
struct
sk_buff
*
skb
)
{
struct
dst_entry
*
dst
;
if
(
!
t
)
return
;
dst
=
sctp_transport_dst_check
(
t
);
if
(
dst
&&
dst
->
ops
->
redirect
)
dst
->
ops
->
redirect
(
dst
,
skb
);
}
/*
* SCTP Implementer's Guide, 2.37 ICMP handling procedures
*
...
...
@@ -628,6 +640,10 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
err
=
EHOSTUNREACH
;
break
;
case
ICMP_REDIRECT
:
sctp_icmp_redirect
(
sk
,
transport
,
skb
);
err
=
0
;
break
;
default:
goto
out_unlock
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment