Skip to content

Commit 0a2f6b3

Browse files
committed
Merge branch 'mptcp-genl-events'
Mat Martineau says: ==================== mptcp: Add genl events for connection info This series from the MPTCP tree adds genl multicast events that are important for implementing a userspace path manager. In MPTCP, a path manager is responsible for adding or removing additional subflows on each MPTCP connection. The in-kernel path manager (already part of the kernel) is a better fit for many server use cases, but the additional flexibility of userspace path managers is often useful for client devices. Patches 1, 2, 4, 5, and 6 do some refactoring to streamline the netlink event implementation in the final patch. Patch 3 improves the timeliness of subflow destruction to ensure the 'subflow closed' event will be sent soon enough. Patch 7 allows use of the GENL_UNS_ADMIN_PERM flag on genl mcast groups to mandate CAP_NET_ADMIN, which is important to protect token information in the MPTCP events. This is a genetlink change. Patch 8 adds the MPTCP netlink events. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 0a82c37 + b911c97 commit 0a2f6b3

File tree

9 files changed

+491
-71
lines changed

9 files changed

+491
-71
lines changed

include/net/genetlink.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
*/
1515
struct genl_multicast_group {
1616
char name[GENL_NAMSIZ];
17+
u8 flags;
1718
};
1819

1920
struct genl_ops;

include/uapi/linux/mptcp.h

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ enum {
3636
/* netlink interface */
3737
#define MPTCP_PM_NAME "mptcp_pm"
3838
#define MPTCP_PM_CMD_GRP_NAME "mptcp_pm_cmds"
39+
#define MPTCP_PM_EV_GRP_NAME "mptcp_pm_events"
3940
#define MPTCP_PM_VER 0x1
4041

4142
/*
@@ -104,4 +105,77 @@ struct mptcp_info {
104105
__u64 mptcpi_rcv_nxt;
105106
};
106107

108+
/*
109+
* MPTCP_EVENT_CREATED: token, family, saddr4 | saddr6, daddr4 | daddr6,
110+
* sport, dport
111+
* A new MPTCP connection has been created. It is the good time to allocate
112+
* memory and send ADD_ADDR if needed. Depending on the traffic-patterns
113+
* it can take a long time until the MPTCP_EVENT_ESTABLISHED is sent.
114+
*
115+
* MPTCP_EVENT_ESTABLISHED: token, family, saddr4 | saddr6, daddr4 | daddr6,
116+
* sport, dport
117+
* A MPTCP connection is established (can start new subflows).
118+
*
119+
* MPTCP_EVENT_CLOSED: token
120+
* A MPTCP connection has stopped.
121+
*
122+
* MPTCP_EVENT_ANNOUNCED: token, rem_id, family, daddr4 | daddr6 [, dport]
123+
* A new address has been announced by the peer.
124+
*
125+
* MPTCP_EVENT_REMOVED: token, rem_id
126+
* An address has been lost by the peer.
127+
*
128+
* MPTCP_EVENT_SUB_ESTABLISHED: token, family, saddr4 | saddr6,
129+
* daddr4 | daddr6, sport, dport, backup,
130+
* if_idx [, error]
131+
* A new subflow has been established. 'error' should not be set.
132+
*
133+
* MPTCP_EVENT_SUB_CLOSED: token, family, saddr4 | saddr6, daddr4 | daddr6,
134+
* sport, dport, backup, if_idx [, error]
135+
* A subflow has been closed. An error (copy of sk_err) could be set if an
136+
* error has been detected for this subflow.
137+
*
138+
* MPTCP_EVENT_SUB_PRIORITY: token, family, saddr4 | saddr6, daddr4 | daddr6,
139+
* sport, dport, backup, if_idx [, error]
140+
* The priority of a subflow has changed. 'error' should not be set.
141+
*/
142+
enum mptcp_event_type {
143+
MPTCP_EVENT_UNSPEC = 0,
144+
MPTCP_EVENT_CREATED = 1,
145+
MPTCP_EVENT_ESTABLISHED = 2,
146+
MPTCP_EVENT_CLOSED = 3,
147+
148+
MPTCP_EVENT_ANNOUNCED = 6,
149+
MPTCP_EVENT_REMOVED = 7,
150+
151+
MPTCP_EVENT_SUB_ESTABLISHED = 10,
152+
MPTCP_EVENT_SUB_CLOSED = 11,
153+
154+
MPTCP_EVENT_SUB_PRIORITY = 13,
155+
};
156+
157+
enum mptcp_event_attr {
158+
MPTCP_ATTR_UNSPEC = 0,
159+
160+
MPTCP_ATTR_TOKEN, /* u32 */
161+
MPTCP_ATTR_FAMILY, /* u16 */
162+
MPTCP_ATTR_LOC_ID, /* u8 */
163+
MPTCP_ATTR_REM_ID, /* u8 */
164+
MPTCP_ATTR_SADDR4, /* be32 */
165+
MPTCP_ATTR_SADDR6, /* struct in6_addr */
166+
MPTCP_ATTR_DADDR4, /* be32 */
167+
MPTCP_ATTR_DADDR6, /* struct in6_addr */
168+
MPTCP_ATTR_SPORT, /* be16 */
169+
MPTCP_ATTR_DPORT, /* be16 */
170+
MPTCP_ATTR_BACKUP, /* u8 */
171+
MPTCP_ATTR_ERROR, /* u8 */
172+
MPTCP_ATTR_FLAGS, /* u16 */
173+
MPTCP_ATTR_TIMEOUT, /* u32 */
174+
MPTCP_ATTR_IF_IDX, /* s32 */
175+
176+
__MPTCP_ATTR_AFTER_LAST
177+
};
178+
179+
#define MPTCP_ATTR_MAX (__MPTCP_ATTR_AFTER_LAST - 1)
180+
107181
#endif /* _UAPI_MPTCP_H */

net/mptcp/options.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,7 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk,
867867
clear_3rdack_retransmission(ssk);
868868
mptcp_pm_subflow_established(msk, subflow);
869869
} else {
870-
mptcp_pm_fully_established(msk);
870+
mptcp_pm_fully_established(msk, ssk, GFP_ATOMIC);
871871
}
872872
return true;
873873

