Skip to content

Commit

Permalink
tgupdate: merge t/upstream base into t/upstream
Browse files Browse the repository at this point in the history
  • Loading branch information
matttbe committed Jan 16, 2021
2 parents 2535f60 + e7a8760 commit 5f5277e
Show file tree
Hide file tree
Showing 9 changed files with 393 additions and 25 deletions.
6 changes: 6 additions & 0 deletions net/mptcp/mib.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ static const struct snmp_mib mptcp_snmp_list[] = {
SNMP_MIB_ITEM("DuplicateData", MPTCP_MIB_DUPDATA),
SNMP_MIB_ITEM("AddAddr", MPTCP_MIB_ADDADDR),
SNMP_MIB_ITEM("EchoAdd", MPTCP_MIB_ECHOADD),
SNMP_MIB_ITEM("PortAdd", MPTCP_MIB_PORTADD),
SNMP_MIB_ITEM("MPJoinPortSynRx", MPTCP_MIB_JOINPORTSYNRX),
SNMP_MIB_ITEM("MPJoinPortSynAckRx", MPTCP_MIB_JOINPORTSYNACKRX),
SNMP_MIB_ITEM("MPJoinPortAckRx", MPTCP_MIB_JOINPORTACKRX),
SNMP_MIB_ITEM("MismatchPortSynRx", MPTCP_MIB_MISMATCHPORTSYNRX),
SNMP_MIB_ITEM("MismatchPortAckRx", MPTCP_MIB_MISMATCHPORTACKRX),
SNMP_MIB_ITEM("RmAddr", MPTCP_MIB_RMADDR),
SNMP_MIB_ITEM("RmSubflow", MPTCP_MIB_RMSUBFLOW),
SNMP_MIB_ITEM("MPPrioTx", MPTCP_MIB_MPPRIOTX),
Expand Down
6 changes: 6 additions & 0 deletions net/mptcp/mib.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ enum linux_mptcp_mib_field {
MPTCP_MIB_DUPDATA, /* Segments discarded due to duplicate DSS */
MPTCP_MIB_ADDADDR, /* Received ADD_ADDR with echo-flag=0 */
MPTCP_MIB_ECHOADD, /* Received ADD_ADDR with echo-flag=1 */
MPTCP_MIB_PORTADD, /* Received ADD_ADDR with a port-number */
MPTCP_MIB_JOINPORTSYNRX, /* Received a SYN MP_JOIN with a different port-number */
MPTCP_MIB_JOINPORTSYNACKRX, /* Received a SYNACK MP_JOIN with a different port-number */
MPTCP_MIB_JOINPORTACKRX, /* Received an ACK MP_JOIN with a different port-number */
MPTCP_MIB_MISMATCHPORTSYNRX, /* Received a SYN MP_JOIN with a mismatched port-number */
MPTCP_MIB_MISMATCHPORTACKRX, /* Received an ACK MP_JOIN with a mismatched port-number */
MPTCP_MIB_RMADDR, /* Received RM_ADDR */
MPTCP_MIB_RMSUBFLOW, /* Remove a subflow */
MPTCP_MIB_MPPRIOTX, /* Transmit a MP_PRIO */
Expand Down
4 changes: 4 additions & 0 deletions net/mptcp/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,10 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb)
mptcp_pm_del_add_timer(msk, &addr);
MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_ECHOADD);
}

if (mp_opt.port)
MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_PORTADD);

mp_opt.add_addr = 0;
}

Expand Down
132 changes: 125 additions & 7 deletions net/mptcp/pm_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ struct mptcp_pm_addr_entry {
struct list_head list;
struct mptcp_addr_info addr;
struct rcu_head rcu;
struct socket *lsk;
};

struct mptcp_pm_add_entry {
Expand Down Expand Up @@ -90,14 +91,14 @@ static bool address_zero(const struct mptcp_addr_info *addr)
memset(&zero, 0, sizeof(zero));
zero.family = addr->family;

return addresses_equal(addr, &zero, false);
return addresses_equal(addr, &zero, true);
}

