@@ -72,6 +72,7 @@ struct geneve_dev {
72
72
bool collect_md ;
73
73
struct gro_cells gro_cells ;
74
74
u32 flags ;
75
+ struct dst_cache dst_cache ;
75
76
};
76
77
77
78
/* Geneve device flags */
@@ -297,13 +298,21 @@ static int geneve_init(struct net_device *dev)
297
298
return err ;
298
299
}
299
300
301
+ err = dst_cache_init (& geneve -> dst_cache , GFP_KERNEL );
302
+ if (err ) {
303
+ free_percpu (dev -> tstats );
304
+ gro_cells_destroy (& geneve -> gro_cells );
305
+ return err ;
306
+ }
307
+
300
308
return 0 ;
301
309
}
302
310
303
311
static void geneve_uninit (struct net_device * dev )
304
312
{
305
313
struct geneve_dev * geneve = netdev_priv (dev );
306
314
315
+ dst_cache_destroy (& geneve -> dst_cache );
307
316
gro_cells_destroy (& geneve -> gro_cells );
308
317
free_percpu (dev -> tstats );
309
318
}
@@ -753,7 +762,9 @@ static struct rtable *geneve_get_v4_rt(struct sk_buff *skb,
753
762
struct ip_tunnel_info * info )
754
763
{
755
764
struct geneve_dev * geneve = netdev_priv (dev );
765
+ struct dst_cache * dst_cache ;
756
766
struct rtable * rt = NULL ;
767
+ bool use_cache = true;
757
768
__u8 tos ;
758
769
759
770
memset (fl4 , 0 , sizeof (* fl4 ));
@@ -764,16 +775,26 @@ static struct rtable *geneve_get_v4_rt(struct sk_buff *skb,
764
775
fl4 -> daddr = info -> key .u .ipv4 .dst ;
765
776
fl4 -> saddr = info -> key .u .ipv4 .src ;
766
777
fl4 -> flowi4_tos = RT_TOS (info -> key .tos );
778
+ dst_cache = & info -> dst_cache ;
767
779
} else {
768
780
tos = geneve -> tos ;
769
781
if (tos == 1 ) {
770
782
const struct iphdr * iip = ip_hdr (skb );
771
783
772
784
tos = ip_tunnel_get_dsfield (iip , skb );
785
+ use_cache = false;
773
786
}
774
787
775
788
fl4 -> flowi4_tos = RT_TOS (tos );
776
789
fl4 -> daddr = geneve -> remote .sin .sin_addr .s_addr ;
790
+ dst_cache = & geneve -> dst_cache ;
791
+ }
792
+
793
+ use_cache = use_cache && !skb -> mark ;
794
+ if (use_cache ) {
795
+ rt = dst_cache_get_ip4 (dst_cache , & fl4 -> saddr );
796
+ if (rt )
797
+ return rt ;
777
798
}
778
799
779
800
rt = ip_route_output_key (geneve -> net , fl4 );
@@ -786,6 +807,8 @@ static struct rtable *geneve_get_v4_rt(struct sk_buff *skb,
786
807
ip_rt_put (rt );
787
808
return ERR_PTR (- ELOOP );
788
809
}
810
+ if (use_cache )
811
+ dst_cache_set_ip4 (dst_cache , & rt -> dst , fl4 -> saddr );
789
812
return rt ;
790
813
}
791
814
@@ -798,6 +821,8 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb,
798
821
struct geneve_dev * geneve = netdev_priv (dev );
799
822
struct geneve_sock * gs6 = geneve -> sock6 ;
800
823
struct dst_entry * dst = NULL ;
824
+ struct dst_cache * dst_cache ;
825
+ bool use_cache = true;
801
826
__u8 prio ;
802
827
803
828
memset (fl6 , 0 , sizeof (* fl6 ));
@@ -808,16 +833,26 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb,
808
833
fl6 -> daddr = info -> key .u .ipv6 .dst ;
809
834
fl6 -> saddr = info -> key .u .ipv6 .src ;
810
835
fl6 -> flowi6_tos = RT_TOS (info -> key .tos );
836
+ dst_cache = & info -> dst_cache ;
811
837
} else {
812
838
prio = geneve -> tos ;
813
839
if (prio == 1 ) {
814
840
const struct iphdr * iip = ip_hdr (skb );
815
841
816
842
prio = ip_tunnel_get_dsfield (iip , skb );
843
+ use_cache = false;
817
844
}
818
845
819
846
fl6 -> flowi6_tos = RT_TOS (prio );
820
847
fl6 -> daddr = geneve -> remote .sin6 .sin6_addr ;
848
+ dst_cache = & geneve -> dst_cache ;
849
+ }
850
+
851
+ use_cache = use_cache && !skb -> mark ;
852
+ if (use_cache ) {
853
+ dst = dst_cache_get_ip6 (dst_cache , & fl6 -> saddr );
854
+ if (dst )
855
+ return dst ;
821
856
}
822
857
823
858
if (ipv6_stub -> ipv6_dst_lookup (geneve -> net , gs6 -> sock -> sk , & dst , fl6 )) {
@@ -830,6 +865,8 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb,
830
865
return ERR_PTR (- ELOOP );
831
866
}
832
867
868
+ if (use_cache )
869
+ dst_cache_set_ip6 (dst_cache , dst , & fl6 -> saddr );
833
870
return dst ;
834
871
}
835
872
#endif
@@ -1272,6 +1309,8 @@ static int geneve_configure(struct net *net, struct net_device *dev,
1272
1309
return - EPERM ;
1273
1310
}
1274
1311
1312
+ dst_cache_reset (& geneve -> dst_cache );
1313
+
1275
1314
err = register_netdevice (dev );
1276
1315
if (err )
1277
1316
return err ;
0 commit comments