Commit 31e4543d authored by David S. Miller's avatar David S. Miller

ipv4: Make caller provide on-stack flow key to ip_route_output_ports().

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f1390160
...@@ -338,8 +338,9 @@ static struct rtable *find_route(struct t3cdev *dev, __be32 local_ip, ...@@ -338,8 +338,9 @@ static struct rtable *find_route(struct t3cdev *dev, __be32 local_ip,
__be16 peer_port, u8 tos) __be16 peer_port, u8 tos)
{ {
struct rtable *rt; struct rtable *rt;
struct flowi4 fl4;
rt = ip_route_output_ports(&init_net, NULL, peer_ip, local_ip, rt = ip_route_output_ports(&init_net, &fl4, NULL, peer_ip, local_ip,
peer_port, local_port, IPPROTO_TCP, peer_port, local_port, IPPROTO_TCP,
tos, 0); tos, 0);
if (IS_ERR(rt)) if (IS_ERR(rt))
......
...@@ -315,8 +315,9 @@ static struct rtable *find_route(struct c4iw_dev *dev, __be32 local_ip, ...@@ -315,8 +315,9 @@ static struct rtable *find_route(struct c4iw_dev *dev, __be32 local_ip,
__be16 peer_port, u8 tos) __be16 peer_port, u8 tos)
{ {
struct rtable *rt; struct rtable *rt;
struct flowi4 fl4;
rt = ip_route_output_ports(&init_net, NULL, peer_ip, local_ip, rt = ip_route_output_ports(&init_net, &fl4, NULL, peer_ip, local_ip,
peer_port, local_port, IPPROTO_TCP, peer_port, local_port, IPPROTO_TCP,
tos, 0); tos, 0);
if (IS_ERR(rt)) if (IS_ERR(rt))
......
...@@ -175,6 +175,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) ...@@ -175,6 +175,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
struct pptp_opt *opt = &po->proto.pptp; struct pptp_opt *opt = &po->proto.pptp;
struct pptp_gre_header *hdr; struct pptp_gre_header *hdr;
unsigned int header_len = sizeof(*hdr); unsigned int header_len = sizeof(*hdr);
struct flowi4 fl4;
int islcp; int islcp;
int len; int len;
unsigned char *data; unsigned char *data;
...@@ -189,7 +190,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) ...@@ -189,7 +190,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
if (sk_pppox(po)->sk_state & PPPOX_DEAD) if (sk_pppox(po)->sk_state & PPPOX_DEAD)
goto tx_error; goto tx_error;
rt = ip_route_output_ports(&init_net, NULL, rt = ip_route_output_ports(&init_net, &fl4, NULL,
opt->dst_addr.sin_addr.s_addr, opt->dst_addr.sin_addr.s_addr,
opt->src_addr.sin_addr.s_addr, opt->src_addr.sin_addr.s_addr,
0, 0, IPPROTO_GRE, 0, 0, IPPROTO_GRE,
...@@ -434,6 +435,7 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr, ...@@ -434,6 +435,7 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr,
struct pppox_sock *po = pppox_sk(sk); struct pppox_sock *po = pppox_sk(sk);
struct pptp_opt *opt = &po->proto.pptp; struct pptp_opt *opt = &po->proto.pptp;
struct rtable *rt; struct rtable *rt;
struct flowi4 fl4;
int error = 0; int error = 0;
if (sp->sa_protocol != PX_PROTO_PPTP) if (sp->sa_protocol != PX_PROTO_PPTP)
...@@ -463,7 +465,7 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr, ...@@ -463,7 +465,7 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr,
po->chan.private = sk; po->chan.private = sk;
po->chan.ops = &pptp_chan_ops; po->chan.ops = &pptp_chan_ops;
rt = ip_route_output_ports(&init_net, sk, rt = ip_route_output_ports(&init_net, &fl4, sk,
opt->dst_addr.sin_addr.s_addr, opt->dst_addr.sin_addr.s_addr,
opt->src_addr.sin_addr.s_addr, opt->src_addr.sin_addr.s_addr,
0, 0, 0, 0,
......
...@@ -454,8 +454,9 @@ static struct rtable *find_route_ipv4(__be32 saddr, __be32 daddr, ...@@ -454,8 +454,9 @@ static struct rtable *find_route_ipv4(__be32 saddr, __be32 daddr,
__be16 sport, __be16 dport, u8 tos) __be16 sport, __be16 dport, u8 tos)
{ {
struct rtable *rt; struct rtable *rt;
struct flowi4 fl4;
rt = ip_route_output_ports(&init_net, NULL, daddr, saddr, rt = ip_route_output_ports(&init_net, &fl4, NULL, daddr, saddr,
dport, sport, IPPROTO_TCP, tos, 0); dport, sport, IPPROTO_TCP, tos, 0);
if (IS_ERR(rt)) if (IS_ERR(rt))
return NULL; return NULL;
......
...@@ -137,20 +137,19 @@ static inline struct rtable *ip_route_output(struct net *net, __be32 daddr, ...@@ -137,20 +137,19 @@ static inline struct rtable *ip_route_output(struct net *net, __be32 daddr,
return ip_route_output_key(net, &fl4); 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 flowi4 *fl4,
struct sock *sk,
__be32 daddr, __be32 saddr, __be32 daddr, __be32 saddr,
__be16 dport, __be16 sport, __be16 dport, __be16 sport,
__u8 proto, __u8 tos, int oif) __u8 proto, __u8 tos, int oif)
{ {
struct flowi4 fl4; flowi4_init_output(fl4, oif, sk ? sk->sk_mark : 0, tos,
flowi4_init_output(&fl4, oif, sk ? sk->sk_mark : 0, tos,
RT_SCOPE_UNIVERSE, proto, RT_SCOPE_UNIVERSE, proto,
sk ? inet_sk_flowi_flags(sk) : 0, sk ? inet_sk_flowi_flags(sk) : 0,
daddr, saddr, dport, sport); daddr, saddr, dport, sport);
if (sk) if (sk)
security_sk_classify_flow(sk, flowi4_to_flowi(&fl4)); security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
return ip_route_output_flow(net, &fl4, 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,
......
...@@ -1152,6 +1152,7 @@ int inet_sk_rebuild_header(struct sock *sk) ...@@ -1152,6 +1152,7 @@ int inet_sk_rebuild_header(struct sock *sk)
struct rtable *rt = (struct rtable *)__sk_dst_check(sk, 0); struct rtable *rt = (struct rtable *)__sk_dst_check(sk, 0);
__be32 daddr; __be32 daddr;
struct ip_options_rcu *inet_opt; struct ip_options_rcu *inet_opt;
struct flowi4 fl4;
int err; int err;
/* Route is OK, nothing to do. */ /* Route is OK, nothing to do. */
...@@ -1165,7 +1166,7 @@ int inet_sk_rebuild_header(struct sock *sk) ...@@ -1165,7 +1166,7 @@ int inet_sk_rebuild_header(struct sock *sk)
if (inet_opt && inet_opt->opt.srr) if (inet_opt && inet_opt->opt.srr)
daddr = inet_opt->opt.faddr; daddr = inet_opt->opt.faddr;
rcu_read_unlock(); rcu_read_unlock();
rt = ip_route_output_ports(sock_net(sk), sk, daddr, inet->inet_saddr, rt = ip_route_output_ports(sock_net(sk), &fl4, sk, daddr, inet->inet_saddr,
inet->inet_dport, inet->inet_sport, inet->inet_dport, inet->inet_sport,
sk->sk_protocol, RT_CONN_FLAGS(sk), sk->sk_protocol, RT_CONN_FLAGS(sk),
sk->sk_bound_dev_if); sk->sk_bound_dev_if);
......
...@@ -309,6 +309,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) ...@@ -309,6 +309,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
struct iphdr *pip; struct iphdr *pip;
struct igmpv3_report *pig; struct igmpv3_report *pig;
struct net *net = dev_net(dev); struct net *net = dev_net(dev);
struct flowi4 fl4;
while (1) { while (1) {
skb = alloc_skb(size + LL_ALLOCATED_SPACE(dev), skb = alloc_skb(size + LL_ALLOCATED_SPACE(dev),
...@@ -321,7 +322,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) ...@@ -321,7 +322,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
} }
igmp_skb_size(skb) = size; igmp_skb_size(skb) = size;
rt = ip_route_output_ports(net, NULL, IGMPV3_ALL_MCR, 0, rt = ip_route_output_ports(net, &fl4, NULL, IGMPV3_ALL_MCR, 0,
0, 0, 0, 0,
IPPROTO_IGMP, 0, dev->ifindex); IPPROTO_IGMP, 0, dev->ifindex);
if (IS_ERR(rt)) { if (IS_ERR(rt)) {
...@@ -650,6 +651,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc, ...@@ -650,6 +651,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
struct net_device *dev = in_dev->dev; struct net_device *dev = in_dev->dev;
struct net *net = dev_net(dev); struct net *net = dev_net(dev);
__be32 group = pmc ? pmc->multiaddr : 0; __be32 group = pmc ? pmc->multiaddr : 0;
struct flowi4 fl4;
__be32 dst; __be32 dst;
if (type == IGMPV3_HOST_MEMBERSHIP_REPORT) if (type == IGMPV3_HOST_MEMBERSHIP_REPORT)
...@@ -659,7 +661,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc, ...@@ -659,7 +661,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
else else
dst = group; dst = group;
rt = ip_route_output_ports(net, NULL, dst, 0, rt = ip_route_output_ports(net, &fl4, NULL, dst, 0,
0, 0, 0, 0,
IPPROTO_IGMP, 0, dev->ifindex); IPPROTO_IGMP, 0, dev->ifindex);
if (IS_ERR(rt)) if (IS_ERR(rt))
......
...@@ -333,6 +333,7 @@ int ip_queue_xmit(struct sk_buff *skb) ...@@ -333,6 +333,7 @@ int ip_queue_xmit(struct sk_buff *skb)
/* Make sure we can route this packet. */ /* Make sure we can route this packet. */
rt = (struct rtable *)__sk_dst_check(sk, 0); rt = (struct rtable *)__sk_dst_check(sk, 0);
if (rt == NULL) { if (rt == NULL) {
struct flowi4 fl4;
__be32 daddr; __be32 daddr;
/* Use correct destination address if we have options. */ /* Use correct destination address if we have options. */
...@@ -344,7 +345,7 @@ int ip_queue_xmit(struct sk_buff *skb) ...@@ -344,7 +345,7 @@ int ip_queue_xmit(struct sk_buff *skb)
* keep trying until route appears or the connection times * keep trying until route appears or the connection times
* itself out. * itself out.
*/ */
rt = ip_route_output_ports(sock_net(sk), sk, rt = ip_route_output_ports(sock_net(sk), &fl4, sk,
daddr, inet->inet_saddr, daddr, inet->inet_saddr,
inet->inet_dport, inet->inet_dport,
inet->inet_sport, inet->inet_sport,
......
...@@ -442,6 +442,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -442,6 +442,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
struct iphdr *iph; /* Our new IP header */ struct iphdr *iph; /* Our new IP header */
unsigned int max_headroom; /* The extra header space needed */ unsigned int max_headroom; /* The extra header space needed */
__be32 dst = tiph->daddr; __be32 dst = tiph->daddr;
struct flowi4 fl4;
int mtu; int mtu;
if (skb->protocol != htons(ETH_P_IP)) if (skb->protocol != htons(ETH_P_IP))
...@@ -460,7 +461,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -460,7 +461,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
goto tx_error_icmp; goto tx_error_icmp;
} }
rt = ip_route_output_ports(dev_net(dev), NULL, rt = ip_route_output_ports(dev_net(dev), &fl4, NULL,
dst, tiph->saddr, dst, tiph->saddr,
0, 0, 0, 0,
IPPROTO_IPIP, RT_TOS(tos), IPPROTO_IPIP, RT_TOS(tos),
...@@ -578,13 +579,15 @@ static void ipip_tunnel_bind_dev(struct net_device *dev) ...@@ -578,13 +579,15 @@ static void ipip_tunnel_bind_dev(struct net_device *dev)
iph = &tunnel->parms.iph; iph = &tunnel->parms.iph;
if (iph->daddr) { if (iph->daddr) {
struct rtable *rt = ip_route_output_ports(dev_net(dev), NULL, struct rtable *rt;
iph->daddr, iph->saddr, struct flowi4 fl4;
0, 0,
IPPROTO_IPIP, rt = ip_route_output_ports(dev_net(dev), &fl4, NULL,
RT_TOS(iph->tos), iph->daddr, iph->saddr,
tunnel->parms.link); 0, 0,
IPPROTO_IPIP,
RT_TOS(iph->tos),
tunnel->parms.link);
if (!IS_ERR(rt)) { if (!IS_ERR(rt)) {
tdev = rt->dst.dev; tdev = rt->dst.dev;
ip_rt_put(rt); ip_rt_put(rt);
......
...@@ -1595,6 +1595,7 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, ...@@ -1595,6 +1595,7 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt,
struct vif_device *vif = &mrt->vif_table[vifi]; struct vif_device *vif = &mrt->vif_table[vifi];
struct net_device *dev; struct net_device *dev;
struct rtable *rt; struct rtable *rt;
struct flowi4 fl4;
int encap = 0; int encap = 0;
if (vif->dev == NULL) if (vif->dev == NULL)
...@@ -1612,7 +1613,7 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, ...@@ -1612,7 +1613,7 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt,
#endif #endif
if (vif->flags & VIFF_TUNNEL) { if (vif->flags & VIFF_TUNNEL) {
rt = ip_route_output_ports(net, NULL, rt = ip_route_output_ports(net, &fl4, NULL,
vif->remote, vif->local, vif->remote, vif->local,
0, 0, 0, 0,
IPPROTO_IPIP, IPPROTO_IPIP,
...@@ -1621,7 +1622,7 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, ...@@ -1621,7 +1622,7 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt,
goto out_free; goto out_free;
encap = sizeof(struct iphdr); encap = sizeof(struct iphdr);
} else { } else {
rt = ip_route_output_ports(net, NULL, iph->daddr, 0, rt = ip_route_output_ports(net, &fl4, NULL, iph->daddr, 0,
0, 0, 0, 0,
IPPROTO_IPIP, IPPROTO_IPIP,
RT_TOS(iph->tos), vif->link); RT_TOS(iph->tos), vif->link);
......
...@@ -537,6 +537,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ...@@ -537,6 +537,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
struct sk_buff *skb2; struct sk_buff *skb2;
const struct iphdr *eiph; const struct iphdr *eiph;
struct rtable *rt; struct rtable *rt;
struct flowi4 fl4;
err = ip6_tnl_err(skb, IPPROTO_IPIP, opt, &rel_type, &rel_code, err = ip6_tnl_err(skb, IPPROTO_IPIP, opt, &rel_type, &rel_code,
&rel_msg, &rel_info, offset); &rel_msg, &rel_info, offset);
...@@ -577,7 +578,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ...@@ -577,7 +578,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
eiph = ip_hdr(skb2); eiph = ip_hdr(skb2);
/* Try to guess incoming interface */ /* Try to guess incoming interface */
rt = ip_route_output_ports(dev_net(skb->dev), NULL, rt = ip_route_output_ports(dev_net(skb->dev), &fl4, NULL,
eiph->saddr, 0, eiph->saddr, 0,
0, 0, 0, 0,
IPPROTO_IPIP, RT_TOS(eiph->tos), 0); IPPROTO_IPIP, RT_TOS(eiph->tos), 0);
...@@ -590,7 +591,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ...@@ -590,7 +591,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
if (rt->rt_flags & RTCF_LOCAL) { if (rt->rt_flags & RTCF_LOCAL) {
ip_rt_put(rt); ip_rt_put(rt);
rt = NULL; rt = NULL;
rt = ip_route_output_ports(dev_net(skb->dev), NULL, rt = ip_route_output_ports(dev_net(skb->dev), &fl4, NULL,
eiph->daddr, eiph->saddr, eiph->daddr, eiph->saddr,
0, 0, 0, 0,
IPPROTO_IPIP, IPPROTO_IPIP,
......
...@@ -674,6 +674,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, ...@@ -674,6 +674,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
struct iphdr *iph; /* Our new IP header */ struct iphdr *iph; /* Our new IP header */
unsigned int max_headroom; /* The extra header space needed */ unsigned int max_headroom; /* The extra header space needed */
__be32 dst = tiph->daddr; __be32 dst = tiph->daddr;
struct flowi4 fl4;
int mtu; int mtu;
const struct in6_addr *addr6; const struct in6_addr *addr6;
int addr_type; int addr_type;
...@@ -733,7 +734,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, ...@@ -733,7 +734,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
dst = addr6->s6_addr32[3]; dst = addr6->s6_addr32[3];
} }
rt = ip_route_output_ports(dev_net(dev), NULL, rt = ip_route_output_ports(dev_net(dev), &fl4, NULL,
dst, tiph->saddr, dst, tiph->saddr,
0, 0, 0, 0,
IPPROTO_IPV6, RT_TOS(tos), IPPROTO_IPV6, RT_TOS(tos),
...@@ -851,12 +852,13 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev) ...@@ -851,12 +852,13 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev)
struct net_device *tdev = NULL; struct net_device *tdev = NULL;
struct ip_tunnel *tunnel; struct ip_tunnel *tunnel;
const struct iphdr *iph; const struct iphdr *iph;
struct flowi4 fl4;
tunnel = netdev_priv(dev); tunnel = netdev_priv(dev);
iph = &tunnel->parms.iph; iph = &tunnel->parms.iph;
if (iph->daddr) { if (iph->daddr) {
struct rtable *rt = ip_route_output_ports(dev_net(dev), NULL, struct rtable *rt = ip_route_output_ports(dev_net(dev), &fl4, NULL,
iph->daddr, iph->saddr, iph->daddr, iph->saddr,
0, 0, 0, 0,
IPPROTO_IPV6, IPPROTO_IPV6,
......
...@@ -471,6 +471,7 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m ...@@ -471,6 +471,7 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
if (rt == NULL) { if (rt == NULL) {
struct ip_options_rcu *inet_opt; struct ip_options_rcu *inet_opt;
struct flowi4 fl4;
rcu_read_lock(); rcu_read_lock();
inet_opt = rcu_dereference(inet->inet_opt); inet_opt = rcu_dereference(inet->inet_opt);
...@@ -485,7 +486,7 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m ...@@ -485,7 +486,7 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
* keep trying until route appears or the connection times * keep trying until route appears or the connection times
* itself out. * itself out.
*/ */
rt = ip_route_output_ports(sock_net(sk), sk, rt = ip_route_output_ports(sock_net(sk), &fl4, sk,
daddr, inet->inet_saddr, daddr, inet->inet_saddr,
inet->inet_dport, inet->inet_sport, inet->inet_dport, inet->inet_sport,
sk->sk_protocol, RT_CONN_FLAGS(sk), sk->sk_protocol, RT_CONN_FLAGS(sk),
......
...@@ -36,10 +36,11 @@ static void rxrpc_destroy_peer(struct work_struct *work); ...@@ -36,10 +36,11 @@ static void rxrpc_destroy_peer(struct work_struct *work);
static void rxrpc_assess_MTU_size(struct rxrpc_peer *peer) static void rxrpc_assess_MTU_size(struct rxrpc_peer *peer)
{ {
struct rtable *rt; struct rtable *rt;
struct flowi4 fl4;
peer->if_mtu = 1500; peer->if_mtu = 1500;
rt = ip_route_output_ports(&init_net, NULL, rt = ip_route_output_ports(&init_net, &fl4, NULL,
peer->srx.transport.sin.sin_addr.s_addr, 0, peer->srx.transport.sin.sin_addr.s_addr, 0,
htons(7000), htons(7001), htons(7000), htons(7001),
IPPROTO_UDP, 0, 0); IPPROTO_UDP, 0, 0);
......
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