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
9d6ec938
Commit
9d6ec938
authored
Mar 12, 2011
by
David S. Miller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ipv4: Use flowi4 in public route lookup interfaces.
Signed-off-by:
David S. Miller
<
davem@davemloft.net
>
parent
68a5e3dd
Changes
14
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
231 additions
and
224 deletions
+231
-224
include/net/route.h
include/net/route.h
+59
-59
net/dccp/ipv4.c
net/dccp/ipv4.c
+10
-10
net/ipv4/icmp.c
net/ipv4/icmp.c
+31
-28
net/ipv4/inet_connection_sock.c
net/ipv4/inet_connection_sock.c
+13
-13
net/ipv4/ip_output.c
net/ipv4/ip_output.c
+11
-11
net/ipv4/netfilter.c
net/ipv4/netfilter.c
+13
-13
net/ipv4/raw.c
net/ipv4/raw.c
+17
-15
net/ipv4/route.c
net/ipv4/route.c
+19
-17
net/ipv4/syncookies.c
net/ipv4/syncookies.c
+12
-12
net/ipv4/udp.c
net/ipv4/udp.c
+13
-13
net/ipv4/xfrm4_policy.c
net/ipv4/xfrm4_policy.c
+5
-5
net/netfilter/ipvs/ip_vs_xmit.c
net/netfilter/ipvs/ip_vs_xmit.c
+6
-6
net/netfilter/xt_TEE.c
net/netfilter/xt_TEE.c
+7
-7
net/sctp/protocol.c
net/sctp/protocol.c
+15
-15
No files found.
include/net/route.h
View file @
9d6ec938
...
...
@@ -122,12 +122,12 @@ extern void ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw,
__be32
src
,
struct
net_device
*
dev
);
extern
void
rt_cache_flush
(
struct
net
*
net
,
int
how
);
extern
void
rt_cache_flush_batch
(
struct
net
*
net
);
extern
struct
rtable
*
__ip_route_output_key
(
struct
net
*
,
const
struct
flowi
*
flp
);
extern
struct
rtable
*
ip_route_output_flow
(
struct
net
*
,
struct
flowi
*
flp
,
extern
struct
rtable
*
__ip_route_output_key
(
struct
net
*
,
const
struct
flowi
4
*
flp
);
extern
struct
rtable
*
ip_route_output_flow
(
struct
net
*
,
struct
flowi
4
*
flp
,
struct
sock
*
sk
);
extern
struct
dst_entry
*
ipv4_blackhole_route
(
struct
net
*
net
,
struct
dst_entry
*
dst_orig
);
static
inline
struct
rtable
*
ip_route_output_key
(
struct
net
*
net
,
struct
flowi
*
flp
)
static
inline
struct
rtable
*
ip_route_output_key
(
struct
net
*
net
,
struct
flowi
4
*
flp
)
{
return
ip_route_output_flow
(
net
,
flp
,
NULL
);
}
...
...
@@ -135,13 +135,13 @@ static inline struct rtable *ip_route_output_key(struct net *net, struct flowi *
static
inline
struct
rtable
*
ip_route_output
(
struct
net
*
net
,
__be32
daddr
,
__be32
saddr
,
u8
tos
,
int
oif
)
{
struct
flowi
fl
=
{
.
flowi_oif
=
oif
,
.
fl4_dst
=
daddr
,
.
fl4_src
=
saddr
,
.
fl4_tos
=
tos
,
struct
flowi
4
fl4
=
{
.
flowi
4
_oif
=
oif
,
.
daddr
=
daddr
,
.
saddr
=
saddr
,
.
fl
owi
4_tos
=
tos
,
};
return
ip_route_output_key
(
net
,
&
fl
);
return
ip_route_output_key
(
net
,
&
fl
4
);
}
static
inline
struct
rtable
*
ip_route_output_ports
(
struct
net
*
net
,
struct
sock
*
sk
,
...
...
@@ -149,35 +149,35 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct sock
__be16
dport
,
__be16
sport
,
__u8
proto
,
__u8
tos
,
int
oif
)
{
struct
flowi
fl
=
{
.
flowi_oif
=
oif
,
.
flowi_flags
=
sk
?
inet_sk_flowi_flags
(
sk
)
:
0
,
.
flowi_mark
=
sk
?
sk
->
sk_mark
:
0
,
.
fl4_dst
=
daddr
,
.
fl4_src
=
saddr
,
.
fl4_tos
=
tos
,
.
flowi_proto
=
proto
,
.
fl4_
dport
=
dport
,
.
fl4_
sport
=
sport
,
struct
flowi
4
fl4
=
{
.
flowi
4
_oif
=
oif
,
.
flowi
4
_flags
=
sk
?
inet_sk_flowi_flags
(
sk
)
:
0
,
.
flowi
4
_mark
=
sk
?
sk
->
sk_mark
:
0
,
.
daddr
=
daddr
,
.
saddr
=
saddr
,
.
fl
owi
4_tos
=
tos
,
.
flowi
4
_proto
=
proto
,
.
uli
.
ports
.
dport
=
dport
,
.
uli
.
ports
.
sport
=
sport
,
};
if
(
sk
)
security_sk_classify_flow
(
sk
,
&
fl
);
return
ip_route_output_flow
(
net
,
&
fl
,
sk
);
security_sk_classify_flow
(
sk
,
flowi4_to_flowi
(
&
fl4
)
);
return
ip_route_output_flow
(
net
,
&
fl
4
,
sk
);
}
static
inline
struct
rtable
*
ip_route_output_gre
(
struct
net
*
net
,
__be32
daddr
,
__be32
saddr
,
__be32
gre_key
,
__u8
tos
,
int
oif
)
{
struct
flowi
fl
=
{
.
flowi_oif
=
oif
,
.
fl4_dst
=
daddr
,
.
fl4_src
=
saddr
,
.
fl4_tos
=
tos
,
.
flowi_proto
=
IPPROTO_GRE
,
.
fl4_
gre_key
=
gre_key
,
struct
flowi
4
fl4
=
{
.
flowi
4
_oif
=
oif
,
.
daddr
=
daddr
,
.
saddr
=
saddr
,
.
fl
owi
4_tos
=
tos
,
.
flowi
4
_proto
=
IPPROTO_GRE
,
.
uli
.
gre_key
=
gre_key
,
};
return
ip_route_output_key
(
net
,
&
fl
);
return
ip_route_output_key
(
net
,
&
fl
4
);
}
extern
int
ip_route_input_common
(
struct
sk_buff
*
skb
,
__be32
dst
,
__be32
src
,
...
...
@@ -228,36 +228,36 @@ static inline struct rtable *ip_route_connect(__be32 dst, __be32 src, u32 tos,
__be16
sport
,
__be16
dport
,
struct
sock
*
sk
,
bool
can_sleep
)
{
struct
flowi
fl
=
{
.
flowi_oif
=
oif
,
.
flowi_mark
=
sk
->
sk_mark
,
.
fl4_dst
=
dst
,
.
fl4_src
=
src
,
.
fl4_tos
=
tos
,
.
flowi_proto
=
protocol
,
.
fl4_
sport
=
sport
,
.
fl4_
dport
=
dport
,
struct
flowi
4
fl4
=
{
.
flowi
4
_oif
=
oif
,
.
flowi
4
_mark
=
sk
->
sk_mark
,
.
daddr
=
dst
,
.
saddr
=
src
,
.
fl
owi
4_tos
=
tos
,
.
flowi
4
_proto
=
protocol
,
.
uli
.
ports
.
sport
=
sport
,
.
uli
.
ports
.
dport
=
dport
,
};
struct
net
*
net
=
sock_net
(
sk
);
struct
rtable
*
rt
;
if
(
inet_sk
(
sk
)
->
transparent
)
fl
.
flowi
_flags
|=
FLOWI_FLAG_ANYSRC
;
fl
4
.
flowi4
_flags
|=
FLOWI_FLAG_ANYSRC
;
if
(
protocol
==
IPPROTO_TCP
)
fl
.
flowi
_flags
|=
FLOWI_FLAG_PRECOW_METRICS
;
fl
4
.
flowi4
_flags
|=
FLOWI_FLAG_PRECOW_METRICS
;
if
(
can_sleep
)
fl
.
flowi
_flags
|=
FLOWI_FLAG_CAN_SLEEP
;
fl
4
.
flowi4
_flags
|=
FLOWI_FLAG_CAN_SLEEP
;
if
(
!
dst
||
!
src
)
{
rt
=
__ip_route_output_key
(
net
,
&
fl
);
rt
=
__ip_route_output_key
(
net
,
&
fl
4
);
if
(
IS_ERR
(
rt
))
return
rt
;
fl
.
fl4_dst
=
rt
->
rt_dst
;
fl
.
fl4_src
=
rt
->
rt_src
;
fl
4
.
daddr
=
rt
->
rt_dst
;
fl
4
.
saddr
=
rt
->
rt_src
;
ip_rt_put
(
rt
);
}
security_sk_classify_flow
(
sk
,
&
fl
);
return
ip_route_output_flow
(
net
,
&
fl
,
sk
);
security_sk_classify_flow
(
sk
,
flowi4_to_flowi
(
&
fl4
)
);
return
ip_route_output_flow
(
net
,
&
fl
4
,
sk
);
}
static
inline
struct
rtable
*
ip_route_newports
(
struct
rtable
*
rt
,
...
...
@@ -266,23 +266,23 @@ static inline struct rtable *ip_route_newports(struct rtable *rt,
__be16
dport
,
struct
sock
*
sk
)
{
if
(
sport
!=
orig_sport
||
dport
!=
orig_dport
)
{
struct
flowi
fl
=
{
.
flowi_oif
=
rt
->
rt_oif
,
.
flowi_mark
=
rt
->
rt_mark
,
.
fl4_dst
=
rt
->
rt_key_dst
,
.
fl4_src
=
rt
->
rt_key_src
,
.
fl4_tos
=
rt
->
rt_tos
,
.
flowi_proto
=
protocol
,
.
fl4_
sport
=
sport
,
.
fl4_
dport
=
dport
struct
flowi
4
fl4
=
{
.
flowi
4
_oif
=
rt
->
rt_oif
,
.
flowi
4
_mark
=
rt
->
rt_mark
,
.
daddr
=
rt
->
rt_key_dst
,
.
saddr
=
rt
->
rt_key_src
,
.
fl
owi
4_tos
=
rt
->
rt_tos
,
.
flowi
4
_proto
=
protocol
,
.
uli
.
ports
.
sport
=
sport
,
.
uli
.
ports
.
dport
=
dport
};
if
(
inet_sk
(
sk
)
->
transparent
)
fl
.
flowi
_flags
|=
FLOWI_FLAG_ANYSRC
;
fl
4
.
flowi4
_flags
|=
FLOWI_FLAG_ANYSRC
;
if
(
protocol
==
IPPROTO_TCP
)
fl
.
flowi
_flags
|=
FLOWI_FLAG_PRECOW_METRICS
;
fl
4
.
flowi4
_flags
|=
FLOWI_FLAG_PRECOW_METRICS
;
ip_rt_put
(
rt
);
security_sk_classify_flow
(
sk
,
&
fl
);
return
ip_route_output_flow
(
sock_net
(
sk
),
&
fl
,
sk
);
security_sk_classify_flow
(
sk
,
flowi4_to_flowi
(
&
fl4
)
);
return
ip_route_output_flow
(
sock_net
(
sk
),
&
fl
4
,
sk
);
}
return
rt
;
}
...
...
net/dccp/ipv4.c
View file @
9d6ec938
...
...
@@ -465,18 +465,18 @@ static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk,
struct
sk_buff
*
skb
)
{
struct
rtable
*
rt
;
struct
flowi
fl
=
{
.
flowi_oif
=
skb_rtable
(
skb
)
->
rt_iif
,
.
fl4_dst
=
ip_hdr
(
skb
)
->
saddr
,
.
fl4_src
=
ip_hdr
(
skb
)
->
daddr
,
.
fl4_tos
=
RT_CONN_FLAGS
(
sk
),
.
flowi_proto
=
sk
->
sk_protocol
,
.
fl4_
sport
=
dccp_hdr
(
skb
)
->
dccph_dport
,
.
fl4_
dport
=
dccp_hdr
(
skb
)
->
dccph_sport
,
struct
flowi
4
fl4
=
{
.
flowi
4
_oif
=
skb_rtable
(
skb
)
->
rt_iif
,
.
daddr
=
ip_hdr
(
skb
)
->
saddr
,
.
saddr
=
ip_hdr
(
skb
)
->
daddr
,
.
fl
owi
4_tos
=
RT_CONN_FLAGS
(
sk
),
.
flowi
4
_proto
=
sk
->
sk_protocol
,
.
uli
.
ports
.
sport
=
dccp_hdr
(
skb
)
->
dccph_dport
,
.
uli
.
ports
.
dport
=
dccp_hdr
(
skb
)
->
dccph_sport
,
};
security_skb_classify_flow
(
skb
,
&
fl
);
rt
=
ip_route_output_flow
(
net
,
&
fl
,
sk
);
security_skb_classify_flow
(
skb
,
flowi4_to_flowi
(
&
fl4
)
);
rt
=
ip_route_output_flow
(
net
,
&
fl
4
,
sk
);
if
(
IS_ERR
(
rt
))
{
IP_INC_STATS_BH
(
net
,
IPSTATS_MIB_OUTNOROUTES
);
return
NULL
;
...
...
net/ipv4/icmp.c
View file @
9d6ec938
...
...
@@ -353,14 +353,14 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
daddr
=
icmp_param
->
replyopts
.
faddr
;
}
{
struct
flowi
fl
=
{
.
fl4_dst
=
daddr
,
.
fl4_src
=
rt
->
rt_spec_dst
,
.
fl4_tos
=
RT_TOS
(
ip_hdr
(
skb
)
->
tos
),
.
flowi_proto
=
IPPROTO_ICMP
,
struct
flowi
4
fl4
=
{
.
daddr
=
daddr
,
.
saddr
=
rt
->
rt_spec_dst
,
.
fl
owi
4_tos
=
RT_TOS
(
ip_hdr
(
skb
)
->
tos
),
.
flowi
4
_proto
=
IPPROTO_ICMP
,
};
security_skb_classify_flow
(
skb
,
&
fl
);
rt
=
ip_route_output_key
(
net
,
&
fl
);
security_skb_classify_flow
(
skb
,
flowi4_to_flowi
(
&
fl4
)
);
rt
=
ip_route_output_key
(
net
,
&
fl
4
);
if
(
IS_ERR
(
rt
))
goto
out_unlock
;
}
...
...
@@ -378,30 +378,31 @@ static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in,
int
type
,
int
code
,
struct
icmp_bxm
*
param
)
{
struct
flowi
fl
=
{
.
fl4_dst
=
(
param
->
replyopts
.
srr
?
struct
flowi
4
fl4
=
{
.
daddr
=
(
param
->
replyopts
.
srr
?
param
->
replyopts
.
faddr
:
iph
->
saddr
),
.
fl4_src
=
saddr
,
.
fl4_tos
=
RT_TOS
(
tos
),
.
flowi_proto
=
IPPROTO_ICMP
,
.
fl4_icmp_
type
=
type
,
.
fl4_icmp_
code
=
code
,
.
saddr
=
saddr
,
.
fl
owi
4_tos
=
RT_TOS
(
tos
),
.
flowi
4
_proto
=
IPPROTO_ICMP
,
.
uli
.
icmpt
.
type
=
type
,
.
uli
.
icmpt
.
code
=
code
,
};
struct
rtable
*
rt
,
*
rt2
;
int
err
;
security_skb_classify_flow
(
skb_in
,
&
fl
);
rt
=
__ip_route_output_key
(
net
,
&
fl
);
security_skb_classify_flow
(
skb_in
,
flowi4_to_flowi
(
&
fl4
)
);
rt
=
__ip_route_output_key
(
net
,
&
fl
4
);
if
(
IS_ERR
(
rt
))
return
rt
;
/* No need to clone since we're just using its address. */
rt2
=
rt
;
if
(
!
fl
.
fl4_src
)
fl
.
fl4_src
=
rt
->
rt_src
;
if
(
!
fl
4
.
saddr
)
fl
4
.
saddr
=
rt
->
rt_src
;
rt
=
(
struct
rtable
*
)
xfrm_lookup
(
net
,
&
rt
->
dst
,
&
fl
,
NULL
,
0
);
rt
=
(
struct
rtable
*
)
xfrm_lookup
(
net
,
&
rt
->
dst
,
flowi4_to_flowi
(
&
fl4
),
NULL
,
0
);
if
(
!
IS_ERR
(
rt
))
{
if
(
rt
!=
rt2
)
return
rt
;
...
...
@@ -410,27 +411,27 @@ static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in,
}
else
return
rt
;
err
=
xfrm_decode_session_reverse
(
skb_in
,
&
fl
,
AF_INET
);
err
=
xfrm_decode_session_reverse
(
skb_in
,
flowi4_to_flowi
(
&
fl4
)
,
AF_INET
);
if
(
err
)
goto
relookup_failed
;
if
(
inet_addr_type
(
net
,
fl
.
fl4_src
)
==
RTN_LOCAL
)
{
rt2
=
__ip_route_output_key
(
net
,
&
fl
);
if
(
inet_addr_type
(
net
,
fl
4
.
saddr
)
==
RTN_LOCAL
)
{
rt2
=
__ip_route_output_key
(
net
,
&
fl
4
);
if
(
IS_ERR
(
rt2
))
err
=
PTR_ERR
(
rt2
);
}
else
{
struct
flowi
fl
2
=
{};
struct
flowi
4
fl4_
2
=
{};
unsigned
long
orefdst
;
fl
2
.
fl4_dst
=
fl
.
fl4_src
;
rt2
=
ip_route_output_key
(
net
,
&
fl2
);
fl
4_2
.
daddr
=
fl4
.
saddr
;
rt2
=
ip_route_output_key
(
net
,
&
fl
4_
2
);
if
(
IS_ERR
(
rt2
))
{
err
=
PTR_ERR
(
rt2
);
goto
relookup_failed
;
}
/* Ugh! */
orefdst
=
skb_in
->
_skb_refdst
;
/* save old refdst */
err
=
ip_route_input
(
skb_in
,
fl
.
fl4_dst
,
fl
.
fl4_src
,
err
=
ip_route_input
(
skb_in
,
fl
4
.
daddr
,
fl4
.
saddr
,
RT_TOS
(
tos
),
rt2
->
dst
.
dev
);
dst_release
(
&
rt2
->
dst
);
...
...
@@ -441,7 +442,9 @@ static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in,
if
(
err
)
goto
relookup_failed
;
rt2
=
(
struct
rtable
*
)
xfrm_lookup
(
net
,
&
rt2
->
dst
,
&
fl
,
NULL
,
XFRM_LOOKUP_ICMP
);
rt2
=
(
struct
rtable
*
)
xfrm_lookup
(
net
,
&
rt2
->
dst
,
flowi4_to_flowi
(
&
fl4
),
NULL
,
XFRM_LOOKUP_ICMP
);
if
(
!
IS_ERR
(
rt2
))
{
dst_release
(
&
rt
->
dst
);
rt
=
rt2
;
...
...
net/ipv4/inet_connection_sock.c
View file @
9d6ec938
...
...
@@ -356,22 +356,22 @@ struct dst_entry *inet_csk_route_req(struct sock *sk,
struct
rtable
*
rt
;
const
struct
inet_request_sock
*
ireq
=
inet_rsk
(
req
);
struct
ip_options
*
opt
=
inet_rsk
(
req
)
->
opt
;
struct
flowi
fl
=
{
.
flowi_oif
=
sk
->
sk_bound_dev_if
,
.
flowi_mark
=
sk
->
sk_mark
,
.
fl4_dst
=
((
opt
&&
opt
->
srr
)
?
struct
flowi
4
fl4
=
{
.
flowi
4
_oif
=
sk
->
sk_bound_dev_if
,
.
flowi
4
_mark
=
sk
->
sk_mark
,
.
daddr
=
((
opt
&&
opt
->
srr
)
?
opt
->
faddr
:
ireq
->
rmt_addr
),
.
fl4_src
=
ireq
->
loc_addr
,
.
fl4_tos
=
RT_CONN_FLAGS
(
sk
),
.
flowi_proto
=
sk
->
sk_protocol
,
.
flowi_flags
=
inet_sk_flowi_flags
(
sk
),
.
fl4_
sport
=
inet_sk
(
sk
)
->
inet_sport
,
.
fl4_
dport
=
ireq
->
rmt_port
,
.
saddr
=
ireq
->
loc_addr
,
.
fl
owi
4_tos
=
RT_CONN_FLAGS
(
sk
),
.
flowi
4
_proto
=
sk
->
sk_protocol
,
.
flowi
4
_flags
=
inet_sk_flowi_flags
(
sk
),
.
uli
.
ports
.
sport
=
inet_sk
(
sk
)
->
inet_sport
,
.
uli
.
ports
.
dport
=
ireq
->
rmt_port
,
};
struct
net
*
net
=
sock_net
(
sk
);
security_req_classify_flow
(
req
,
&
fl
);
rt
=
ip_route_output_flow
(
net
,
&
fl
,
sk
);
security_req_classify_flow
(
req
,
flowi4_to_flowi
(
&
fl4
)
);
rt
=
ip_route_output_flow
(
net
,
&
fl
4
,
sk
);
if
(
IS_ERR
(
rt
))
goto
no_route
;
if
(
opt
&&
opt
->
is_strictroute
&&
rt
->
rt_dst
!=
rt
->
rt_gateway
)
...
...
net/ipv4/ip_output.c
View file @
9d6ec938
...
...
@@ -1474,18 +1474,18 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
}
{
struct
flowi
fl
=
{
.
flowi_oif
=
arg
->
bound_dev_if
,
.
fl4_dst
=
daddr
,
.
fl4_src
=
rt
->
rt_spec_dst
,
.
fl4_tos
=
RT_TOS
(
ip_hdr
(
skb
)
->
tos
),
.
fl4_
sport
=
tcp_hdr
(
skb
)
->
dest
,
.
fl4_
dport
=
tcp_hdr
(
skb
)
->
source
,
.
flowi_proto
=
sk
->
sk_protocol
,
.
flowi_flags
=
ip_reply_arg_flowi_flags
(
arg
),
struct
flowi
4
fl4
=
{
.
flowi
4
_oif
=
arg
->
bound_dev_if
,
.
daddr
=
daddr
,
.
saddr
=
rt
->
rt_spec_dst
,
.
fl
owi
4_tos
=
RT_TOS
(
ip_hdr
(
skb
)
->
tos
),
.
uli
.
ports
.
sport
=
tcp_hdr
(
skb
)
->
dest
,
.
uli
.
ports
.
dport
=
tcp_hdr
(
skb
)
->
source
,
.
flowi
4
_proto
=
sk
->
sk_protocol
,
.
flowi
4
_flags
=
ip_reply_arg_flowi_flags
(
arg
),
};
security_skb_classify_flow
(
skb
,
&
fl
);
rt
=
ip_route_output_key
(
sock_net
(
sk
),
&
fl
);
security_skb_classify_flow
(
skb
,
flowi4_to_flowi
(
&
fl4
)
);
rt
=
ip_route_output_key
(
sock_net
(
sk
),
&
fl
4
);
if
(
IS_ERR
(
rt
))
return
;
}
...
...
net/ipv4/netfilter.c
View file @
9d6ec938
...
...
@@ -16,7 +16,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
struct
net
*
net
=
dev_net
(
skb_dst
(
skb
)
->
dev
);
const
struct
iphdr
*
iph
=
ip_hdr
(
skb
);
struct
rtable
*
rt
;
struct
flowi
fl
=
{};
struct
flowi
4
fl4
=
{};
unsigned
long
orefdst
;
unsigned
int
hh_len
;
unsigned
int
type
;
...
...
@@ -31,14 +31,14 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
* packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook.
*/
if
(
addr_type
==
RTN_LOCAL
)
{
fl
.
fl4_dst
=
iph
->
daddr
;
fl
4
.
daddr
=
iph
->
daddr
;
if
(
type
==
RTN_LOCAL
)
fl
.
fl4_src
=
iph
->
saddr
;
fl
.
fl
4_tos
=
RT_TOS
(
iph
->
tos
);
fl
.
flowi
_oif
=
skb
->
sk
?
skb
->
sk
->
sk_bound_dev_if
:
0
;
fl
.
flowi
_mark
=
skb
->
mark
;
fl
.
flowi
_flags
=
skb
->
sk
?
inet_sk_flowi_flags
(
skb
->
sk
)
:
0
;
rt
=
ip_route_output_key
(
net
,
&
fl
);
fl
4
.
saddr
=
iph
->
saddr
;
fl
4
.
flowi
4_tos
=
RT_TOS
(
iph
->
tos
);
fl
4
.
flowi4
_oif
=
skb
->
sk
?
skb
->
sk
->
sk_bound_dev_if
:
0
;
fl
4
.
flowi4
_mark
=
skb
->
mark
;
fl
4
.
flowi4
_flags
=
skb
->
sk
?
inet_sk_flowi_flags
(
skb
->
sk
)
:
0
;
rt
=
ip_route_output_key
(
net
,
&
fl
4
);
if
(
IS_ERR
(
rt
))
return
-
1
;
...
...
@@ -48,8 +48,8 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
}
else
{
/* non-local src, find valid iif to satisfy
* rp-filter when calling ip_route_input. */
fl
.
fl4_dst
=
iph
->
saddr
;
rt
=
ip_route_output_key
(
net
,
&
fl
);
fl
4
.
daddr
=
iph
->
saddr
;
rt
=
ip_route_output_key
(
net
,
&
fl
4
);
if
(
IS_ERR
(
rt
))
return
-
1
;
...
...
@@ -68,10 +68,10 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
#ifdef CONFIG_XFRM
if
(
!
(
IPCB
(
skb
)
->
flags
&
IPSKB_XFRM_TRANSFORMED
)
&&
xfrm_decode_session
(
skb
,
&
fl
,
AF_INET
)
==
0
)
{
xfrm_decode_session
(
skb
,
flowi4_to_flowi
(
&
fl4
)
,
AF_INET
)
==
0
)
{
struct
dst_entry
*
dst
=
skb_dst
(
skb
);
skb_dst_set
(
skb
,
NULL
);
dst
=
xfrm_lookup
(
net
,
dst
,
&
fl
,
skb
->
sk
,
0
);
dst
=
xfrm_lookup
(
net
,
dst
,
flowi4_to_flowi
(
&
fl4
)
,
skb
->
sk
,
0
);
if
(
IS_ERR
(
dst
))
return
-
1
;
skb_dst_set
(
skb
,
dst
);
...
...
@@ -223,7 +223,7 @@ static __sum16 nf_ip_checksum_partial(struct sk_buff *skb, unsigned int hook,
static
int
nf_ip_route
(
struct
dst_entry
**
dst
,
struct
flowi
*
fl
)
{
struct
rtable
*
rt
=
ip_route_output_key
(
&
init_net
,
fl
);
struct
rtable
*
rt
=
ip_route_output_key
(
&
init_net
,
&
fl
->
u
.
ip4
);
if
(
IS_ERR
(
rt
))
return
PTR_ERR
(
rt
);
*
dst
=
&
rt
->
dst
;
...
...
net/ipv4/raw.c
View file @
9d6ec938
...
...
@@ -402,7 +402,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
return
err
;
}
static
int
raw_probe_proto_opt
(
struct
flowi
*
fl
,
struct
msghdr
*
msg
)
static
int
raw_probe_proto_opt
(
struct
flowi
4
*
fl4
,
struct
msghdr
*
msg
)
{
struct
iovec
*
iov
;
u8
__user
*
type
=
NULL
;
...
...
@@ -418,7 +418,7 @@ static int raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
if
(
!
iov
)
continue
;
switch
(
fl
->
flowi
_proto
)
{
switch
(
fl
4
->
flowi4
_proto
)
{
case
IPPROTO_ICMP
:
/* check if one-byte field is readable or not. */
if
(
iov
->
iov_base
&&
iov
->
iov_len
<
1
)
...
...
@@ -433,8 +433,8 @@ static int raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
code
=
iov
->
iov_base
;
if
(
type
&&
code
)
{
if
(
get_user
(
fl
->
fl4_icmp_
type
,
type
)
||
get_user
(
fl
->
fl4_icmp_
code
,
code
))
if
(
get_user
(
fl
4
->
uli
.
icmpt
.
type
,
type
)
||
get_user
(
fl
4
->
uli
.
icmpt
.
code
,
code
))
return
-
EFAULT
;
probed
=
1
;
}
...
...
@@ -548,23 +548,25 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
}
{
struct
flowi
fl
=
{
.
flowi_oif
=
ipc
.
oif
,
.
flowi_mark
=
sk
->
sk_mark
,
.
fl4_dst
=
daddr
,
.
fl4_src
=
saddr
,
.
fl4_tos
=
tos
,
.
flowi_proto
=
inet
->
hdrincl
?
IPPROTO_RAW
:
sk
->
sk_protocol
,
.
flowi_flags
=
FLOWI_FLAG_CAN_SLEEP
,
struct
flowi4
fl4
=
{
.
flowi4_oif
=
ipc
.
oif
,
.
flowi4_mark
=
sk
->
sk_mark
,
.
daddr
=
daddr
,
.
saddr
=
saddr
,
.
flowi4_tos
=
tos
,
.
flowi4_proto
=
(
inet
->
hdrincl
?
IPPROTO_RAW
:
sk
->
sk_protocol
),
.
flowi4_flags
=
FLOWI_FLAG_CAN_SLEEP
,
};
if
(
!
inet
->
hdrincl
)
{
err
=
raw_probe_proto_opt
(
&
fl
,
msg
);
err
=
raw_probe_proto_opt
(
&
fl
4
,
msg
);
if
(
err
)
goto
done
;
}
security_sk_classify_flow
(
sk
,
&
fl
);
rt
=
ip_route_output_flow
(
sock_net
(
sk
),
&
fl
,
sk
);
security_sk_classify_flow
(
sk
,
flowi4_to_flowi
(
&
fl4
)
);
rt
=
ip_route_output_flow
(
sock_net
(
sk
),
&
fl
4
,
sk
);
if
(
IS_ERR
(
rt
))
{
err
=
PTR_ERR
(
rt
);
goto
done
;
...
...
net/ipv4/route.c
View file @
9d6ec938
...
...
@@ -2626,7 +2626,7 @@ static struct rtable *ip_route_output_slow(struct net *net,
return
rth
;
}
struct
rtable
*
__ip_route_output_key
(
struct
net
*
net
,
const
struct
flowi
*
flp
)
struct
rtable
*
__ip_route_output_key
(
struct
net
*
net
,
const
struct
flowi
4
*
flp4
)
{
struct
rtable
*
rth
;
unsigned
int
hash
;
...
...
@@ -2634,17 +2634,17 @@ struct rtable *__ip_route_output_key(struct net *net, const struct flowi *flp)
if
(
!
rt_caching
(
net
))
goto
slow_output
;
hash
=
rt_hash
(
flp
->
fl4_dst
,
flp
->
fl4_src
,
flp
->
flowi
_oif
,
rt_genid
(
net
));
hash
=
rt_hash
(
flp
4
->
daddr
,
flp4
->
saddr
,
flp4
->
flowi4
_oif
,
rt_genid
(
net
));
rcu_read_lock_bh
();
for
(
rth
=
rcu_dereference_bh
(
rt_hash_table
[
hash
].
chain
);
rth
;
rth
=
rcu_dereference_bh
(
rth
->
dst
.
rt_next
))
{
if
(
rth
->
rt_key_dst
==
flp
->
fl4_dst
&&
rth
->
rt_key_src
==
flp
->
fl4_src
&&
if
(
rth
->
rt_key_dst
==
flp
4
->
daddr
&&
rth
->
rt_key_src
==
flp
4
->
saddr
&&
rt_is_output_route
(
rth
)
&&
rth
->
rt_oif
==
flp
->
flowi
_oif
&&
rth
->
rt_mark
==
flp
->
flowi
_mark
&&
!
((
rth
->
rt_tos
^
flp
->
fl
4_tos
)
&
rth
->
rt_oif
==
flp
4
->
flowi4
_oif
&&
rth
->
rt_mark
==
flp
4
->
flowi4
_mark
&&
!
((
rth
->
rt_tos
^
flp
4
->
flowi
4_tos
)
&
(
IPTOS_RT_MASK
|
RTO_ONLINK
))
&&
net_eq
(
dev_net
(
rth
->
dst
.
dev
),
net
)
&&
!
rt_is_expired
(
rth
))
{
...
...
@@ -2658,7 +2658,7 @@ struct rtable *__ip_route_output_key(struct net *net, const struct flowi *flp)
rcu_read_unlock_bh
();
slow_output:
return
ip_route_output_slow
(
net
,
&
flp
->
u
.
i
p4
);
return
ip_route_output_slow
(
net
,
fl
p4
);
}
EXPORT_SYMBOL_GPL
(
__ip_route_output_key
);
...
...
@@ -2733,20 +2733,22 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or
return
rt
?
&
rt
->
dst
:
ERR_PTR
(
-
ENOMEM
);
}
struct
rtable
*
ip_route_output_flow
(
struct
net
*
net
,
struct
flowi
*
flp
,
struct
rtable
*
ip_route_output_flow
(
struct
net
*
net
,
struct
flowi
4
*
flp4
,
struct
sock
*
sk
)
{
struct
rtable
*
rt
=
__ip_route_output_key
(
net
,
flp
);
struct
rtable
*
rt
=
__ip_route_output_key
(
net
,
flp
4
);
if
(
IS_ERR
(
rt
))
return
rt
;
if
(
flp
->
flowi_proto
)
{
if
(
!
flp
->
fl4_src
)
flp
->
fl4_src
=
rt
->
rt_src
;
if
(
!
flp
->
fl4_dst
)
flp
->
fl4_dst
=
rt
->
rt_dst
;
rt
=
(
struct
rtable
*
)
xfrm_lookup
(
net
,
&
rt
->
dst
,
flp
,
sk
,
0
);
if
(
flp4
->
flowi4_proto
)
{
if
(
!
flp4
->
saddr
)
flp4
->
saddr
=
rt
->
rt_src
;
if
(
!
flp4
->
daddr
)
flp4
->
daddr
=
rt
->
rt_dst
;
rt
=
(
struct
rtable
*
)
xfrm_lookup
(
net
,
&
rt
->
dst
,
flowi4_to_flowi
(
flp4
),
sk
,
0
);
}
return
rt
;
...
...
@@ -2920,7 +2922,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
.
flowi4_oif
=
tb
[
RTA_OIF
]
?
nla_get_u32
(
tb
[
RTA_OIF
])
:
0
,
.
flowi4_mark
=
mark
,
};
rt
=
ip_route_output_key
(
net
,
flowi4_to_flowi
(
&
fl4
)
);
rt
=
ip_route_output_key
(
net
,
&
fl4
);
err
=
0
;
if
(
IS_ERR
(
rt
))
...
...
net/ipv4/syncookies.c
View file @
9d6ec938
...
...
@@ -345,19 +345,19 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
* no easy way to do this.
*/
{
struct
flowi
fl
=
{
.
flowi_mark
=
sk
->
sk_mark
,
.
fl4_dst
=
((
opt
&&
opt
->
srr
)
?
struct
flowi
4
fl4
=
{
.
flowi
4
_mark
=
sk
->
sk_mark
,
.
daddr
=
((
opt
&&
opt
->
srr
)
?
opt
->
faddr
:
ireq
->
rmt_addr
),
.
fl4_src
=
ireq
->
loc_addr
,
.
fl4_tos
=
RT_CONN_FLAGS
(
sk
),
.
flowi_proto
=
IPPROTO_TCP
,
.
flowi_flags
=
inet_sk_flowi_flags
(
sk
),
.
fl4_
sport
=
th
->
dest
,
.
fl4_
dport
=
th
->
source
,
.
saddr
=
ireq
->
loc_addr
,
.
fl
owi
4_tos
=
RT_CONN_FLAGS
(
sk
),
.
flowi
4
_proto
=
IPPROTO_TCP
,
.
flowi
4
_flags
=
inet_sk_flowi_flags
(
sk
),
.
uli
.
ports
.
sport
=
th
->
dest
,
.
uli
.
ports
.
dport
=
th
->
source
,
};
security_req_classify_flow
(
req
,
&
fl
);
rt
=
ip_route_output_key
(
sock_net
(
sk
),
&
fl
);
security_req_classify_flow
(
req
,
flowi4_to_flowi
(
&
fl4
)
);
rt
=
ip_route_output_key
(
sock_net
(
sk
),
&
fl
4
);
if
(
IS_ERR
(
rt
))
{
reqsk_free
(
req
);
goto
out
;
...
...
net/ipv4/udp.c
View file @
9d6ec938
...
...
@@ -908,22 +908,22 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
rt
=
(
struct
rtable
*
)
sk_dst_check
(
sk
,
0
);
if
(
rt
==
NULL
)
{
struct
flowi
fl
=
{
.
flowi_oif
=
ipc
.
oif
,
.
flowi_mark
=
sk
->
sk_mark
,
.
fl4_dst
=
faddr
,
.
fl4_src
=
saddr
,
.
fl4_tos
=
tos
,
.
flowi_proto
=
sk
->
sk_protocol
,
.
flowi_flags
=
(
inet_sk_flowi_flags
(
sk
)
|
struct
flowi
4
fl4
=
{
.
flowi
4
_oif
=
ipc
.
oif
,
.
flowi
4
_mark
=
sk
->
sk_mark
,
.
daddr
=
faddr
,
.
saddr
=
saddr
,
.
fl
owi
4_tos
=
tos
,
.
flowi
4
_proto
=
sk
->
sk_protocol
,
.
flowi
4
_flags
=
(
inet_sk_flowi_flags
(
sk
)
|
FLOWI_FLAG_CAN_SLEEP
),
.
fl4_
sport
=
inet
->
inet_sport
,
.
fl4_
dport
=
dport
,
.
uli
.
ports
.
sport
=
inet
->
inet_sport
,
.
uli
.
ports
.
dport
=
dport
,
};
struct
net
*
net
=
sock_net
(
sk
);
security_sk_classify_flow
(
sk
,
&
fl
);
rt
=
ip_route_output_flow
(
net
,
&
fl
,
sk
);
security_sk_classify_flow
(
sk
,
flowi4_to_flowi
(
&
fl4
)
);
rt
=
ip_route_output_flow
(
net
,
&
fl
4
,
sk
);
if
(
IS_ERR
(
rt
))
{
err
=
PTR_ERR
(
rt
);
rt
=
NULL
;
...
...
net/ipv4/xfrm4_policy.c
View file @
9d6ec938
...
...
@@ -22,16 +22,16 @@ static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos,
const
xfrm_address_t
*
saddr
,
const
xfrm_address_t
*
daddr
)
{
struct
flowi
fl
=
{
.
fl4_dst
=
daddr
->
a4
,
.
fl4_tos
=
tos
,
struct
flowi
4
fl4
=
{
.
daddr
=
daddr
->
a4
,
.
fl
owi
4_tos
=
tos
,
};
struct
rtable
*
rt
;
if
(
saddr
)
fl
.
fl4_src
=
saddr
->
a4
;
fl
4
.
saddr
=
saddr
->
a4
;
rt
=
__ip_route_output_key
(
net
,
&
fl
);
rt
=
__ip_route_output_key
(
net
,
&
fl
4
);
if
(
!
IS_ERR
(
rt
))
return
&
rt
->
dst
;
...
...
net/netfilter/ipvs/ip_vs_xmit.c
View file @
9d6ec938
...
...
@@ -165,14 +165,14 @@ __ip_vs_reroute_locally(struct sk_buff *skb)
return
0
;
refdst_drop
(
orefdst
);
}
else
{
struct
flowi
fl
=
{
.
fl4_dst
=
iph
->
daddr
,
.
fl4_src
=
iph
->
saddr
,
.
fl4_tos
=
RT_TOS
(
iph
->
tos
),
.
flowi_mark
=
skb
->
mark
,
struct
flowi
4
fl4
=
{
.
daddr
=
iph
->
daddr
,
.
saddr
=
iph
->
saddr
,
.
fl
owi
4_tos
=
RT_TOS
(
iph
->
tos
),
.
flowi
4
_mark
=
skb
->
mark
,
};
rt
=
ip_route_output_key
(
net
,
&
fl
);
rt
=
ip_route_output_key
(
net
,
&
fl
4
);
if
(
IS_ERR
(
rt
))
return
0
;
if
(
!
(
rt
->
rt_flags
&
RTCF_LOCAL
))
{
...
...
net/netfilter/xt_TEE.c
View file @
9d6ec938
...
...
@@ -62,18 +62,18 @@ tee_tg_route4(struct sk_buff *skb, const struct xt_tee_tginfo *info)
const
struct
iphdr
*
iph
=
ip_hdr
(
skb
);
struct
net
*
net
=
pick_net
(
skb
);
struct
rtable
*
rt
;
struct
flowi
fl
;
struct
flowi
4
fl4
;
memset
(
&
fl
,
0
,
sizeof
(
fl
));
memset
(
&
fl
4
,
0
,
sizeof
(
fl4
));
if
(
info
->
priv
)
{
if
(
info
->
priv
->
oif
==
-
1
)
return
false
;
fl
.
flowi
_oif
=
info
->
priv
->
oif
;
fl
4
.
flowi4
_oif
=
info
->
priv
->
oif
;
}
fl
.
fl4_dst
=
info
->
gw
.
ip
;
fl
.
fl
4_tos
=
RT_TOS
(
iph
->
tos
);
fl
.
fl
4_scope
=
RT_SCOPE_UNIVERSE
;
rt
=
ip_route_output_key
(
net
,
&
fl
);
fl
4
.
daddr
=
info
->
gw
.
ip
;
fl
4
.
flowi
4_tos
=
RT_TOS
(
iph
->
tos
);
fl
4
.
flowi
4_scope
=
RT_SCOPE_UNIVERSE
;
rt
=
ip_route_output_key
(
net
,
&
fl
4
);
if
(
IS_ERR
(
rt
))
return
false
;
...
...
net/sctp/protocol.c
View file @
9d6ec938
...
...
@@ -468,30 +468,30 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
union
sctp_addr
*
saddr
)
{
struct
rtable
*
rt
;
struct
flowi
fl
;
struct
flowi
4
fl4
;
struct
sctp_bind_addr
*
bp
;
struct
sctp_sockaddr_entry
*
laddr
;
struct
dst_entry
*
dst
=
NULL
;
union
sctp_addr
dst_saddr
;
memset
(
&
fl
,
0x0
,
sizeof
(
struct
flowi
));
fl
.
fl4_dst
=
daddr
->
v4
.
sin_addr
.
s_addr
;
fl
.
fl4_
dport
=
daddr
->
v4
.
sin_port
;
fl
.
flowi
_proto
=
IPPROTO_SCTP
;
memset
(
&
fl
4
,
0x0
,
sizeof
(
struct
flowi4
));
fl
4
.
daddr
=
daddr
->
v4
.
sin_addr
.
s_addr
;
fl
4
.
uli
.
ports
.
dport
=
daddr
->
v4
.
sin_port
;
fl
4
.
flowi4
_proto
=
IPPROTO_SCTP
;
if
(
asoc
)
{
fl
.
fl
4_tos
=
RT_CONN_FLAGS
(
asoc
->
base
.
sk
);
fl
.
flowi
_oif
=
asoc
->
base
.
sk
->
sk_bound_dev_if
;
fl
.
fl4_
sport
=
htons
(
asoc
->
base
.
bind_addr
.
port
);
fl
4
.
flowi
4_tos
=
RT_CONN_FLAGS
(
asoc
->
base
.
sk
);
fl
4
.
flowi4
_oif
=
asoc
->
base
.
sk
->
sk_bound_dev_if
;
fl
4
.
uli
.
ports
.
sport
=
htons
(
asoc
->
base
.
bind_addr
.
port
);
}
if
(
saddr
)
{
fl
.
fl4_src
=
saddr
->
v4
.
sin_addr
.
s_addr
;
fl
.
fl4_
sport
=
saddr
->
v4
.
sin_port
;
fl
4
.
saddr
=
saddr
->
v4
.
sin_addr
.
s_addr
;
fl
4
.
uli
.
ports
.
sport
=
saddr
->
v4
.
sin_port
;
}
SCTP_DEBUG_PRINTK
(
"%s: DST:%pI4, SRC:%pI4 - "
,
__func__
,
&
fl
.
fl4_dst
,
&
fl
.
fl4_src
);
__func__
,
&
fl
4
.
daddr
,
&
fl4
.
saddr
);
rt
=
ip_route_output_key
(
&
init_net
,
&
fl
);
rt
=
ip_route_output_key
(
&
init_net
,
&
fl
4
);
if
(
!
IS_ERR
(
rt
))
dst
=
&
rt
->
dst
;
...
...
@@ -533,9 +533,9 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
continue
;
if
((
laddr
->
state
==
SCTP_ADDR_SRC
)
&&
(
AF_INET
==
laddr
->
a
.
sa
.
sa_family
))
{
fl
.
fl4_src
=
laddr
->
a
.
v4
.
sin_addr
.
s_addr
;
fl
.
fl4_
sport
=
laddr
->
a
.
v4
.
sin_port
;
rt
=
ip_route_output_key
(
&
init_net
,
&
fl
);
fl
4
.
saddr
=
laddr
->
a
.
v4
.
sin_addr
.
s_addr
;
fl
4
.
uli
.
ports
.
sport
=
laddr
->
a
.
v4
.
sin_port
;
rt
=
ip_route_output_key
(
&
init_net
,
&
fl
4
);
if
(
!
IS_ERR
(
rt
))
{
dst
=
&
rt
->
dst
;
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