net/mptcp/pm.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,14 @@ int mptcp_pm_remove_subflow(struct mptcp_sock *msk, u8 local_id)
6868

6969
/* path manager event handlers */
7070

71-
void mptcp_pm_new_connection(struct mptcp_sock *msk, int server_side)
71+
void mptcp_pm_new_connection(struct mptcp_sock *msk, const struct sock *ssk, int server_side)
7272
{
7373
struct mptcp_pm_data *pm = &msk->pm;
7474

7575
pr_debug("msk=%p, token=%u side=%d", msk, msk->token, server_side);
7676

7777
WRITE_ONCE(pm->server_side, server_side);
78+
mptcp_event(MPTCP_EVENT_CREATED, msk, ssk, GFP_ATOMIC);
7879
}
7980

8081
bool mptcp_pm_allow_new_subflow(struct mptcp_sock *msk)
@@ -119,16 +120,13 @@ static bool mptcp_pm_schedule_work(struct mptcp_sock *msk,
119120
return true;
120121
}
121122

122-
void mptcp_pm_fully_established(struct mptcp_sock *msk)
123+
void mptcp_pm_fully_established(struct mptcp_sock *msk, const struct sock *ssk, gfp_t gfp)
123124
{
124125
struct mptcp_pm_data *pm = &msk->pm;
126+
bool announce = false;
125127

126128
pr_debug("msk=%p", msk);
127129

128-
/* try to avoid acquiring the lock below */
129-
if (!READ_ONCE(pm->work_pending))
130-
return;
131-
132130
spin_lock_bh(&pm->lock);
133131

134132
/* mptcp_pm_fully_established() can be invoked by multiple
@@ -138,9 +136,15 @@ void mptcp_pm_fully_established(struct mptcp_sock *msk)
138136
if (READ_ONCE(pm->work_pending) &&
139137
!(msk->pm.status & BIT(MPTCP_PM_ALREADY_ESTABLISHED)))
140138
mptcp_pm_schedule_work(msk, MPTCP_PM_ESTABLISHED);
141-
msk->pm.status |= BIT(MPTCP_PM_ALREADY_ESTABLISHED);
142139

140+
if ((msk->pm.status & BIT(MPTCP_PM_ALREADY_ESTABLISHED)) == 0)
141+
announce = true;
142+
143+
msk->pm.status |= BIT(MPTCP_PM_ALREADY_ESTABLISHED);
143144
spin_unlock_bh(&pm->lock);
145+
146+
if (announce)
147+
mptcp_event(MPTCP_EVENT_ESTABLISHED, msk, ssk, gfp);
144148
}
145149

146150
void mptcp_pm_connection_closed(struct mptcp_sock *msk)
@@ -179,6 +183,8 @@ void mptcp_pm_add_addr_received(struct mptcp_sock *msk,
179183
pr_debug("msk=%p remote_id=%d accept=%d", msk, addr->id,
180184
READ_ONCE(pm->accept_addr));
181185

186+
mptcp_event_addr_announced(msk, addr);
187+
182188
spin_lock_bh(&pm->lock);
183189

184190
if (!READ_ONCE(pm->accept_addr)) {
@@ -205,6 +211,8 @@ void mptcp_pm_rm_addr_received(struct mptcp_sock *msk, u8 rm_id)
205211

206212
pr_debug("msk=%p remote_id=%d", msk, rm_id);
207213

214+
mptcp_event_addr_removed(msk, rm_id);
215+
208216
spin_lock_bh(&pm->lock);
209217
mptcp_pm_schedule_work(msk, MPTCP_PM_RM_ADDR_RECEIVED);
210218
pm->rm_id = rm_id;
@@ -217,6 +225,8 @@ void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup)
217225

218226
pr_debug("subflow->backup=%d, bkup=%d\n", subflow->backup, bkup);
219227
subflow->backup = bkup;
228+
229+
mptcp_event(MPTCP_EVENT_SUB_PRIORITY, mptcp_sk(subflow->conn), sk, GFP_ATOMIC);
220230
}
221231

222232
/* path manager helpers */

0 commit comments

Comments
 (0)