Skip to content

Commit d98c821

Browse files
committed
Merge branch 'mptcp-fixes'
Mat Martineau says: ==================== mptcp: Bug fixes Here are two bug fixes for the net tree: Patch 1 fixes a memory leak that could be encountered when clearing the list of advertised MPTCP addresses. Patch 2 fixes a protocol issue early in an MPTCP connection, to ensure both peers correctly understand that the full MPTCP connection handshake has completed even when the server side quickly sends an ADD_ADDR option. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents fb4b137 + 67b12f7 commit d98c821

File tree

2 files changed

+15
-39
lines changed

2 files changed

+15
-39
lines changed

net/mptcp/options.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -885,20 +885,16 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk,
885885
return subflow->mp_capable;
886886
}
887887

888-
if (mp_opt->dss && mp_opt->use_ack) {
888+
if ((mp_opt->dss && mp_opt->use_ack) ||
889+
(mp_opt->add_addr && !mp_opt->echo)) {
889890
/* subflows are fully established as soon as we get any
890-
* additional ack.
891+
* additional ack, including ADD_ADDR.
891892
*/
892893
subflow->fully_established = 1;
893894
WRITE_ONCE(msk->fully_established, true);
894895
goto fully_established;
895896
}
896897

897-
if (mp_opt->add_addr) {
898-
WRITE_ONCE(msk->fully_established, true);
899-
return true;
900-
}
901-
902898
/* If the first established packet does not contain MP_CAPABLE + data
903899
* then fallback to TCP. Fallback scenarios requires a reset for
904900
* MP_JOIN subflows.

net/mptcp/pm_netlink.c

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,36 +1135,12 @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
11351135
return 0;
11361136
}
11371137

1138-
struct addr_entry_release_work {
1139-
struct rcu_work rwork;
1140-
struct mptcp_pm_addr_entry *entry;
1141-
};
1142-
1143-
static void mptcp_pm_release_addr_entry(struct work_struct *work)
1138+
/* caller must ensure the RCU grace period is already elapsed */
1139+
static void __mptcp_pm_release_addr_entry(struct mptcp_pm_addr_entry *entry)
11441140
{
1145-
struct addr_entry_release_work *w;
1146-
struct mptcp_pm_addr_entry *entry;
1147-
1148-
w = container_of(to_rcu_work(work), struct addr_entry_release_work, rwork);
1149-
entry = w->entry;
1150-
if (entry) {
1151-
if (entry->lsk)
1152-
sock_release(entry->lsk);
1153-
kfree(entry);
1154-
}
1155-
kfree(w);
1156-
}
1157-
1158-
static void mptcp_pm_free_addr_entry(struct mptcp_pm_addr_entry *entry)
1159-
{
1160-
struct addr_entry_release_work *w;
1161-
1162-
w = kmalloc(sizeof(*w), GFP_ATOMIC);
1163-
if (w) {
1164-
INIT_RCU_WORK(&w->rwork, mptcp_pm_release_addr_entry);
1165-
w->entry = entry;
1166-
queue_rcu_work(system_wq, &w->rwork);
1167-
}
1141+
if (entry->lsk)
1142+
sock_release(entry->lsk);
1143+
kfree(entry);
11681144
}
11691145

11701146
static int mptcp_nl_remove_id_zero_address(struct net *net,
@@ -1244,7 +1220,8 @@ static int mptcp_nl_cmd_del_addr(struct sk_buff *skb, struct genl_info *info)
12441220
spin_unlock_bh(&pernet->lock);
12451221

12461222
mptcp_nl_remove_subflow_and_signal_addr(sock_net(skb->sk), &entry->addr);
1247-
mptcp_pm_free_addr_entry(entry);
1223+
synchronize_rcu();
1224+
__mptcp_pm_release_addr_entry(entry);
12481225

12491226
return ret;
12501227
}
@@ -1297,6 +1274,7 @@ static void mptcp_nl_remove_addrs_list(struct net *net,
12971274
}
12981275
}
12991276

1277+
/* caller must ensure the RCU grace period is already elapsed */
13001278
static void __flush_addrs(struct list_head *list)
13011279
{
13021280
while (!list_empty(list)) {
@@ -1305,7 +1283,7 @@ static void __flush_addrs(struct list_head *list)
13051283
cur = list_entry(list->next,
13061284
struct mptcp_pm_addr_entry, list);
13071285
list_del_rcu(&cur->list);
1308-
mptcp_pm_free_addr_entry(cur);
1286+
__mptcp_pm_release_addr_entry(cur);
13091287
}
13101288
}
13111289

@@ -1329,6 +1307,7 @@ static int mptcp_nl_cmd_flush_addrs(struct sk_buff *skb, struct genl_info *info)
13291307
bitmap_zero(pernet->id_bitmap, MAX_ADDR_ID + 1);
13301308
spin_unlock_bh(&pernet->lock);
13311309
mptcp_nl_remove_addrs_list(sock_net(skb->sk), &free_list);
1310+
synchronize_rcu();
13321311
__flush_addrs(&free_list);
13331312
return 0;
13341313
}
@@ -1939,7 +1918,8 @@ static void __net_exit pm_nl_exit_net(struct list_head *net_list)
19391918
struct pm_nl_pernet *pernet = net_generic(net, pm_nl_pernet_id);
19401919

19411920
/* net is removed from namespace list, can't race with
1942-
* other modifiers
1921+
* other modifiers, also netns core already waited for a
1922+
* RCU grace period.
19431923
*/
19441924
__flush_addrs(&pernet->local_addr_list);
19451925
}

0 commit comments

Comments
 (0)