| .. | .. |
|---|
| 44 | 44 | #include <net/sock.h> |
|---|
| 45 | 45 | #include <net/ip.h> |
|---|
| 46 | 46 | #include <net/udp_tunnel.h> |
|---|
| 47 | | -#include <net/addrconf.h> |
|---|
| 47 | +#include <net/ipv6_stubs.h> |
|---|
| 48 | 48 | #include <linux/tipc_netlink.h> |
|---|
| 49 | 49 | #include "core.h" |
|---|
| 50 | 50 | #include "addr.h" |
|---|
| .. | .. |
|---|
| 52 | 52 | #include "bearer.h" |
|---|
| 53 | 53 | #include "netlink.h" |
|---|
| 54 | 54 | #include "msg.h" |
|---|
| 55 | +#include "udp_media.h" |
|---|
| 55 | 56 | |
|---|
| 56 | 57 | /* IANA assigned UDP port */ |
|---|
| 57 | 58 | #define UDP_PORT_DEFAULT 6118 |
|---|
| .. | .. |
|---|
| 76 | 77 | /* struct udp_replicast - container for UDP remote addresses */ |
|---|
| 77 | 78 | struct udp_replicast { |
|---|
| 78 | 79 | struct udp_media_addr addr; |
|---|
| 80 | + struct dst_cache dst_cache; |
|---|
| 79 | 81 | struct rcu_head rcu; |
|---|
| 80 | 82 | struct list_head list; |
|---|
| 81 | 83 | }; |
|---|
| .. | .. |
|---|
| 158 | 160 | /* tipc_send_msg - enqueue a send request */ |
|---|
| 159 | 161 | static int tipc_udp_xmit(struct net *net, struct sk_buff *skb, |
|---|
| 160 | 162 | 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) |
|---|
| 162 | 164 | { |
|---|
| 165 | + struct dst_entry *ndst; |
|---|
| 163 | 166 | int ttl, err = 0; |
|---|
| 164 | | - struct rtable *rt; |
|---|
| 165 | 167 | |
|---|
| 168 | + local_bh_disable(); |
|---|
| 169 | + ndst = dst_cache_get(cache); |
|---|
| 166 | 170 | 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); |
|---|
| 177 | 186 | } |
|---|
| 178 | 187 | |
|---|
| 179 | 188 | ttl = ip4_dst_hoplimit(&rt->dst); |
|---|
| .. | .. |
|---|
| 182 | 191 | dst->port, false, true); |
|---|
| 183 | 192 | #if IS_ENABLED(CONFIG_IPV6) |
|---|
| 184 | 193 | } 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); |
|---|
| 198 | 209 | } |
|---|
| 199 | 210 | ttl = ip6_dst_hoplimit(ndst); |
|---|
| 200 | 211 | err = udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, skb, NULL, |
|---|
| .. | .. |
|---|
| 202 | 213 | src->port, dst->port, false); |
|---|
| 203 | 214 | #endif |
|---|
| 204 | 215 | } |
|---|
| 216 | + local_bh_enable(); |
|---|
| 205 | 217 | return err; |
|---|
| 206 | 218 | |
|---|
| 207 | 219 | tx_error: |
|---|
| 220 | + local_bh_enable(); |
|---|
| 208 | 221 | kfree_skb(skb); |
|---|
| 209 | 222 | return err; |
|---|
| 210 | 223 | } |
|---|
| .. | .. |
|---|
| 226 | 239 | } |
|---|
| 227 | 240 | |
|---|
| 228 | 241 | skb_set_inner_protocol(skb, htons(ETH_P_TIPC)); |
|---|
| 229 | | - ub = rcu_dereference_rtnl(b->media_ptr); |
|---|
| 242 | + ub = rcu_dereference(b->media_ptr); |
|---|
| 230 | 243 | if (!ub) { |
|---|
| 231 | 244 | err = -ENODEV; |
|---|
| 232 | 245 | goto out; |
|---|
| 233 | 246 | } |
|---|
| 234 | 247 | |
|---|
| 235 | 248 | 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); |
|---|
| 237 | 251 | |
|---|
| 238 | 252 | /* Replicast, send an skb to each configured IP address */ |
|---|
| 239 | 253 | list_for_each_entry_rcu(rcast, &ub->rcast.list, list) { |
|---|
| .. | .. |
|---|
| 245 | 259 | goto out; |
|---|
| 246 | 260 | } |
|---|
| 247 | 261 | |
|---|
| 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); |
|---|
| 249 | 264 | if (err) |
|---|
| 250 | 265 | goto out; |
|---|
| 251 | 266 | } |
|---|
| .. | .. |
|---|
| 288 | 303 | rcast = kmalloc(sizeof(*rcast), GFP_ATOMIC); |
|---|
| 289 | 304 | if (!rcast) |
|---|
| 290 | 305 | return -ENOMEM; |
|---|
| 306 | + |
|---|
| 307 | + if (dst_cache_init(&rcast->dst_cache, GFP_ATOMIC)) { |
|---|
| 308 | + kfree(rcast); |
|---|
| 309 | + return -ENOMEM; |
|---|
| 310 | + } |
|---|
| 291 | 311 | |
|---|
| 292 | 312 | memcpy(&rcast->addr, addr, sizeof(struct udp_media_addr)); |
|---|
| 293 | 313 | |
|---|
| .. | .. |
|---|
| 355 | 375 | skb_pull(skb, sizeof(struct udphdr)); |
|---|
| 356 | 376 | hdr = buf_msg(skb); |
|---|
| 357 | 377 | |
|---|
| 358 | | - rcu_read_lock(); |
|---|
| 359 | | - b = rcu_dereference_rtnl(ub->bearer); |
|---|
| 378 | + b = rcu_dereference(ub->bearer); |
|---|
| 360 | 379 | if (!b) |
|---|
| 361 | | - goto rcu_out; |
|---|
| 380 | + goto out; |
|---|
| 362 | 381 | |
|---|
| 363 | 382 | if (b && test_bit(0, &b->up)) { |
|---|
| 383 | + TIPC_SKB_CB(skb)->flags = 0; |
|---|
| 364 | 384 | tipc_rcv(sock_net(sk), skb, b); |
|---|
| 365 | | - rcu_read_unlock(); |
|---|
| 366 | 385 | return 0; |
|---|
| 367 | 386 | } |
|---|
| 368 | 387 | |
|---|
| 369 | 388 | if (unlikely(msg_user(hdr) == LINK_CONFIG)) { |
|---|
| 370 | 389 | err = tipc_udp_rcast_disc(b, skb); |
|---|
| 371 | 390 | if (err) |
|---|
| 372 | | - goto rcu_out; |
|---|
| 391 | + goto out; |
|---|
| 373 | 392 | } |
|---|
| 374 | 393 | |
|---|
| 375 | | -rcu_out: |
|---|
| 376 | | - rcu_read_unlock(); |
|---|
| 377 | 394 | out: |
|---|
| 378 | 395 | kfree_skb(skb); |
|---|
| 379 | 396 | return 0; |
|---|
| .. | .. |
|---|
| 440 | 457 | int i; |
|---|
| 441 | 458 | |
|---|
| 442 | 459 | if (!bid && !skip_cnt) { |
|---|
| 460 | + struct nlattr **attrs = genl_dumpit_info(cb)->attrs; |
|---|
| 443 | 461 | struct net *net = sock_net(skb->sk); |
|---|
| 444 | 462 | struct nlattr *battrs[TIPC_NLA_BEARER_MAX + 1]; |
|---|
| 445 | | - struct nlattr **attrs; |
|---|
| 446 | 463 | char *bname; |
|---|
| 447 | | - |
|---|
| 448 | | - err = tipc_nlmsg_parse(cb->nlh, &attrs); |
|---|
| 449 | | - if (err) |
|---|
| 450 | | - return err; |
|---|
| 451 | 464 | |
|---|
| 452 | 465 | if (!attrs[TIPC_NLA_BEARER]) |
|---|
| 453 | 466 | return -EINVAL; |
|---|
| 454 | 467 | |
|---|
| 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); |
|---|
| 458 | 471 | if (err) |
|---|
| 459 | 472 | return err; |
|---|
| 460 | 473 | |
|---|
| .. | .. |
|---|
| 482 | 495 | } |
|---|
| 483 | 496 | } |
|---|
| 484 | 497 | |
|---|
| 485 | | - ub = rcu_dereference_rtnl(b->media_ptr); |
|---|
| 498 | + ub = rtnl_dereference(b->media_ptr); |
|---|
| 486 | 499 | if (!ub) { |
|---|
| 487 | 500 | rtnl_unlock(); |
|---|
| 488 | 501 | return -EINVAL; |
|---|
| .. | .. |
|---|
| 524 | 537 | struct udp_bearer *ub; |
|---|
| 525 | 538 | struct nlattr *nest; |
|---|
| 526 | 539 | |
|---|
| 527 | | - ub = rcu_dereference_rtnl(b->media_ptr); |
|---|
| 540 | + ub = rtnl_dereference(b->media_ptr); |
|---|
| 528 | 541 | if (!ub) |
|---|
| 529 | 542 | return -ENODEV; |
|---|
| 530 | 543 | |
|---|
| 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); |
|---|
| 532 | 545 | if (!nest) |
|---|
| 533 | 546 | goto msg_full; |
|---|
| 534 | 547 | |
|---|
| .. | .. |
|---|
| 553 | 566 | |
|---|
| 554 | 567 | /** |
|---|
| 555 | 568 | * 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 |
|---|
| 557 | 570 | * @addr: tipc media address to fill with address, port and protocol type |
|---|
| 558 | 571 | * @scope_id: IPv6 scope id pointer, not NULL indicates it's required |
|---|
| 559 | 572 | */ |
|---|
| .. | .. |
|---|
| 606 | 619 | struct nlattr *opts[TIPC_NLA_UDP_MAX + 1]; |
|---|
| 607 | 620 | struct udp_media_addr *dst; |
|---|
| 608 | 621 | |
|---|
| 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)) |
|---|
| 611 | 623 | return -EINVAL; |
|---|
| 612 | 624 | |
|---|
| 613 | 625 | if (!opts[TIPC_NLA_UDP_REMOTE]) |
|---|
| .. | .. |
|---|
| 649 | 661 | struct udp_tunnel_sock_cfg tuncfg = {NULL}; |
|---|
| 650 | 662 | struct nlattr *opts[TIPC_NLA_UDP_MAX + 1]; |
|---|
| 651 | 663 | u8 node_id[NODE_ID_LEN] = {0,}; |
|---|
| 664 | + struct net_device *dev; |
|---|
| 665 | + int rmcast = 0; |
|---|
| 652 | 666 | |
|---|
| 653 | 667 | ub = kzalloc(sizeof(*ub), GFP_ATOMIC); |
|---|
| 654 | 668 | if (!ub) |
|---|
| .. | .. |
|---|
| 659 | 673 | if (!attrs[TIPC_NLA_BEARER_UDP_OPTS]) |
|---|
| 660 | 674 | goto err; |
|---|
| 661 | 675 | |
|---|
| 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)) |
|---|
| 665 | 677 | goto err; |
|---|
| 666 | 678 | |
|---|
| 667 | 679 | if (!opts[TIPC_NLA_UDP_LOCAL] || !opts[TIPC_NLA_UDP_REMOTE]) { |
|---|
| .. | .. |
|---|
| 684 | 696 | goto err; |
|---|
| 685 | 697 | } |
|---|
| 686 | 698 | |
|---|
| 699 | + /* Checking remote ip address */ |
|---|
| 700 | + rmcast = tipc_udp_is_mcast_addr(&remote); |
|---|
| 701 | + |
|---|
| 687 | 702 | /* Autoconfigure own node identity if needed */ |
|---|
| 688 | 703 | if (!tipc_own_id(net)) { |
|---|
| 689 | 704 | memcpy(node_id, local.ipv6.in6_u.u6_addr8, 16); |
|---|
| .. | .. |
|---|
| 701 | 716 | rcu_assign_pointer(ub->bearer, b); |
|---|
| 702 | 717 | tipc_udp_media_addr_set(&b->addr, &local); |
|---|
| 703 | 718 | if (local.proto == htons(ETH_P_IP)) { |
|---|
| 704 | | - struct net_device *dev; |
|---|
| 705 | | - |
|---|
| 706 | 719 | dev = __ip_dev_find(net, local.ipv4.s_addr, false); |
|---|
| 707 | 720 | if (!dev) { |
|---|
| 708 | 721 | err = -ENODEV; |
|---|
| 709 | 722 | goto err; |
|---|
| 710 | 723 | } |
|---|
| 711 | 724 | 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; |
|---|
| 713 | 731 | udp_conf.use_udp_checksums = false; |
|---|
| 714 | 732 | ub->ifindex = dev->ifindex; |
|---|
| 715 | 733 | if (tipc_mtu_bad(dev, sizeof(struct iphdr) + |
|---|
| .. | .. |
|---|
| 720 | 738 | b->mtu = b->media->mtu; |
|---|
| 721 | 739 | #if IS_ENABLED(CONFIG_IPV6) |
|---|
| 722 | 740 | } 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 | + } |
|---|
| 723 | 747 | udp_conf.family = AF_INET6; |
|---|
| 724 | 748 | udp_conf.use_udp6_tx_checksums = true; |
|---|
| 725 | 749 | 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; |
|---|
| 727 | 755 | b->mtu = 1280; |
|---|
| 728 | 756 | #endif |
|---|
| 729 | 757 | } else { |
|---|
| .. | .. |
|---|
| 740 | 768 | tuncfg.encap_destroy = NULL; |
|---|
| 741 | 769 | setup_udp_tunnel_sock(net, ub->ubsock, &tuncfg); |
|---|
| 742 | 770 | |
|---|
| 771 | + err = dst_cache_init(&ub->rcast.dst_cache, GFP_ATOMIC); |
|---|
| 772 | + if (err) |
|---|
| 773 | + goto free; |
|---|
| 774 | + |
|---|
| 743 | 775 | /** |
|---|
| 744 | 776 | * The bcast media address port is used for all peers and the ip |
|---|
| 745 | 777 | * is used if it's a multicast address. |
|---|
| 746 | 778 | */ |
|---|
| 747 | 779 | memcpy(&b->bcast_addr.value, &remote, sizeof(remote)); |
|---|
| 748 | | - if (tipc_udp_is_mcast_addr(&remote)) |
|---|
| 780 | + if (rmcast) |
|---|
| 749 | 781 | err = enable_mcast(ub, &remote); |
|---|
| 750 | 782 | else |
|---|
| 751 | 783 | err = tipc_udp_rcast_add(b, &remote); |
|---|
| 752 | 784 | if (err) |
|---|
| 753 | | - goto err; |
|---|
| 785 | + goto free; |
|---|
| 754 | 786 | |
|---|
| 755 | 787 | return 0; |
|---|
| 788 | + |
|---|
| 789 | +free: |
|---|
| 790 | + dst_cache_destroy(&ub->rcast.dst_cache); |
|---|
| 791 | + udp_tunnel_sock_release(ub->ubsock); |
|---|
| 756 | 792 | err: |
|---|
| 757 | | - if (ub->ubsock) |
|---|
| 758 | | - udp_tunnel_sock_release(ub->ubsock); |
|---|
| 759 | 793 | kfree(ub); |
|---|
| 760 | 794 | return err; |
|---|
| 761 | 795 | } |
|---|
| .. | .. |
|---|
| 767 | 801 | struct udp_replicast *rcast, *tmp; |
|---|
| 768 | 802 | |
|---|
| 769 | 803 | list_for_each_entry_safe(rcast, tmp, &ub->rcast.list, list) { |
|---|
| 804 | + dst_cache_destroy(&rcast->dst_cache); |
|---|
| 770 | 805 | list_del_rcu(&rcast->list); |
|---|
| 771 | 806 | kfree_rcu(rcast, rcu); |
|---|
| 772 | 807 | } |
|---|
| 773 | 808 | |
|---|
| 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); |
|---|
| 776 | 812 | synchronize_net(); |
|---|
| 777 | 813 | kfree(ub); |
|---|
| 778 | 814 | } |
|---|
| .. | .. |
|---|
| 782 | 818 | { |
|---|
| 783 | 819 | struct udp_bearer *ub; |
|---|
| 784 | 820 | |
|---|
| 785 | | - ub = rcu_dereference_rtnl(b->media_ptr); |
|---|
| 821 | + ub = rtnl_dereference(b->media_ptr); |
|---|
| 786 | 822 | if (!ub) { |
|---|
| 787 | 823 | pr_err("UDP bearer instance not found\n"); |
|---|
| 788 | 824 | return; |
|---|
| 789 | 825 | } |
|---|
| 790 | | - if (ub->ubsock) |
|---|
| 791 | | - sock_set_flag(ub->ubsock->sk, SOCK_DEAD); |
|---|
| 826 | + sock_set_flag(ub->ubsock->sk, SOCK_DEAD); |
|---|
| 792 | 827 | RCU_INIT_POINTER(ub->bearer, NULL); |
|---|
| 793 | 828 | |
|---|
| 794 | 829 | /* sock_release need to be done outside of rtnl lock */ |
|---|
| 830 | + atomic_inc(&tipc_net(sock_net(ub->ubsock->sk))->wq_count); |
|---|
| 795 | 831 | INIT_WORK(&ub->work, cleanup_bearer); |
|---|
| 796 | 832 | schedule_work(&ub->work); |
|---|
| 797 | 833 | } |
|---|
| .. | .. |
|---|
| 805 | 841 | .msg2addr = tipc_udp_msg2addr, |
|---|
| 806 | 842 | .priority = TIPC_DEF_LINK_PRI, |
|---|
| 807 | 843 | .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, |
|---|
| 809 | 846 | .mtu = TIPC_DEF_LINK_UDP_MTU, |
|---|
| 810 | 847 | .type_id = TIPC_MEDIA_TYPE_UDP, |
|---|
| 811 | 848 | .hwaddr_len = 0, |
|---|