static void local_address(const struct sock_common *skc,
struct mptcp_addr_info *addr)
{
addr->port = 0;
addr->family = skc->skc_family;
addr->port = htons(skc->skc_num);
if (addr->family == AF_INET)
addr->addr.s_addr = skc->skc_rcv_saddr;
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
Expand Down Expand Up @@ -130,7 +131,7 @@ static bool lookup_subflow_by_saddr(const struct list_head *list,
skc = (struct sock_common *)mptcp_subflow_tcp_sock(subflow);

local_address(skc, &cur);
if (addresses_equal(&cur, saddr, false))
if (addresses_equal(&cur, saddr, saddr->port))
return true;
}

Expand Down Expand Up @@ -243,13 +244,34 @@ lookup_anno_list_by_saddr(struct mptcp_sock *msk,
struct mptcp_pm_add_entry *entry;

list_for_each_entry(entry, &msk->pm.anno_list, list) {
if (addresses_equal(&entry->addr, addr, false))
if (addresses_equal(&entry->addr, addr, true))
return entry;
}

return NULL;
}

bool mptcp_pm_sport_in_anno_list(struct mptcp_sock *msk, const struct sock *sk)
{
struct mptcp_pm_add_entry *entry;
struct mptcp_addr_info saddr;
bool ret = false;

local_address((struct sock_common *)sk, &saddr);

spin_lock_bh(&msk->pm.lock);
list_for_each_entry(entry, &msk->pm.anno_list, list) {
if (addresses_equal(&entry->addr, &saddr, true)) {
ret = true;
goto out;
}
}

out:
spin_unlock_bh(&msk->pm.lock);
return ret;
}

static void mptcp_pm_add_timer(struct timer_list *timer)
{
struct mptcp_pm_add_entry *entry = from_timer(entry, timer, add_timer);
Expand Down Expand Up @@ -677,6 +699,53 @@ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
return ret;
}

static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
struct mptcp_pm_addr_entry *entry)
{
struct sockaddr_storage addr;
struct mptcp_sock *msk;
struct socket *ssock;
int backlog = 1024;
int err;

err = sock_create_kern(sock_net(sk), entry->addr.family,
SOCK_STREAM, IPPROTO_MPTCP, &entry->lsk);
if (err)
return err;

msk = mptcp_sk(entry->lsk->sk);
if (!msk) {
err = -EINVAL;
goto out;
}

ssock = __mptcp_nmpc_socket(msk);
if (!ssock) {
err = -EINVAL;
goto out;
}

mptcp_info2sockaddr(&entry->addr, &addr, entry->addr.family);
err = kernel_bind(ssock, (struct sockaddr *)&addr,
sizeof(struct sockaddr_in));
if (err) {
pr_warn("kernel_bind error, err=%d", err);
goto out;
}

err = kernel_listen(ssock, backlog);
if (err) {
pr_warn("kernel_listen error, err=%d", err);
goto out;
}

return 0;

out:
sock_release(entry->lsk);
return err;
}

int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
{
struct mptcp_pm_addr_entry *entry;
Expand All @@ -703,7 +772,7 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)

rcu_read_lock();
list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
if (addresses_equal(&entry->addr, &skc_local, false)) {
if (addresses_equal(&entry->addr, &skc_local, entry->addr.port)) {
ret = entry->addr.id;
break;
}
Expand All @@ -721,6 +790,8 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
entry->addr.ifindex = 0;
entry->addr.flags = 0;
entry->addr.id = 0;
entry->addr.port = 0;
entry->lsk = NULL;
ret = mptcp_pm_nl_append_new_local_addr(pernet, entry);
if (ret < 0)
kfree(entry);
Expand Down Expand Up @@ -839,6 +910,9 @@ static int mptcp_pm_parse_addr(struct nlattr *attr, struct genl_info *info,
if (tb[MPTCP_PM_ADDR_ATTR_FLAGS])
entry->addr.flags = nla_get_u32(tb[MPTCP_PM_ADDR_ATTR_FLAGS]);

if (tb[MPTCP_PM_ADDR_ATTR_PORT])
entry->addr.port = htons(nla_get_u16(tb[MPTCP_PM_ADDR_ATTR_PORT]));

return 0;
}

Expand Down Expand Up @@ -890,9 +964,19 @@ static int mptcp_nl_cmd_add_addr(struct sk_buff *skb, struct genl_info *info)
}

*entry = addr;
if (entry->addr.port) {
ret = mptcp_pm_nl_create_listen_socket(skb->sk, entry);
if (ret) {
GENL_SET_ERR_MSG(info, "create listen socket error");
kfree(entry);
return ret;
}
}
ret = mptcp_pm_nl_append_new_local_addr(pernet, entry);
if (ret < 0) {
GENL_SET_ERR_MSG(info, "too many addresses or duplicate one");
if (entry->lsk)
sock_release(entry->lsk);
kfree(entry);
return ret;
}
Expand Down Expand Up @@ -976,6 +1060,38 @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
return 0;
}

