Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'mptcp-ipv4-mapped-ipv6-addressing-for-subflows'

Mat Martineau says:

====================
MPTCP: IPv4-mapped IPv6 addressing for subflows

This patch series from the MPTCP tree adds support for IPv4-mapped IPv6
addressing that was missing when multiple subflows were first
implemented.

Patches 1 and 2 handle the conversion and comparison of the mapped
addresses.

Patch 3 contains a minor refactor in the path manager's handling of
addresses.

Patches 4 and 5 add selftests for the new functionality and adjust the
selftest timeout.
====================

Link: https://lore.kernel.org/r/20210125185904.6997-1-mathew.j.martineau@linux.intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+120 -20
+27 -12
net/mptcp/pm_netlink.c
··· 60 60 { 61 61 bool addr_equals = false; 62 62 63 - if (a->family != b->family) 64 - return false; 65 - 66 - if (a->family == AF_INET) 67 - addr_equals = a->addr.s_addr == b->addr.s_addr; 63 + if (a->family == b->family) { 64 + if (a->family == AF_INET) 65 + addr_equals = a->addr.s_addr == b->addr.s_addr; 68 66 #if IS_ENABLED(CONFIG_MPTCP_IPV6) 69 - else 70 - addr_equals = !ipv6_addr_cmp(&a->addr6, &b->addr6); 67 + else 68 + addr_equals = !ipv6_addr_cmp(&a->addr6, &b->addr6); 69 + } else if (a->family == AF_INET) { 70 + if (ipv6_addr_v4mapped(&b->addr6)) 71 + addr_equals = a->addr.s_addr == b->addr6.s6_addr32[3]; 72 + } else if (b->family == AF_INET) { 73 + if (ipv6_addr_v4mapped(&a->addr6)) 74 + addr_equals = a->addr6.s6_addr32[3] == b->addr.s_addr; 71 75 #endif 76 + } 72 77 73 78 if (!addr_equals) 74 79 return false; ··· 142 137 struct mptcp_sock *msk) 143 138 { 144 139 struct mptcp_pm_addr_entry *entry, *ret = NULL; 140 + struct sock *sk = (struct sock *)msk; 145 141 146 142 rcu_read_lock(); 147 143 __mptcp_flush_join_list(msk); ··· 150 144 if (!(entry->addr.flags & MPTCP_PM_ADDR_FLAG_SUBFLOW)) 151 145 continue; 152 146 147 + if (entry->addr.family != sk->sk_family) { 148 + #if IS_ENABLED(CONFIG_MPTCP_IPV6) 149 + if ((entry->addr.family == AF_INET && 150 + !ipv6_addr_v4mapped(&sk->sk_v6_daddr)) || 151 + (sk->sk_family == AF_INET && 152 + !ipv6_addr_v4mapped(&entry->addr.addr6))) 153 + #endif 154 + continue; 155 + } 156 + 153 157 /* avoid any address already in use by subflows and 154 158 * pending join 155 159 */ 156 - if (entry->addr.family == ((struct sock *)msk)->sk_family && 157 - !lookup_subflow_by_saddr(&msk->conn_list, &entry->addr)) { 160 + if (!lookup_subflow_by_saddr(&msk->conn_list, &entry->addr)) { 158 161 ret = entry; 159 162 break; 160 163 } ··· 325 310 326 311 static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) 327 312 { 328 - struct mptcp_addr_info remote = { 0 }; 329 313 struct sock *sk = (struct sock *)msk; 330 314 struct mptcp_pm_addr_entry *local; 331 315 struct pm_nl_pernet *pernet; ··· 358 344 /* check if should create a new subflow */ 359 345 if (msk->pm.local_addr_used < msk->pm.local_addr_max && 360 346 msk->pm.subflows < msk->pm.subflows_max) { 361 - remote_address((struct sock_common *)sk, &remote); 362 - 363 347 local = select_local_address(pernet, msk); 364 348 if (local) { 349 + struct mptcp_addr_info remote = { 0 }; 350 + 365 351 msk->pm.local_addr_used++; 366 352 msk->pm.subflows++; 367 353 check_work_pending(msk); 354 + remote_address((struct sock_common *)sk, &remote); 368 355 spin_unlock_bh(&msk->pm.lock); 369 356 __mptcp_subflow_connect(sk, &local->addr, &remote); 370 357 spin_lock_bh(&msk->pm.lock);
+17 -7
net/mptcp/subflow.c
··· 1085 1085 #endif 1086 1086 1087 1087 static void mptcp_info2sockaddr(const struct mptcp_addr_info *info, 1088 - struct sockaddr_storage *addr) 1088 + struct sockaddr_storage *addr, 1089 + unsigned short family) 1089 1090 { 1090 1091 memset(addr, 0, sizeof(*addr)); 1091 - addr->ss_family = info->family; 1092 + addr->ss_family = family; 1092 1093 if (addr->ss_family == AF_INET) { 1093 1094 struct sockaddr_in *in_addr = (struct sockaddr_in *)addr; 1094 1095 1095 - in_addr->sin_addr = info->addr; 1096 + if (info->family == AF_INET) 1097 + in_addr->sin_addr = info->addr; 1098 + #if IS_ENABLED(CONFIG_MPTCP_IPV6) 1099 + else if (ipv6_addr_v4mapped(&info->addr6)) 1100 + in_addr->sin_addr.s_addr = info->addr6.s6_addr32[3]; 1101 + #endif 1096 1102 in_addr->sin_port = info->port; 1097 1103 } 1098 1104 #if IS_ENABLED(CONFIG_MPTCP_IPV6) 1099 1105 else if (addr->ss_family == AF_INET6) { 1100 1106 struct sockaddr_in6 *in6_addr = (struct sockaddr_in6 *)addr; 1101 1107 1102 - in6_addr->sin6_addr = info->addr6; 1108 + if (info->family == AF_INET) 1109 + ipv6_addr_set_v4mapped(info->addr.s_addr, 1110 + &in6_addr->sin6_addr); 1111 + else 1112 + in6_addr->sin6_addr = info->addr6; 1103 1113 in6_addr->sin6_port = info->port; 1104 1114 } 1105 1115 #endif ··· 1153 1143 subflow->remote_key = msk->remote_key; 1154 1144 subflow->local_key = msk->local_key; 1155 1145 subflow->token = msk->token; 1156 - mptcp_info2sockaddr(loc, &addr); 1146 + mptcp_info2sockaddr(loc, &addr, ssk->sk_family); 1157 1147 1158 1148 addrlen = sizeof(struct sockaddr_in); 1159 1149 #if IS_ENABLED(CONFIG_MPTCP_IPV6) 1160 - if (loc->family == AF_INET6) 1150 + if (addr.ss_family == AF_INET6) 1161 1151 addrlen = sizeof(struct sockaddr_in6); 1162 1152 #endif 1163 1153 ssk->sk_bound_dev_if = loc->ifindex; ··· 1173 1163 subflow->remote_id = remote_id; 1174 1164 subflow->request_join = 1; 1175 1165 subflow->request_bkup = !!(loc->flags & MPTCP_PM_ADDR_FLAG_BACKUP); 1176 - mptcp_info2sockaddr(remote, &addr); 1166 + mptcp_info2sockaddr(remote, &addr, ssk->sk_family); 1177 1167 1178 1168 mptcp_add_pending_subflow(msk, subflow); 1179 1169 err = kernel_connect(sf, (struct sockaddr *)&addr, addrlen, O_NONBLOCK);
+75
tools/testing/selftests/net/mptcp/mptcp_join.sh
··· 790 790 chk_add_nr 1 1 791 791 chk_rm_nr 1 1 792 792 793 + # subflow IPv4-mapped to IPv4-mapped 794 + reset 795 + ip netns exec $ns1 ./pm_nl_ctl limits 0 1 796 + ip netns exec $ns2 ./pm_nl_ctl limits 0 1 797 + ip netns exec $ns2 ./pm_nl_ctl add "::ffff:10.0.3.2" flags subflow 798 + run_tests $ns1 $ns2 "::ffff:10.0.1.1" 799 + chk_join_nr "single subflow IPv4-mapped" 1 1 1 800 + 801 + # signal address IPv4-mapped with IPv4-mapped sk 802 + reset 803 + ip netns exec $ns1 ./pm_nl_ctl limits 0 1 804 + ip netns exec $ns2 ./pm_nl_ctl limits 1 1 805 + ip netns exec $ns1 ./pm_nl_ctl add "::ffff:10.0.2.1" flags signal 806 + run_tests $ns1 $ns2 "::ffff:10.0.1.1" 807 + chk_join_nr "signal address IPv4-mapped" 1 1 1 808 + chk_add_nr 1 1 809 + 810 + # subflow v4-map-v6 811 + reset 812 + ip netns exec $ns1 ./pm_nl_ctl limits 0 1 813 + ip netns exec $ns2 ./pm_nl_ctl limits 0 1 814 + ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 815 + run_tests $ns1 $ns2 "::ffff:10.0.1.1" 816 + chk_join_nr "single subflow v4-map-v6" 1 1 1 817 + 818 + # signal address v4-map-v6 819 + reset 820 + ip netns exec $ns1 ./pm_nl_ctl limits 0 1 821 + ip netns exec $ns2 ./pm_nl_ctl limits 1 1 822 + ip netns exec $ns1 ./pm_nl_ctl add 10.0.2.1 flags signal 823 + run_tests $ns1 $ns2 "::ffff:10.0.1.1" 824 + chk_join_nr "signal address v4-map-v6" 1 1 1 825 + chk_add_nr 1 1 826 + 827 + # subflow v6-map-v4 828 + reset 829 + ip netns exec $ns1 ./pm_nl_ctl limits 0 1 830 + ip netns exec $ns2 ./pm_nl_ctl limits 0 1 831 + ip netns exec $ns2 ./pm_nl_ctl add "::ffff:10.0.3.2" flags subflow 832 + run_tests $ns1 $ns2 10.0.1.1 833 + chk_join_nr "single subflow v6-map-v4" 1 1 1 834 + 835 + # signal address v6-map-v4 836 + reset 837 + ip netns exec $ns1 ./pm_nl_ctl limits 0 1 838 + ip netns exec $ns2 ./pm_nl_ctl limits 1 1 839 + ip netns exec $ns1 ./pm_nl_ctl add "::ffff:10.0.2.1" flags signal 840 + run_tests $ns1 $ns2 10.0.1.1 841 + chk_join_nr "signal address v6-map-v4" 1 1 1 842 + chk_add_nr 1 1 843 + 844 + # no subflow IPv6 to v4 address 845 + reset 846 + ip netns exec $ns1 ./pm_nl_ctl limits 0 1 847 + ip netns exec $ns2 ./pm_nl_ctl limits 0 1 848 + ip netns exec $ns2 ./pm_nl_ctl add dead:beef:2::2 flags subflow 849 + run_tests $ns1 $ns2 10.0.1.1 850 + chk_join_nr "no JOIN with diff families v4-v6" 0 0 0 851 + 852 + # no subflow IPv6 to v4 address even if v6 has a valid v4 at the end 853 + reset 854 + ip netns exec $ns1 ./pm_nl_ctl limits 0 1 855 + ip netns exec $ns2 ./pm_nl_ctl limits 0 1 856 + ip netns exec $ns2 ./pm_nl_ctl add dead:beef:2::10.0.3.2 flags subflow 857 + run_tests $ns1 $ns2 10.0.1.1 858 + chk_join_nr "no JOIN with diff families v4-v6-2" 0 0 0 859 + 860 + # no subflow IPv4 to v6 address, no need to slow down too then 861 + reset 862 + ip netns exec $ns1 ./pm_nl_ctl limits 0 1 863 + ip netns exec $ns2 ./pm_nl_ctl limits 0 1 864 + ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow 865 + run_tests $ns1 $ns2 dead:beef:1::1 866 + chk_join_nr "no JOIN with diff families v6-v4" 0 0 0 867 + 793 868 # single subflow, backup 794 869 reset 795 870 ip netns exec $ns1 ./pm_nl_ctl limits 0 1
+1 -1
tools/testing/selftests/net/mptcp/settings
··· 1 - timeout=450 1 + timeout=600