hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/tipc/udp_media.c
....@@ -44,7 +44,7 @@
4444 #include <net/sock.h>
4545 #include <net/ip.h>
4646 #include <net/udp_tunnel.h>
47
-#include <net/addrconf.h>
47
+#include <net/ipv6_stubs.h>
4848 #include <linux/tipc_netlink.h>
4949 #include "core.h"
5050 #include "addr.h"
....@@ -52,6 +52,7 @@
5252 #include "bearer.h"
5353 #include "netlink.h"
5454 #include "msg.h"
55
+#include "udp_media.h"
5556
5657 /* IANA assigned UDP port */
5758 #define UDP_PORT_DEFAULT 6118
....@@ -76,6 +77,7 @@
7677 /* struct udp_replicast - container for UDP remote addresses */
7778 struct udp_replicast {
7879 struct udp_media_addr addr;
80
+ struct dst_cache dst_cache;
7981 struct rcu_head rcu;
8082 struct list_head list;
8183 };
....@@ -158,22 +160,29 @@
158160 /* tipc_send_msg - enqueue a send request */
159161 static int tipc_udp_xmit(struct net *net, struct sk_buff *skb,
160162 struct udp_bearer *ub, struct udp_media_addr *src,
161
- struct udp_media_addr *dst)
163
+ struct udp_media_addr *dst, struct dst_cache *cache)
162164 {
165
+ struct dst_entry *ndst;
163166 int ttl, err = 0;
164
- struct rtable *rt;
165167
168
+ local_bh_disable();
169
+ ndst = dst_cache_get(cache);
166170 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;
171
+ struct rtable *rt = (struct rtable *)ndst;
172
+
173
+ if (!rt) {
174
+ struct flowi4 fl = {
175
+ .daddr = dst->ipv4.s_addr,
176
+ .saddr = src->ipv4.s_addr,
177
+ .flowi4_mark = skb->mark,
178
+ .flowi4_proto = IPPROTO_UDP
179
+ };
180
+ rt = ip_route_output_key(net, &fl);
181
+ if (IS_ERR(rt)) {
182
+ err = PTR_ERR(rt);
183
+ goto tx_error;
184
+ }
185
+ dst_cache_set_ip4(cache, &rt->dst, fl.saddr);
177186 }
178187
179188 ttl = ip4_dst_hoplimit(&rt->dst);
....@@ -182,19 +191,21 @@
182191 dst->port, false, true);
183192 #if IS_ENABLED(CONFIG_IPV6)
184193 } 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
- ndst = ipv6_stub->ipv6_dst_lookup_flow(net,
193
- ub->ubsock->sk,
194
- &fl6, NULL);
195
- if (IS_ERR(ndst)) {
196
- err = PTR_ERR(ndst);
197
- goto tx_error;
194
+ if (!ndst) {
195
+ struct flowi6 fl6 = {
196
+ .flowi6_oif = ub->ifindex,
197
+ .daddr = dst->ipv6,
198
+ .saddr = src->ipv6,
199
+ .flowi6_proto = IPPROTO_UDP
200
+ };
201
+ ndst = ipv6_stub->ipv6_dst_lookup_flow(net,
202
+ ub->ubsock->sk,
203
+ &fl6, NULL);
204
+ if (IS_ERR(ndst)) {
205
+ err = PTR_ERR(ndst);
206
+ goto tx_error;
207
+ }
208
+ dst_cache_set_ip6(cache, ndst, &fl6.saddr);
198209 }
199210 ttl = ip6_dst_hoplimit(ndst);
200211 err = udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, skb, NULL,
....@@ -202,9 +213,11 @@
202213 src->port, dst->port, false);
203214 #endif
204215 }
216
+ local_bh_enable();
205217 return err;
206218
207219 tx_error:
220
+ local_bh_enable();
208221 kfree_skb(skb);
209222 return err;
210223 }
....@@ -226,14 +239,15 @@
226239 }
227240
228241 skb_set_inner_protocol(skb, htons(ETH_P_TIPC));
229
- ub = rcu_dereference_rtnl(b->media_ptr);
242
+ ub = rcu_dereference(b->media_ptr);
230243 if (!ub) {
231244 err = -ENODEV;
232245 goto out;
233246 }
234247
235248 if (addr->broadcast != TIPC_REPLICAST_SUPPORT)
236
- return tipc_udp_xmit(net, skb, ub, src, dst);
249
+ return tipc_udp_xmit(net, skb, ub, src, dst,
250
+ &ub->rcast.dst_cache);
237251
238252 /* Replicast, send an skb to each configured IP address */
239253 list_for_each_entry_rcu(rcast, &ub->rcast.list, list) {
....@@ -245,7 +259,8 @@
245259 goto out;
246260 }
247261
248
- err = tipc_udp_xmit(net, _skb, ub, src, &rcast->addr);
262
+ err = tipc_udp_xmit(net, _skb, ub, src, &rcast->addr,
263
+ &rcast->dst_cache);
249264 if (err)
250265 goto out;
251266 }
....@@ -288,6 +303,11 @@
288303 rcast = kmalloc(sizeof(*rcast), GFP_ATOMIC);
289304 if (!rcast)
290305 return -ENOMEM;
306
+
307
+ if (dst_cache_init(&rcast->dst_cache, GFP_ATOMIC)) {
308
+ kfree(rcast);
309
+ return -ENOMEM;
310
+ }
291311
292312 memcpy(&rcast->addr, addr, sizeof(struct udp_media_addr));
293313
....@@ -355,25 +375,22 @@
355375 skb_pull(skb, sizeof(struct udphdr));
356376 hdr = buf_msg(skb);
357377
358
- rcu_read_lock();
359
- b = rcu_dereference_rtnl(ub->bearer);
378
+ b = rcu_dereference(ub->bearer);
360379 if (!b)
361
- goto rcu_out;
380
+ goto out;
362381
363382 if (b && test_bit(0, &b->up)) {
383
+ TIPC_SKB_CB(skb)->flags = 0;
364384 tipc_rcv(sock_net(sk), skb, b);
365
- rcu_read_unlock();
366385 return 0;
367386 }
368387
369388 if (unlikely(msg_user(hdr) == LINK_CONFIG)) {
370389 err = tipc_udp_rcast_disc(b, skb);
371390 if (err)
372
- goto rcu_out;
391
+ goto out;
373392 }
374393
375
-rcu_out:
376
- rcu_read_unlock();
377394 out:
378395 kfree_skb(skb);
379396 return 0;
....@@ -440,21 +457,17 @@
440457 int i;
441458
442459 if (!bid && !skip_cnt) {
460
+ struct nlattr **attrs = genl_dumpit_info(cb)->attrs;
443461 struct net *net = sock_net(skb->sk);
444462 struct nlattr *battrs[TIPC_NLA_BEARER_MAX + 1];
445
- struct nlattr **attrs;
446463 char *bname;
447
-
448
- err = tipc_nlmsg_parse(cb->nlh, &attrs);
449
- if (err)
450
- return err;
451464
452465 if (!attrs[TIPC_NLA_BEARER])
453466 return -EINVAL;
454467
455
- err = nla_parse_nested(battrs, TIPC_NLA_BEARER_MAX,
456
- attrs[TIPC_NLA_BEARER],
457
- tipc_nl_bearer_policy, NULL);
468
+ err = nla_parse_nested_deprecated(battrs, TIPC_NLA_BEARER_MAX,
469
+ attrs[TIPC_NLA_BEARER],
470
+ tipc_nl_bearer_policy, NULL);
458471 if (err)
459472 return err;
460473
....@@ -482,7 +495,7 @@
482495 }
483496 }
484497
485
- ub = rcu_dereference_rtnl(b->media_ptr);
498
+ ub = rtnl_dereference(b->media_ptr);
486499 if (!ub) {
487500 rtnl_unlock();
488501 return -EINVAL;
....@@ -524,11 +537,11 @@
524537 struct udp_bearer *ub;
525538 struct nlattr *nest;
526539
527
- ub = rcu_dereference_rtnl(b->media_ptr);
540
+ ub = rtnl_dereference(b->media_ptr);
528541 if (!ub)
529542 return -ENODEV;
530543
531
- nest = nla_nest_start(msg->skb, TIPC_NLA_BEARER_UDP_OPTS);
544
+ nest = nla_nest_start_noflag(msg->skb, TIPC_NLA_BEARER_UDP_OPTS);
532545 if (!nest)
533546 goto msg_full;
534547
....@@ -553,7 +566,7 @@
553566
554567 /**
555568 * tipc_parse_udp_addr - build udp media address from netlink data
556
- * @nlattr: netlink attribute containing sockaddr storage aligned address
569
+ * @nla: netlink attribute containing sockaddr storage aligned address
557570 * @addr: tipc media address to fill with address, port and protocol type
558571 * @scope_id: IPv6 scope id pointer, not NULL indicates it's required
559572 */
....@@ -606,8 +619,7 @@
606619 struct nlattr *opts[TIPC_NLA_UDP_MAX + 1];
607620 struct udp_media_addr *dst;
608621
609
- if (nla_parse_nested(opts, TIPC_NLA_UDP_MAX, attr,
610
- tipc_nl_udp_policy, NULL))
622
+ if (nla_parse_nested_deprecated(opts, TIPC_NLA_UDP_MAX, attr, tipc_nl_udp_policy, NULL))
611623 return -EINVAL;
612624
613625 if (!opts[TIPC_NLA_UDP_REMOTE])
....@@ -649,6 +661,8 @@
649661 struct udp_tunnel_sock_cfg tuncfg = {NULL};
650662 struct nlattr *opts[TIPC_NLA_UDP_MAX + 1];
651663 u8 node_id[NODE_ID_LEN] = {0,};
664
+ struct net_device *dev;
665
+ int rmcast = 0;
652666
653667 ub = kzalloc(sizeof(*ub), GFP_ATOMIC);
654668 if (!ub)
....@@ -659,9 +673,7 @@
659673 if (!attrs[TIPC_NLA_BEARER_UDP_OPTS])
660674 goto err;
661675
662
- if (nla_parse_nested(opts, TIPC_NLA_UDP_MAX,
663
- attrs[TIPC_NLA_BEARER_UDP_OPTS],
664
- tipc_nl_udp_policy, NULL))
676
+ if (nla_parse_nested_deprecated(opts, TIPC_NLA_UDP_MAX, attrs[TIPC_NLA_BEARER_UDP_OPTS], tipc_nl_udp_policy, NULL))
665677 goto err;
666678
667679 if (!opts[TIPC_NLA_UDP_LOCAL] || !opts[TIPC_NLA_UDP_REMOTE]) {
....@@ -684,6 +696,9 @@
684696 goto err;
685697 }
686698
699
+ /* Checking remote ip address */
700
+ rmcast = tipc_udp_is_mcast_addr(&remote);
701
+
687702 /* Autoconfigure own node identity if needed */
688703 if (!tipc_own_id(net)) {
689704 memcpy(node_id, local.ipv6.in6_u.u6_addr8, 16);
....@@ -701,15 +716,18 @@
701716 rcu_assign_pointer(ub->bearer, b);
702717 tipc_udp_media_addr_set(&b->addr, &local);
703718 if (local.proto == htons(ETH_P_IP)) {
704
- struct net_device *dev;
705
-
706719 dev = __ip_dev_find(net, local.ipv4.s_addr, false);
707720 if (!dev) {
708721 err = -ENODEV;
709722 goto err;
710723 }
711724 udp_conf.family = AF_INET;
712
- udp_conf.local_ip.s_addr = htonl(INADDR_ANY);
725
+
726
+ /* Switch to use ANY to receive packets from group */
727
+ if (rmcast)
728
+ udp_conf.local_ip.s_addr = htonl(INADDR_ANY);
729
+ else
730
+ udp_conf.local_ip.s_addr = local.ipv4.s_addr;
713731 udp_conf.use_udp_checksums = false;
714732 ub->ifindex = dev->ifindex;
715733 if (tipc_mtu_bad(dev, sizeof(struct iphdr) +
....@@ -720,10 +738,20 @@
720738 b->mtu = b->media->mtu;
721739 #if IS_ENABLED(CONFIG_IPV6)
722740 } else if (local.proto == htons(ETH_P_IPV6)) {
741
+ dev = ub->ifindex ? __dev_get_by_index(net, ub->ifindex) : NULL;
742
+ dev = ipv6_dev_find(net, &local.ipv6, dev);
743
+ if (!dev) {
744
+ err = -ENODEV;
745
+ goto err;
746
+ }
723747 udp_conf.family = AF_INET6;
724748 udp_conf.use_udp6_tx_checksums = true;
725749 udp_conf.use_udp6_rx_checksums = true;
726
- udp_conf.local_ip6 = in6addr_any;
750
+ if (rmcast)
751
+ udp_conf.local_ip6 = in6addr_any;
752
+ else
753
+ udp_conf.local_ip6 = local.ipv6;
754
+ ub->ifindex = dev->ifindex;
727755 b->mtu = 1280;
728756 #endif
729757 } else {
....@@ -740,22 +768,28 @@
740768 tuncfg.encap_destroy = NULL;
741769 setup_udp_tunnel_sock(net, ub->ubsock, &tuncfg);
742770
771
+ err = dst_cache_init(&ub->rcast.dst_cache, GFP_ATOMIC);
772
+ if (err)
773
+ goto free;
774
+
743775 /**
744776 * The bcast media address port is used for all peers and the ip
745777 * is used if it's a multicast address.
746778 */
747779 memcpy(&b->bcast_addr.value, &remote, sizeof(remote));
748
- if (tipc_udp_is_mcast_addr(&remote))
780
+ if (rmcast)
749781 err = enable_mcast(ub, &remote);
750782 else
751783 err = tipc_udp_rcast_add(b, &remote);
752784 if (err)
753
- goto err;
785
+ goto free;
754786
755787 return 0;
788
+
789
+free:
790
+ dst_cache_destroy(&ub->rcast.dst_cache);
791
+ udp_tunnel_sock_release(ub->ubsock);
756792 err:
757
- if (ub->ubsock)
758
- udp_tunnel_sock_release(ub->ubsock);
759793 kfree(ub);
760794 return err;
761795 }
....@@ -767,12 +801,14 @@
767801 struct udp_replicast *rcast, *tmp;
768802
769803 list_for_each_entry_safe(rcast, tmp, &ub->rcast.list, list) {
804
+ dst_cache_destroy(&rcast->dst_cache);
770805 list_del_rcu(&rcast->list);
771806 kfree_rcu(rcast, rcu);
772807 }
773808
774
- if (ub->ubsock)
775
- udp_tunnel_sock_release(ub->ubsock);
809
+ atomic_dec(&tipc_net(sock_net(ub->ubsock->sk))->wq_count);
810
+ dst_cache_destroy(&ub->rcast.dst_cache);
811
+ udp_tunnel_sock_release(ub->ubsock);
776812 synchronize_net();
777813 kfree(ub);
778814 }
....@@ -782,16 +818,16 @@
782818 {
783819 struct udp_bearer *ub;
784820
785
- ub = rcu_dereference_rtnl(b->media_ptr);
821
+ ub = rtnl_dereference(b->media_ptr);
786822 if (!ub) {
787823 pr_err("UDP bearer instance not found\n");
788824 return;
789825 }
790
- if (ub->ubsock)
791
- sock_set_flag(ub->ubsock->sk, SOCK_DEAD);
826
+ sock_set_flag(ub->ubsock->sk, SOCK_DEAD);
792827 RCU_INIT_POINTER(ub->bearer, NULL);
793828
794829 /* sock_release need to be done outside of rtnl lock */
830
+ atomic_inc(&tipc_net(sock_net(ub->ubsock->sk))->wq_count);
795831 INIT_WORK(&ub->work, cleanup_bearer);
796832 schedule_work(&ub->work);
797833 }
....@@ -805,7 +841,8 @@
805841 .msg2addr = tipc_udp_msg2addr,
806842 .priority = TIPC_DEF_LINK_PRI,
807843 .tolerance = TIPC_DEF_LINK_TOL,
808
- .window = TIPC_DEF_LINK_WIN,
844
+ .min_win = TIPC_DEF_LINK_WIN,
845
+ .max_win = TIPC_DEF_LINK_WIN,
809846 .mtu = TIPC_DEF_LINK_UDP_MTU,
810847 .type_id = TIPC_MEDIA_TYPE_UDP,
811848 .hwaddr_len = 0,