1*8617e85eSMatthieu Baerts (NGI0) // SPDX-License-Identifier: GPL-2.0 2*8617e85eSMatthieu Baerts (NGI0) /* Multipath TCP 3*8617e85eSMatthieu Baerts (NGI0) * 4*8617e85eSMatthieu Baerts (NGI0) * Copyright (c) 2025, Matthieu Baerts. 5*8617e85eSMatthieu Baerts (NGI0) */ 6*8617e85eSMatthieu Baerts (NGI0) 7*8617e85eSMatthieu Baerts (NGI0) #define pr_fmt(fmt) "MPTCP: " fmt 8*8617e85eSMatthieu Baerts (NGI0) 9*8617e85eSMatthieu Baerts (NGI0) #include <net/netns/generic.h> 10*8617e85eSMatthieu Baerts (NGI0) 11*8617e85eSMatthieu Baerts (NGI0) #include "protocol.h" 12*8617e85eSMatthieu Baerts (NGI0) #include "mib.h" 13*8617e85eSMatthieu Baerts (NGI0) #include "mptcp_pm_gen.h" 14*8617e85eSMatthieu Baerts (NGI0) 15*8617e85eSMatthieu Baerts (NGI0) static int pm_nl_pernet_id; 16*8617e85eSMatthieu Baerts (NGI0) 17*8617e85eSMatthieu Baerts (NGI0) struct pm_nl_pernet { 18*8617e85eSMatthieu Baerts (NGI0) /* protects pernet updates */ 19*8617e85eSMatthieu Baerts (NGI0) spinlock_t lock; 20*8617e85eSMatthieu Baerts (NGI0) struct list_head local_addr_list; 21*8617e85eSMatthieu Baerts (NGI0) unsigned int addrs; 22*8617e85eSMatthieu Baerts (NGI0) unsigned int stale_loss_cnt; 23*8617e85eSMatthieu Baerts (NGI0) unsigned int add_addr_signal_max; 24*8617e85eSMatthieu Baerts (NGI0) unsigned int add_addr_accept_max; 25*8617e85eSMatthieu Baerts (NGI0) unsigned int local_addr_max; 26*8617e85eSMatthieu Baerts (NGI0) unsigned int subflows_max; 27*8617e85eSMatthieu Baerts (NGI0) unsigned int next_id; 28*8617e85eSMatthieu Baerts (NGI0) DECLARE_BITMAP(id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1); 29*8617e85eSMatthieu Baerts (NGI0) }; 30*8617e85eSMatthieu Baerts (NGI0) 31*8617e85eSMatthieu Baerts (NGI0) #define MPTCP_PM_ADDR_MAX 8 32*8617e85eSMatthieu Baerts (NGI0) 33*8617e85eSMatthieu Baerts (NGI0) static struct pm_nl_pernet *pm_nl_get_pernet(const struct net *net) 34*8617e85eSMatthieu Baerts (NGI0) { 35*8617e85eSMatthieu Baerts (NGI0) return net_generic(net, pm_nl_pernet_id); 36*8617e85eSMatthieu Baerts (NGI0) } 37*8617e85eSMatthieu Baerts (NGI0) 38*8617e85eSMatthieu Baerts (NGI0) static struct pm_nl_pernet * 39*8617e85eSMatthieu Baerts (NGI0) pm_nl_get_pernet_from_msk(const struct mptcp_sock *msk) 40*8617e85eSMatthieu Baerts (NGI0) { 41*8617e85eSMatthieu Baerts (NGI0) return pm_nl_get_pernet(sock_net((struct sock *)msk)); 42*8617e85eSMatthieu Baerts (NGI0) } 43*8617e85eSMatthieu Baerts (NGI0) 44*8617e85eSMatthieu Baerts (NGI0) static struct pm_nl_pernet *genl_info_pm_nl(struct genl_info *info) 45*8617e85eSMatthieu Baerts (NGI0) { 46*8617e85eSMatthieu Baerts (NGI0) return pm_nl_get_pernet(genl_info_net(info)); 47*8617e85eSMatthieu Baerts (NGI0) } 48*8617e85eSMatthieu Baerts (NGI0) 49*8617e85eSMatthieu Baerts (NGI0) unsigned int mptcp_pm_get_add_addr_signal_max(const struct mptcp_sock *msk) 50*8617e85eSMatthieu Baerts (NGI0) { 51*8617e85eSMatthieu Baerts (NGI0) const struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk); 52*8617e85eSMatthieu Baerts (NGI0) 53*8617e85eSMatthieu Baerts (NGI0) return READ_ONCE(pernet->add_addr_signal_max); 54*8617e85eSMatthieu Baerts (NGI0) } 55*8617e85eSMatthieu Baerts (NGI0) EXPORT_SYMBOL_GPL(mptcp_pm_get_add_addr_signal_max); 56*8617e85eSMatthieu Baerts (NGI0) 57*8617e85eSMatthieu Baerts (NGI0) unsigned int mptcp_pm_get_add_addr_accept_max(const struct mptcp_sock *msk) 58*8617e85eSMatthieu Baerts (NGI0) { 59*8617e85eSMatthieu Baerts (NGI0) struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk); 60*8617e85eSMatthieu Baerts (NGI0) 61*8617e85eSMatthieu Baerts (NGI0) return READ_ONCE(pernet->add_addr_accept_max); 62*8617e85eSMatthieu Baerts (NGI0) } 63*8617e85eSMatthieu Baerts (NGI0) EXPORT_SYMBOL_GPL(mptcp_pm_get_add_addr_accept_max); 64*8617e85eSMatthieu Baerts (NGI0) 65*8617e85eSMatthieu Baerts (NGI0) unsigned int mptcp_pm_get_subflows_max(const struct mptcp_sock *msk) 66*8617e85eSMatthieu Baerts (NGI0) { 67*8617e85eSMatthieu Baerts (NGI0) struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk); 68*8617e85eSMatthieu Baerts (NGI0) 69*8617e85eSMatthieu Baerts (NGI0) return READ_ONCE(pernet->subflows_max); 70*8617e85eSMatthieu Baerts (NGI0) } 71*8617e85eSMatthieu Baerts (NGI0) EXPORT_SYMBOL_GPL(mptcp_pm_get_subflows_max); 72*8617e85eSMatthieu Baerts (NGI0) 73*8617e85eSMatthieu Baerts (NGI0) unsigned int mptcp_pm_get_local_addr_max(const struct mptcp_sock *msk) 74*8617e85eSMatthieu Baerts (NGI0) { 75*8617e85eSMatthieu Baerts (NGI0) struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk); 76*8617e85eSMatthieu Baerts (NGI0) 77*8617e85eSMatthieu Baerts (NGI0) return READ_ONCE(pernet->local_addr_max); 78*8617e85eSMatthieu Baerts (NGI0) } 79*8617e85eSMatthieu Baerts (NGI0) EXPORT_SYMBOL_GPL(mptcp_pm_get_local_addr_max); 80*8617e85eSMatthieu Baerts (NGI0) 81*8617e85eSMatthieu Baerts (NGI0) static bool lookup_subflow_by_daddr(const struct list_head *list, 82*8617e85eSMatthieu Baerts (NGI0) const struct mptcp_addr_info *daddr) 83*8617e85eSMatthieu Baerts (NGI0) { 84*8617e85eSMatthieu Baerts (NGI0) struct mptcp_subflow_context *subflow; 85*8617e85eSMatthieu Baerts (NGI0) struct mptcp_addr_info cur; 86*8617e85eSMatthieu Baerts (NGI0) 87*8617e85eSMatthieu Baerts (NGI0) list_for_each_entry(subflow, list, node) { 88*8617e85eSMatthieu Baerts (NGI0) struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 89*8617e85eSMatthieu Baerts (NGI0) 90*8617e85eSMatthieu Baerts (NGI0) if (!((1 << inet_sk_state_load(ssk)) & 91*8617e85eSMatthieu Baerts (NGI0) (TCPF_ESTABLISHED | TCPF_SYN_SENT | TCPF_SYN_RECV))) 92*8617e85eSMatthieu Baerts (NGI0) continue; 93*8617e85eSMatthieu Baerts (NGI0) 94*8617e85eSMatthieu Baerts (NGI0) mptcp_remote_address((struct sock_common *)ssk, &cur); 95*8617e85eSMatthieu Baerts (NGI0) if (mptcp_addresses_equal(&cur, daddr, daddr->port)) 96*8617e85eSMatthieu Baerts (NGI0) return true; 97*8617e85eSMatthieu Baerts (NGI0) } 98*8617e85eSMatthieu Baerts (NGI0) 99*8617e85eSMatthieu Baerts (NGI0) return false; 100*8617e85eSMatthieu Baerts (NGI0) } 101*8617e85eSMatthieu Baerts (NGI0) 102*8617e85eSMatthieu Baerts (NGI0) static bool 103*8617e85eSMatthieu Baerts (NGI0) select_local_address(const struct pm_nl_pernet *pernet, 104*8617e85eSMatthieu Baerts (NGI0) const struct mptcp_sock *msk, 105*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_local *new_local) 106*8617e85eSMatthieu Baerts (NGI0) { 107*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_addr_entry *entry; 108*8617e85eSMatthieu Baerts (NGI0) bool found = false; 109*8617e85eSMatthieu Baerts (NGI0) 110*8617e85eSMatthieu Baerts (NGI0) msk_owned_by_me(msk); 111*8617e85eSMatthieu Baerts (NGI0) 112*8617e85eSMatthieu Baerts (NGI0) rcu_read_lock(); 113*8617e85eSMatthieu Baerts (NGI0) list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) { 114*8617e85eSMatthieu Baerts (NGI0) if (!(entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW)) 115*8617e85eSMatthieu Baerts (NGI0) continue; 116*8617e85eSMatthieu Baerts (NGI0) 117*8617e85eSMatthieu Baerts (NGI0) if (!test_bit(entry->addr.id, msk->pm.id_avail_bitmap)) 118*8617e85eSMatthieu Baerts (NGI0) continue; 119*8617e85eSMatthieu Baerts (NGI0) 120*8617e85eSMatthieu Baerts (NGI0) new_local->addr = entry->addr; 121*8617e85eSMatthieu Baerts (NGI0) new_local->flags = entry->flags; 122*8617e85eSMatthieu Baerts (NGI0) new_local->ifindex = entry->ifindex; 123*8617e85eSMatthieu Baerts (NGI0) found = true; 124*8617e85eSMatthieu Baerts (NGI0) break; 125*8617e85eSMatthieu Baerts (NGI0) } 126*8617e85eSMatthieu Baerts (NGI0) rcu_read_unlock(); 127*8617e85eSMatthieu Baerts (NGI0) 128*8617e85eSMatthieu Baerts (NGI0) return found; 129*8617e85eSMatthieu Baerts (NGI0) } 130*8617e85eSMatthieu Baerts (NGI0) 131*8617e85eSMatthieu Baerts (NGI0) static bool 132*8617e85eSMatthieu Baerts (NGI0) select_signal_address(struct pm_nl_pernet *pernet, const struct mptcp_sock *msk, 133*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_local *new_local) 134*8617e85eSMatthieu Baerts (NGI0) { 135*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_addr_entry *entry; 136*8617e85eSMatthieu Baerts (NGI0) bool found = false; 137*8617e85eSMatthieu Baerts (NGI0) 138*8617e85eSMatthieu Baerts (NGI0) rcu_read_lock(); 139*8617e85eSMatthieu Baerts (NGI0) /* do not keep any additional per socket state, just signal 140*8617e85eSMatthieu Baerts (NGI0) * the address list in order. 141*8617e85eSMatthieu Baerts (NGI0) * Note: removal from the local address list during the msk life-cycle 142*8617e85eSMatthieu Baerts (NGI0) * can lead to additional addresses not being announced. 143*8617e85eSMatthieu Baerts (NGI0) */ 144*8617e85eSMatthieu Baerts (NGI0) list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) { 145*8617e85eSMatthieu Baerts (NGI0) if (!test_bit(entry->addr.id, msk->pm.id_avail_bitmap)) 146*8617e85eSMatthieu Baerts (NGI0) continue; 147*8617e85eSMatthieu Baerts (NGI0) 148*8617e85eSMatthieu Baerts (NGI0) if (!(entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL)) 149*8617e85eSMatthieu Baerts (NGI0) continue; 150*8617e85eSMatthieu Baerts (NGI0) 151*8617e85eSMatthieu Baerts (NGI0) new_local->addr = entry->addr; 152*8617e85eSMatthieu Baerts (NGI0) new_local->flags = entry->flags; 153*8617e85eSMatthieu Baerts (NGI0) new_local->ifindex = entry->ifindex; 154*8617e85eSMatthieu Baerts (NGI0) found = true; 155*8617e85eSMatthieu Baerts (NGI0) break; 156*8617e85eSMatthieu Baerts (NGI0) } 157*8617e85eSMatthieu Baerts (NGI0) rcu_read_unlock(); 158*8617e85eSMatthieu Baerts (NGI0) 159*8617e85eSMatthieu Baerts (NGI0) return found; 160*8617e85eSMatthieu Baerts (NGI0) } 161*8617e85eSMatthieu Baerts (NGI0) 162*8617e85eSMatthieu Baerts (NGI0) /* Fill all the remote addresses into the array addrs[], 163*8617e85eSMatthieu Baerts (NGI0) * and return the array size. 164*8617e85eSMatthieu Baerts (NGI0) */ 165*8617e85eSMatthieu Baerts (NGI0) static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk, 166*8617e85eSMatthieu Baerts (NGI0) struct mptcp_addr_info *local, 167*8617e85eSMatthieu Baerts (NGI0) bool fullmesh, 168*8617e85eSMatthieu Baerts (NGI0) struct mptcp_addr_info *addrs) 169*8617e85eSMatthieu Baerts (NGI0) { 170*8617e85eSMatthieu Baerts (NGI0) bool deny_id0 = READ_ONCE(msk->pm.remote_deny_join_id0); 171*8617e85eSMatthieu Baerts (NGI0) struct sock *sk = (struct sock *)msk, *ssk; 172*8617e85eSMatthieu Baerts (NGI0) struct mptcp_subflow_context *subflow; 173*8617e85eSMatthieu Baerts (NGI0) struct mptcp_addr_info remote = { 0 }; 174*8617e85eSMatthieu Baerts (NGI0) unsigned int subflows_max; 175*8617e85eSMatthieu Baerts (NGI0) int i = 0; 176*8617e85eSMatthieu Baerts (NGI0) 177*8617e85eSMatthieu Baerts (NGI0) subflows_max = mptcp_pm_get_subflows_max(msk); 178*8617e85eSMatthieu Baerts (NGI0) mptcp_remote_address((struct sock_common *)sk, &remote); 179*8617e85eSMatthieu Baerts (NGI0) 180*8617e85eSMatthieu Baerts (NGI0) /* Non-fullmesh endpoint, fill in the single entry 181*8617e85eSMatthieu Baerts (NGI0) * corresponding to the primary MPC subflow remote address 182*8617e85eSMatthieu Baerts (NGI0) */ 183*8617e85eSMatthieu Baerts (NGI0) if (!fullmesh) { 184*8617e85eSMatthieu Baerts (NGI0) if (deny_id0) 185*8617e85eSMatthieu Baerts (NGI0) return 0; 186*8617e85eSMatthieu Baerts (NGI0) 187*8617e85eSMatthieu Baerts (NGI0) if (!mptcp_pm_addr_families_match(sk, local, &remote)) 188*8617e85eSMatthieu Baerts (NGI0) return 0; 189*8617e85eSMatthieu Baerts (NGI0) 190*8617e85eSMatthieu Baerts (NGI0) msk->pm.subflows++; 191*8617e85eSMatthieu Baerts (NGI0) addrs[i++] = remote; 192*8617e85eSMatthieu Baerts (NGI0) } else { 193*8617e85eSMatthieu Baerts (NGI0) DECLARE_BITMAP(unavail_id, MPTCP_PM_MAX_ADDR_ID + 1); 194*8617e85eSMatthieu Baerts (NGI0) 195*8617e85eSMatthieu Baerts (NGI0) /* Forbid creation of new subflows matching existing 196*8617e85eSMatthieu Baerts (NGI0) * ones, possibly already created by incoming ADD_ADDR 197*8617e85eSMatthieu Baerts (NGI0) */ 198*8617e85eSMatthieu Baerts (NGI0) bitmap_zero(unavail_id, MPTCP_PM_MAX_ADDR_ID + 1); 199*8617e85eSMatthieu Baerts (NGI0) mptcp_for_each_subflow(msk, subflow) 200*8617e85eSMatthieu Baerts (NGI0) if (READ_ONCE(subflow->local_id) == local->id) 201*8617e85eSMatthieu Baerts (NGI0) __set_bit(subflow->remote_id, unavail_id); 202*8617e85eSMatthieu Baerts (NGI0) 203*8617e85eSMatthieu Baerts (NGI0) mptcp_for_each_subflow(msk, subflow) { 204*8617e85eSMatthieu Baerts (NGI0) ssk = mptcp_subflow_tcp_sock(subflow); 205*8617e85eSMatthieu Baerts (NGI0) mptcp_remote_address((struct sock_common *)ssk, &addrs[i]); 206*8617e85eSMatthieu Baerts (NGI0) addrs[i].id = READ_ONCE(subflow->remote_id); 207*8617e85eSMatthieu Baerts (NGI0) if (deny_id0 && !addrs[i].id) 208*8617e85eSMatthieu Baerts (NGI0) continue; 209*8617e85eSMatthieu Baerts (NGI0) 210*8617e85eSMatthieu Baerts (NGI0) if (test_bit(addrs[i].id, unavail_id)) 211*8617e85eSMatthieu Baerts (NGI0) continue; 212*8617e85eSMatthieu Baerts (NGI0) 213*8617e85eSMatthieu Baerts (NGI0) if (!mptcp_pm_addr_families_match(sk, local, &addrs[i])) 214*8617e85eSMatthieu Baerts (NGI0) continue; 215*8617e85eSMatthieu Baerts (NGI0) 216*8617e85eSMatthieu Baerts (NGI0) if (msk->pm.subflows < subflows_max) { 217*8617e85eSMatthieu Baerts (NGI0) /* forbid creating multiple address towards 218*8617e85eSMatthieu Baerts (NGI0) * this id 219*8617e85eSMatthieu Baerts (NGI0) */ 220*8617e85eSMatthieu Baerts (NGI0) __set_bit(addrs[i].id, unavail_id); 221*8617e85eSMatthieu Baerts (NGI0) msk->pm.subflows++; 222*8617e85eSMatthieu Baerts (NGI0) i++; 223*8617e85eSMatthieu Baerts (NGI0) } 224*8617e85eSMatthieu Baerts (NGI0) } 225*8617e85eSMatthieu Baerts (NGI0) } 226*8617e85eSMatthieu Baerts (NGI0) 227*8617e85eSMatthieu Baerts (NGI0) return i; 228*8617e85eSMatthieu Baerts (NGI0) } 229*8617e85eSMatthieu Baerts (NGI0) 230*8617e85eSMatthieu Baerts (NGI0) static struct mptcp_pm_addr_entry * 231*8617e85eSMatthieu Baerts (NGI0) __lookup_addr_by_id(struct pm_nl_pernet *pernet, unsigned int id) 232*8617e85eSMatthieu Baerts (NGI0) { 233*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_addr_entry *entry; 234*8617e85eSMatthieu Baerts (NGI0) 235*8617e85eSMatthieu Baerts (NGI0) list_for_each_entry_rcu(entry, &pernet->local_addr_list, list, 236*8617e85eSMatthieu Baerts (NGI0) lockdep_is_held(&pernet->lock)) { 237*8617e85eSMatthieu Baerts (NGI0) if (entry->addr.id == id) 238*8617e85eSMatthieu Baerts (NGI0) return entry; 239*8617e85eSMatthieu Baerts (NGI0) } 240*8617e85eSMatthieu Baerts (NGI0) return NULL; 241*8617e85eSMatthieu Baerts (NGI0) } 242*8617e85eSMatthieu Baerts (NGI0) 243*8617e85eSMatthieu Baerts (NGI0) static struct mptcp_pm_addr_entry * 244*8617e85eSMatthieu Baerts (NGI0) __lookup_addr(struct pm_nl_pernet *pernet, const struct mptcp_addr_info *info) 245*8617e85eSMatthieu Baerts (NGI0) { 246*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_addr_entry *entry; 247*8617e85eSMatthieu Baerts (NGI0) 248*8617e85eSMatthieu Baerts (NGI0) list_for_each_entry_rcu(entry, &pernet->local_addr_list, list, 249*8617e85eSMatthieu Baerts (NGI0) lockdep_is_held(&pernet->lock)) { 250*8617e85eSMatthieu Baerts (NGI0) if (mptcp_addresses_equal(&entry->addr, info, entry->addr.port)) 251*8617e85eSMatthieu Baerts (NGI0) return entry; 252*8617e85eSMatthieu Baerts (NGI0) } 253*8617e85eSMatthieu Baerts (NGI0) return NULL; 254*8617e85eSMatthieu Baerts (NGI0) } 255*8617e85eSMatthieu Baerts (NGI0) 256*8617e85eSMatthieu Baerts (NGI0) static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) 257*8617e85eSMatthieu Baerts (NGI0) { 258*8617e85eSMatthieu Baerts (NGI0) struct sock *sk = (struct sock *)msk; 259*8617e85eSMatthieu Baerts (NGI0) unsigned int add_addr_signal_max; 260*8617e85eSMatthieu Baerts (NGI0) bool signal_and_subflow = false; 261*8617e85eSMatthieu Baerts (NGI0) unsigned int local_addr_max; 262*8617e85eSMatthieu Baerts (NGI0) struct pm_nl_pernet *pernet; 263*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_local local; 264*8617e85eSMatthieu Baerts (NGI0) unsigned int subflows_max; 265*8617e85eSMatthieu Baerts (NGI0) 266*8617e85eSMatthieu Baerts (NGI0) pernet = pm_nl_get_pernet(sock_net(sk)); 267*8617e85eSMatthieu Baerts (NGI0) 268*8617e85eSMatthieu Baerts (NGI0) add_addr_signal_max = mptcp_pm_get_add_addr_signal_max(msk); 269*8617e85eSMatthieu Baerts (NGI0) local_addr_max = mptcp_pm_get_local_addr_max(msk); 270*8617e85eSMatthieu Baerts (NGI0) subflows_max = mptcp_pm_get_subflows_max(msk); 271*8617e85eSMatthieu Baerts (NGI0) 272*8617e85eSMatthieu Baerts (NGI0) /* do lazy endpoint usage accounting for the MPC subflows */ 273*8617e85eSMatthieu Baerts (NGI0) if (unlikely(!(msk->pm.status & BIT(MPTCP_PM_MPC_ENDPOINT_ACCOUNTED))) && msk->first) { 274*8617e85eSMatthieu Baerts (NGI0) struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(msk->first); 275*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_addr_entry *entry; 276*8617e85eSMatthieu Baerts (NGI0) struct mptcp_addr_info mpc_addr; 277*8617e85eSMatthieu Baerts (NGI0) bool backup = false; 278*8617e85eSMatthieu Baerts (NGI0) 279*8617e85eSMatthieu Baerts (NGI0) mptcp_local_address((struct sock_common *)msk->first, &mpc_addr); 280*8617e85eSMatthieu Baerts (NGI0) rcu_read_lock(); 281*8617e85eSMatthieu Baerts (NGI0) entry = __lookup_addr(pernet, &mpc_addr); 282*8617e85eSMatthieu Baerts (NGI0) if (entry) { 283*8617e85eSMatthieu Baerts (NGI0) __clear_bit(entry->addr.id, msk->pm.id_avail_bitmap); 284*8617e85eSMatthieu Baerts (NGI0) msk->mpc_endpoint_id = entry->addr.id; 285*8617e85eSMatthieu Baerts (NGI0) backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP); 286*8617e85eSMatthieu Baerts (NGI0) } 287*8617e85eSMatthieu Baerts (NGI0) rcu_read_unlock(); 288*8617e85eSMatthieu Baerts (NGI0) 289*8617e85eSMatthieu Baerts (NGI0) if (backup) 290*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_send_ack(msk, subflow, true, backup); 291*8617e85eSMatthieu Baerts (NGI0) 292*8617e85eSMatthieu Baerts (NGI0) msk->pm.status |= BIT(MPTCP_PM_MPC_ENDPOINT_ACCOUNTED); 293*8617e85eSMatthieu Baerts (NGI0) } 294*8617e85eSMatthieu Baerts (NGI0) 295*8617e85eSMatthieu Baerts (NGI0) pr_debug("local %d:%d signal %d:%d subflows %d:%d\n", 296*8617e85eSMatthieu Baerts (NGI0) msk->pm.local_addr_used, local_addr_max, 297*8617e85eSMatthieu Baerts (NGI0) msk->pm.add_addr_signaled, add_addr_signal_max, 298*8617e85eSMatthieu Baerts (NGI0) msk->pm.subflows, subflows_max); 299*8617e85eSMatthieu Baerts (NGI0) 300*8617e85eSMatthieu Baerts (NGI0) /* check first for announce */ 301*8617e85eSMatthieu Baerts (NGI0) if (msk->pm.add_addr_signaled < add_addr_signal_max) { 302*8617e85eSMatthieu Baerts (NGI0) /* due to racing events on both ends we can reach here while 303*8617e85eSMatthieu Baerts (NGI0) * previous add address is still running: if we invoke now 304*8617e85eSMatthieu Baerts (NGI0) * mptcp_pm_announce_addr(), that will fail and the 305*8617e85eSMatthieu Baerts (NGI0) * corresponding id will be marked as used. 306*8617e85eSMatthieu Baerts (NGI0) * Instead let the PM machinery reschedule us when the 307*8617e85eSMatthieu Baerts (NGI0) * current address announce will be completed. 308*8617e85eSMatthieu Baerts (NGI0) */ 309*8617e85eSMatthieu Baerts (NGI0) if (msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL)) 310*8617e85eSMatthieu Baerts (NGI0) return; 311*8617e85eSMatthieu Baerts (NGI0) 312*8617e85eSMatthieu Baerts (NGI0) if (!select_signal_address(pernet, msk, &local)) 313*8617e85eSMatthieu Baerts (NGI0) goto subflow; 314*8617e85eSMatthieu Baerts (NGI0) 315*8617e85eSMatthieu Baerts (NGI0) /* If the alloc fails, we are on memory pressure, not worth 316*8617e85eSMatthieu Baerts (NGI0) * continuing, and trying to create subflows. 317*8617e85eSMatthieu Baerts (NGI0) */ 318*8617e85eSMatthieu Baerts (NGI0) if (!mptcp_pm_alloc_anno_list(msk, &local.addr)) 319*8617e85eSMatthieu Baerts (NGI0) return; 320*8617e85eSMatthieu Baerts (NGI0) 321*8617e85eSMatthieu Baerts (NGI0) __clear_bit(local.addr.id, msk->pm.id_avail_bitmap); 322*8617e85eSMatthieu Baerts (NGI0) msk->pm.add_addr_signaled++; 323*8617e85eSMatthieu Baerts (NGI0) 324*8617e85eSMatthieu Baerts (NGI0) /* Special case for ID0: set the correct ID */ 325*8617e85eSMatthieu Baerts (NGI0) if (local.addr.id == msk->mpc_endpoint_id) 326*8617e85eSMatthieu Baerts (NGI0) local.addr.id = 0; 327*8617e85eSMatthieu Baerts (NGI0) 328*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_announce_addr(msk, &local.addr, false); 329*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_addr_send_ack(msk); 330*8617e85eSMatthieu Baerts (NGI0) 331*8617e85eSMatthieu Baerts (NGI0) if (local.flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) 332*8617e85eSMatthieu Baerts (NGI0) signal_and_subflow = true; 333*8617e85eSMatthieu Baerts (NGI0) } 334*8617e85eSMatthieu Baerts (NGI0) 335*8617e85eSMatthieu Baerts (NGI0) subflow: 336*8617e85eSMatthieu Baerts (NGI0) /* check if should create a new subflow */ 337*8617e85eSMatthieu Baerts (NGI0) while (msk->pm.local_addr_used < local_addr_max && 338*8617e85eSMatthieu Baerts (NGI0) msk->pm.subflows < subflows_max) { 339*8617e85eSMatthieu Baerts (NGI0) struct mptcp_addr_info addrs[MPTCP_PM_ADDR_MAX]; 340*8617e85eSMatthieu Baerts (NGI0) bool fullmesh; 341*8617e85eSMatthieu Baerts (NGI0) int i, nr; 342*8617e85eSMatthieu Baerts (NGI0) 343*8617e85eSMatthieu Baerts (NGI0) if (signal_and_subflow) 344*8617e85eSMatthieu Baerts (NGI0) signal_and_subflow = false; 345*8617e85eSMatthieu Baerts (NGI0) else if (!select_local_address(pernet, msk, &local)) 346*8617e85eSMatthieu Baerts (NGI0) break; 347*8617e85eSMatthieu Baerts (NGI0) 348*8617e85eSMatthieu Baerts (NGI0) fullmesh = !!(local.flags & MPTCP_PM_ADDR_FLAG_FULLMESH); 349*8617e85eSMatthieu Baerts (NGI0) 350*8617e85eSMatthieu Baerts (NGI0) __clear_bit(local.addr.id, msk->pm.id_avail_bitmap); 351*8617e85eSMatthieu Baerts (NGI0) 352*8617e85eSMatthieu Baerts (NGI0) /* Special case for ID0: set the correct ID */ 353*8617e85eSMatthieu Baerts (NGI0) if (local.addr.id == msk->mpc_endpoint_id) 354*8617e85eSMatthieu Baerts (NGI0) local.addr.id = 0; 355*8617e85eSMatthieu Baerts (NGI0) else /* local_addr_used is not decr for ID 0 */ 356*8617e85eSMatthieu Baerts (NGI0) msk->pm.local_addr_used++; 357*8617e85eSMatthieu Baerts (NGI0) 358*8617e85eSMatthieu Baerts (NGI0) nr = fill_remote_addresses_vec(msk, &local.addr, fullmesh, addrs); 359*8617e85eSMatthieu Baerts (NGI0) if (nr == 0) 360*8617e85eSMatthieu Baerts (NGI0) continue; 361*8617e85eSMatthieu Baerts (NGI0) 362*8617e85eSMatthieu Baerts (NGI0) spin_unlock_bh(&msk->pm.lock); 363*8617e85eSMatthieu Baerts (NGI0) for (i = 0; i < nr; i++) 364*8617e85eSMatthieu Baerts (NGI0) __mptcp_subflow_connect(sk, &local, &addrs[i]); 365*8617e85eSMatthieu Baerts (NGI0) spin_lock_bh(&msk->pm.lock); 366*8617e85eSMatthieu Baerts (NGI0) } 367*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_nl_check_work_pending(msk); 368*8617e85eSMatthieu Baerts (NGI0) } 369*8617e85eSMatthieu Baerts (NGI0) 370*8617e85eSMatthieu Baerts (NGI0) static void mptcp_pm_nl_fully_established(struct mptcp_sock *msk) 371*8617e85eSMatthieu Baerts (NGI0) { 372*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_create_subflow_or_signal_addr(msk); 373*8617e85eSMatthieu Baerts (NGI0) } 374*8617e85eSMatthieu Baerts (NGI0) 375*8617e85eSMatthieu Baerts (NGI0) static void mptcp_pm_nl_subflow_established(struct mptcp_sock *msk) 376*8617e85eSMatthieu Baerts (NGI0) { 377*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_create_subflow_or_signal_addr(msk); 378*8617e85eSMatthieu Baerts (NGI0) } 379*8617e85eSMatthieu Baerts (NGI0) 380*8617e85eSMatthieu Baerts (NGI0) /* Fill all the local addresses into the array addrs[], 381*8617e85eSMatthieu Baerts (NGI0) * and return the array size. 382*8617e85eSMatthieu Baerts (NGI0) */ 383*8617e85eSMatthieu Baerts (NGI0) static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk, 384*8617e85eSMatthieu Baerts (NGI0) struct mptcp_addr_info *remote, 385*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_local *locals) 386*8617e85eSMatthieu Baerts (NGI0) { 387*8617e85eSMatthieu Baerts (NGI0) struct sock *sk = (struct sock *)msk; 388*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_addr_entry *entry; 389*8617e85eSMatthieu Baerts (NGI0) struct mptcp_addr_info mpc_addr; 390*8617e85eSMatthieu Baerts (NGI0) struct pm_nl_pernet *pernet; 391*8617e85eSMatthieu Baerts (NGI0) unsigned int subflows_max; 392*8617e85eSMatthieu Baerts (NGI0) int i = 0; 393*8617e85eSMatthieu Baerts (NGI0) 394*8617e85eSMatthieu Baerts (NGI0) pernet = pm_nl_get_pernet_from_msk(msk); 395*8617e85eSMatthieu Baerts (NGI0) subflows_max = mptcp_pm_get_subflows_max(msk); 396*8617e85eSMatthieu Baerts (NGI0) 397*8617e85eSMatthieu Baerts (NGI0) mptcp_local_address((struct sock_common *)msk, &mpc_addr); 398*8617e85eSMatthieu Baerts (NGI0) 399*8617e85eSMatthieu Baerts (NGI0) rcu_read_lock(); 400*8617e85eSMatthieu Baerts (NGI0) list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) { 401*8617e85eSMatthieu Baerts (NGI0) if (!(entry->flags & MPTCP_PM_ADDR_FLAG_FULLMESH)) 402*8617e85eSMatthieu Baerts (NGI0) continue; 403*8617e85eSMatthieu Baerts (NGI0) 404*8617e85eSMatthieu Baerts (NGI0) if (!mptcp_pm_addr_families_match(sk, &entry->addr, remote)) 405*8617e85eSMatthieu Baerts (NGI0) continue; 406*8617e85eSMatthieu Baerts (NGI0) 407*8617e85eSMatthieu Baerts (NGI0) if (msk->pm.subflows < subflows_max) { 408*8617e85eSMatthieu Baerts (NGI0) locals[i].addr = entry->addr; 409*8617e85eSMatthieu Baerts (NGI0) locals[i].flags = entry->flags; 410*8617e85eSMatthieu Baerts (NGI0) locals[i].ifindex = entry->ifindex; 411*8617e85eSMatthieu Baerts (NGI0) 412*8617e85eSMatthieu Baerts (NGI0) /* Special case for ID0: set the correct ID */ 413*8617e85eSMatthieu Baerts (NGI0) if (mptcp_addresses_equal(&locals[i].addr, &mpc_addr, locals[i].addr.port)) 414*8617e85eSMatthieu Baerts (NGI0) locals[i].addr.id = 0; 415*8617e85eSMatthieu Baerts (NGI0) 416*8617e85eSMatthieu Baerts (NGI0) msk->pm.subflows++; 417*8617e85eSMatthieu Baerts (NGI0) i++; 418*8617e85eSMatthieu Baerts (NGI0) } 419*8617e85eSMatthieu Baerts (NGI0) } 420*8617e85eSMatthieu Baerts (NGI0) rcu_read_unlock(); 421*8617e85eSMatthieu Baerts (NGI0) 422*8617e85eSMatthieu Baerts (NGI0) /* If the array is empty, fill in the single 423*8617e85eSMatthieu Baerts (NGI0) * 'IPADDRANY' local address 424*8617e85eSMatthieu Baerts (NGI0) */ 425*8617e85eSMatthieu Baerts (NGI0) if (!i) { 426*8617e85eSMatthieu Baerts (NGI0) memset(&locals[i], 0, sizeof(locals[i])); 427*8617e85eSMatthieu Baerts (NGI0) locals[i].addr.family = 428*8617e85eSMatthieu Baerts (NGI0) #if IS_ENABLED(CONFIG_MPTCP_IPV6) 429*8617e85eSMatthieu Baerts (NGI0) remote->family == AF_INET6 && 430*8617e85eSMatthieu Baerts (NGI0) ipv6_addr_v4mapped(&remote->addr6) ? AF_INET : 431*8617e85eSMatthieu Baerts (NGI0) #endif 432*8617e85eSMatthieu Baerts (NGI0) remote->family; 433*8617e85eSMatthieu Baerts (NGI0) 434*8617e85eSMatthieu Baerts (NGI0) if (!mptcp_pm_addr_families_match(sk, &locals[i].addr, remote)) 435*8617e85eSMatthieu Baerts (NGI0) return 0; 436*8617e85eSMatthieu Baerts (NGI0) 437*8617e85eSMatthieu Baerts (NGI0) msk->pm.subflows++; 438*8617e85eSMatthieu Baerts (NGI0) i++; 439*8617e85eSMatthieu Baerts (NGI0) } 440*8617e85eSMatthieu Baerts (NGI0) 441*8617e85eSMatthieu Baerts (NGI0) return i; 442*8617e85eSMatthieu Baerts (NGI0) } 443*8617e85eSMatthieu Baerts (NGI0) 444*8617e85eSMatthieu Baerts (NGI0) static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk) 445*8617e85eSMatthieu Baerts (NGI0) { 446*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_local locals[MPTCP_PM_ADDR_MAX]; 447*8617e85eSMatthieu Baerts (NGI0) struct sock *sk = (struct sock *)msk; 448*8617e85eSMatthieu Baerts (NGI0) unsigned int add_addr_accept_max; 449*8617e85eSMatthieu Baerts (NGI0) struct mptcp_addr_info remote; 450*8617e85eSMatthieu Baerts (NGI0) unsigned int subflows_max; 451*8617e85eSMatthieu Baerts (NGI0) bool sf_created = false; 452*8617e85eSMatthieu Baerts (NGI0) int i, nr; 453*8617e85eSMatthieu Baerts (NGI0) 454*8617e85eSMatthieu Baerts (NGI0) add_addr_accept_max = mptcp_pm_get_add_addr_accept_max(msk); 455*8617e85eSMatthieu Baerts (NGI0) subflows_max = mptcp_pm_get_subflows_max(msk); 456*8617e85eSMatthieu Baerts (NGI0) 457*8617e85eSMatthieu Baerts (NGI0) pr_debug("accepted %d:%d remote family %d\n", 458*8617e85eSMatthieu Baerts (NGI0) msk->pm.add_addr_accepted, add_addr_accept_max, 459*8617e85eSMatthieu Baerts (NGI0) msk->pm.remote.family); 460*8617e85eSMatthieu Baerts (NGI0) 461*8617e85eSMatthieu Baerts (NGI0) remote = msk->pm.remote; 462*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_announce_addr(msk, &remote, true); 463*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_addr_send_ack(msk); 464*8617e85eSMatthieu Baerts (NGI0) 465*8617e85eSMatthieu Baerts (NGI0) if (lookup_subflow_by_daddr(&msk->conn_list, &remote)) 466*8617e85eSMatthieu Baerts (NGI0) return; 467*8617e85eSMatthieu Baerts (NGI0) 468*8617e85eSMatthieu Baerts (NGI0) /* pick id 0 port, if none is provided the remote address */ 469*8617e85eSMatthieu Baerts (NGI0) if (!remote.port) 470*8617e85eSMatthieu Baerts (NGI0) remote.port = sk->sk_dport; 471*8617e85eSMatthieu Baerts (NGI0) 472*8617e85eSMatthieu Baerts (NGI0) /* connect to the specified remote address, using whatever 473*8617e85eSMatthieu Baerts (NGI0) * local address the routing configuration will pick. 474*8617e85eSMatthieu Baerts (NGI0) */ 475*8617e85eSMatthieu Baerts (NGI0) nr = fill_local_addresses_vec(msk, &remote, locals); 476*8617e85eSMatthieu Baerts (NGI0) if (nr == 0) 477*8617e85eSMatthieu Baerts (NGI0) return; 478*8617e85eSMatthieu Baerts (NGI0) 479*8617e85eSMatthieu Baerts (NGI0) spin_unlock_bh(&msk->pm.lock); 480*8617e85eSMatthieu Baerts (NGI0) for (i = 0; i < nr; i++) 481*8617e85eSMatthieu Baerts (NGI0) if (__mptcp_subflow_connect(sk, &locals[i], &remote) == 0) 482*8617e85eSMatthieu Baerts (NGI0) sf_created = true; 483*8617e85eSMatthieu Baerts (NGI0) spin_lock_bh(&msk->pm.lock); 484*8617e85eSMatthieu Baerts (NGI0) 485*8617e85eSMatthieu Baerts (NGI0) if (sf_created) { 486*8617e85eSMatthieu Baerts (NGI0) /* add_addr_accepted is not decr for ID 0 */ 487*8617e85eSMatthieu Baerts (NGI0) if (remote.id) 488*8617e85eSMatthieu Baerts (NGI0) msk->pm.add_addr_accepted++; 489*8617e85eSMatthieu Baerts (NGI0) if (msk->pm.add_addr_accepted >= add_addr_accept_max || 490*8617e85eSMatthieu Baerts (NGI0) msk->pm.subflows >= subflows_max) 491*8617e85eSMatthieu Baerts (NGI0) WRITE_ONCE(msk->pm.accept_addr, false); 492*8617e85eSMatthieu Baerts (NGI0) } 493*8617e85eSMatthieu Baerts (NGI0) } 494*8617e85eSMatthieu Baerts (NGI0) 495*8617e85eSMatthieu Baerts (NGI0) void mptcp_pm_nl_rm_addr(struct mptcp_sock *msk, u8 rm_id) 496*8617e85eSMatthieu Baerts (NGI0) { 497*8617e85eSMatthieu Baerts (NGI0) if (rm_id && WARN_ON_ONCE(msk->pm.add_addr_accepted == 0)) { 498*8617e85eSMatthieu Baerts (NGI0) /* Note: if the subflow has been closed before, this 499*8617e85eSMatthieu Baerts (NGI0) * add_addr_accepted counter will not be decremented. 500*8617e85eSMatthieu Baerts (NGI0) */ 501*8617e85eSMatthieu Baerts (NGI0) if (--msk->pm.add_addr_accepted < mptcp_pm_get_add_addr_accept_max(msk)) 502*8617e85eSMatthieu Baerts (NGI0) WRITE_ONCE(msk->pm.accept_addr, true); 503*8617e85eSMatthieu Baerts (NGI0) } 504*8617e85eSMatthieu Baerts (NGI0) } 505*8617e85eSMatthieu Baerts (NGI0) 506*8617e85eSMatthieu Baerts (NGI0) static bool address_use_port(struct mptcp_pm_addr_entry *entry) 507*8617e85eSMatthieu Baerts (NGI0) { 508*8617e85eSMatthieu Baerts (NGI0) return (entry->flags & 509*8617e85eSMatthieu Baerts (NGI0) (MPTCP_PM_ADDR_FLAG_SIGNAL | MPTCP_PM_ADDR_FLAG_SUBFLOW)) == 510*8617e85eSMatthieu Baerts (NGI0) MPTCP_PM_ADDR_FLAG_SIGNAL; 511*8617e85eSMatthieu Baerts (NGI0) } 512*8617e85eSMatthieu Baerts (NGI0) 513*8617e85eSMatthieu Baerts (NGI0) /* caller must ensure the RCU grace period is already elapsed */ 514*8617e85eSMatthieu Baerts (NGI0) static void __mptcp_pm_release_addr_entry(struct mptcp_pm_addr_entry *entry) 515*8617e85eSMatthieu Baerts (NGI0) { 516*8617e85eSMatthieu Baerts (NGI0) if (entry->lsk) 517*8617e85eSMatthieu Baerts (NGI0) sock_release(entry->lsk); 518*8617e85eSMatthieu Baerts (NGI0) kfree(entry); 519*8617e85eSMatthieu Baerts (NGI0) } 520*8617e85eSMatthieu Baerts (NGI0) 521*8617e85eSMatthieu Baerts (NGI0) static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet, 522*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_addr_entry *entry, 523*8617e85eSMatthieu Baerts (NGI0) bool needs_id, bool replace) 524*8617e85eSMatthieu Baerts (NGI0) { 525*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_addr_entry *cur, *del_entry = NULL; 526*8617e85eSMatthieu Baerts (NGI0) unsigned int addr_max; 527*8617e85eSMatthieu Baerts (NGI0) int ret = -EINVAL; 528*8617e85eSMatthieu Baerts (NGI0) 529*8617e85eSMatthieu Baerts (NGI0) spin_lock_bh(&pernet->lock); 530*8617e85eSMatthieu Baerts (NGI0) /* to keep the code simple, don't do IDR-like allocation for address ID, 531*8617e85eSMatthieu Baerts (NGI0) * just bail when we exceed limits 532*8617e85eSMatthieu Baerts (NGI0) */ 533*8617e85eSMatthieu Baerts (NGI0) if (pernet->next_id == MPTCP_PM_MAX_ADDR_ID) 534*8617e85eSMatthieu Baerts (NGI0) pernet->next_id = 1; 535*8617e85eSMatthieu Baerts (NGI0) if (pernet->addrs >= MPTCP_PM_ADDR_MAX) { 536*8617e85eSMatthieu Baerts (NGI0) ret = -ERANGE; 537*8617e85eSMatthieu Baerts (NGI0) goto out; 538*8617e85eSMatthieu Baerts (NGI0) } 539*8617e85eSMatthieu Baerts (NGI0) if (test_bit(entry->addr.id, pernet->id_bitmap)) { 540*8617e85eSMatthieu Baerts (NGI0) ret = -EBUSY; 541*8617e85eSMatthieu Baerts (NGI0) goto out; 542*8617e85eSMatthieu Baerts (NGI0) } 543*8617e85eSMatthieu Baerts (NGI0) 544*8617e85eSMatthieu Baerts (NGI0) /* do not insert duplicate address, differentiate on port only 545*8617e85eSMatthieu Baerts (NGI0) * singled addresses 546*8617e85eSMatthieu Baerts (NGI0) */ 547*8617e85eSMatthieu Baerts (NGI0) if (!address_use_port(entry)) 548*8617e85eSMatthieu Baerts (NGI0) entry->addr.port = 0; 549*8617e85eSMatthieu Baerts (NGI0) list_for_each_entry(cur, &pernet->local_addr_list, list) { 550*8617e85eSMatthieu Baerts (NGI0) if (mptcp_addresses_equal(&cur->addr, &entry->addr, 551*8617e85eSMatthieu Baerts (NGI0) cur->addr.port || entry->addr.port)) { 552*8617e85eSMatthieu Baerts (NGI0) /* allow replacing the exiting endpoint only if such 553*8617e85eSMatthieu Baerts (NGI0) * endpoint is an implicit one and the user-space 554*8617e85eSMatthieu Baerts (NGI0) * did not provide an endpoint id 555*8617e85eSMatthieu Baerts (NGI0) */ 556*8617e85eSMatthieu Baerts (NGI0) if (!(cur->flags & MPTCP_PM_ADDR_FLAG_IMPLICIT)) { 557*8617e85eSMatthieu Baerts (NGI0) ret = -EEXIST; 558*8617e85eSMatthieu Baerts (NGI0) goto out; 559*8617e85eSMatthieu Baerts (NGI0) } 560*8617e85eSMatthieu Baerts (NGI0) if (entry->addr.id) 561*8617e85eSMatthieu Baerts (NGI0) goto out; 562*8617e85eSMatthieu Baerts (NGI0) 563*8617e85eSMatthieu Baerts (NGI0) /* allow callers that only need to look up the local 564*8617e85eSMatthieu Baerts (NGI0) * addr's id to skip replacement. This allows them to 565*8617e85eSMatthieu Baerts (NGI0) * avoid calling synchronize_rcu in the packet recv 566*8617e85eSMatthieu Baerts (NGI0) * path. 567*8617e85eSMatthieu Baerts (NGI0) */ 568*8617e85eSMatthieu Baerts (NGI0) if (!replace) { 569*8617e85eSMatthieu Baerts (NGI0) kfree(entry); 570*8617e85eSMatthieu Baerts (NGI0) ret = cur->addr.id; 571*8617e85eSMatthieu Baerts (NGI0) goto out; 572*8617e85eSMatthieu Baerts (NGI0) } 573*8617e85eSMatthieu Baerts (NGI0) 574*8617e85eSMatthieu Baerts (NGI0) pernet->addrs--; 575*8617e85eSMatthieu Baerts (NGI0) entry->addr.id = cur->addr.id; 576*8617e85eSMatthieu Baerts (NGI0) list_del_rcu(&cur->list); 577*8617e85eSMatthieu Baerts (NGI0) del_entry = cur; 578*8617e85eSMatthieu Baerts (NGI0) break; 579*8617e85eSMatthieu Baerts (NGI0) } 580*8617e85eSMatthieu Baerts (NGI0) } 581*8617e85eSMatthieu Baerts (NGI0) 582*8617e85eSMatthieu Baerts (NGI0) if (!entry->addr.id && needs_id) { 583*8617e85eSMatthieu Baerts (NGI0) find_next: 584*8617e85eSMatthieu Baerts (NGI0) entry->addr.id = find_next_zero_bit(pernet->id_bitmap, 585*8617e85eSMatthieu Baerts (NGI0) MPTCP_PM_MAX_ADDR_ID + 1, 586*8617e85eSMatthieu Baerts (NGI0) pernet->next_id); 587*8617e85eSMatthieu Baerts (NGI0) if (!entry->addr.id && pernet->next_id != 1) { 588*8617e85eSMatthieu Baerts (NGI0) pernet->next_id = 1; 589*8617e85eSMatthieu Baerts (NGI0) goto find_next; 590*8617e85eSMatthieu Baerts (NGI0) } 591*8617e85eSMatthieu Baerts (NGI0) } 592*8617e85eSMatthieu Baerts (NGI0) 593*8617e85eSMatthieu Baerts (NGI0) if (!entry->addr.id && needs_id) 594*8617e85eSMatthieu Baerts (NGI0) goto out; 595*8617e85eSMatthieu Baerts (NGI0) 596*8617e85eSMatthieu Baerts (NGI0) __set_bit(entry->addr.id, pernet->id_bitmap); 597*8617e85eSMatthieu Baerts (NGI0) if (entry->addr.id > pernet->next_id) 598*8617e85eSMatthieu Baerts (NGI0) pernet->next_id = entry->addr.id; 599*8617e85eSMatthieu Baerts (NGI0) 600*8617e85eSMatthieu Baerts (NGI0) if (entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL) { 601*8617e85eSMatthieu Baerts (NGI0) addr_max = pernet->add_addr_signal_max; 602*8617e85eSMatthieu Baerts (NGI0) WRITE_ONCE(pernet->add_addr_signal_max, addr_max + 1); 603*8617e85eSMatthieu Baerts (NGI0) } 604*8617e85eSMatthieu Baerts (NGI0) if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) { 605*8617e85eSMatthieu Baerts (NGI0) addr_max = pernet->local_addr_max; 606*8617e85eSMatthieu Baerts (NGI0) WRITE_ONCE(pernet->local_addr_max, addr_max + 1); 607*8617e85eSMatthieu Baerts (NGI0) } 608*8617e85eSMatthieu Baerts (NGI0) 609*8617e85eSMatthieu Baerts (NGI0) pernet->addrs++; 610*8617e85eSMatthieu Baerts (NGI0) if (!entry->addr.port) 611*8617e85eSMatthieu Baerts (NGI0) list_add_tail_rcu(&entry->list, &pernet->local_addr_list); 612*8617e85eSMatthieu Baerts (NGI0) else 613*8617e85eSMatthieu Baerts (NGI0) list_add_rcu(&entry->list, &pernet->local_addr_list); 614*8617e85eSMatthieu Baerts (NGI0) ret = entry->addr.id; 615*8617e85eSMatthieu Baerts (NGI0) 616*8617e85eSMatthieu Baerts (NGI0) out: 617*8617e85eSMatthieu Baerts (NGI0) spin_unlock_bh(&pernet->lock); 618*8617e85eSMatthieu Baerts (NGI0) 619*8617e85eSMatthieu Baerts (NGI0) /* just replaced an existing entry, free it */ 620*8617e85eSMatthieu Baerts (NGI0) if (del_entry) { 621*8617e85eSMatthieu Baerts (NGI0) synchronize_rcu(); 622*8617e85eSMatthieu Baerts (NGI0) __mptcp_pm_release_addr_entry(del_entry); 623*8617e85eSMatthieu Baerts (NGI0) } 624*8617e85eSMatthieu Baerts (NGI0) return ret; 625*8617e85eSMatthieu Baerts (NGI0) } 626*8617e85eSMatthieu Baerts (NGI0) 627*8617e85eSMatthieu Baerts (NGI0) static struct lock_class_key mptcp_slock_keys[2]; 628*8617e85eSMatthieu Baerts (NGI0) static struct lock_class_key mptcp_keys[2]; 629*8617e85eSMatthieu Baerts (NGI0) 630*8617e85eSMatthieu Baerts (NGI0) static int mptcp_pm_nl_create_listen_socket(struct sock *sk, 631*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_addr_entry *entry) 632*8617e85eSMatthieu Baerts (NGI0) { 633*8617e85eSMatthieu Baerts (NGI0) bool is_ipv6 = sk->sk_family == AF_INET6; 634*8617e85eSMatthieu Baerts (NGI0) int addrlen = sizeof(struct sockaddr_in); 635*8617e85eSMatthieu Baerts (NGI0) struct sockaddr_storage addr; 636*8617e85eSMatthieu Baerts (NGI0) struct sock *newsk, *ssk; 637*8617e85eSMatthieu Baerts (NGI0) int backlog = 1024; 638*8617e85eSMatthieu Baerts (NGI0) int err; 639*8617e85eSMatthieu Baerts (NGI0) 640*8617e85eSMatthieu Baerts (NGI0) err = sock_create_kern(sock_net(sk), entry->addr.family, 641*8617e85eSMatthieu Baerts (NGI0) SOCK_STREAM, IPPROTO_MPTCP, &entry->lsk); 642*8617e85eSMatthieu Baerts (NGI0) if (err) 643*8617e85eSMatthieu Baerts (NGI0) return err; 644*8617e85eSMatthieu Baerts (NGI0) 645*8617e85eSMatthieu Baerts (NGI0) newsk = entry->lsk->sk; 646*8617e85eSMatthieu Baerts (NGI0) if (!newsk) 647*8617e85eSMatthieu Baerts (NGI0) return -EINVAL; 648*8617e85eSMatthieu Baerts (NGI0) 649*8617e85eSMatthieu Baerts (NGI0) /* The subflow socket lock is acquired in a nested to the msk one 650*8617e85eSMatthieu Baerts (NGI0) * in several places, even by the TCP stack, and this msk is a kernel 651*8617e85eSMatthieu Baerts (NGI0) * socket: lockdep complains. Instead of propagating the _nested 652*8617e85eSMatthieu Baerts (NGI0) * modifiers in several places, re-init the lock class for the msk 653*8617e85eSMatthieu Baerts (NGI0) * socket to an mptcp specific one. 654*8617e85eSMatthieu Baerts (NGI0) */ 655*8617e85eSMatthieu Baerts (NGI0) sock_lock_init_class_and_name(newsk, 656*8617e85eSMatthieu Baerts (NGI0) is_ipv6 ? "mlock-AF_INET6" : "mlock-AF_INET", 657*8617e85eSMatthieu Baerts (NGI0) &mptcp_slock_keys[is_ipv6], 658*8617e85eSMatthieu Baerts (NGI0) is_ipv6 ? "msk_lock-AF_INET6" : "msk_lock-AF_INET", 659*8617e85eSMatthieu Baerts (NGI0) &mptcp_keys[is_ipv6]); 660*8617e85eSMatthieu Baerts (NGI0) 661*8617e85eSMatthieu Baerts (NGI0) lock_sock(newsk); 662*8617e85eSMatthieu Baerts (NGI0) ssk = __mptcp_nmpc_sk(mptcp_sk(newsk)); 663*8617e85eSMatthieu Baerts (NGI0) release_sock(newsk); 664*8617e85eSMatthieu Baerts (NGI0) if (IS_ERR(ssk)) 665*8617e85eSMatthieu Baerts (NGI0) return PTR_ERR(ssk); 666*8617e85eSMatthieu Baerts (NGI0) 667*8617e85eSMatthieu Baerts (NGI0) mptcp_info2sockaddr(&entry->addr, &addr, entry->addr.family); 668*8617e85eSMatthieu Baerts (NGI0) #if IS_ENABLED(CONFIG_MPTCP_IPV6) 669*8617e85eSMatthieu Baerts (NGI0) if (entry->addr.family == AF_INET6) 670*8617e85eSMatthieu Baerts (NGI0) addrlen = sizeof(struct sockaddr_in6); 671*8617e85eSMatthieu Baerts (NGI0) #endif 672*8617e85eSMatthieu Baerts (NGI0) if (ssk->sk_family == AF_INET) 673*8617e85eSMatthieu Baerts (NGI0) err = inet_bind_sk(ssk, (struct sockaddr *)&addr, addrlen); 674*8617e85eSMatthieu Baerts (NGI0) #if IS_ENABLED(CONFIG_MPTCP_IPV6) 675*8617e85eSMatthieu Baerts (NGI0) else if (ssk->sk_family == AF_INET6) 676*8617e85eSMatthieu Baerts (NGI0) err = inet6_bind_sk(ssk, (struct sockaddr *)&addr, addrlen); 677*8617e85eSMatthieu Baerts (NGI0) #endif 678*8617e85eSMatthieu Baerts (NGI0) if (err) 679*8617e85eSMatthieu Baerts (NGI0) return err; 680*8617e85eSMatthieu Baerts (NGI0) 681*8617e85eSMatthieu Baerts (NGI0) /* We don't use mptcp_set_state() here because it needs to be called 682*8617e85eSMatthieu Baerts (NGI0) * under the msk socket lock. For the moment, that will not bring 683*8617e85eSMatthieu Baerts (NGI0) * anything more than only calling inet_sk_state_store(), because the 684*8617e85eSMatthieu Baerts (NGI0) * old status is known (TCP_CLOSE). 685*8617e85eSMatthieu Baerts (NGI0) */ 686*8617e85eSMatthieu Baerts (NGI0) inet_sk_state_store(newsk, TCP_LISTEN); 687*8617e85eSMatthieu Baerts (NGI0) lock_sock(ssk); 688*8617e85eSMatthieu Baerts (NGI0) WRITE_ONCE(mptcp_subflow_ctx(ssk)->pm_listener, true); 689*8617e85eSMatthieu Baerts (NGI0) err = __inet_listen_sk(ssk, backlog); 690*8617e85eSMatthieu Baerts (NGI0) if (!err) 691*8617e85eSMatthieu Baerts (NGI0) mptcp_event_pm_listener(ssk, MPTCP_EVENT_LISTENER_CREATED); 692*8617e85eSMatthieu Baerts (NGI0) release_sock(ssk); 693*8617e85eSMatthieu Baerts (NGI0) return err; 694*8617e85eSMatthieu Baerts (NGI0) } 695*8617e85eSMatthieu Baerts (NGI0) 696*8617e85eSMatthieu Baerts (NGI0) int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, 697*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_addr_entry *skc) 698*8617e85eSMatthieu Baerts (NGI0) { 699*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_addr_entry *entry; 700*8617e85eSMatthieu Baerts (NGI0) struct pm_nl_pernet *pernet; 701*8617e85eSMatthieu Baerts (NGI0) int ret; 702*8617e85eSMatthieu Baerts (NGI0) 703*8617e85eSMatthieu Baerts (NGI0) pernet = pm_nl_get_pernet_from_msk(msk); 704*8617e85eSMatthieu Baerts (NGI0) 705*8617e85eSMatthieu Baerts (NGI0) rcu_read_lock(); 706*8617e85eSMatthieu Baerts (NGI0) entry = __lookup_addr(pernet, &skc->addr); 707*8617e85eSMatthieu Baerts (NGI0) ret = entry ? entry->addr.id : -1; 708*8617e85eSMatthieu Baerts (NGI0) rcu_read_unlock(); 709*8617e85eSMatthieu Baerts (NGI0) if (ret >= 0) 710*8617e85eSMatthieu Baerts (NGI0) return ret; 711*8617e85eSMatthieu Baerts (NGI0) 712*8617e85eSMatthieu Baerts (NGI0) /* address not found, add to local list */ 713*8617e85eSMatthieu Baerts (NGI0) entry = kmalloc(sizeof(*entry), GFP_ATOMIC); 714*8617e85eSMatthieu Baerts (NGI0) if (!entry) 715*8617e85eSMatthieu Baerts (NGI0) return -ENOMEM; 716*8617e85eSMatthieu Baerts (NGI0) 717*8617e85eSMatthieu Baerts (NGI0) *entry = *skc; 718*8617e85eSMatthieu Baerts (NGI0) entry->addr.port = 0; 719*8617e85eSMatthieu Baerts (NGI0) ret = mptcp_pm_nl_append_new_local_addr(pernet, entry, true, false); 720*8617e85eSMatthieu Baerts (NGI0) if (ret < 0) 721*8617e85eSMatthieu Baerts (NGI0) kfree(entry); 722*8617e85eSMatthieu Baerts (NGI0) 723*8617e85eSMatthieu Baerts (NGI0) return ret; 724*8617e85eSMatthieu Baerts (NGI0) } 725*8617e85eSMatthieu Baerts (NGI0) 726*8617e85eSMatthieu Baerts (NGI0) bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc) 727*8617e85eSMatthieu Baerts (NGI0) { 728*8617e85eSMatthieu Baerts (NGI0) struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk); 729*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_addr_entry *entry; 730*8617e85eSMatthieu Baerts (NGI0) bool backup; 731*8617e85eSMatthieu Baerts (NGI0) 732*8617e85eSMatthieu Baerts (NGI0) rcu_read_lock(); 733*8617e85eSMatthieu Baerts (NGI0) entry = __lookup_addr(pernet, skc); 734*8617e85eSMatthieu Baerts (NGI0) backup = entry && !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP); 735*8617e85eSMatthieu Baerts (NGI0) rcu_read_unlock(); 736*8617e85eSMatthieu Baerts (NGI0) 737*8617e85eSMatthieu Baerts (NGI0) return backup; 738*8617e85eSMatthieu Baerts (NGI0) } 739*8617e85eSMatthieu Baerts (NGI0) 740*8617e85eSMatthieu Baerts (NGI0) static int mptcp_nl_add_subflow_or_signal_addr(struct net *net, 741*8617e85eSMatthieu Baerts (NGI0) struct mptcp_addr_info *addr) 742*8617e85eSMatthieu Baerts (NGI0) { 743*8617e85eSMatthieu Baerts (NGI0) struct mptcp_sock *msk; 744*8617e85eSMatthieu Baerts (NGI0) long s_slot = 0, s_num = 0; 745*8617e85eSMatthieu Baerts (NGI0) 746*8617e85eSMatthieu Baerts (NGI0) while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) { 747*8617e85eSMatthieu Baerts (NGI0) struct sock *sk = (struct sock *)msk; 748*8617e85eSMatthieu Baerts (NGI0) struct mptcp_addr_info mpc_addr; 749*8617e85eSMatthieu Baerts (NGI0) 750*8617e85eSMatthieu Baerts (NGI0) if (!READ_ONCE(msk->fully_established) || 751*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_is_userspace(msk)) 752*8617e85eSMatthieu Baerts (NGI0) goto next; 753*8617e85eSMatthieu Baerts (NGI0) 754*8617e85eSMatthieu Baerts (NGI0) /* if the endp linked to the init sf is re-added with a != ID */ 755*8617e85eSMatthieu Baerts (NGI0) mptcp_local_address((struct sock_common *)msk, &mpc_addr); 756*8617e85eSMatthieu Baerts (NGI0) 757*8617e85eSMatthieu Baerts (NGI0) lock_sock(sk); 758*8617e85eSMatthieu Baerts (NGI0) spin_lock_bh(&msk->pm.lock); 759*8617e85eSMatthieu Baerts (NGI0) if (mptcp_addresses_equal(addr, &mpc_addr, addr->port)) 760*8617e85eSMatthieu Baerts (NGI0) msk->mpc_endpoint_id = addr->id; 761*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_create_subflow_or_signal_addr(msk); 762*8617e85eSMatthieu Baerts (NGI0) spin_unlock_bh(&msk->pm.lock); 763*8617e85eSMatthieu Baerts (NGI0) release_sock(sk); 764*8617e85eSMatthieu Baerts (NGI0) 765*8617e85eSMatthieu Baerts (NGI0) next: 766*8617e85eSMatthieu Baerts (NGI0) sock_put(sk); 767*8617e85eSMatthieu Baerts (NGI0) cond_resched(); 768*8617e85eSMatthieu Baerts (NGI0) } 769*8617e85eSMatthieu Baerts (NGI0) 770*8617e85eSMatthieu Baerts (NGI0) return 0; 771*8617e85eSMatthieu Baerts (NGI0) } 772*8617e85eSMatthieu Baerts (NGI0) 773*8617e85eSMatthieu Baerts (NGI0) static bool mptcp_pm_has_addr_attr_id(const struct nlattr *attr, 774*8617e85eSMatthieu Baerts (NGI0) struct genl_info *info) 775*8617e85eSMatthieu Baerts (NGI0) { 776*8617e85eSMatthieu Baerts (NGI0) struct nlattr *tb[MPTCP_PM_ADDR_ATTR_MAX + 1]; 777*8617e85eSMatthieu Baerts (NGI0) 778*8617e85eSMatthieu Baerts (NGI0) if (!nla_parse_nested_deprecated(tb, MPTCP_PM_ADDR_ATTR_MAX, attr, 779*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_address_nl_policy, info->extack) && 780*8617e85eSMatthieu Baerts (NGI0) tb[MPTCP_PM_ADDR_ATTR_ID]) 781*8617e85eSMatthieu Baerts (NGI0) return true; 782*8617e85eSMatthieu Baerts (NGI0) return false; 783*8617e85eSMatthieu Baerts (NGI0) } 784*8617e85eSMatthieu Baerts (NGI0) 785*8617e85eSMatthieu Baerts (NGI0) /* Add an MPTCP endpoint */ 786*8617e85eSMatthieu Baerts (NGI0) int mptcp_pm_nl_add_addr_doit(struct sk_buff *skb, struct genl_info *info) 787*8617e85eSMatthieu Baerts (NGI0) { 788*8617e85eSMatthieu Baerts (NGI0) struct pm_nl_pernet *pernet = genl_info_pm_nl(info); 789*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_addr_entry addr, *entry; 790*8617e85eSMatthieu Baerts (NGI0) struct nlattr *attr; 791*8617e85eSMatthieu Baerts (NGI0) int ret; 792*8617e85eSMatthieu Baerts (NGI0) 793*8617e85eSMatthieu Baerts (NGI0) if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ENDPOINT_ADDR)) 794*8617e85eSMatthieu Baerts (NGI0) return -EINVAL; 795*8617e85eSMatthieu Baerts (NGI0) 796*8617e85eSMatthieu Baerts (NGI0) attr = info->attrs[MPTCP_PM_ENDPOINT_ADDR]; 797*8617e85eSMatthieu Baerts (NGI0) ret = mptcp_pm_parse_entry(attr, info, true, &addr); 798*8617e85eSMatthieu Baerts (NGI0) if (ret < 0) 799*8617e85eSMatthieu Baerts (NGI0) return ret; 800*8617e85eSMatthieu Baerts (NGI0) 801*8617e85eSMatthieu Baerts (NGI0) if (addr.addr.port && !address_use_port(&addr)) { 802*8617e85eSMatthieu Baerts (NGI0) NL_SET_ERR_MSG_ATTR(info->extack, attr, 803*8617e85eSMatthieu Baerts (NGI0) "flags must have signal and not subflow when using port"); 804*8617e85eSMatthieu Baerts (NGI0) return -EINVAL; 805*8617e85eSMatthieu Baerts (NGI0) } 806*8617e85eSMatthieu Baerts (NGI0) 807*8617e85eSMatthieu Baerts (NGI0) if (addr.flags & MPTCP_PM_ADDR_FLAG_SIGNAL && 808*8617e85eSMatthieu Baerts (NGI0) addr.flags & MPTCP_PM_ADDR_FLAG_FULLMESH) { 809*8617e85eSMatthieu Baerts (NGI0) NL_SET_ERR_MSG_ATTR(info->extack, attr, 810*8617e85eSMatthieu Baerts (NGI0) "flags mustn't have both signal and fullmesh"); 811*8617e85eSMatthieu Baerts (NGI0) return -EINVAL; 812*8617e85eSMatthieu Baerts (NGI0) } 813*8617e85eSMatthieu Baerts (NGI0) 814*8617e85eSMatthieu Baerts (NGI0) if (addr.flags & MPTCP_PM_ADDR_FLAG_IMPLICIT) { 815*8617e85eSMatthieu Baerts (NGI0) NL_SET_ERR_MSG_ATTR(info->extack, attr, 816*8617e85eSMatthieu Baerts (NGI0) "can't create IMPLICIT endpoint"); 817*8617e85eSMatthieu Baerts (NGI0) return -EINVAL; 818*8617e85eSMatthieu Baerts (NGI0) } 819*8617e85eSMatthieu Baerts (NGI0) 820*8617e85eSMatthieu Baerts (NGI0) entry = kzalloc(sizeof(*entry), GFP_KERNEL_ACCOUNT); 821*8617e85eSMatthieu Baerts (NGI0) if (!entry) { 822*8617e85eSMatthieu Baerts (NGI0) GENL_SET_ERR_MSG(info, "can't allocate addr"); 823*8617e85eSMatthieu Baerts (NGI0) return -ENOMEM; 824*8617e85eSMatthieu Baerts (NGI0) } 825*8617e85eSMatthieu Baerts (NGI0) 826*8617e85eSMatthieu Baerts (NGI0) *entry = addr; 827*8617e85eSMatthieu Baerts (NGI0) if (entry->addr.port) { 828*8617e85eSMatthieu Baerts (NGI0) ret = mptcp_pm_nl_create_listen_socket(skb->sk, entry); 829*8617e85eSMatthieu Baerts (NGI0) if (ret) { 830*8617e85eSMatthieu Baerts (NGI0) GENL_SET_ERR_MSG_FMT(info, "create listen socket error: %d", ret); 831*8617e85eSMatthieu Baerts (NGI0) goto out_free; 832*8617e85eSMatthieu Baerts (NGI0) } 833*8617e85eSMatthieu Baerts (NGI0) } 834*8617e85eSMatthieu Baerts (NGI0) ret = mptcp_pm_nl_append_new_local_addr(pernet, entry, 835*8617e85eSMatthieu Baerts (NGI0) !mptcp_pm_has_addr_attr_id(attr, info), 836*8617e85eSMatthieu Baerts (NGI0) true); 837*8617e85eSMatthieu Baerts (NGI0) if (ret < 0) { 838*8617e85eSMatthieu Baerts (NGI0) GENL_SET_ERR_MSG_FMT(info, "too many addresses or duplicate one: %d", ret); 839*8617e85eSMatthieu Baerts (NGI0) goto out_free; 840*8617e85eSMatthieu Baerts (NGI0) } 841*8617e85eSMatthieu Baerts (NGI0) 842*8617e85eSMatthieu Baerts (NGI0) mptcp_nl_add_subflow_or_signal_addr(sock_net(skb->sk), &entry->addr); 843*8617e85eSMatthieu Baerts (NGI0) return 0; 844*8617e85eSMatthieu Baerts (NGI0) 845*8617e85eSMatthieu Baerts (NGI0) out_free: 846*8617e85eSMatthieu Baerts (NGI0) __mptcp_pm_release_addr_entry(entry); 847*8617e85eSMatthieu Baerts (NGI0) return ret; 848*8617e85eSMatthieu Baerts (NGI0) } 849*8617e85eSMatthieu Baerts (NGI0) 850*8617e85eSMatthieu Baerts (NGI0) static u8 mptcp_endp_get_local_id(struct mptcp_sock *msk, 851*8617e85eSMatthieu Baerts (NGI0) const struct mptcp_addr_info *addr) 852*8617e85eSMatthieu Baerts (NGI0) { 853*8617e85eSMatthieu Baerts (NGI0) return msk->mpc_endpoint_id == addr->id ? 0 : addr->id; 854*8617e85eSMatthieu Baerts (NGI0) } 855*8617e85eSMatthieu Baerts (NGI0) 856*8617e85eSMatthieu Baerts (NGI0) static bool mptcp_pm_remove_anno_addr(struct mptcp_sock *msk, 857*8617e85eSMatthieu Baerts (NGI0) const struct mptcp_addr_info *addr, 858*8617e85eSMatthieu Baerts (NGI0) bool force) 859*8617e85eSMatthieu Baerts (NGI0) { 860*8617e85eSMatthieu Baerts (NGI0) struct mptcp_rm_list list = { .nr = 0 }; 861*8617e85eSMatthieu Baerts (NGI0) bool ret; 862*8617e85eSMatthieu Baerts (NGI0) 863*8617e85eSMatthieu Baerts (NGI0) list.ids[list.nr++] = mptcp_endp_get_local_id(msk, addr); 864*8617e85eSMatthieu Baerts (NGI0) 865*8617e85eSMatthieu Baerts (NGI0) ret = mptcp_remove_anno_list_by_saddr(msk, addr); 866*8617e85eSMatthieu Baerts (NGI0) if (ret || force) { 867*8617e85eSMatthieu Baerts (NGI0) spin_lock_bh(&msk->pm.lock); 868*8617e85eSMatthieu Baerts (NGI0) if (ret) { 869*8617e85eSMatthieu Baerts (NGI0) __set_bit(addr->id, msk->pm.id_avail_bitmap); 870*8617e85eSMatthieu Baerts (NGI0) msk->pm.add_addr_signaled--; 871*8617e85eSMatthieu Baerts (NGI0) } 872*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_remove_addr(msk, &list); 873*8617e85eSMatthieu Baerts (NGI0) spin_unlock_bh(&msk->pm.lock); 874*8617e85eSMatthieu Baerts (NGI0) } 875*8617e85eSMatthieu Baerts (NGI0) return ret; 876*8617e85eSMatthieu Baerts (NGI0) } 877*8617e85eSMatthieu Baerts (NGI0) 878*8617e85eSMatthieu Baerts (NGI0) static void __mark_subflow_endp_available(struct mptcp_sock *msk, u8 id) 879*8617e85eSMatthieu Baerts (NGI0) { 880*8617e85eSMatthieu Baerts (NGI0) /* If it was marked as used, and not ID 0, decrement local_addr_used */ 881*8617e85eSMatthieu Baerts (NGI0) if (!__test_and_set_bit(id ? : msk->mpc_endpoint_id, msk->pm.id_avail_bitmap) && 882*8617e85eSMatthieu Baerts (NGI0) id && !WARN_ON_ONCE(msk->pm.local_addr_used == 0)) 883*8617e85eSMatthieu Baerts (NGI0) msk->pm.local_addr_used--; 884*8617e85eSMatthieu Baerts (NGI0) } 885*8617e85eSMatthieu Baerts (NGI0) 886*8617e85eSMatthieu Baerts (NGI0) static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net, 887*8617e85eSMatthieu Baerts (NGI0) const struct mptcp_pm_addr_entry *entry) 888*8617e85eSMatthieu Baerts (NGI0) { 889*8617e85eSMatthieu Baerts (NGI0) const struct mptcp_addr_info *addr = &entry->addr; 890*8617e85eSMatthieu Baerts (NGI0) struct mptcp_rm_list list = { .nr = 1 }; 891*8617e85eSMatthieu Baerts (NGI0) long s_slot = 0, s_num = 0; 892*8617e85eSMatthieu Baerts (NGI0) struct mptcp_sock *msk; 893*8617e85eSMatthieu Baerts (NGI0) 894*8617e85eSMatthieu Baerts (NGI0) pr_debug("remove_id=%d\n", addr->id); 895*8617e85eSMatthieu Baerts (NGI0) 896*8617e85eSMatthieu Baerts (NGI0) while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) { 897*8617e85eSMatthieu Baerts (NGI0) struct sock *sk = (struct sock *)msk; 898*8617e85eSMatthieu Baerts (NGI0) bool remove_subflow; 899*8617e85eSMatthieu Baerts (NGI0) 900*8617e85eSMatthieu Baerts (NGI0) if (mptcp_pm_is_userspace(msk)) 901*8617e85eSMatthieu Baerts (NGI0) goto next; 902*8617e85eSMatthieu Baerts (NGI0) 903*8617e85eSMatthieu Baerts (NGI0) lock_sock(sk); 904*8617e85eSMatthieu Baerts (NGI0) remove_subflow = mptcp_lookup_subflow_by_saddr(&msk->conn_list, addr); 905*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_remove_anno_addr(msk, addr, remove_subflow && 906*8617e85eSMatthieu Baerts (NGI0) !(entry->flags & MPTCP_PM_ADDR_FLAG_IMPLICIT)); 907*8617e85eSMatthieu Baerts (NGI0) 908*8617e85eSMatthieu Baerts (NGI0) list.ids[0] = mptcp_endp_get_local_id(msk, addr); 909*8617e85eSMatthieu Baerts (NGI0) if (remove_subflow) { 910*8617e85eSMatthieu Baerts (NGI0) spin_lock_bh(&msk->pm.lock); 911*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_rm_subflow(msk, &list); 912*8617e85eSMatthieu Baerts (NGI0) spin_unlock_bh(&msk->pm.lock); 913*8617e85eSMatthieu Baerts (NGI0) } 914*8617e85eSMatthieu Baerts (NGI0) 915*8617e85eSMatthieu Baerts (NGI0) if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) { 916*8617e85eSMatthieu Baerts (NGI0) spin_lock_bh(&msk->pm.lock); 917*8617e85eSMatthieu Baerts (NGI0) __mark_subflow_endp_available(msk, list.ids[0]); 918*8617e85eSMatthieu Baerts (NGI0) spin_unlock_bh(&msk->pm.lock); 919*8617e85eSMatthieu Baerts (NGI0) } 920*8617e85eSMatthieu Baerts (NGI0) 921*8617e85eSMatthieu Baerts (NGI0) if (msk->mpc_endpoint_id == entry->addr.id) 922*8617e85eSMatthieu Baerts (NGI0) msk->mpc_endpoint_id = 0; 923*8617e85eSMatthieu Baerts (NGI0) release_sock(sk); 924*8617e85eSMatthieu Baerts (NGI0) 925*8617e85eSMatthieu Baerts (NGI0) next: 926*8617e85eSMatthieu Baerts (NGI0) sock_put(sk); 927*8617e85eSMatthieu Baerts (NGI0) cond_resched(); 928*8617e85eSMatthieu Baerts (NGI0) } 929*8617e85eSMatthieu Baerts (NGI0) 930*8617e85eSMatthieu Baerts (NGI0) return 0; 931*8617e85eSMatthieu Baerts (NGI0) } 932*8617e85eSMatthieu Baerts (NGI0) 933*8617e85eSMatthieu Baerts (NGI0) static int mptcp_nl_remove_id_zero_address(struct net *net, 934*8617e85eSMatthieu Baerts (NGI0) struct mptcp_addr_info *addr) 935*8617e85eSMatthieu Baerts (NGI0) { 936*8617e85eSMatthieu Baerts (NGI0) struct mptcp_rm_list list = { .nr = 0 }; 937*8617e85eSMatthieu Baerts (NGI0) long s_slot = 0, s_num = 0; 938*8617e85eSMatthieu Baerts (NGI0) struct mptcp_sock *msk; 939*8617e85eSMatthieu Baerts (NGI0) 940*8617e85eSMatthieu Baerts (NGI0) list.ids[list.nr++] = 0; 941*8617e85eSMatthieu Baerts (NGI0) 942*8617e85eSMatthieu Baerts (NGI0) while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) { 943*8617e85eSMatthieu Baerts (NGI0) struct sock *sk = (struct sock *)msk; 944*8617e85eSMatthieu Baerts (NGI0) struct mptcp_addr_info msk_local; 945*8617e85eSMatthieu Baerts (NGI0) 946*8617e85eSMatthieu Baerts (NGI0) if (list_empty(&msk->conn_list) || mptcp_pm_is_userspace(msk)) 947*8617e85eSMatthieu Baerts (NGI0) goto next; 948*8617e85eSMatthieu Baerts (NGI0) 949*8617e85eSMatthieu Baerts (NGI0) mptcp_local_address((struct sock_common *)msk, &msk_local); 950*8617e85eSMatthieu Baerts (NGI0) if (!mptcp_addresses_equal(&msk_local, addr, addr->port)) 951*8617e85eSMatthieu Baerts (NGI0) goto next; 952*8617e85eSMatthieu Baerts (NGI0) 953*8617e85eSMatthieu Baerts (NGI0) lock_sock(sk); 954*8617e85eSMatthieu Baerts (NGI0) spin_lock_bh(&msk->pm.lock); 955*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_remove_addr(msk, &list); 956*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_rm_subflow(msk, &list); 957*8617e85eSMatthieu Baerts (NGI0) __mark_subflow_endp_available(msk, 0); 958*8617e85eSMatthieu Baerts (NGI0) spin_unlock_bh(&msk->pm.lock); 959*8617e85eSMatthieu Baerts (NGI0) release_sock(sk); 960*8617e85eSMatthieu Baerts (NGI0) 961*8617e85eSMatthieu Baerts (NGI0) next: 962*8617e85eSMatthieu Baerts (NGI0) sock_put(sk); 963*8617e85eSMatthieu Baerts (NGI0) cond_resched(); 964*8617e85eSMatthieu Baerts (NGI0) } 965*8617e85eSMatthieu Baerts (NGI0) 966*8617e85eSMatthieu Baerts (NGI0) return 0; 967*8617e85eSMatthieu Baerts (NGI0) } 968*8617e85eSMatthieu Baerts (NGI0) 969*8617e85eSMatthieu Baerts (NGI0) /* Remove an MPTCP endpoint */ 970*8617e85eSMatthieu Baerts (NGI0) int mptcp_pm_nl_del_addr_doit(struct sk_buff *skb, struct genl_info *info) 971*8617e85eSMatthieu Baerts (NGI0) { 972*8617e85eSMatthieu Baerts (NGI0) struct pm_nl_pernet *pernet = genl_info_pm_nl(info); 973*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_addr_entry addr, *entry; 974*8617e85eSMatthieu Baerts (NGI0) unsigned int addr_max; 975*8617e85eSMatthieu Baerts (NGI0) struct nlattr *attr; 976*8617e85eSMatthieu Baerts (NGI0) int ret; 977*8617e85eSMatthieu Baerts (NGI0) 978*8617e85eSMatthieu Baerts (NGI0) if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ENDPOINT_ADDR)) 979*8617e85eSMatthieu Baerts (NGI0) return -EINVAL; 980*8617e85eSMatthieu Baerts (NGI0) 981*8617e85eSMatthieu Baerts (NGI0) attr = info->attrs[MPTCP_PM_ENDPOINT_ADDR]; 982*8617e85eSMatthieu Baerts (NGI0) ret = mptcp_pm_parse_entry(attr, info, false, &addr); 983*8617e85eSMatthieu Baerts (NGI0) if (ret < 0) 984*8617e85eSMatthieu Baerts (NGI0) return ret; 985*8617e85eSMatthieu Baerts (NGI0) 986*8617e85eSMatthieu Baerts (NGI0) /* the zero id address is special: the first address used by the msk 987*8617e85eSMatthieu Baerts (NGI0) * always gets such an id, so different subflows can have different zero 988*8617e85eSMatthieu Baerts (NGI0) * id addresses. Additionally zero id is not accounted for in id_bitmap. 989*8617e85eSMatthieu Baerts (NGI0) * Let's use an 'mptcp_rm_list' instead of the common remove code. 990*8617e85eSMatthieu Baerts (NGI0) */ 991*8617e85eSMatthieu Baerts (NGI0) if (addr.addr.id == 0) 992*8617e85eSMatthieu Baerts (NGI0) return mptcp_nl_remove_id_zero_address(sock_net(skb->sk), &addr.addr); 993*8617e85eSMatthieu Baerts (NGI0) 994*8617e85eSMatthieu Baerts (NGI0) spin_lock_bh(&pernet->lock); 995*8617e85eSMatthieu Baerts (NGI0) entry = __lookup_addr_by_id(pernet, addr.addr.id); 996*8617e85eSMatthieu Baerts (NGI0) if (!entry) { 997*8617e85eSMatthieu Baerts (NGI0) NL_SET_ERR_MSG_ATTR(info->extack, attr, "address not found"); 998*8617e85eSMatthieu Baerts (NGI0) spin_unlock_bh(&pernet->lock); 999*8617e85eSMatthieu Baerts (NGI0) return -EINVAL; 1000*8617e85eSMatthieu Baerts (NGI0) } 1001*8617e85eSMatthieu Baerts (NGI0) if (entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL) { 1002*8617e85eSMatthieu Baerts (NGI0) addr_max = pernet->add_addr_signal_max; 1003*8617e85eSMatthieu Baerts (NGI0) WRITE_ONCE(pernet->add_addr_signal_max, addr_max - 1); 1004*8617e85eSMatthieu Baerts (NGI0) } 1005*8617e85eSMatthieu Baerts (NGI0) if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) { 1006*8617e85eSMatthieu Baerts (NGI0) addr_max = pernet->local_addr_max; 1007*8617e85eSMatthieu Baerts (NGI0) WRITE_ONCE(pernet->local_addr_max, addr_max - 1); 1008*8617e85eSMatthieu Baerts (NGI0) } 1009*8617e85eSMatthieu Baerts (NGI0) 1010*8617e85eSMatthieu Baerts (NGI0) pernet->addrs--; 1011*8617e85eSMatthieu Baerts (NGI0) list_del_rcu(&entry->list); 1012*8617e85eSMatthieu Baerts (NGI0) __clear_bit(entry->addr.id, pernet->id_bitmap); 1013*8617e85eSMatthieu Baerts (NGI0) spin_unlock_bh(&pernet->lock); 1014*8617e85eSMatthieu Baerts (NGI0) 1015*8617e85eSMatthieu Baerts (NGI0) mptcp_nl_remove_subflow_and_signal_addr(sock_net(skb->sk), entry); 1016*8617e85eSMatthieu Baerts (NGI0) synchronize_rcu(); 1017*8617e85eSMatthieu Baerts (NGI0) __mptcp_pm_release_addr_entry(entry); 1018*8617e85eSMatthieu Baerts (NGI0) 1019*8617e85eSMatthieu Baerts (NGI0) return ret; 1020*8617e85eSMatthieu Baerts (NGI0) } 1021*8617e85eSMatthieu Baerts (NGI0) 1022*8617e85eSMatthieu Baerts (NGI0) static void mptcp_pm_flush_addrs_and_subflows(struct mptcp_sock *msk, 1023*8617e85eSMatthieu Baerts (NGI0) struct list_head *rm_list) 1024*8617e85eSMatthieu Baerts (NGI0) { 1025*8617e85eSMatthieu Baerts (NGI0) struct mptcp_rm_list alist = { .nr = 0 }, slist = { .nr = 0 }; 1026*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_addr_entry *entry; 1027*8617e85eSMatthieu Baerts (NGI0) 1028*8617e85eSMatthieu Baerts (NGI0) list_for_each_entry(entry, rm_list, list) { 1029*8617e85eSMatthieu Baerts (NGI0) if (slist.nr < MPTCP_RM_IDS_MAX && 1030*8617e85eSMatthieu Baerts (NGI0) mptcp_lookup_subflow_by_saddr(&msk->conn_list, &entry->addr)) 1031*8617e85eSMatthieu Baerts (NGI0) slist.ids[slist.nr++] = mptcp_endp_get_local_id(msk, &entry->addr); 1032*8617e85eSMatthieu Baerts (NGI0) 1033*8617e85eSMatthieu Baerts (NGI0) if (alist.nr < MPTCP_RM_IDS_MAX && 1034*8617e85eSMatthieu Baerts (NGI0) mptcp_remove_anno_list_by_saddr(msk, &entry->addr)) 1035*8617e85eSMatthieu Baerts (NGI0) alist.ids[alist.nr++] = mptcp_endp_get_local_id(msk, &entry->addr); 1036*8617e85eSMatthieu Baerts (NGI0) } 1037*8617e85eSMatthieu Baerts (NGI0) 1038*8617e85eSMatthieu Baerts (NGI0) spin_lock_bh(&msk->pm.lock); 1039*8617e85eSMatthieu Baerts (NGI0) if (alist.nr) { 1040*8617e85eSMatthieu Baerts (NGI0) msk->pm.add_addr_signaled -= alist.nr; 1041*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_remove_addr(msk, &alist); 1042*8617e85eSMatthieu Baerts (NGI0) } 1043*8617e85eSMatthieu Baerts (NGI0) if (slist.nr) 1044*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_rm_subflow(msk, &slist); 1045*8617e85eSMatthieu Baerts (NGI0) /* Reset counters: maybe some subflows have been removed before */ 1046*8617e85eSMatthieu Baerts (NGI0) bitmap_fill(msk->pm.id_avail_bitmap, MPTCP_PM_MAX_ADDR_ID + 1); 1047*8617e85eSMatthieu Baerts (NGI0) msk->pm.local_addr_used = 0; 1048*8617e85eSMatthieu Baerts (NGI0) spin_unlock_bh(&msk->pm.lock); 1049*8617e85eSMatthieu Baerts (NGI0) } 1050*8617e85eSMatthieu Baerts (NGI0) 1051*8617e85eSMatthieu Baerts (NGI0) static void mptcp_nl_flush_addrs_list(struct net *net, 1052*8617e85eSMatthieu Baerts (NGI0) struct list_head *rm_list) 1053*8617e85eSMatthieu Baerts (NGI0) { 1054*8617e85eSMatthieu Baerts (NGI0) long s_slot = 0, s_num = 0; 1055*8617e85eSMatthieu Baerts (NGI0) struct mptcp_sock *msk; 1056*8617e85eSMatthieu Baerts (NGI0) 1057*8617e85eSMatthieu Baerts (NGI0) if (list_empty(rm_list)) 1058*8617e85eSMatthieu Baerts (NGI0) return; 1059*8617e85eSMatthieu Baerts (NGI0) 1060*8617e85eSMatthieu Baerts (NGI0) while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) { 1061*8617e85eSMatthieu Baerts (NGI0) struct sock *sk = (struct sock *)msk; 1062*8617e85eSMatthieu Baerts (NGI0) 1063*8617e85eSMatthieu Baerts (NGI0) if (!mptcp_pm_is_userspace(msk)) { 1064*8617e85eSMatthieu Baerts (NGI0) lock_sock(sk); 1065*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_flush_addrs_and_subflows(msk, rm_list); 1066*8617e85eSMatthieu Baerts (NGI0) release_sock(sk); 1067*8617e85eSMatthieu Baerts (NGI0) } 1068*8617e85eSMatthieu Baerts (NGI0) 1069*8617e85eSMatthieu Baerts (NGI0) sock_put(sk); 1070*8617e85eSMatthieu Baerts (NGI0) cond_resched(); 1071*8617e85eSMatthieu Baerts (NGI0) } 1072*8617e85eSMatthieu Baerts (NGI0) } 1073*8617e85eSMatthieu Baerts (NGI0) 1074*8617e85eSMatthieu Baerts (NGI0) /* caller must ensure the RCU grace period is already elapsed */ 1075*8617e85eSMatthieu Baerts (NGI0) static void __flush_addrs(struct list_head *list) 1076*8617e85eSMatthieu Baerts (NGI0) { 1077*8617e85eSMatthieu Baerts (NGI0) while (!list_empty(list)) { 1078*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_addr_entry *cur; 1079*8617e85eSMatthieu Baerts (NGI0) 1080*8617e85eSMatthieu Baerts (NGI0) cur = list_entry(list->next, 1081*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_addr_entry, list); 1082*8617e85eSMatthieu Baerts (NGI0) list_del_rcu(&cur->list); 1083*8617e85eSMatthieu Baerts (NGI0) __mptcp_pm_release_addr_entry(cur); 1084*8617e85eSMatthieu Baerts (NGI0) } 1085*8617e85eSMatthieu Baerts (NGI0) } 1086*8617e85eSMatthieu Baerts (NGI0) 1087*8617e85eSMatthieu Baerts (NGI0) static void __reset_counters(struct pm_nl_pernet *pernet) 1088*8617e85eSMatthieu Baerts (NGI0) { 1089*8617e85eSMatthieu Baerts (NGI0) WRITE_ONCE(pernet->add_addr_signal_max, 0); 1090*8617e85eSMatthieu Baerts (NGI0) WRITE_ONCE(pernet->add_addr_accept_max, 0); 1091*8617e85eSMatthieu Baerts (NGI0) WRITE_ONCE(pernet->local_addr_max, 0); 1092*8617e85eSMatthieu Baerts (NGI0) pernet->addrs = 0; 1093*8617e85eSMatthieu Baerts (NGI0) } 1094*8617e85eSMatthieu Baerts (NGI0) 1095*8617e85eSMatthieu Baerts (NGI0) int mptcp_pm_nl_flush_addrs_doit(struct sk_buff *skb, struct genl_info *info) 1096*8617e85eSMatthieu Baerts (NGI0) { 1097*8617e85eSMatthieu Baerts (NGI0) struct pm_nl_pernet *pernet = genl_info_pm_nl(info); 1098*8617e85eSMatthieu Baerts (NGI0) LIST_HEAD(free_list); 1099*8617e85eSMatthieu Baerts (NGI0) 1100*8617e85eSMatthieu Baerts (NGI0) spin_lock_bh(&pernet->lock); 1101*8617e85eSMatthieu Baerts (NGI0) list_splice_init(&pernet->local_addr_list, &free_list); 1102*8617e85eSMatthieu Baerts (NGI0) __reset_counters(pernet); 1103*8617e85eSMatthieu Baerts (NGI0) pernet->next_id = 1; 1104*8617e85eSMatthieu Baerts (NGI0) bitmap_zero(pernet->id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1); 1105*8617e85eSMatthieu Baerts (NGI0) spin_unlock_bh(&pernet->lock); 1106*8617e85eSMatthieu Baerts (NGI0) mptcp_nl_flush_addrs_list(sock_net(skb->sk), &free_list); 1107*8617e85eSMatthieu Baerts (NGI0) synchronize_rcu(); 1108*8617e85eSMatthieu Baerts (NGI0) __flush_addrs(&free_list); 1109*8617e85eSMatthieu Baerts (NGI0) return 0; 1110*8617e85eSMatthieu Baerts (NGI0) } 1111*8617e85eSMatthieu Baerts (NGI0) 1112*8617e85eSMatthieu Baerts (NGI0) int mptcp_pm_nl_get_addr(u8 id, struct mptcp_pm_addr_entry *addr, 1113*8617e85eSMatthieu Baerts (NGI0) struct genl_info *info) 1114*8617e85eSMatthieu Baerts (NGI0) { 1115*8617e85eSMatthieu Baerts (NGI0) struct pm_nl_pernet *pernet = genl_info_pm_nl(info); 1116*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_addr_entry *entry; 1117*8617e85eSMatthieu Baerts (NGI0) int ret = -EINVAL; 1118*8617e85eSMatthieu Baerts (NGI0) 1119*8617e85eSMatthieu Baerts (NGI0) rcu_read_lock(); 1120*8617e85eSMatthieu Baerts (NGI0) entry = __lookup_addr_by_id(pernet, id); 1121*8617e85eSMatthieu Baerts (NGI0) if (entry) { 1122*8617e85eSMatthieu Baerts (NGI0) *addr = *entry; 1123*8617e85eSMatthieu Baerts (NGI0) ret = 0; 1124*8617e85eSMatthieu Baerts (NGI0) } 1125*8617e85eSMatthieu Baerts (NGI0) rcu_read_unlock(); 1126*8617e85eSMatthieu Baerts (NGI0) 1127*8617e85eSMatthieu Baerts (NGI0) return ret; 1128*8617e85eSMatthieu Baerts (NGI0) } 1129*8617e85eSMatthieu Baerts (NGI0) 1130*8617e85eSMatthieu Baerts (NGI0) int mptcp_pm_nl_dump_addr(struct sk_buff *msg, 1131*8617e85eSMatthieu Baerts (NGI0) struct netlink_callback *cb) 1132*8617e85eSMatthieu Baerts (NGI0) { 1133*8617e85eSMatthieu Baerts (NGI0) struct net *net = sock_net(msg->sk); 1134*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_addr_entry *entry; 1135*8617e85eSMatthieu Baerts (NGI0) struct pm_nl_pernet *pernet; 1136*8617e85eSMatthieu Baerts (NGI0) int id = cb->args[0]; 1137*8617e85eSMatthieu Baerts (NGI0) int i; 1138*8617e85eSMatthieu Baerts (NGI0) 1139*8617e85eSMatthieu Baerts (NGI0) pernet = pm_nl_get_pernet(net); 1140*8617e85eSMatthieu Baerts (NGI0) 1141*8617e85eSMatthieu Baerts (NGI0) rcu_read_lock(); 1142*8617e85eSMatthieu Baerts (NGI0) for (i = id; i < MPTCP_PM_MAX_ADDR_ID + 1; i++) { 1143*8617e85eSMatthieu Baerts (NGI0) if (test_bit(i, pernet->id_bitmap)) { 1144*8617e85eSMatthieu Baerts (NGI0) entry = __lookup_addr_by_id(pernet, i); 1145*8617e85eSMatthieu Baerts (NGI0) if (!entry) 1146*8617e85eSMatthieu Baerts (NGI0) break; 1147*8617e85eSMatthieu Baerts (NGI0) 1148*8617e85eSMatthieu Baerts (NGI0) if (entry->addr.id <= id) 1149*8617e85eSMatthieu Baerts (NGI0) continue; 1150*8617e85eSMatthieu Baerts (NGI0) 1151*8617e85eSMatthieu Baerts (NGI0) if (mptcp_pm_genl_fill_addr(msg, cb, entry) < 0) 1152*8617e85eSMatthieu Baerts (NGI0) break; 1153*8617e85eSMatthieu Baerts (NGI0) 1154*8617e85eSMatthieu Baerts (NGI0) id = entry->addr.id; 1155*8617e85eSMatthieu Baerts (NGI0) } 1156*8617e85eSMatthieu Baerts (NGI0) } 1157*8617e85eSMatthieu Baerts (NGI0) rcu_read_unlock(); 1158*8617e85eSMatthieu Baerts (NGI0) 1159*8617e85eSMatthieu Baerts (NGI0) cb->args[0] = id; 1160*8617e85eSMatthieu Baerts (NGI0) return msg->len; 1161*8617e85eSMatthieu Baerts (NGI0) } 1162*8617e85eSMatthieu Baerts (NGI0) 1163*8617e85eSMatthieu Baerts (NGI0) static int parse_limit(struct genl_info *info, int id, unsigned int *limit) 1164*8617e85eSMatthieu Baerts (NGI0) { 1165*8617e85eSMatthieu Baerts (NGI0) struct nlattr *attr = info->attrs[id]; 1166*8617e85eSMatthieu Baerts (NGI0) 1167*8617e85eSMatthieu Baerts (NGI0) if (!attr) 1168*8617e85eSMatthieu Baerts (NGI0) return 0; 1169*8617e85eSMatthieu Baerts (NGI0) 1170*8617e85eSMatthieu Baerts (NGI0) *limit = nla_get_u32(attr); 1171*8617e85eSMatthieu Baerts (NGI0) if (*limit > MPTCP_PM_ADDR_MAX) { 1172*8617e85eSMatthieu Baerts (NGI0) NL_SET_ERR_MSG_ATTR_FMT(info->extack, attr, 1173*8617e85eSMatthieu Baerts (NGI0) "limit greater than maximum (%u)", 1174*8617e85eSMatthieu Baerts (NGI0) MPTCP_PM_ADDR_MAX); 1175*8617e85eSMatthieu Baerts (NGI0) return -EINVAL; 1176*8617e85eSMatthieu Baerts (NGI0) } 1177*8617e85eSMatthieu Baerts (NGI0) return 0; 1178*8617e85eSMatthieu Baerts (NGI0) } 1179*8617e85eSMatthieu Baerts (NGI0) 1180*8617e85eSMatthieu Baerts (NGI0) int mptcp_pm_nl_set_limits_doit(struct sk_buff *skb, struct genl_info *info) 1181*8617e85eSMatthieu Baerts (NGI0) { 1182*8617e85eSMatthieu Baerts (NGI0) struct pm_nl_pernet *pernet = genl_info_pm_nl(info); 1183*8617e85eSMatthieu Baerts (NGI0) unsigned int rcv_addrs, subflows; 1184*8617e85eSMatthieu Baerts (NGI0) int ret; 1185*8617e85eSMatthieu Baerts (NGI0) 1186*8617e85eSMatthieu Baerts (NGI0) spin_lock_bh(&pernet->lock); 1187*8617e85eSMatthieu Baerts (NGI0) rcv_addrs = pernet->add_addr_accept_max; 1188*8617e85eSMatthieu Baerts (NGI0) ret = parse_limit(info, MPTCP_PM_ATTR_RCV_ADD_ADDRS, &rcv_addrs); 1189*8617e85eSMatthieu Baerts (NGI0) if (ret) 1190*8617e85eSMatthieu Baerts (NGI0) goto unlock; 1191*8617e85eSMatthieu Baerts (NGI0) 1192*8617e85eSMatthieu Baerts (NGI0) subflows = pernet->subflows_max; 1193*8617e85eSMatthieu Baerts (NGI0) ret = parse_limit(info, MPTCP_PM_ATTR_SUBFLOWS, &subflows); 1194*8617e85eSMatthieu Baerts (NGI0) if (ret) 1195*8617e85eSMatthieu Baerts (NGI0) goto unlock; 1196*8617e85eSMatthieu Baerts (NGI0) 1197*8617e85eSMatthieu Baerts (NGI0) WRITE_ONCE(pernet->add_addr_accept_max, rcv_addrs); 1198*8617e85eSMatthieu Baerts (NGI0) WRITE_ONCE(pernet->subflows_max, subflows); 1199*8617e85eSMatthieu Baerts (NGI0) 1200*8617e85eSMatthieu Baerts (NGI0) unlock: 1201*8617e85eSMatthieu Baerts (NGI0) spin_unlock_bh(&pernet->lock); 1202*8617e85eSMatthieu Baerts (NGI0) return ret; 1203*8617e85eSMatthieu Baerts (NGI0) } 1204*8617e85eSMatthieu Baerts (NGI0) 1205*8617e85eSMatthieu Baerts (NGI0) int mptcp_pm_nl_get_limits_doit(struct sk_buff *skb, struct genl_info *info) 1206*8617e85eSMatthieu Baerts (NGI0) { 1207*8617e85eSMatthieu Baerts (NGI0) struct pm_nl_pernet *pernet = genl_info_pm_nl(info); 1208*8617e85eSMatthieu Baerts (NGI0) struct sk_buff *msg; 1209*8617e85eSMatthieu Baerts (NGI0) void *reply; 1210*8617e85eSMatthieu Baerts (NGI0) 1211*8617e85eSMatthieu Baerts (NGI0) msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1212*8617e85eSMatthieu Baerts (NGI0) if (!msg) 1213*8617e85eSMatthieu Baerts (NGI0) return -ENOMEM; 1214*8617e85eSMatthieu Baerts (NGI0) 1215*8617e85eSMatthieu Baerts (NGI0) reply = genlmsg_put_reply(msg, info, &mptcp_genl_family, 0, 1216*8617e85eSMatthieu Baerts (NGI0) MPTCP_PM_CMD_GET_LIMITS); 1217*8617e85eSMatthieu Baerts (NGI0) if (!reply) 1218*8617e85eSMatthieu Baerts (NGI0) goto fail; 1219*8617e85eSMatthieu Baerts (NGI0) 1220*8617e85eSMatthieu Baerts (NGI0) if (nla_put_u32(msg, MPTCP_PM_ATTR_RCV_ADD_ADDRS, 1221*8617e85eSMatthieu Baerts (NGI0) READ_ONCE(pernet->add_addr_accept_max))) 1222*8617e85eSMatthieu Baerts (NGI0) goto fail; 1223*8617e85eSMatthieu Baerts (NGI0) 1224*8617e85eSMatthieu Baerts (NGI0) if (nla_put_u32(msg, MPTCP_PM_ATTR_SUBFLOWS, 1225*8617e85eSMatthieu Baerts (NGI0) READ_ONCE(pernet->subflows_max))) 1226*8617e85eSMatthieu Baerts (NGI0) goto fail; 1227*8617e85eSMatthieu Baerts (NGI0) 1228*8617e85eSMatthieu Baerts (NGI0) genlmsg_end(msg, reply); 1229*8617e85eSMatthieu Baerts (NGI0) return genlmsg_reply(msg, info); 1230*8617e85eSMatthieu Baerts (NGI0) 1231*8617e85eSMatthieu Baerts (NGI0) fail: 1232*8617e85eSMatthieu Baerts (NGI0) GENL_SET_ERR_MSG(info, "not enough space in Netlink message"); 1233*8617e85eSMatthieu Baerts (NGI0) nlmsg_free(msg); 1234*8617e85eSMatthieu Baerts (NGI0) return -EMSGSIZE; 1235*8617e85eSMatthieu Baerts (NGI0) } 1236*8617e85eSMatthieu Baerts (NGI0) 1237*8617e85eSMatthieu Baerts (NGI0) static void mptcp_pm_nl_fullmesh(struct mptcp_sock *msk, 1238*8617e85eSMatthieu Baerts (NGI0) struct mptcp_addr_info *addr) 1239*8617e85eSMatthieu Baerts (NGI0) { 1240*8617e85eSMatthieu Baerts (NGI0) struct mptcp_rm_list list = { .nr = 0 }; 1241*8617e85eSMatthieu Baerts (NGI0) 1242*8617e85eSMatthieu Baerts (NGI0) list.ids[list.nr++] = mptcp_endp_get_local_id(msk, addr); 1243*8617e85eSMatthieu Baerts (NGI0) 1244*8617e85eSMatthieu Baerts (NGI0) spin_lock_bh(&msk->pm.lock); 1245*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_rm_subflow(msk, &list); 1246*8617e85eSMatthieu Baerts (NGI0) __mark_subflow_endp_available(msk, list.ids[0]); 1247*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_create_subflow_or_signal_addr(msk); 1248*8617e85eSMatthieu Baerts (NGI0) spin_unlock_bh(&msk->pm.lock); 1249*8617e85eSMatthieu Baerts (NGI0) } 1250*8617e85eSMatthieu Baerts (NGI0) 1251*8617e85eSMatthieu Baerts (NGI0) static void mptcp_pm_nl_set_flags_all(struct net *net, 1252*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_addr_entry *local, 1253*8617e85eSMatthieu Baerts (NGI0) u8 changed) 1254*8617e85eSMatthieu Baerts (NGI0) { 1255*8617e85eSMatthieu Baerts (NGI0) u8 is_subflow = !!(local->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW); 1256*8617e85eSMatthieu Baerts (NGI0) u8 bkup = !!(local->flags & MPTCP_PM_ADDR_FLAG_BACKUP); 1257*8617e85eSMatthieu Baerts (NGI0) long s_slot = 0, s_num = 0; 1258*8617e85eSMatthieu Baerts (NGI0) struct mptcp_sock *msk; 1259*8617e85eSMatthieu Baerts (NGI0) 1260*8617e85eSMatthieu Baerts (NGI0) if (changed == MPTCP_PM_ADDR_FLAG_FULLMESH && !is_subflow) 1261*8617e85eSMatthieu Baerts (NGI0) return; 1262*8617e85eSMatthieu Baerts (NGI0) 1263*8617e85eSMatthieu Baerts (NGI0) while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) { 1264*8617e85eSMatthieu Baerts (NGI0) struct sock *sk = (struct sock *)msk; 1265*8617e85eSMatthieu Baerts (NGI0) 1266*8617e85eSMatthieu Baerts (NGI0) if (list_empty(&msk->conn_list) || mptcp_pm_is_userspace(msk)) 1267*8617e85eSMatthieu Baerts (NGI0) goto next; 1268*8617e85eSMatthieu Baerts (NGI0) 1269*8617e85eSMatthieu Baerts (NGI0) lock_sock(sk); 1270*8617e85eSMatthieu Baerts (NGI0) if (changed & MPTCP_PM_ADDR_FLAG_BACKUP) 1271*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_mp_prio_send_ack(msk, &local->addr, NULL, bkup); 1272*8617e85eSMatthieu Baerts (NGI0) /* Subflows will only be recreated if the SUBFLOW flag is set */ 1273*8617e85eSMatthieu Baerts (NGI0) if (is_subflow && (changed & MPTCP_PM_ADDR_FLAG_FULLMESH)) 1274*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_nl_fullmesh(msk, &local->addr); 1275*8617e85eSMatthieu Baerts (NGI0) release_sock(sk); 1276*8617e85eSMatthieu Baerts (NGI0) 1277*8617e85eSMatthieu Baerts (NGI0) next: 1278*8617e85eSMatthieu Baerts (NGI0) sock_put(sk); 1279*8617e85eSMatthieu Baerts (NGI0) cond_resched(); 1280*8617e85eSMatthieu Baerts (NGI0) } 1281*8617e85eSMatthieu Baerts (NGI0) } 1282*8617e85eSMatthieu Baerts (NGI0) 1283*8617e85eSMatthieu Baerts (NGI0) int mptcp_pm_nl_set_flags(struct mptcp_pm_addr_entry *local, 1284*8617e85eSMatthieu Baerts (NGI0) struct genl_info *info) 1285*8617e85eSMatthieu Baerts (NGI0) { 1286*8617e85eSMatthieu Baerts (NGI0) struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR]; 1287*8617e85eSMatthieu Baerts (NGI0) u8 changed, mask = MPTCP_PM_ADDR_FLAG_BACKUP | 1288*8617e85eSMatthieu Baerts (NGI0) MPTCP_PM_ADDR_FLAG_FULLMESH; 1289*8617e85eSMatthieu Baerts (NGI0) struct net *net = genl_info_net(info); 1290*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_addr_entry *entry; 1291*8617e85eSMatthieu Baerts (NGI0) struct pm_nl_pernet *pernet; 1292*8617e85eSMatthieu Baerts (NGI0) u8 lookup_by_id = 0; 1293*8617e85eSMatthieu Baerts (NGI0) 1294*8617e85eSMatthieu Baerts (NGI0) pernet = pm_nl_get_pernet(net); 1295*8617e85eSMatthieu Baerts (NGI0) 1296*8617e85eSMatthieu Baerts (NGI0) if (local->addr.family == AF_UNSPEC) { 1297*8617e85eSMatthieu Baerts (NGI0) lookup_by_id = 1; 1298*8617e85eSMatthieu Baerts (NGI0) if (!local->addr.id) { 1299*8617e85eSMatthieu Baerts (NGI0) NL_SET_ERR_MSG_ATTR(info->extack, attr, 1300*8617e85eSMatthieu Baerts (NGI0) "missing address ID"); 1301*8617e85eSMatthieu Baerts (NGI0) return -EOPNOTSUPP; 1302*8617e85eSMatthieu Baerts (NGI0) } 1303*8617e85eSMatthieu Baerts (NGI0) } 1304*8617e85eSMatthieu Baerts (NGI0) 1305*8617e85eSMatthieu Baerts (NGI0) spin_lock_bh(&pernet->lock); 1306*8617e85eSMatthieu Baerts (NGI0) entry = lookup_by_id ? __lookup_addr_by_id(pernet, local->addr.id) : 1307*8617e85eSMatthieu Baerts (NGI0) __lookup_addr(pernet, &local->addr); 1308*8617e85eSMatthieu Baerts (NGI0) if (!entry) { 1309*8617e85eSMatthieu Baerts (NGI0) spin_unlock_bh(&pernet->lock); 1310*8617e85eSMatthieu Baerts (NGI0) NL_SET_ERR_MSG_ATTR(info->extack, attr, "address not found"); 1311*8617e85eSMatthieu Baerts (NGI0) return -EINVAL; 1312*8617e85eSMatthieu Baerts (NGI0) } 1313*8617e85eSMatthieu Baerts (NGI0) if ((local->flags & MPTCP_PM_ADDR_FLAG_FULLMESH) && 1314*8617e85eSMatthieu Baerts (NGI0) (entry->flags & (MPTCP_PM_ADDR_FLAG_SIGNAL | 1315*8617e85eSMatthieu Baerts (NGI0) MPTCP_PM_ADDR_FLAG_IMPLICIT))) { 1316*8617e85eSMatthieu Baerts (NGI0) spin_unlock_bh(&pernet->lock); 1317*8617e85eSMatthieu Baerts (NGI0) NL_SET_ERR_MSG_ATTR(info->extack, attr, "invalid addr flags"); 1318*8617e85eSMatthieu Baerts (NGI0) return -EINVAL; 1319*8617e85eSMatthieu Baerts (NGI0) } 1320*8617e85eSMatthieu Baerts (NGI0) 1321*8617e85eSMatthieu Baerts (NGI0) changed = (local->flags ^ entry->flags) & mask; 1322*8617e85eSMatthieu Baerts (NGI0) entry->flags = (entry->flags & ~mask) | (local->flags & mask); 1323*8617e85eSMatthieu Baerts (NGI0) *local = *entry; 1324*8617e85eSMatthieu Baerts (NGI0) spin_unlock_bh(&pernet->lock); 1325*8617e85eSMatthieu Baerts (NGI0) 1326*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_nl_set_flags_all(net, local, changed); 1327*8617e85eSMatthieu Baerts (NGI0) return 0; 1328*8617e85eSMatthieu Baerts (NGI0) } 1329*8617e85eSMatthieu Baerts (NGI0) 1330*8617e85eSMatthieu Baerts (NGI0) bool mptcp_pm_nl_check_work_pending(struct mptcp_sock *msk) 1331*8617e85eSMatthieu Baerts (NGI0) { 1332*8617e85eSMatthieu Baerts (NGI0) struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk); 1333*8617e85eSMatthieu Baerts (NGI0) 1334*8617e85eSMatthieu Baerts (NGI0) if (msk->pm.subflows == mptcp_pm_get_subflows_max(msk) || 1335*8617e85eSMatthieu Baerts (NGI0) (find_next_and_bit(pernet->id_bitmap, msk->pm.id_avail_bitmap, 1336*8617e85eSMatthieu Baerts (NGI0) MPTCP_PM_MAX_ADDR_ID + 1, 0) == MPTCP_PM_MAX_ADDR_ID + 1)) { 1337*8617e85eSMatthieu Baerts (NGI0) WRITE_ONCE(msk->pm.work_pending, false); 1338*8617e85eSMatthieu Baerts (NGI0) return false; 1339*8617e85eSMatthieu Baerts (NGI0) } 1340*8617e85eSMatthieu Baerts (NGI0) return true; 1341*8617e85eSMatthieu Baerts (NGI0) } 1342*8617e85eSMatthieu Baerts (NGI0) 1343*8617e85eSMatthieu Baerts (NGI0) /* Called under PM lock */ 1344*8617e85eSMatthieu Baerts (NGI0) void __mptcp_pm_kernel_worker(struct mptcp_sock *msk) 1345*8617e85eSMatthieu Baerts (NGI0) { 1346*8617e85eSMatthieu Baerts (NGI0) struct mptcp_pm_data *pm = &msk->pm; 1347*8617e85eSMatthieu Baerts (NGI0) 1348*8617e85eSMatthieu Baerts (NGI0) if (pm->status & BIT(MPTCP_PM_ADD_ADDR_RECEIVED)) { 1349*8617e85eSMatthieu Baerts (NGI0) pm->status &= ~BIT(MPTCP_PM_ADD_ADDR_RECEIVED); 1350*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_nl_add_addr_received(msk); 1351*8617e85eSMatthieu Baerts (NGI0) } 1352*8617e85eSMatthieu Baerts (NGI0) if (pm->status & BIT(MPTCP_PM_ESTABLISHED)) { 1353*8617e85eSMatthieu Baerts (NGI0) pm->status &= ~BIT(MPTCP_PM_ESTABLISHED); 1354*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_nl_fully_established(msk); 1355*8617e85eSMatthieu Baerts (NGI0) } 1356*8617e85eSMatthieu Baerts (NGI0) if (pm->status & BIT(MPTCP_PM_SUBFLOW_ESTABLISHED)) { 1357*8617e85eSMatthieu Baerts (NGI0) pm->status &= ~BIT(MPTCP_PM_SUBFLOW_ESTABLISHED); 1358*8617e85eSMatthieu Baerts (NGI0) mptcp_pm_nl_subflow_established(msk); 1359*8617e85eSMatthieu Baerts (NGI0) } 1360*8617e85eSMatthieu Baerts (NGI0) } 1361*8617e85eSMatthieu Baerts (NGI0) 1362*8617e85eSMatthieu Baerts (NGI0) static int __net_init pm_nl_init_net(struct net *net) 1363*8617e85eSMatthieu Baerts (NGI0) { 1364*8617e85eSMatthieu Baerts (NGI0) struct pm_nl_pernet *pernet = pm_nl_get_pernet(net); 1365*8617e85eSMatthieu Baerts (NGI0) 1366*8617e85eSMatthieu Baerts (NGI0) INIT_LIST_HEAD_RCU(&pernet->local_addr_list); 1367*8617e85eSMatthieu Baerts (NGI0) 1368*8617e85eSMatthieu Baerts (NGI0) /* Cit. 2 subflows ought to be enough for anybody. */ 1369*8617e85eSMatthieu Baerts (NGI0) pernet->subflows_max = 2; 1370*8617e85eSMatthieu Baerts (NGI0) pernet->next_id = 1; 1371*8617e85eSMatthieu Baerts (NGI0) pernet->stale_loss_cnt = 4; 1372*8617e85eSMatthieu Baerts (NGI0) spin_lock_init(&pernet->lock); 1373*8617e85eSMatthieu Baerts (NGI0) 1374*8617e85eSMatthieu Baerts (NGI0) /* No need to initialize other pernet fields, the struct is zeroed at 1375*8617e85eSMatthieu Baerts (NGI0) * allocation time. 1376*8617e85eSMatthieu Baerts (NGI0) */ 1377*8617e85eSMatthieu Baerts (NGI0) 1378*8617e85eSMatthieu Baerts (NGI0) return 0; 1379*8617e85eSMatthieu Baerts (NGI0) } 1380*8617e85eSMatthieu Baerts (NGI0) 1381*8617e85eSMatthieu Baerts (NGI0) static void __net_exit pm_nl_exit_net(struct list_head *net_list) 1382*8617e85eSMatthieu Baerts (NGI0) { 1383*8617e85eSMatthieu Baerts (NGI0) struct net *net; 1384*8617e85eSMatthieu Baerts (NGI0) 1385*8617e85eSMatthieu Baerts (NGI0) list_for_each_entry(net, net_list, exit_list) { 1386*8617e85eSMatthieu Baerts (NGI0) struct pm_nl_pernet *pernet = pm_nl_get_pernet(net); 1387*8617e85eSMatthieu Baerts (NGI0) 1388*8617e85eSMatthieu Baerts (NGI0) /* net is removed from namespace list, can't race with 1389*8617e85eSMatthieu Baerts (NGI0) * other modifiers, also netns core already waited for a 1390*8617e85eSMatthieu Baerts (NGI0) * RCU grace period. 1391*8617e85eSMatthieu Baerts (NGI0) */ 1392*8617e85eSMatthieu Baerts (NGI0) __flush_addrs(&pernet->local_addr_list); 1393*8617e85eSMatthieu Baerts (NGI0) } 1394*8617e85eSMatthieu Baerts (NGI0) } 1395*8617e85eSMatthieu Baerts (NGI0) 1396*8617e85eSMatthieu Baerts (NGI0) static struct pernet_operations mptcp_pm_pernet_ops = { 1397*8617e85eSMatthieu Baerts (NGI0) .init = pm_nl_init_net, 1398*8617e85eSMatthieu Baerts (NGI0) .exit_batch = pm_nl_exit_net, 1399*8617e85eSMatthieu Baerts (NGI0) .id = &pm_nl_pernet_id, 1400*8617e85eSMatthieu Baerts (NGI0) .size = sizeof(struct pm_nl_pernet), 1401*8617e85eSMatthieu Baerts (NGI0) }; 1402*8617e85eSMatthieu Baerts (NGI0) 1403*8617e85eSMatthieu Baerts (NGI0) void __init mptcp_pm_nl_init(void) 1404*8617e85eSMatthieu Baerts (NGI0) { 1405*8617e85eSMatthieu Baerts (NGI0) if (register_pernet_subsys(&mptcp_pm_pernet_ops) < 0) 1406*8617e85eSMatthieu Baerts (NGI0) panic("Failed to register MPTCP PM pernet subsystem.\n"); 1407*8617e85eSMatthieu Baerts (NGI0) 1408*8617e85eSMatthieu Baerts (NGI0) if (genl_register_family(&mptcp_genl_family)) 1409*8617e85eSMatthieu Baerts (NGI0) panic("Failed to register MPTCP PM netlink family\n"); 1410*8617e85eSMatthieu Baerts (NGI0) } 1411