Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Multipath TCP
0003  *
0004  * Copyright (c) 2022, Intel Corporation.
0005  */
0006 
0007 #include "protocol.h"
0008 #include "mib.h"
0009 
0010 void mptcp_free_local_addr_list(struct mptcp_sock *msk)
0011 {
0012     struct mptcp_pm_addr_entry *entry, *tmp;
0013     struct sock *sk = (struct sock *)msk;
0014     LIST_HEAD(free_list);
0015 
0016     if (!mptcp_pm_is_userspace(msk))
0017         return;
0018 
0019     spin_lock_bh(&msk->pm.lock);
0020     list_splice_init(&msk->pm.userspace_pm_local_addr_list, &free_list);
0021     spin_unlock_bh(&msk->pm.lock);
0022 
0023     list_for_each_entry_safe(entry, tmp, &free_list, list) {
0024         sock_kfree_s(sk, entry, sizeof(*entry));
0025     }
0026 }
0027 
0028 int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
0029                          struct mptcp_pm_addr_entry *entry)
0030 {
0031     DECLARE_BITMAP(id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
0032     struct mptcp_pm_addr_entry *match = NULL;
0033     struct sock *sk = (struct sock *)msk;
0034     struct mptcp_pm_addr_entry *e;
0035     bool addr_match = false;
0036     bool id_match = false;
0037     int ret = -EINVAL;
0038 
0039     bitmap_zero(id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
0040 
0041     spin_lock_bh(&msk->pm.lock);
0042     list_for_each_entry(e, &msk->pm.userspace_pm_local_addr_list, list) {
0043         addr_match = mptcp_addresses_equal(&e->addr, &entry->addr, true);
0044         if (addr_match && entry->addr.id == 0)
0045             entry->addr.id = e->addr.id;
0046         id_match = (e->addr.id == entry->addr.id);
0047         if (addr_match && id_match) {
0048             match = e;
0049             break;
0050         } else if (addr_match || id_match) {
0051             break;
0052         }
0053         __set_bit(e->addr.id, id_bitmap);
0054     }
0055 
0056     if (!match && !addr_match && !id_match) {
0057         /* Memory for the entry is allocated from the
0058          * sock option buffer.
0059          */
0060         e = sock_kmalloc(sk, sizeof(*e), GFP_ATOMIC);
0061         if (!e) {
0062             spin_unlock_bh(&msk->pm.lock);
0063             return -ENOMEM;
0064         }
0065 
0066         *e = *entry;
0067         if (!e->addr.id)
0068             e->addr.id = find_next_zero_bit(id_bitmap,
0069                             MPTCP_PM_MAX_ADDR_ID + 1,
0070                             1);
0071         list_add_tail_rcu(&e->list, &msk->pm.userspace_pm_local_addr_list);
0072         ret = e->addr.id;
0073     } else if (match) {
0074         ret = entry->addr.id;
0075     }
0076 
0077     spin_unlock_bh(&msk->pm.lock);
0078     return ret;
0079 }
0080 
0081 int mptcp_userspace_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
0082                            unsigned int id,
0083                            u8 *flags, int *ifindex)
0084 {
0085     struct mptcp_pm_addr_entry *entry, *match = NULL;
0086 
0087     *flags = 0;
0088     *ifindex = 0;
0089 
0090     spin_lock_bh(&msk->pm.lock);
0091     list_for_each_entry(entry, &msk->pm.userspace_pm_local_addr_list, list) {
0092         if (id == entry->addr.id) {
0093             match = entry;
0094             break;
0095         }
0096     }
0097     spin_unlock_bh(&msk->pm.lock);
0098     if (match) {
0099         *flags = match->flags;
0100         *ifindex = match->ifindex;
0101     }
0102 
0103     return 0;
0104 }
0105 
0106 int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk,
0107                     struct mptcp_addr_info *skc)
0108 {
0109     struct mptcp_pm_addr_entry new_entry;
0110     __be16 msk_sport =  ((struct inet_sock *)
0111                  inet_sk((struct sock *)msk))->inet_sport;
0112 
0113     memset(&new_entry, 0, sizeof(struct mptcp_pm_addr_entry));
0114     new_entry.addr = *skc;
0115     new_entry.addr.id = 0;
0116     new_entry.flags = MPTCP_PM_ADDR_FLAG_IMPLICIT;
0117 
0118     if (new_entry.addr.port == msk_sport)
0119         new_entry.addr.port = 0;
0120 
0121     return mptcp_userspace_pm_append_new_local_addr(msk, &new_entry);
0122 }
0123 
0124 int mptcp_nl_cmd_announce(struct sk_buff *skb, struct genl_info *info)
0125 {
0126     struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
0127     struct nlattr *addr = info->attrs[MPTCP_PM_ATTR_ADDR];
0128     struct mptcp_pm_addr_entry addr_val;
0129     struct mptcp_sock *msk;
0130     int err = -EINVAL;
0131     u32 token_val;
0132 
0133     if (!addr || !token) {
0134         GENL_SET_ERR_MSG(info, "missing required inputs");
0135         return err;
0136     }
0137 
0138     token_val = nla_get_u32(token);
0139 
0140     msk = mptcp_token_get_sock(sock_net(skb->sk), token_val);
0141     if (!msk) {
0142         NL_SET_ERR_MSG_ATTR(info->extack, token, "invalid token");
0143         return err;
0144     }
0145 
0146     if (!mptcp_pm_is_userspace(msk)) {
0147         GENL_SET_ERR_MSG(info, "invalid request; userspace PM not selected");
0148         goto announce_err;
0149     }
0150 
0151     err = mptcp_pm_parse_entry(addr, info, true, &addr_val);
0152     if (err < 0) {
0153         GENL_SET_ERR_MSG(info, "error parsing local address");
0154         goto announce_err;
0155     }
0156 
0157     if (addr_val.addr.id == 0 || !(addr_val.flags & MPTCP_PM_ADDR_FLAG_SIGNAL)) {
0158         GENL_SET_ERR_MSG(info, "invalid addr id or flags");
0159         goto announce_err;
0160     }
0161 
0162     err = mptcp_userspace_pm_append_new_local_addr(msk, &addr_val);
0163     if (err < 0) {
0164         GENL_SET_ERR_MSG(info, "did not match address and id");
0165         goto announce_err;
0166     }
0167 
0168     lock_sock((struct sock *)msk);
0169     spin_lock_bh(&msk->pm.lock);
0170 
0171     if (mptcp_pm_alloc_anno_list(msk, &addr_val)) {
0172         mptcp_pm_announce_addr(msk, &addr_val.addr, false);
0173         mptcp_pm_nl_addr_send_ack(msk);
0174     }
0175 
0176     spin_unlock_bh(&msk->pm.lock);
0177     release_sock((struct sock *)msk);
0178 
0179     err = 0;
0180  announce_err:
0181     sock_put((struct sock *)msk);
0182     return err;
0183 }
0184 
0185 int mptcp_nl_cmd_remove(struct sk_buff *skb, struct genl_info *info)
0186 {
0187     struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
0188     struct nlattr *id = info->attrs[MPTCP_PM_ATTR_LOC_ID];
0189     struct mptcp_pm_addr_entry *match = NULL;
0190     struct mptcp_pm_addr_entry *entry;
0191     struct mptcp_sock *msk;
0192     LIST_HEAD(free_list);
0193     int err = -EINVAL;
0194     u32 token_val;
0195     u8 id_val;
0196 
0197     if (!id || !token) {
0198         GENL_SET_ERR_MSG(info, "missing required inputs");
0199         return err;
0200     }
0201 
0202     id_val = nla_get_u8(id);
0203     token_val = nla_get_u32(token);
0204 
0205     msk = mptcp_token_get_sock(sock_net(skb->sk), token_val);
0206     if (!msk) {
0207         NL_SET_ERR_MSG_ATTR(info->extack, token, "invalid token");
0208         return err;
0209     }
0210 
0211     if (!mptcp_pm_is_userspace(msk)) {
0212         GENL_SET_ERR_MSG(info, "invalid request; userspace PM not selected");
0213         goto remove_err;
0214     }
0215 
0216     lock_sock((struct sock *)msk);
0217 
0218     list_for_each_entry(entry, &msk->pm.userspace_pm_local_addr_list, list) {
0219         if (entry->addr.id == id_val) {
0220             match = entry;
0221             break;
0222         }
0223     }
0224 
0225     if (!match) {
0226         GENL_SET_ERR_MSG(info, "address with specified id not found");
0227         release_sock((struct sock *)msk);
0228         goto remove_err;
0229     }
0230 
0231     list_move(&match->list, &free_list);
0232 
0233     mptcp_pm_remove_addrs_and_subflows(msk, &free_list);
0234 
0235     release_sock((struct sock *)msk);
0236 
0237     list_for_each_entry_safe(match, entry, &free_list, list) {
0238         sock_kfree_s((struct sock *)msk, match, sizeof(*match));
0239     }
0240 
0241     err = 0;
0242  remove_err:
0243     sock_put((struct sock *)msk);
0244     return err;
0245 }
0246 
0247 int mptcp_nl_cmd_sf_create(struct sk_buff *skb, struct genl_info *info)
0248 {
0249     struct nlattr *raddr = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
0250     struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
0251     struct nlattr *laddr = info->attrs[MPTCP_PM_ATTR_ADDR];
0252     struct mptcp_addr_info addr_r;
0253     struct mptcp_addr_info addr_l;
0254     struct mptcp_sock *msk;
0255     int err = -EINVAL;
0256     struct sock *sk;
0257     u32 token_val;
0258 
0259     if (!laddr || !raddr || !token) {
0260         GENL_SET_ERR_MSG(info, "missing required inputs");
0261         return err;
0262     }
0263 
0264     token_val = nla_get_u32(token);
0265 
0266     msk = mptcp_token_get_sock(genl_info_net(info), token_val);
0267     if (!msk) {
0268         NL_SET_ERR_MSG_ATTR(info->extack, token, "invalid token");
0269         return err;
0270     }
0271 
0272     if (!mptcp_pm_is_userspace(msk)) {
0273         GENL_SET_ERR_MSG(info, "invalid request; userspace PM not selected");
0274         goto create_err;
0275     }
0276 
0277     err = mptcp_pm_parse_addr(laddr, info, &addr_l);
0278     if (err < 0) {
0279         NL_SET_ERR_MSG_ATTR(info->extack, laddr, "error parsing local addr");
0280         goto create_err;
0281     }
0282 
0283     if (addr_l.id == 0) {
0284         NL_SET_ERR_MSG_ATTR(info->extack, laddr, "missing local addr id");
0285         goto create_err;
0286     }
0287 
0288     err = mptcp_pm_parse_addr(raddr, info, &addr_r);
0289     if (err < 0) {
0290         NL_SET_ERR_MSG_ATTR(info->extack, raddr, "error parsing remote addr");
0291         goto create_err;
0292     }
0293 
0294     sk = &msk->sk.icsk_inet.sk;
0295     lock_sock(sk);
0296 
0297     err = __mptcp_subflow_connect(sk, &addr_l, &addr_r);
0298 
0299     release_sock(sk);
0300 
0301  create_err:
0302     sock_put((struct sock *)msk);
0303     return err;
0304 }
0305 
0306 static struct sock *mptcp_nl_find_ssk(struct mptcp_sock *msk,
0307                       const struct mptcp_addr_info *local,
0308                       const struct mptcp_addr_info *remote)
0309 {
0310     struct mptcp_subflow_context *subflow;
0311 
0312     if (local->family != remote->family)
0313         return NULL;
0314 
0315     mptcp_for_each_subflow(msk, subflow) {
0316         const struct inet_sock *issk;
0317         struct sock *ssk;
0318 
0319         ssk = mptcp_subflow_tcp_sock(subflow);
0320 
0321         if (local->family != ssk->sk_family)
0322             continue;
0323 
0324         issk = inet_sk(ssk);
0325 
0326         switch (ssk->sk_family) {
0327         case AF_INET:
0328             if (issk->inet_saddr != local->addr.s_addr ||
0329                 issk->inet_daddr != remote->addr.s_addr)
0330                 continue;
0331             break;
0332 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
0333         case AF_INET6: {
0334             const struct ipv6_pinfo *pinfo = inet6_sk(ssk);
0335 
0336             if (!ipv6_addr_equal(&local->addr6, &pinfo->saddr) ||
0337                 !ipv6_addr_equal(&remote->addr6, &ssk->sk_v6_daddr))
0338                 continue;
0339             break;
0340         }
0341 #endif
0342         default:
0343             continue;
0344         }
0345 
0346         if (issk->inet_sport == local->port &&
0347             issk->inet_dport == remote->port)
0348             return ssk;
0349     }
0350 
0351     return NULL;
0352 }
0353 
0354 int mptcp_nl_cmd_sf_destroy(struct sk_buff *skb, struct genl_info *info)
0355 {
0356     struct nlattr *raddr = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE];
0357     struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
0358     struct nlattr *laddr = info->attrs[MPTCP_PM_ATTR_ADDR];
0359     struct mptcp_addr_info addr_l;
0360     struct mptcp_addr_info addr_r;
0361     struct mptcp_sock *msk;
0362     struct sock *sk, *ssk;
0363     int err = -EINVAL;
0364     u32 token_val;
0365 
0366     if (!laddr || !raddr || !token) {
0367         GENL_SET_ERR_MSG(info, "missing required inputs");
0368         return err;
0369     }
0370 
0371     token_val = nla_get_u32(token);
0372 
0373     msk = mptcp_token_get_sock(genl_info_net(info), token_val);
0374     if (!msk) {
0375         NL_SET_ERR_MSG_ATTR(info->extack, token, "invalid token");
0376         return err;
0377     }
0378 
0379     if (!mptcp_pm_is_userspace(msk)) {
0380         GENL_SET_ERR_MSG(info, "invalid request; userspace PM not selected");
0381         goto destroy_err;
0382     }
0383 
0384     err = mptcp_pm_parse_addr(laddr, info, &addr_l);
0385     if (err < 0) {
0386         NL_SET_ERR_MSG_ATTR(info->extack, laddr, "error parsing local addr");
0387         goto destroy_err;
0388     }
0389 
0390     err = mptcp_pm_parse_addr(raddr, info, &addr_r);
0391     if (err < 0) {
0392         NL_SET_ERR_MSG_ATTR(info->extack, raddr, "error parsing remote addr");
0393         goto destroy_err;
0394     }
0395 
0396     if (addr_l.family != addr_r.family) {
0397         GENL_SET_ERR_MSG(info, "address families do not match");
0398         goto destroy_err;
0399     }
0400 
0401     if (!addr_l.port || !addr_r.port) {
0402         GENL_SET_ERR_MSG(info, "missing local or remote port");
0403         goto destroy_err;
0404     }
0405 
0406     sk = &msk->sk.icsk_inet.sk;
0407     lock_sock(sk);
0408     ssk = mptcp_nl_find_ssk(msk, &addr_l, &addr_r);
0409     if (ssk) {
0410         struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
0411 
0412         mptcp_subflow_shutdown(sk, ssk, RCV_SHUTDOWN | SEND_SHUTDOWN);
0413         mptcp_close_ssk(sk, ssk, subflow);
0414         MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RMSUBFLOW);
0415         err = 0;
0416     } else {
0417         err = -ESRCH;
0418     }
0419     release_sock(sk);
0420 
0421 destroy_err:
0422     sock_put((struct sock *)msk);
0423     return err;
0424 }
0425 
0426 int mptcp_userspace_pm_set_flags(struct net *net, struct nlattr *token,
0427                  struct mptcp_pm_addr_entry *loc,
0428                  struct mptcp_pm_addr_entry *rem, u8 bkup)
0429 {
0430     struct mptcp_sock *msk;
0431     int ret = -EINVAL;
0432     u32 token_val;
0433 
0434     token_val = nla_get_u32(token);
0435 
0436     msk = mptcp_token_get_sock(net, token_val);
0437     if (!msk)
0438         return ret;
0439 
0440     if (!mptcp_pm_is_userspace(msk))
0441         goto set_flags_err;
0442 
0443     if (loc->addr.family == AF_UNSPEC ||
0444         rem->addr.family == AF_UNSPEC)
0445         goto set_flags_err;
0446 
0447     lock_sock((struct sock *)msk);
0448     ret = mptcp_pm_nl_mp_prio_send_ack(msk, &loc->addr, &rem->addr, bkup);
0449     release_sock((struct sock *)msk);
0450 
0451 set_flags_err:
0452     sock_put((struct sock *)msk);
0453     return ret;
0454 }