Commit 9d6ec938 authored by David S. Miller's avatar David S. Miller

ipv4: Use flowi4 in public route lookup interfaces.

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 68a5e3dd
...@@ -122,12 +122,12 @@ extern void ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw, ...@@ -122,12 +122,12 @@ extern void ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw,
__be32 src, struct net_device *dev); __be32 src, struct net_device *dev);
extern void rt_cache_flush(struct net *net, int how); extern void rt_cache_flush(struct net *net, int how);
extern void rt_cache_flush_batch(struct net *net); 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_key(struct net *, const struct flowi4 *flp);
extern struct rtable *ip_route_output_flow(struct net *, struct flowi *flp, extern struct rtable *ip_route_output_flow(struct net *, struct flowi4 *flp,
struct sock *sk); struct sock *sk);
extern struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig); 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 flowi4 *flp)
{ {
return ip_route_output_flow(net, flp, NULL); 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 * ...@@ -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, static inline struct rtable *ip_route_output(struct net *net, __be32 daddr,
__be32 saddr, u8 tos, int oif) __be32 saddr, u8 tos, int oif)
{ {
struct flowi fl = { struct flowi4 fl4 = {
.flowi_oif = oif, .flowi4_oif = oif,
.fl4_dst = daddr, .daddr = daddr,
.fl4_src = saddr, .saddr = saddr,
.fl4_tos = tos, .flowi4_tos = tos,
}; };
return ip_route_output_key(net, &fl); return ip_route_output_key(net, &fl4);
} }
static inline struct rtable *ip_route_output_ports(struct net *net, struct sock *sk, 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 ...@@ -149,35 +149,35 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct sock
__be16 dport, __be16 sport, __be16 dport, __be16 sport,
__u8 proto, __u8 tos, int oif) __u8 proto, __u8 tos, int oif)
{ {
struct flowi fl = { struct flowi4 fl4 = {
.flowi_oif = oif, .flowi4_oif = oif,
.flowi_flags = sk ? inet_sk_flowi_flags(sk) : 0, .flowi4_flags = sk ? inet_sk_flowi_flags(sk) : 0,
.flowi_mark = sk ? sk->sk_mark : 0, .flowi4_mark = sk ? sk->sk_mark : 0,
.fl4_dst = daddr, .daddr = daddr,
.fl4_src = saddr, .saddr = saddr,
.fl4_tos = tos, .flowi4_tos = tos,
.flowi_proto = proto, .flowi4_proto = proto,
.fl4_dport = dport, .uli.ports.dport = dport,
.fl4_sport = sport, .uli.ports.sport = sport,
}; };
if (sk) if (sk)
security_sk_classify_flow(sk, &fl); security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
return ip_route_output_flow(net, &fl, sk); return ip_route_output_flow(net, &fl4, sk);
} }
static inline struct rtable *ip_route_output_gre(struct net *net, static inline struct rtable *ip_route_output_gre(struct net *net,
__be32 daddr, __be32 saddr, __be32 daddr, __be32 saddr,
__be32 gre_key, __u8 tos, int oif) __be32 gre_key, __u8 tos, int oif)
{ {
struct flowi fl = { struct flowi4 fl4 = {
.flowi_oif = oif, .flowi4_oif = oif,
.fl4_dst = daddr, .daddr = daddr,
.fl4_src = saddr, .saddr = saddr,
.fl4_tos = tos, .flowi4_tos = tos,
.flowi_proto = IPPROTO_GRE, .flowi4_proto = IPPROTO_GRE,
.fl4_gre_key = gre_key, .uli.gre_key = gre_key,
}; };
return ip_route_output_key(net, &fl); return ip_route_output_key(net, &fl4);
} }
extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src, 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, ...@@ -228,36 +228,36 @@ static inline struct rtable *ip_route_connect(__be32 dst, __be32 src, u32 tos,
__be16 sport, __be16 dport, __be16 sport, __be16 dport,
struct sock *sk, bool can_sleep) struct sock *sk, bool can_sleep)
{ {
struct flowi fl = { struct flowi4 fl4 = {
.flowi_oif = oif, .flowi4_oif = oif,
.flowi_mark = sk->sk_mark, .flowi4_mark = sk->sk_mark,
.fl4_dst = dst, .daddr = dst,
.fl4_src = src, .saddr = src,
.fl4_tos = tos, .flowi4_tos = tos,
.flowi_proto = protocol, .flowi4_proto = protocol,
.fl4_sport = sport, .uli.ports.sport = sport,
.fl4_dport = dport, .uli.ports.dport = dport,
}; };
struct net *net = sock_net(sk); struct net *net = sock_net(sk);
struct rtable *rt; struct rtable *rt;
if (inet_sk(sk)->transparent) if (inet_sk(sk)->transparent)
fl.flowi_flags |= FLOWI_FLAG_ANYSRC; fl4.flowi4_flags |= FLOWI_FLAG_ANYSRC;
if (protocol == IPPROTO_TCP) if (protocol == IPPROTO_TCP)
fl.flowi_flags |= FLOWI_FLAG_PRECOW_METRICS; fl4.flowi4_flags |= FLOWI_FLAG_PRECOW_METRICS;
if (can_sleep) if (can_sleep)
fl.flowi_flags |= FLOWI_FLAG_CAN_SLEEP; fl4.flowi4_flags |= FLOWI_FLAG_CAN_SLEEP;
if (!dst || !src) { if (!dst || !src) {
rt = __ip_route_output_key(net, &fl); rt = __ip_route_output_key(net, &fl4);
if (IS_ERR(rt)) if (IS_ERR(rt))
return rt; return rt;
fl.fl4_dst = rt->rt_dst; fl4.daddr = rt->rt_dst;
fl.fl4_src = rt->rt_src; fl4.saddr = rt->rt_src;
ip_rt_put(rt); ip_rt_put(rt);
} }
security_sk_classify_flow(sk, &fl); security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
return ip_route_output_flow(net, &fl, sk); return ip_route_output_flow(net, &fl4, sk);
} }
static inline struct rtable *ip_route_newports(struct rtable *rt, static inline struct rtable *ip_route_newports(struct rtable *rt,
...@@ -266,23 +266,23 @@ 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) __be16 dport, struct sock *sk)
{ {
if (sport != orig_sport || dport != orig_dport) { if (sport != orig_sport || dport != orig_dport) {
struct flowi fl = { struct flowi4 fl4 = {
.flowi_oif = rt->rt_oif, .flowi4_oif = rt->rt_oif,
.flowi_mark = rt->rt_mark, .flowi4_mark = rt->rt_mark,
.fl4_dst = rt->rt_key_dst, .daddr = rt->rt_key_dst,
.fl4_src = rt->rt_key_src, .saddr = rt->rt_key_src,
.fl4_tos = rt->rt_tos, .flowi4_tos = rt->rt_tos,
.flowi_proto = protocol, .flowi4_proto = protocol,
.fl4_sport = sport, .uli.ports.sport = sport,
.fl4_dport = dport .uli.ports.dport = dport
}; };
if (inet_sk(sk)->transparent) if (inet_sk(sk)->transparent)
fl.flowi_flags |= FLOWI_FLAG_ANYSRC; fl4.flowi4_flags |= FLOWI_FLAG_ANYSRC;
if (protocol == IPPROTO_TCP) if (protocol == IPPROTO_TCP)
fl.flowi_flags |= FLOWI_FLAG_PRECOW_METRICS; fl4.flowi4_flags |= FLOWI_FLAG_PRECOW_METRICS;
ip_rt_put(rt); ip_rt_put(rt);
security_sk_classify_flow(sk, &fl); security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
return ip_route_output_flow(sock_net(sk), &fl, sk); return ip_route_output_flow(sock_net(sk), &fl4, sk);
} }
return rt; return rt;
} }
......
...@@ -465,18 +465,18 @@ static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk, ...@@ -465,18 +465,18 @@ static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk,
struct sk_buff *skb) struct sk_buff *skb)
{ {
struct rtable *rt; struct rtable *rt;
struct flowi fl = { struct flowi4 fl4 = {
.flowi_oif = skb_rtable(skb)->rt_iif, .flowi4_oif = skb_rtable(skb)->rt_iif,
.fl4_dst = ip_hdr(skb)->saddr, .daddr = ip_hdr(skb)->saddr,
.fl4_src = ip_hdr(skb)->daddr, .saddr = ip_hdr(skb)->daddr,
.fl4_tos = RT_CONN_FLAGS(sk), .flowi4_tos = RT_CONN_FLAGS(sk),
.flowi_proto = sk->sk_protocol, .flowi4_proto = sk->sk_protocol,
.fl4_sport = dccp_hdr(skb)->dccph_dport, .uli.ports.sport = dccp_hdr(skb)->dccph_dport,
.fl4_dport = dccp_hdr(skb)->dccph_sport, .uli.ports.dport = dccp_hdr(skb)->dccph_sport,
}; };
security_skb_classify_flow(skb, &fl); security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));
rt = ip_route_output_flow(net, &fl, sk); rt = ip_route_output_flow(net, &fl4, sk);
if (IS_ERR(rt)) { if (IS_ERR(rt)) {
IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES);
return NULL; return NULL;
......
...@@ -353,14 +353,14 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) ...@@ -353,14 +353,14 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
daddr = icmp_param->replyopts.faddr; daddr = icmp_param->replyopts.faddr;
} }
{ {
struct flowi fl = { struct flowi4 fl4 = {
.fl4_dst = daddr, .daddr = daddr,
.fl4_src = rt->rt_spec_dst, .saddr = rt->rt_spec_dst,
.fl4_tos = RT_TOS(ip_hdr(skb)->tos), .flowi4_tos = RT_TOS(ip_hdr(skb)->tos),
.flowi_proto = IPPROTO_ICMP, .flowi4_proto = IPPROTO_ICMP,
}; };
security_skb_classify_flow(skb, &fl); security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));
rt = ip_route_output_key(net, &fl); rt = ip_route_output_key(net, &fl4);
if (IS_ERR(rt)) if (IS_ERR(rt))
goto out_unlock; goto out_unlock;
} }
...@@ -378,30 +378,31 @@ static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in, ...@@ -378,30 +378,31 @@ static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in,
int type, int code, int type, int code,
struct icmp_bxm *param) struct icmp_bxm *param)
{ {
struct flowi fl = { struct flowi4 fl4 = {
.fl4_dst = (param->replyopts.srr ? .daddr = (param->replyopts.srr ?
param->replyopts.faddr : iph->saddr), param->replyopts.faddr : iph->saddr),
.fl4_src = saddr, .saddr = saddr,
.fl4_tos = RT_TOS(tos), .flowi4_tos = RT_TOS(tos),
.flowi_proto = IPPROTO_ICMP, .flowi4_proto = IPPROTO_ICMP,
.fl4_icmp_type = type, .uli.icmpt.type = type,
.fl4_icmp_code = code, .uli.icmpt.code = code,
}; };
struct rtable *rt, *rt2; struct rtable *rt, *rt2;
int err; int err;
security_skb_classify_flow(skb_in, &fl); security_skb_classify_flow(skb_in, flowi4_to_flowi(&fl4));
rt = __ip_route_output_key(net, &fl); rt = __ip_route_output_key(net, &fl4);
if (IS_ERR(rt)) if (IS_ERR(rt))
return rt; return rt;
/* No need to clone since we're just using its address. */ /* No need to clone since we're just using its address. */
rt2 = rt; rt2 = rt;
if (!fl.fl4_src) if (!fl4.saddr)
fl.fl4_src = rt->rt_src; fl4.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 (!IS_ERR(rt)) {
if (rt != rt2) if (rt != rt2)
return rt; return rt;
...@@ -410,27 +411,27 @@ static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in, ...@@ -410,27 +411,27 @@ static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in,
} else } else
return rt; 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) if (err)
goto relookup_failed; goto relookup_failed;
if (inet_addr_type(net, fl.fl4_src) == RTN_LOCAL) { if (inet_addr_type(net, fl4.saddr) == RTN_LOCAL) {
rt2 = __ip_route_output_key(net, &fl); rt2 = __ip_route_output_key(net, &fl4);
if (IS_ERR(rt2)) if (IS_ERR(rt2))
err = PTR_ERR(rt2); err = PTR_ERR(rt2);
} else { } else {
struct flowi fl2 = {}; struct flowi4 fl4_2 = {};
unsigned long orefdst; unsigned long orefdst;
fl2.fl4_dst = fl.fl4_src; fl4_2.daddr = fl4.saddr;
rt2 = ip_route_output_key(net, &fl2); rt2 = ip_route_output_key(net, &fl4_2);
if (IS_ERR(rt2)) { if (IS_ERR(rt2)) {
err = PTR_ERR(rt2); err = PTR_ERR(rt2);
goto relookup_failed; goto relookup_failed;
} }
/* Ugh! */ /* Ugh! */
orefdst = skb_in->_skb_refdst; /* save old refdst */ 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, fl4.daddr, fl4.saddr,
RT_TOS(tos), rt2->dst.dev); RT_TOS(tos), rt2->dst.dev);
dst_release(&rt2->dst); dst_release(&rt2->dst);
...@@ -441,7 +442,9 @@ static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in, ...@@ -441,7 +442,9 @@ static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in,
if (err) if (err)
goto relookup_failed; 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)) { if (!IS_ERR(rt2)) {
dst_release(&rt->dst); dst_release(&rt->dst);
rt = rt2; rt = rt2;
......
...@@ -356,22 +356,22 @@ struct dst_entry *inet_csk_route_req(struct sock *sk, ...@@ -356,22 +356,22 @@ struct dst_entry *inet_csk_route_req(struct sock *sk,
struct rtable *rt; struct rtable *rt;
const struct inet_request_sock *ireq = inet_rsk(req); const struct inet_request_sock *ireq = inet_rsk(req);
struct ip_options *opt = inet_rsk(req)->opt; struct ip_options *opt = inet_rsk(req)->opt;
struct flowi fl = { struct flowi4 fl4 = {
.flowi_oif = sk->sk_bound_dev_if, .flowi4_oif = sk->sk_bound_dev_if,
.flowi_mark = sk->sk_mark, .flowi4_mark = sk->sk_mark,
.fl4_dst = ((opt && opt->srr) ? .daddr = ((opt && opt->srr) ?
opt->faddr : ireq->rmt_addr), opt->faddr : ireq->rmt_addr),
.fl4_src = ireq->loc_addr, .saddr = ireq->loc_addr,
.fl4_tos = RT_CONN_FLAGS(sk), .flowi4_tos = RT_CONN_FLAGS(sk),
.flowi_proto = sk->sk_protocol, .flowi4_proto = sk->sk_protocol,
.flowi_flags = inet_sk_flowi_flags(sk), .flowi4_flags = inet_sk_flowi_flags(sk),
.fl4_sport = inet_sk(sk)->inet_sport, .uli.ports.sport = inet_sk(sk)->inet_sport,
.fl4_dport = ireq->rmt_port, .uli.ports.dport = ireq->rmt_port,
}; };
struct net *net = sock_net(sk); struct net *net = sock_net(sk);
security_req_classify_flow(req, &fl); security_req_classify_flow(req, flowi4_to_flowi(&fl4));
rt = ip_route_output_flow(net, &fl, sk); rt = ip_route_output_flow(net, &fl4, sk);
if (IS_ERR(rt)) if (IS_ERR(rt))
goto no_route; goto no_route;
if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway) if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway)
......
...@@ -1474,18 +1474,18 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar ...@@ -1474,18 +1474,18 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
} }
{ {
struct flowi fl = { struct flowi4 fl4 = {
.flowi_oif = arg->bound_dev_if, .flowi4_oif = arg->bound_dev_if,
.fl4_dst = daddr, .daddr = daddr,
.fl4_src = rt->rt_spec_dst, .saddr = rt->rt_spec_dst,
.fl4_tos = RT_TOS(ip_hdr(skb)->tos), .flowi4_tos = RT_TOS(ip_hdr(skb)->tos),
.fl4_sport = tcp_hdr(skb)->dest, .uli.ports.sport = tcp_hdr(skb)->dest,
.fl4_dport = tcp_hdr(skb)->source, .uli.ports.dport = tcp_hdr(skb)->source,
.flowi_proto = sk->sk_protocol, .flowi4_proto = sk->sk_protocol,
.flowi_flags = ip_reply_arg_flowi_flags(arg), .flowi4_flags = ip_reply_arg_flowi_flags(arg),
}; };
security_skb_classify_flow(skb, &fl); security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));
rt = ip_route_output_key(sock_net(sk), &fl); rt = ip_route_output_key(sock_net(sk), &fl4);
if (IS_ERR(rt)) if (IS_ERR(rt))
return; return;
} }
......
...@@ -16,7 +16,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) ...@@ -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); struct net *net = dev_net(skb_dst(skb)->dev);
const struct iphdr *iph = ip_hdr(skb); const struct iphdr *iph = ip_hdr(skb);
struct rtable *rt; struct rtable *rt;
struct flowi fl = {}; struct flowi4 fl4 = {};
unsigned long orefdst; unsigned long orefdst;
unsigned int hh_len; unsigned int hh_len;
unsigned int type; unsigned int type;
...@@ -31,14 +31,14 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_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. * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook.
*/ */
if (addr_type == RTN_LOCAL) { if (addr_type == RTN_LOCAL) {
fl.fl4_dst = iph->daddr; fl4.daddr = iph->daddr;
if (type == RTN_LOCAL) if (type == RTN_LOCAL)
fl.fl4_src = iph->saddr; fl4.saddr = iph->saddr;
fl.fl4_tos = RT_TOS(iph->tos); fl4.flowi4_tos = RT_TOS(iph->tos);
fl.flowi_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0;
fl.flowi_mark = skb->mark; fl4.flowi4_mark = skb->mark;
fl.flowi_flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; fl4.flowi4_flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0;
rt = ip_route_output_key(net, &fl); rt = ip_route_output_key(net, &fl4);
if (IS_ERR(rt)) if (IS_ERR(rt))
return -1; return -1;
...@@ -48,8 +48,8 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) ...@@ -48,8 +48,8 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
} else { } else {
/* non-local src, find valid iif to satisfy /* non-local src, find valid iif to satisfy
* rp-filter when calling ip_route_input. */ * rp-filter when calling ip_route_input. */
fl.fl4_dst = iph->saddr; fl4.daddr = iph->saddr;
rt = ip_route_output_key(net, &fl); rt = ip_route_output_key(net, &fl4);
if (IS_ERR(rt)) if (IS_ERR(rt))
return -1; return -1;
...@@ -68,10 +68,10 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) ...@@ -68,10 +68,10 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
#ifdef CONFIG_XFRM #ifdef CONFIG_XFRM
if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) && 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); struct dst_entry *dst = skb_dst(skb);
skb_dst_set(skb, NULL); 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)) if (IS_ERR(dst))
return -1; return -1;
skb_dst_set(skb, dst); skb_dst_set(skb, dst);
...@@ -223,7 +223,7 @@ static __sum16 nf_ip_checksum_partial(struct sk_buff *skb, unsigned int hook, ...@@ -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) 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)) if (IS_ERR(rt))
return PTR_ERR(rt); return PTR_ERR(rt);
*dst = &rt->dst; *dst = &rt->dst;
......
...@@ -402,7 +402,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length, ...@@ -402,7 +402,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
return err; return err;
} }
static int raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) static int raw_probe_proto_opt(struct flowi4 *fl4, struct msghdr *msg)
{ {
struct iovec *iov; struct iovec *iov;
u8 __user *type = NULL; u8 __user *type = NULL;
...@@ -418,7 +418,7 @@ static int raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) ...@@ -418,7 +418,7 @@ static int raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
if (!iov) if (!iov)
continue; continue;
switch (fl->flowi_proto) { switch (fl4->flowi4_proto) {
case IPPROTO_ICMP: case IPPROTO_ICMP:
/* check if one-byte field is readable or not. */ /* check if one-byte field is readable or not. */
if (iov->iov_base && iov->iov_len < 1) if (iov->iov_base && iov->iov_len < 1)
...@@ -433,8 +433,8 @@ static int raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) ...@@ -433,8 +433,8 @@ static int raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
code = iov->iov_base; code = iov->iov_base;
if (type && code) { if (type && code) {
if (get_user(fl->fl4_icmp_type, type) || if (get_user(fl4->uli.icmpt.type, type) ||
get_user(fl->fl4_icmp_code, code)) get_user(fl4->uli.icmpt.code, code))
return -EFAULT; return -EFAULT;
probed = 1; probed = 1;
} }
...@@ -548,23 +548,25 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, ...@@ -548,23 +548,25 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
} }
{ {
struct flowi fl = { .flowi_oif = ipc.oif, struct flowi4 fl4 = {
.flowi_mark = sk->sk_mark, .flowi4_oif = ipc.oif,
.fl4_dst = daddr, .flowi4_mark = sk->sk_mark,
.fl4_src = saddr, .daddr = daddr,
.fl4_tos = tos, .saddr = saddr,
.flowi_proto = inet->hdrincl ? IPPROTO_RAW : .flowi4_tos = tos,
sk->sk_protocol, .flowi4_proto = (inet->hdrincl ?
.flowi_flags = FLOWI_FLAG_CAN_SLEEP, IPPROTO_RAW :
sk->sk_protocol),
.flowi4_flags = FLOWI_FLAG_CAN_SLEEP,
}; };
if (!inet->hdrincl) { if (!inet->hdrincl) {
err = raw_probe_proto_opt(&fl, msg); err = raw_probe_proto_opt(&fl4, msg);
if (err) if (err)
goto done; goto done;
} }
security_sk_classify_flow(sk, &fl); security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
rt = ip_route_output_flow(sock_net(sk), &fl, sk); rt = ip_route_output_flow(sock_net(sk), &fl4, sk);
if (IS_ERR(rt)) { if (IS_ERR(rt)) {
err = PTR_ERR(rt); err = PTR_ERR(rt);
goto done; goto done;
......
...@@ -2626,7 +2626,7 @@ static struct rtable *ip_route_output_slow(struct net *net, ...@@ -2626,7 +2626,7 @@ static struct rtable *ip_route_output_slow(struct net *net,
return rth; 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 flowi4 *flp4)
{ {
struct rtable *rth; struct rtable *rth;
unsigned int hash; unsigned int hash;
...@@ -2634,17 +2634,17 @@ struct rtable *__ip_route_output_key(struct net *net, const struct flowi *flp) ...@@ -2634,17 +2634,17 @@ struct rtable *__ip_route_output_key(struct net *net, const struct flowi *flp)
if (!rt_caching(net)) if (!rt_caching(net))
goto slow_output; goto slow_output;
hash = rt_hash(flp->fl4_dst, flp->fl4_src, flp->flowi_oif, rt_genid(net)); hash = rt_hash(flp4->daddr, flp4->saddr, flp4->flowi4_oif, rt_genid(net));
rcu_read_lock_bh(); rcu_read_lock_bh();
for (rth = rcu_dereference_bh(rt_hash_table[hash].chain); rth; for (rth = rcu_dereference_bh(rt_hash_table[hash].chain); rth;
rth = rcu_dereference_bh(rth->dst.rt_next)) { rth = rcu_dereference_bh(rth->dst.rt_next)) {
if (rth->rt_key_dst == flp->fl4_dst && if (rth->rt_key_dst == flp4->daddr &&
rth->rt_key_src == flp->fl4_src && rth->rt_key_src == flp4->saddr &&
rt_is_output_route(rth) && rt_is_output_route(rth) &&
rth->rt_oif == flp->flowi_oif && rth->rt_oif == flp4->flowi4_oif &&
rth->rt_mark == flp->flowi_mark && rth->rt_mark == flp4->flowi4_mark &&
!((rth->rt_tos ^ flp->fl4_tos) & !((rth->rt_tos ^ flp4->flowi4_tos) &
(IPTOS_RT_MASK | RTO_ONLINK)) && (IPTOS_RT_MASK | RTO_ONLINK)) &&
net_eq(dev_net(rth->dst.dev), net) && net_eq(dev_net(rth->dst.dev), net) &&
!rt_is_expired(rth)) { !rt_is_expired(rth)) {
...@@ -2658,7 +2658,7 @@ struct rtable *__ip_route_output_key(struct net *net, const struct flowi *flp) ...@@ -2658,7 +2658,7 @@ struct rtable *__ip_route_output_key(struct net *net, const struct flowi *flp)
rcu_read_unlock_bh(); rcu_read_unlock_bh();
slow_output: slow_output:
return ip_route_output_slow(net, &flp->u.ip4); return ip_route_output_slow(net, flp4);
} }
EXPORT_SYMBOL_GPL(__ip_route_output_key); 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 ...@@ -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); 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 flowi4 *flp4,
struct sock *sk) struct sock *sk)
{ {
struct rtable *rt = __ip_route_output_key(net, flp); struct rtable *rt = __ip_route_output_key(net, flp4);
if (IS_ERR(rt)) if (IS_ERR(rt))
return rt; return rt;
if (flp->flowi_proto) { if (flp4->flowi4_proto) {
if (!flp->fl4_src) if (!flp4->saddr)
flp->fl4_src = rt->rt_src; flp4->saddr = rt->rt_src;
if (!flp->fl4_dst) if (!flp4->daddr)
flp->fl4_dst = rt->rt_dst; flp4->daddr = rt->rt_dst;
rt = (struct rtable *) xfrm_lookup(net, &rt->dst, flp, sk, 0); rt = (struct rtable *) xfrm_lookup(net, &rt->dst,
flowi4_to_flowi(flp4),
sk, 0);
} }
return rt; return rt;
...@@ -2920,7 +2922,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void ...@@ -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_oif = tb[RTA_OIF] ? nla_get_u32(tb[RTA_OIF]) : 0,
.flowi4_mark = mark, .flowi4_mark = mark,
}; };
rt = ip_route_output_key(net, flowi4_to_flowi(&fl4)); rt = ip_route_output_key(net, &fl4);
err = 0; err = 0;
if (IS_ERR(rt)) if (IS_ERR(rt))
......
...@@ -345,19 +345,19 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, ...@@ -345,19 +345,19 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
* no easy way to do this. * no easy way to do this.
*/ */
{ {
struct flowi fl = { struct flowi4 fl4 = {
.flowi_mark = sk->sk_mark, .flowi4_mark = sk->sk_mark,
.fl4_dst = ((opt && opt->srr) ? .daddr = ((opt && opt->srr) ?
opt->faddr : ireq->rmt_addr), opt->faddr : ireq->rmt_addr),
.fl4_src = ireq->loc_addr, .saddr = ireq->loc_addr,
.fl4_tos = RT_CONN_FLAGS(sk), .flowi4_tos = RT_CONN_FLAGS(sk),
.flowi_proto = IPPROTO_TCP, .flowi4_proto = IPPROTO_TCP,
.flowi_flags = inet_sk_flowi_flags(sk), .flowi4_flags = inet_sk_flowi_flags(sk),
.fl4_sport = th->dest, .uli.ports.sport = th->dest,
.fl4_dport = th->source, .uli.ports.dport = th->source,
}; };
security_req_classify_flow(req, &fl); security_req_classify_flow(req, flowi4_to_flowi(&fl4));
rt = ip_route_output_key(sock_net(sk), &fl); rt = ip_route_output_key(sock_net(sk), &fl4);
if (IS_ERR(rt)) { if (IS_ERR(rt)) {
reqsk_free(req); reqsk_free(req);
goto out; goto out;
......
...@@ -908,22 +908,22 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, ...@@ -908,22 +908,22 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
rt = (struct rtable *)sk_dst_check(sk, 0); rt = (struct rtable *)sk_dst_check(sk, 0);
if (rt == NULL) { if (rt == NULL) {
struct flowi fl = { struct flowi4 fl4 = {
.flowi_oif = ipc.oif, .flowi4_oif = ipc.oif,
.flowi_mark = sk->sk_mark, .flowi4_mark = sk->sk_mark,
.fl4_dst = faddr, .daddr = faddr,
.fl4_src = saddr, .saddr = saddr,
.fl4_tos = tos, .flowi4_tos = tos,
.flowi_proto = sk->sk_protocol, .flowi4_proto = sk->sk_protocol,
.flowi_flags = (inet_sk_flowi_flags(sk) | .flowi4_flags = (inet_sk_flowi_flags(sk) |
FLOWI_FLAG_CAN_SLEEP), FLOWI_FLAG_CAN_SLEEP),
.fl4_sport = inet->inet_sport, .uli.ports.sport = inet->inet_sport,
.fl4_dport = dport, .uli.ports.dport = dport,
}; };
struct net *net = sock_net(sk); struct net *net = sock_net(sk);
security_sk_classify_flow(sk, &fl); security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
rt = ip_route_output_flow(net, &fl, sk); rt = ip_route_output_flow(net, &fl4, sk);
if (IS_ERR(rt)) { if (IS_ERR(rt)) {
err = PTR_ERR(rt); err = PTR_ERR(rt);
rt = NULL; rt = NULL;
......
...@@ -22,16 +22,16 @@ static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos, ...@@ -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 *saddr,
const xfrm_address_t *daddr) const xfrm_address_t *daddr)
{ {
struct flowi fl = { struct flowi4 fl4 = {
.fl4_dst = daddr->a4, .daddr = daddr->a4,
.fl4_tos = tos, .flowi4_tos = tos,
}; };
struct rtable *rt; struct rtable *rt;
if (saddr) if (saddr)
fl.fl4_src = saddr->a4; fl4.saddr = saddr->a4;
rt = __ip_route_output_key(net, &fl); rt = __ip_route_output_key(net, &fl4);
if (!IS_ERR(rt)) if (!IS_ERR(rt))
return &rt->dst; return &rt->dst;
......
...@@ -165,14 +165,14 @@ __ip_vs_reroute_locally(struct sk_buff *skb) ...@@ -165,14 +165,14 @@ __ip_vs_reroute_locally(struct sk_buff *skb)
return 0; return 0;
refdst_drop(orefdst); refdst_drop(orefdst);
} else { } else {
struct flowi fl = { struct flowi4 fl4 = {
.fl4_dst = iph->daddr, .daddr = iph->daddr,
.fl4_src = iph->saddr, .saddr = iph->saddr,
.fl4_tos = RT_TOS(iph->tos), .flowi4_tos = RT_TOS(iph->tos),
.flowi_mark = skb->mark, .flowi4_mark = skb->mark,
}; };
rt = ip_route_output_key(net, &fl); rt = ip_route_output_key(net, &fl4);
if (IS_ERR(rt)) if (IS_ERR(rt))
return 0; return 0;
if (!(rt->rt_flags & RTCF_LOCAL)) { if (!(rt->rt_flags & RTCF_LOCAL)) {
......
...@@ -62,18 +62,18 @@ tee_tg_route4(struct sk_buff *skb, const struct xt_tee_tginfo *info) ...@@ -62,18 +62,18 @@ tee_tg_route4(struct sk_buff *skb, const struct xt_tee_tginfo *info)
const struct iphdr *iph = ip_hdr(skb); const struct iphdr *iph = ip_hdr(skb);
struct net *net = pick_net(skb); struct net *net = pick_net(skb);
struct rtable *rt; struct rtable *rt;
struct flowi fl; struct flowi4 fl4;
memset(&fl, 0, sizeof(fl)); memset(&fl4, 0, sizeof(fl4));
if (info->priv) { if (info->priv) {
if (info->priv->oif == -1) if (info->priv->oif == -1)
return false; return false;
fl.flowi_oif = info->priv->oif; fl4.flowi4_oif = info->priv->oif;
} }
fl.fl4_dst = info->gw.ip; fl4.daddr = info->gw.ip;
fl.fl4_tos = RT_TOS(iph->tos); fl4.flowi4_tos = RT_TOS(iph->tos);
fl.fl4_scope = RT_SCOPE_UNIVERSE; fl4.flowi4_scope = RT_SCOPE_UNIVERSE;
rt = ip_route_output_key(net, &fl); rt = ip_route_output_key(net, &fl4);
if (IS_ERR(rt)) if (IS_ERR(rt))
return false; return false;
......
...@@ -468,30 +468,30 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, ...@@ -468,30 +468,30 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
union sctp_addr *saddr) union sctp_addr *saddr)
{ {
struct rtable *rt; struct rtable *rt;
struct flowi fl; struct flowi4 fl4;
struct sctp_bind_addr *bp; struct sctp_bind_addr *bp;
struct sctp_sockaddr_entry *laddr; struct sctp_sockaddr_entry *laddr;
struct dst_entry *dst = NULL; struct dst_entry *dst = NULL;
union sctp_addr dst_saddr; union sctp_addr dst_saddr;
memset(&fl, 0x0, sizeof(struct flowi)); memset(&fl4, 0x0, sizeof(struct flowi4));
fl.fl4_dst = daddr->v4.sin_addr.s_addr; fl4.daddr = daddr->v4.sin_addr.s_addr;
fl.fl4_dport = daddr->v4.sin_port; fl4.uli.ports.dport = daddr->v4.sin_port;
fl.flowi_proto = IPPROTO_SCTP; fl4.flowi4_proto = IPPROTO_SCTP;
if (asoc) { if (asoc) {
fl.fl4_tos = RT_CONN_FLAGS(asoc->base.sk); fl4.flowi4_tos = RT_CONN_FLAGS(asoc->base.sk);
fl.flowi_oif = asoc->base.sk->sk_bound_dev_if; fl4.flowi4_oif = asoc->base.sk->sk_bound_dev_if;
fl.fl4_sport = htons(asoc->base.bind_addr.port); fl4.uli.ports.sport = htons(asoc->base.bind_addr.port);
} }
if (saddr) { if (saddr) {
fl.fl4_src = saddr->v4.sin_addr.s_addr; fl4.saddr = saddr->v4.sin_addr.s_addr;
fl.fl4_sport = saddr->v4.sin_port; fl4.uli.ports.sport = saddr->v4.sin_port;
} }
SCTP_DEBUG_PRINTK("%s: DST:%pI4, SRC:%pI4 - ", SCTP_DEBUG_PRINTK("%s: DST:%pI4, SRC:%pI4 - ",
__func__, &fl.fl4_dst, &fl.fl4_src); __func__, &fl4.daddr, &fl4.saddr);
rt = ip_route_output_key(&init_net, &fl); rt = ip_route_output_key(&init_net, &fl4);
if (!IS_ERR(rt)) if (!IS_ERR(rt))
dst = &rt->dst; dst = &rt->dst;
...@@ -533,9 +533,9 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, ...@@ -533,9 +533,9 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
continue; continue;
if ((laddr->state == SCTP_ADDR_SRC) && if ((laddr->state == SCTP_ADDR_SRC) &&
(AF_INET == laddr->a.sa.sa_family)) { (AF_INET == laddr->a.sa.sa_family)) {
fl.fl4_src = laddr->a.v4.sin_addr.s_addr; fl4.saddr = laddr->a.v4.sin_addr.s_addr;
fl.fl4_sport = laddr->a.v4.sin_port; fl4.uli.ports.sport = laddr->a.v4.sin_port;
rt = ip_route_output_key(&init_net, &fl); rt = ip_route_output_key(&init_net, &fl4);
if (!IS_ERR(rt)) { if (!IS_ERR(rt)) {
dst = &rt->dst; dst = &rt->dst;
goto out_unlock; goto out_unlock;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment