aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-05-04 15:33:34 -0400
committerDavid S. Miller <davem@davemloft.net>2011-05-04 15:55:07 -0400
commitcbb1e85f9cfd2bd9b7edfd21d167e89a4279faf0 (patch)
tree352ce07ff62b9fc38212d72f3d1b0d124dafea39
parent9a1b9496cd2b013f74885218947fa7120d53e74c (diff)
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: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/route.h19
-rw-r--r--net/ipv4/ip_gre.c37
2 files changed, 30 insertions, 26 deletions
diff --git a/include/net/route.h b/include/net/route.h
index 8c02c871a8ce..9f8070b251fb 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -152,19 +152,18 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct flowi
152 return ip_route_output_flow(net, fl4, sk); 152 return ip_route_output_flow(net, fl4, sk);
153} 153}
154 154
155static inline struct rtable *ip_route_output_gre(struct net *net, 155static inline struct rtable *ip_route_output_gre(struct net *net, struct flowi4 *fl4,
156 __be32 daddr, __be32 saddr, 156 __be32 daddr, __be32 saddr,
157 __be32 gre_key, __u8 tos, int oif) 157 __be32 gre_key, __u8 tos, int oif)
158{ 158{
159 struct flowi4 fl4 = { 159 memset(fl4, 0, sizeof(*fl4));
160 .flowi4_oif = oif, 160 fl4->flowi4_oif = oif;
161 .daddr = daddr, 161 fl4->daddr = daddr;
162 .saddr = saddr, 162 fl4->saddr = saddr;
163 .flowi4_tos = tos, 163 fl4->flowi4_tos = tos;
164 .flowi4_proto = IPPROTO_GRE, 164 fl4->flowi4_proto = IPPROTO_GRE;
165 .fl4_gre_key = gre_key, 165 fl4->fl4_gre_key = gre_key;
166 }; 166 return ip_route_output_key(net, fl4);
167 return ip_route_output_key(net, &fl4);
168} 167}
169 168
170extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src, 169extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src,
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 24efd353279a..10e9b5aea070 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -699,6 +699,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
699 struct pcpu_tstats *tstats; 699 struct pcpu_tstats *tstats;
700 const struct iphdr *old_iph = ip_hdr(skb); 700 const struct iphdr *old_iph = ip_hdr(skb);
701 const struct iphdr *tiph; 701 const struct iphdr *tiph;
702 struct flowi4 fl4;
702 u8 tos; 703 u8 tos;
703 __be16 df; 704 __be16 df;
704 struct rtable *rt; /* Route to the other host */ 705 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 tos = ipv6_get_dsfield((const struct ipv6hdr *)old_iph); 770 tos = ipv6_get_dsfield((const struct ipv6hdr *)old_iph);
770 } 771 }
771 772
772 rt = ip_route_output_gre(dev_net(dev), dst, tiph->saddr, 773 rt = ip_route_output_gre(dev_net(dev), &fl4, dst, tiph->saddr,
773 tunnel->parms.o_key, RT_TOS(tos), 774 tunnel->parms.o_key, RT_TOS(tos),
774 tunnel->parms.link); 775 tunnel->parms.link);
775 if (IS_ERR(rt)) { 776 if (IS_ERR(rt)) {
@@ -873,8 +874,8 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
873 iph->frag_off = df; 874 iph->frag_off = df;
874 iph->protocol = IPPROTO_GRE; 875 iph->protocol = IPPROTO_GRE;
875 iph->tos = ipgre_ecn_encapsulate(tos, old_iph, skb); 876 iph->tos = ipgre_ecn_encapsulate(tos, old_iph, skb);
876 iph->daddr = rt->rt_dst; 877 iph->daddr = fl4.daddr;
877 iph->saddr = rt->rt_src; 878 iph->saddr = fl4.saddr;
878 879
879 if ((iph->ttl = tiph->ttl) == 0) { 880 if ((iph->ttl = tiph->ttl) == 0) {
880 if (skb->protocol == htons(ETH_P_IP)) 881 if (skb->protocol == htons(ETH_P_IP))
@@ -938,12 +939,14 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev)
938 /* Guess output device to choose reasonable mtu and needed_headroom */ 939 /* Guess output device to choose reasonable mtu and needed_headroom */
939 940
940 if (iph->daddr) { 941 if (iph->daddr) {
941 struct rtable *rt = ip_route_output_gre(dev_net(dev), 942 struct flowi4 fl4;
942 iph->daddr, iph->saddr, 943 struct rtable *rt;
943 tunnel->parms.o_key, 944
944 RT_TOS(iph->tos), 945 rt = ip_route_output_gre(dev_net(dev), &fl4,
945 tunnel->parms.link); 946 iph->daddr, iph->saddr,
946 947 tunnel->parms.o_key,
948 RT_TOS(iph->tos),
949 tunnel->parms.link);
947 if (!IS_ERR(rt)) { 950 if (!IS_ERR(rt)) {
948 tdev = rt->dst.dev; 951 tdev = rt->dst.dev;
949 ip_rt_put(rt); 952 ip_rt_put(rt);
@@ -1196,13 +1199,15 @@ static int ipgre_open(struct net_device *dev)
1196 struct ip_tunnel *t = netdev_priv(dev); 1199 struct ip_tunnel *t = netdev_priv(dev);
1197 1200
1198 if (ipv4_is_multicast(t->parms.iph.daddr)) { 1201 if (ipv4_is_multicast(t->parms.iph.daddr)) {
1199 struct rtable *rt = ip_route_output_gre(dev_net(dev), 1202 struct flowi4 fl4;
1200 t->parms.iph.daddr, 1203 struct rtable *rt;
1201 t->parms.iph.saddr, 1204
1202 t->parms.o_key, 1205 rt = ip_route_output_gre(dev_net(dev), &fl4,
1203 RT_TOS(t->parms.iph.tos), 1206 t->parms.iph.daddr,
1204 t->parms.link); 1207 t->parms.iph.saddr,
1205 1208 t->parms.o_key,
1209 RT_TOS(t->parms.iph.tos),
1210 t->parms.link);
1206 if (IS_ERR(rt)) 1211 if (IS_ERR(rt))
1207 return -EADDRNOTAVAIL; 1212 return -EADDRNOTAVAIL;
1208 dev = rt->dst.dev; 1213 dev = rt->dst.dev;