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
Kirill Smelkov
linux
Commits
0e7caa2a
Commit
0e7caa2a
authored
Aug 17, 2003
by
Ville Nuorvala
Committed by
David S. Miller
Aug 17, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[IPV6]: Fix ip6_dst_lookup() route corruption.
parent
f8d1f5ed
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
57 additions
and
79 deletions
+57
-79
include/net/ipv6.h
include/net/ipv6.h
+3
-1
net/ipv6/icmp.c
net/ipv6/icmp.c
+4
-4
net/ipv6/ip6_output.c
net/ipv6/ip6_output.c
+23
-22
net/ipv6/raw.c
net/ipv6/raw.c
+2
-2
net/ipv6/tcp_ipv6.c
net/ipv6/tcp_ipv6.c
+20
-35
net/ipv6/udp.c
net/ipv6/udp.c
+5
-15
No files found.
include/net/ipv6.h
View file @
0e7caa2a
...
...
@@ -353,7 +353,9 @@ extern int ip6_push_pending_frames(struct sock *sk);
extern
void
ip6_flush_pending_frames
(
struct
sock
*
sk
);
extern
struct
dst_entry
*
ip6_dst_lookup
(
struct
sock
*
sk
,
struct
flowi
*
fl
);
extern
int
ip6_dst_lookup
(
struct
sock
*
sk
,
struct
dst_entry
**
dst
,
struct
flowi
*
fl
);
/*
* skb processing functions
...
...
net/ipv6/icmp.c
View file @
0e7caa2a
...
...
@@ -355,8 +355,8 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
if
(
!
fl
.
oif
&&
ipv6_addr_is_multicast
(
&
fl
.
fl6_dst
))
fl
.
oif
=
np
->
mcast_oif
;
dst
=
ip6_dst_lookup
(
sk
,
&
fl
);
if
(
dst
->
erro
r
)
goto
out
;
err
=
ip6_dst_lookup
(
sk
,
&
dst
,
&
fl
);
if
(
er
r
)
goto
out
;
if
(
hlimit
<
0
)
{
if
(
ipv6_addr_is_multicast
(
&
fl
.
fl6_dst
))
...
...
@@ -434,9 +434,9 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
if
(
!
fl
.
oif
&&
ipv6_addr_is_multicast
(
&
fl
.
fl6_dst
))
fl
.
oif
=
np
->
mcast_oif
;
dst
=
ip6_dst_lookup
(
sk
,
&
fl
);
err
=
ip6_dst_lookup
(
sk
,
&
dst
,
&
fl
);
if
(
dst
->
erro
r
)
goto
out
;
if
(
er
r
)
goto
out
;
if
(
hlimit
<
0
)
{
if
(
ipv6_addr_is_multicast
(
&
fl
.
fl6_dst
))
...
...
net/ipv6/ip6_output.c
View file @
0e7caa2a
...
...
@@ -1136,17 +1136,16 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
return
err
;
}
struct
dst_entry
*
ip6_dst_lookup
(
struct
sock
*
sk
,
struct
flowi
*
fl
)
int
ip6_dst_lookup
(
struct
sock
*
sk
,
struct
dst_entry
**
dst
,
struct
flowi
*
fl
)
{
struct
dst_entry
*
dst
=
NULL
;
int
err
=
0
;
if
(
sk
)
{
struct
ipv6_pinfo
*
np
=
inet6_sk
(
sk
);
dst
=
__sk_dst_check
(
sk
,
np
->
dst_cookie
);
if
(
dst
)
{
struct
rt6_info
*
rt
=
(
struct
rt6_info
*
)
dst
;
*
dst
=
__sk_dst_check
(
sk
,
np
->
dst_cookie
);
if
(
*
dst
)
{
struct
rt6_info
*
rt
=
(
struct
rt6_info
*
)
*
dst
;
/* Yes, checking route validity in not connected
case is not very simple. Take into account,
...
...
@@ -1170,39 +1169,41 @@ struct dst_entry *ip6_dst_lookup(struct sock *sk, struct flowi *fl)
ipv6_addr_cmp
(
&
fl
->
fl6_dst
,
&
rt
->
rt6i_dst
.
addr
))
&&
(
np
->
daddr_cache
==
NULL
||
ipv6_addr_cmp
(
&
fl
->
fl6_dst
,
np
->
daddr_cache
)))
||
(
fl
->
oif
&&
fl
->
oif
!=
dst
->
dev
->
ifindex
))
{
dst
=
NULL
;
||
(
fl
->
oif
&&
fl
->
oif
!=
(
*
dst
)
->
dev
->
ifindex
))
{
*
dst
=
NULL
;
}
else
dst_hold
(
dst
);
dst_hold
(
*
dst
);
}
}
if
(
dst
==
NULL
)
dst
=
ip6_route_output
(
sk
,
fl
);
if
(
*
dst
==
NULL
)
*
dst
=
ip6_route_output
(
sk
,
fl
);
if
(
dst
->
error
)
return
dst
;
if
(
(
err
=
(
*
dst
)
->
error
)
)
goto
out_err_release
;
if
(
ipv6_addr_any
(
&
fl
->
fl6_src
))
{
err
=
ipv6_get_saddr
(
dst
,
&
fl
->
fl6_dst
,
&
fl
->
fl6_src
);
err
=
ipv6_get_saddr
(
*
dst
,
&
fl
->
fl6_dst
,
&
fl
->
fl6_src
);
if
(
err
)
{
#if IP6_DEBUG >= 2
printk
(
KERN_DEBUG
"ip6_
build_xmit
: "
printk
(
KERN_DEBUG
"ip6_
dst_lookup
: "
"no available source address
\n
"
);
#endif
dst
->
error
=
err
;
return
dst
;
goto
out_err_release
;
}
}
if
(
dst
)
{
if
((
err
=
xfrm_lookup
(
&
dst
,
fl
,
sk
,
0
))
<
0
)
{
dst
->
error
=
-
ENETUNREACH
;
}
if
((
err
=
xfrm_lookup
(
dst
,
fl
,
sk
,
0
))
<
0
)
{
err
=
-
ENETUNREACH
;
goto
out_err_release
;
}
return
dst
;
return
0
;
out_err_release:
dst_release
(
*
dst
);
*
dst
=
NULL
;
return
err
;
}
int
ip6_append_data
(
struct
sock
*
sk
,
int
getfrag
(
void
*
from
,
char
*
to
,
int
offset
,
int
len
,
int
odd
,
struct
sk_buff
*
skb
),
...
...
net/ipv6/raw.c
View file @
0e7caa2a
...
...
@@ -658,8 +658,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg
if
(
!
fl
.
oif
&&
ipv6_addr_is_multicast
(
&
fl
.
fl6_dst
))
fl
.
oif
=
np
->
mcast_oif
;
dst
=
ip6_dst_lookup
(
sk
,
&
fl
);
if
(
(
err
=
dst
->
error
)
)
err
=
ip6_dst_lookup
(
sk
,
&
dst
,
&
fl
);
if
(
err
)
goto
out
;
if
(
hlimit
<
0
)
{
...
...
net/ipv6/tcp_ipv6.c
View file @
0e7caa2a
...
...
@@ -663,19 +663,12 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
ipv6_addr_copy
(
&
fl
.
fl6_dst
,
rt0
->
addr
);
}
dst
=
ip6_dst_lookup
(
sk
,
&
fl
);
err
=
ip6_dst_lookup
(
sk
,
&
dst
,
&
fl
);
if
((
err
=
dst
->
error
)
!=
0
)
{
dst_release
(
dst
);
if
(
err
)
goto
failure
;
}
if
(
saddr
==
NULL
)
{
err
=
ipv6_get_saddr
(
dst
,
&
np
->
daddr
,
&
fl
.
fl6_src
);
if
(
err
)
{
dst_release
(
dst
);
goto
failure
;
}
saddr
=
&
fl
.
fl6_src
;
ipv6_addr_copy
(
&
np
->
rcv_saddr
,
saddr
);
}
...
...
@@ -790,13 +783,14 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
fl
.
fl_ip_dport
=
inet
->
dport
;
fl
.
fl_ip_sport
=
inet
->
sport
;
dst
=
ip6_dst_lookup
(
sk
,
&
fl
);
if
((
err
=
ip6_dst_lookup
(
sk
,
&
dst
,
&
fl
)))
{
sk
->
sk_err_soft
=
-
err
;
goto
out
;
}
}
else
dst_hold
(
dst
);
if
(
dst
->
error
)
{
sk
->
sk_err_soft
=
-
dst
->
error
;
}
else
if
(
tp
->
pmtu_cookie
>
dst_pmtu
(
dst
))
{
if
(
tp
->
pmtu_cookie
>
dst_pmtu
(
dst
))
{
tcp_sync_mss
(
sk
,
dst_pmtu
(
dst
));
tcp_simple_retransmit
(
sk
);
}
/* else let the usual retransmit timer handle it */
...
...
@@ -891,8 +885,8 @@ static int tcp_v6_send_synack(struct sock *sk, struct open_request *req,
ipv6_addr_copy
(
&
fl
.
fl6_dst
,
rt0
->
addr
);
}
dst
=
ip6_dst_lookup
(
sk
,
&
fl
);
if
(
dst
->
erro
r
)
err
=
ip6_dst_lookup
(
sk
,
&
dst
,
&
fl
);
if
(
er
r
)
goto
done
;
}
...
...
@@ -1020,9 +1014,7 @@ static void tcp_v6_send_reset(struct sk_buff *skb)
fl
.
fl_ip_sport
=
t1
->
source
;
/* sk = NULL, but it is safe for now. RST socket required. */
buff
->
dst
=
ip6_dst_lookup
(
NULL
,
&
fl
);
if
(
buff
->
dst
->
error
==
0
)
{
if
(
!
ip6_dst_lookup
(
NULL
,
&
buff
->
dst
,
&
fl
))
{
ip6_xmit
(
NULL
,
buff
,
&
fl
,
NULL
,
0
);
TCP_INC_STATS_BH
(
TcpOutSegs
);
TCP_INC_STATS_BH
(
TcpOutRsts
);
...
...
@@ -1083,9 +1075,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
fl
.
fl_ip_dport
=
t1
->
dest
;
fl
.
fl_ip_sport
=
t1
->
source
;
buff
->
dst
=
ip6_dst_lookup
(
NULL
,
&
fl
);
if
(
buff
->
dst
->
error
==
0
)
{
if
(
!
ip6_dst_lookup
(
NULL
,
&
buff
->
dst
,
&
fl
))
{
ip6_xmit
(
NULL
,
buff
,
&
fl
,
NULL
,
0
);
TCP_INC_STATS_BH
(
TcpOutSegs
);
return
;
...
...
@@ -1331,11 +1321,9 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
fl
.
fl_ip_dport
=
req
->
rmt_port
;
fl
.
fl_ip_sport
=
inet_sk
(
sk
)
->
sport
;
dst
=
ip6_dst_lookup
(
sk
,
&
fl
);
}
if
(
dst
->
error
)
goto
out
;
if
(
ip6_dst_lookup
(
sk
,
&
dst
,
&
fl
))
goto
out
;
}
newsk
=
tcp_create_openreq_child
(
sk
,
req
,
skb
);
if
(
newsk
==
NULL
)
...
...
@@ -1730,11 +1718,9 @@ static int tcp_v6_rebuild_header(struct sock *sk)
ipv6_addr_copy
(
&
fl
.
fl6_dst
,
rt0
->
addr
);
}
dst
=
ip6_dst_lookup
(
sk
,
&
fl
);
err
=
ip6_dst_lookup
(
sk
,
&
dst
,
&
fl
);
if
(
dst
->
error
)
{
err
=
dst
->
error
;
dst_release
(
dst
);
if
(
err
)
{
sk
->
sk_route_caps
=
0
;
return
err
;
}
...
...
@@ -1774,12 +1760,11 @@ static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok)
dst
=
__sk_dst_check
(
sk
,
np
->
dst_cookie
);
if
(
dst
==
NULL
)
{
dst
=
ip6_dst_lookup
(
sk
,
&
fl
);
int
err
=
ip6_dst_lookup
(
sk
,
&
dst
,
&
fl
);
if
(
dst
->
error
)
{
sk
->
sk_err_soft
=
-
dst
->
error
;
dst_release
(
dst
);
return
-
sk
->
sk_err_soft
;
if
(
err
)
{
sk
->
sk_err_soft
=
-
err
;
return
err
;
}
ip6_dst_store
(
sk
,
dst
,
NULL
);
...
...
net/ipv6/udp.c
View file @
0e7caa2a
...
...
@@ -330,21 +330,11 @@ int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
ipv6_addr_copy
(
&
fl
.
fl6_dst
,
rt0
->
addr
);
}
dst
=
ip6_route_output
(
sk
,
&
fl
);
if
((
err
=
dst
->
error
)
!=
0
)
{
dst_release
(
dst
);
err
=
ip6_dst_lookup
(
sk
,
&
dst
,
&
fl
);
if
(
err
)
goto
out
;
}
/* get the source address used in the appropriate device */
err
=
ipv6_get_saddr
(
dst
,
daddr
,
&
fl
.
fl6_src
);
if
(
err
)
{
dst_release
(
dst
);
goto
out
;
}
/* source address lookup done in ip6_dst_lookup */
if
(
ipv6_addr_any
(
&
np
->
saddr
))
ipv6_addr_copy
(
&
np
->
saddr
,
&
fl
.
fl6_src
);
...
...
@@ -930,8 +920,8 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg
if
(
!
fl
.
oif
&&
ipv6_addr_is_multicast
(
&
fl
.
fl6_dst
))
fl
.
oif
=
np
->
mcast_oif
;
dst
=
ip6_dst_lookup
(
sk
,
&
fl
);
if
(
(
err
=
dst
->
error
)
)
err
=
ip6_dst_lookup
(
sk
,
&
dst
,
&
fl
);
if
(
err
)
goto
out
;
if
(
hlimit
<
0
)
{
...
...
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