Commit cbb1e85f authored by David S. Miller's avatar David S. Miller

ipv4: Kill rt->rt_{src, dst} usage in IP GRE tunnels.

First, make callers pass on-stack flowi4 to ip_route_output_gre()
so they can get at the fully resolved flow key.

Next, use that in ipgre_tunnel_xmit() to avoid the need to use
rt->rt_{dst,src}.
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9a1b9496
...@@ -152,19 +152,18 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct flowi ...@@ -152,19 +152,18 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct flowi
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, struct flowi4 *fl4,
__be32 daddr, __be32 saddr, __be32 daddr, __be32 saddr,
__be32 gre_key, __u8 tos, int oif) __be32 gre_key, __u8 tos, int oif)
{ {
struct flowi4 fl4 = { memset(fl4, 0, sizeof(*fl4));
.flowi4_oif = oif, fl4->flowi4_oif = oif;
.daddr = daddr, fl4->daddr = daddr;
.saddr = saddr, fl4->saddr = saddr;
.flowi4_tos = tos, fl4->flowi4_tos = tos;
.flowi4_proto = IPPROTO_GRE, fl4->flowi4_proto = IPPROTO_GRE;
.fl4_gre_key = gre_key, fl4->fl4_gre_key = gre_key;
}; return ip_route_output_key(net, fl4);
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,
......
...@@ -699,6 +699,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev ...@@ -699,6 +699,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
struct pcpu_tstats *tstats; struct pcpu_tstats *tstats;
const struct iphdr *old_iph = ip_hdr(skb); const struct iphdr *old_iph = ip_hdr(skb);
const struct iphdr *tiph; const struct iphdr *tiph;
struct flowi4 fl4;
u8 tos; u8 tos;
__be16 df; __be16 df;
struct rtable *rt; /* Route to the other host */ struct rtable *rt; /* Route to the other host */
...@@ -769,7 +770,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev ...@@ -769,7 +770,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
tos = ipv6_get_dsfield((const struct ipv6hdr *)old_iph); tos = ipv6_get_dsfield((const struct ipv6hdr *)old_iph);
} }
rt = ip_route_output_gre(dev_net(dev), dst, tiph->saddr, rt = ip_route_output_gre(dev_net(dev), &fl4, dst, tiph->saddr,
tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.o_key, RT_TOS(tos),
tunnel->parms.link); tunnel->parms.link);
if (IS_ERR(rt)) { if (IS_ERR(rt)) {
...@@ -873,8 +874,8 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev ...@@ -873,8 +874,8 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
iph->frag_off = df; iph->frag_off = df;
iph->protocol = IPPROTO_GRE; iph->protocol = IPPROTO_GRE;
iph->tos = ipgre_ecn_encapsulate(tos, old_iph, skb); iph->tos = ipgre_ecn_encapsulate(tos, old_iph, skb);
iph->daddr = rt->rt_dst; iph->daddr = fl4.daddr;
iph->saddr = rt->rt_src; iph->saddr = fl4.saddr;
if ((iph->ttl = tiph->ttl) == 0) { if ((iph->ttl = tiph->ttl) == 0) {
if (skb->protocol == htons(ETH_P_IP)) if (skb->protocol == htons(ETH_P_IP))
...@@ -938,12 +939,14 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev) ...@@ -938,12 +939,14 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev)
/* Guess output device to choose reasonable mtu and needed_headroom */ /* Guess output device to choose reasonable mtu and needed_headroom */
if (iph->daddr) { if (iph->daddr) {
struct rtable *rt = ip_route_output_gre(dev_net(dev), struct flowi4 fl4;
iph->daddr, iph->saddr, struct rtable *rt;
tunnel->parms.o_key,
RT_TOS(iph->tos), rt = ip_route_output_gre(dev_net(dev), &fl4,
tunnel->parms.link); iph->daddr, iph->saddr,
tunnel->parms.o_key,
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);
...@@ -1196,13 +1199,15 @@ static int ipgre_open(struct net_device *dev) ...@@ -1196,13 +1199,15 @@ static int ipgre_open(struct net_device *dev)
struct ip_tunnel *t = netdev_priv(dev); struct ip_tunnel *t = netdev_priv(dev);
if (ipv4_is_multicast(t->parms.iph.daddr)) { if (ipv4_is_multicast(t->parms.iph.daddr)) {
struct rtable *rt = ip_route_output_gre(dev_net(dev), struct flowi4 fl4;
t->parms.iph.daddr, struct rtable *rt;
t->parms.iph.saddr,
t->parms.o_key, rt = ip_route_output_gre(dev_net(dev), &fl4,
RT_TOS(t->parms.iph.tos), t->parms.iph.daddr,
t->parms.link); t->parms.iph.saddr,
t->parms.o_key,
RT_TOS(t->parms.iph.tos),
t->parms.link);
if (IS_ERR(rt)) if (IS_ERR(rt))
return -EADDRNOTAVAIL; return -EADDRNOTAVAIL;
dev = rt->dst.dev; dev = rt->dst.dev;
......
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