struct addr_entry_release_work {
struct rcu_work rwork;
struct mptcp_pm_addr_entry *entry;
};

static void mptcp_pm_release_addr_entry(struct work_struct *work)
{
struct addr_entry_release_work *w;
struct mptcp_pm_addr_entry *entry;

w = container_of(to_rcu_work(work), struct addr_entry_release_work, rwork);
entry = w->entry;
if (entry) {
if (entry->lsk)
sock_release(entry->lsk);
kfree(entry);
}
kfree(w);
}

static void mptcp_pm_free_addr_entry(struct mptcp_pm_addr_entry *entry)
{
struct addr_entry_release_work *w;

w = kmalloc(sizeof(*w), GFP_ATOMIC);
if (w) {
INIT_RCU_WORK(&w->rwork, mptcp_pm_release_addr_entry);
w->entry = entry;
queue_rcu_work(system_wq, &w->rwork);
}
}

static int mptcp_nl_cmd_del_addr(struct sk_buff *skb, struct genl_info *info)
{
struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
Expand Down Expand Up @@ -1010,7 +1126,7 @@ static int mptcp_nl_cmd_del_addr(struct sk_buff *skb, struct genl_info *info)
spin_unlock_bh(&pernet->lock);

mptcp_nl_remove_subflow_and_signal_addr(sock_net(skb->sk), &entry->addr);
kfree_rcu(entry, rcu);
mptcp_pm_free_addr_entry(entry);

return ret;
}
Expand All @@ -1024,7 +1140,7 @@ static void __flush_addrs(struct net *net, struct list_head *list)
struct mptcp_pm_addr_entry, list);
mptcp_nl_remove_subflow_and_signal_addr(net, &cur->addr);
list_del_rcu(&cur->list);
kfree_rcu(cur, rcu);
mptcp_pm_free_addr_entry(cur);
}
}

Expand Down Expand Up @@ -1063,6 +1179,8 @@ static int mptcp_nl_fill_addr(struct sk_buff *skb,

if (nla_put_u16(skb, MPTCP_PM_ADDR_ATTR_FAMILY, addr->family))
goto nla_put_failure;
if (nla_put_u16(skb, MPTCP_PM_ADDR_ATTR_PORT, ntohs(addr->port)))
goto nla_put_failure;
if (nla_put_u8(skb, MPTCP_PM_ADDR_ATTR_ID, addr->id))
goto nla_put_failure;
if (nla_put_u32(skb, MPTCP_PM_ADDR_ATTR_FLAGS, entry->addr.flags))
Expand Down
2 changes: 1 addition & 1 deletion net/mptcp/protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ static struct net_device mptcp_napi_dev;
* completed yet or has failed, return the subflow socket.
* Otherwise return NULL.
*/
static struct socket *__mptcp_nmpc_socket(const struct mptcp_sock *msk)
struct socket *__mptcp_nmpc_socket(const struct mptcp_sock *msk)
{
if (!msk->subflow || READ_ONCE(msk->can_ack))
return NULL;
Expand Down
5 changes: 5 additions & 0 deletions net/mptcp/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -522,11 +522,15 @@ void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
struct mptcp_subflow_context *subflow);
void mptcp_subflow_reset(struct sock *ssk);
void mptcp_sock_graft(struct sock *sk, struct socket *parent);
struct socket *__mptcp_nmpc_socket(const struct mptcp_sock *msk);

/* called with sk socket lock held */
int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
const struct mptcp_addr_info *remote);
int mptcp_subflow_create_socket(struct sock *sk, struct socket **new_sock);
void mptcp_info2sockaddr(const struct mptcp_addr_info *info,
struct sockaddr_storage *addr,
unsigned short family);

static inline void mptcp_subflow_tcp_fallback(struct sock *sk,
struct mptcp_subflow_context *ctx)
Expand Down Expand Up @@ -630,6 +634,7 @@ int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
struct mptcp_addr_info *addr,
u8 bkup);
void mptcp_pm_free_anno_list(struct mptcp_sock *msk);
bool mptcp_pm_sport_in_anno_list(struct mptcp_sock *msk, const struct sock *sk);
struct mptcp_pm_add_entry *
mptcp_pm_del_add_timer(struct mptcp_sock *msk,
struct mptcp_addr_info *addr);
Expand Down
Loading

0 comments on commit 5f5277e

Please sign in to comment.