@@ -76,6 +76,7 @@ struct udp_media_addr {
7676/* struct udp_replicast - container for UDP remote addresses */
7777struct udp_replicast {
7878 struct udp_media_addr addr ;
79+ struct dst_cache dst_cache ;
7980 struct rcu_head rcu ;
8081 struct list_head list ;
8182};
@@ -158,22 +159,27 @@ static int tipc_udp_addr2msg(char *msg, struct tipc_media_addr *a)
158159/* tipc_send_msg - enqueue a send request */
159160static int tipc_udp_xmit (struct net * net , struct sk_buff * skb ,
160161 struct udp_bearer * ub , struct udp_media_addr * src ,
161- struct udp_media_addr * dst )
162+ struct udp_media_addr * dst , struct dst_cache * cache )
162163{
164+ struct dst_entry * ndst = dst_cache_get (cache );
163165 int ttl , err = 0 ;
164- struct rtable * rt ;
165166
166167 if (dst -> proto == htons (ETH_P_IP )) {
167- struct flowi4 fl = {
168- .daddr = dst -> ipv4 .s_addr ,
169- .saddr = src -> ipv4 .s_addr ,
170- .flowi4_mark = skb -> mark ,
171- .flowi4_proto = IPPROTO_UDP
172- };
173- rt = ip_route_output_key (net , & fl );
174- if (IS_ERR (rt )) {
175- err = PTR_ERR (rt );
176- goto tx_error ;
168+ struct rtable * rt = (struct rtable * )ndst ;
169+
170+ if (!rt ) {
171+ struct flowi4 fl = {
172+ .daddr = dst -> ipv4 .s_addr ,
173+ .saddr = src -> ipv4 .s_addr ,
174+ .flowi4_mark = skb -> mark ,
175+ .flowi4_proto = IPPROTO_UDP
176+ };
177+ rt = ip_route_output_key (net , & fl );
178+ if (IS_ERR (rt )) {
179+ err = PTR_ERR (rt );
180+ goto tx_error ;
181+ }
182+ dst_cache_set_ip4 (cache , & rt -> dst , fl .saddr );
177183 }
178184
179185 ttl = ip4_dst_hoplimit (& rt -> dst );
@@ -182,17 +188,19 @@ static int tipc_udp_xmit(struct net *net, struct sk_buff *skb,
182188 dst -> port , false, true);
183189#if IS_ENABLED (CONFIG_IPV6 )
184190 } else {
185- struct dst_entry * ndst ;
186- struct flowi6 fl6 = {
187- .flowi6_oif = ub -> ifindex ,
188- .daddr = dst -> ipv6 ,
189- .saddr = src -> ipv6 ,
190- .flowi6_proto = IPPROTO_UDP
191- };
192- err = ipv6_stub -> ipv6_dst_lookup (net , ub -> ubsock -> sk , & ndst ,
193- & fl6 );
194- if (err )
195- goto tx_error ;
191+ if (!ndst ) {
192+ struct flowi6 fl6 = {
193+ .flowi6_oif = ub -> ifindex ,
194+ .daddr = dst -> ipv6 ,
195+ .saddr = src -> ipv6 ,
196+ .flowi6_proto = IPPROTO_UDP
197+ };
198+ err = ipv6_stub -> ipv6_dst_lookup (net , ub -> ubsock -> sk ,
199+ & ndst , & fl6 );
200+ if (err )
201+ goto tx_error ;
202+ dst_cache_set_ip6 (cache , ndst , & fl6 .saddr );
203+ }
196204 ttl = ip6_dst_hoplimit (ndst );
197205 err = udp_tunnel6_xmit_skb (ndst , ub -> ubsock -> sk , skb , NULL ,
198206 & src -> ipv6 , & dst -> ipv6 , 0 , ttl , 0 ,
@@ -230,7 +238,8 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
230238 }
231239
232240 if (addr -> broadcast != TIPC_REPLICAST_SUPPORT )
233- return tipc_udp_xmit (net , skb , ub , src , dst );
241+ return tipc_udp_xmit (net , skb , ub , src , dst ,
242+ & ub -> rcast .dst_cache );
234243
235244 /* Replicast, send an skb to each configured IP address */
236245 list_for_each_entry_rcu (rcast , & ub -> rcast .list , list ) {
@@ -242,7 +251,8 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
242251 goto out ;
243252 }
244253
245- err = tipc_udp_xmit (net , _skb , ub , src , & rcast -> addr );
254+ err = tipc_udp_xmit (net , _skb , ub , src , & rcast -> addr ,
255+ & rcast -> dst_cache );
246256 if (err )
247257 goto out ;
248258 }
@@ -286,6 +296,11 @@ static int tipc_udp_rcast_add(struct tipc_bearer *b,
286296 if (!rcast )
287297 return - ENOMEM ;
288298
299+ if (dst_cache_init (& rcast -> dst_cache , GFP_ATOMIC )) {
300+ kfree (rcast );
301+ return - ENOMEM ;
302+ }
303+
289304 memcpy (& rcast -> addr , addr , sizeof (struct udp_media_addr ));
290305
291306 if (ntohs (addr -> proto ) == ETH_P_IP )
@@ -742,6 +757,10 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
742757 tuncfg .encap_destroy = NULL ;
743758 setup_udp_tunnel_sock (net , ub -> ubsock , & tuncfg );
744759
760+ err = dst_cache_init (& ub -> rcast .dst_cache , GFP_ATOMIC );
761+ if (err )
762+ goto err ;
763+
745764 /**
746765 * The bcast media address port is used for all peers and the ip
747766 * is used if it's a multicast address.
@@ -756,6 +775,7 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
756775
757776 return 0 ;
758777err :
778+ dst_cache_destroy (& ub -> rcast .dst_cache );
759779 if (ub -> ubsock )
760780 udp_tunnel_sock_release (ub -> ubsock );
761781 kfree (ub );
@@ -769,10 +789,12 @@ static void cleanup_bearer(struct work_struct *work)
769789 struct udp_replicast * rcast , * tmp ;
770790
771791 list_for_each_entry_safe (rcast , tmp , & ub -> rcast .list , list ) {
792+ dst_cache_destroy (& rcast -> dst_cache );
772793 list_del_rcu (& rcast -> list );
773794 kfree_rcu (rcast , rcu );
774795 }
775796
797+ dst_cache_destroy (& ub -> rcast .dst_cache );
776798 if (ub -> ubsock )
777799 udp_tunnel_sock_release (ub -> ubsock );
778800 synchronize_net ();
0 commit comments