File Index
Files and directories
Sign in
FILE

pm_netlink.c

File preview with syntax highlighting.

linux-6.19.14/net/mptcp/pm_netlink.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/* Multipath TCP
  3 *
  4 * Copyright (c) 2020, Red Hat, Inc.
  5 */
  6
  7#define pr_fmt(fmt) "MPTCP: " fmt
  8
  9#include "protocol.h"
 10#include "mptcp_pm_gen.h"
 11
 12#define MPTCP_PM_CMD_GRP_OFFSET       0
 13#define MPTCP_PM_EV_GRP_OFFSET        1
 14
 15static const struct genl_multicast_group mptcp_pm_mcgrps[] = {
 16	[MPTCP_PM_CMD_GRP_OFFSET]	= { .name = MPTCP_PM_CMD_GRP_NAME, },
 17	[MPTCP_PM_EV_GRP_OFFSET]        = { .name = MPTCP_PM_EV_GRP_NAME,
 18					    .flags = GENL_MCAST_CAP_NET_ADMIN,
 19					  },
 20};
 21
 22static int mptcp_pm_family_to_addr(int family)
 23{
 24#if IS_ENABLED(CONFIG_MPTCP_IPV6)
 25	if (family == AF_INET6)
 26		return MPTCP_PM_ADDR_ATTR_ADDR6;
 27#endif
 28	return MPTCP_PM_ADDR_ATTR_ADDR4;
 29}
 30
 31static int mptcp_pm_parse_pm_addr_attr(struct nlattr *tb[],
 32				       const struct nlattr *attr,
 33				       struct genl_info *info,
 34				       struct mptcp_addr_info *addr,
 35				       bool require_family)
 36{
 37	int err, addr_addr;
 38
 39	if (!attr) {
 40		GENL_SET_ERR_MSG(info, "missing address info");
 41		return -EINVAL;
 42	}
 43
 44	/* no validation needed - was already done via nested policy */
 45	err = nla_parse_nested_deprecated(tb, MPTCP_PM_ADDR_ATTR_MAX, attr,
 46					  mptcp_pm_address_nl_policy, info->extack);
 47	if (err)
 48		return err;
 49
 50	if (tb[MPTCP_PM_ADDR_ATTR_ID])
 51		addr->id = nla_get_u8(tb[MPTCP_PM_ADDR_ATTR_ID]);
 52
 53	if (!tb[MPTCP_PM_ADDR_ATTR_FAMILY]) {
 54		if (!require_family)
 55			return 0;
 56
 57		NL_SET_ERR_MSG_ATTR(info->extack, attr,
 58				    "missing family");
 59		return -EINVAL;
 60	}
 61
 62	addr->family = nla_get_u16(tb[MPTCP_PM_ADDR_ATTR_FAMILY]);
 63	if (addr->family != AF_INET
 64#if IS_ENABLED(CONFIG_MPTCP_IPV6)
 65	    && addr->family != AF_INET6
 66#endif
 67	    ) {
 68		NL_SET_ERR_MSG_ATTR(info->extack, attr,
 69				    "unknown address family");
 70		return -EINVAL;
 71	}
 72	addr_addr = mptcp_pm_family_to_addr(addr->family);
 73	if (!tb[addr_addr]) {
 74		NL_SET_ERR_MSG_ATTR(info->extack, attr,
 75				    "missing address data");
 76		return -EINVAL;
 77	}
 78
 79#if IS_ENABLED(CONFIG_MPTCP_IPV6)
 80	if (addr->family == AF_INET6)
 81		addr->addr6 = nla_get_in6_addr(tb[addr_addr]);
 82	else
 83#endif
 84		addr->addr.s_addr = nla_get_in_addr(tb[addr_addr]);
 85
 86	if (tb[MPTCP_PM_ADDR_ATTR_PORT])
 87		addr->port = htons(nla_get_u16(tb[MPTCP_PM_ADDR_ATTR_PORT]));
 88
 89	return 0;
 90}
 91
 92int mptcp_pm_parse_addr(struct nlattr *attr, struct genl_info *info,
 93			struct mptcp_addr_info *addr)
 94{
 95	struct nlattr *tb[MPTCP_PM_ADDR_ATTR_MAX + 1];
 96
 97	memset(addr, 0, sizeof(*addr));
 98
 99	return mptcp_pm_parse_pm_addr_attr(tb, attr, info, addr, true);
100}
101
102int mptcp_pm_parse_entry(struct nlattr *attr, struct genl_info *info,
103			 bool require_family,
104			 struct mptcp_pm_addr_entry *entry)
105{
106	struct nlattr *tb[MPTCP_PM_ADDR_ATTR_MAX + 1];
107	int err;
108
109	memset(entry, 0, sizeof(*entry));
110
111	err = mptcp_pm_parse_pm_addr_attr(tb, attr, info, &entry->addr, require_family);
112	if (err)
113		return err;
114
115	if (tb[MPTCP_PM_ADDR_ATTR_IF_IDX]) {
116		s32 val = nla_get_s32(tb[MPTCP_PM_ADDR_ATTR_IF_IDX]);
117
118		entry->ifindex = val;
119	}
120
121	if (tb[MPTCP_PM_ADDR_ATTR_FLAGS])
122		entry->flags = nla_get_u32(tb[MPTCP_PM_ADDR_ATTR_FLAGS]) &
123			       MPTCP_PM_ADDR_FLAGS_MASK;
124
125	if (tb[MPTCP_PM_ADDR_ATTR_PORT])
126		entry->addr.port = htons(nla_get_u16(tb[MPTCP_PM_ADDR_ATTR_PORT]));
127
128	return 0;
129}
130
131static int mptcp_nl_fill_addr(struct sk_buff *skb,
132			      struct mptcp_pm_addr_entry *entry)
133{
134	struct mptcp_addr_info *addr = &entry->addr;
135	struct nlattr *attr;
136
137	attr = nla_nest_start(skb, MPTCP_PM_ATTR_ADDR);
138	if (!attr)
139		return -EMSGSIZE;
140
141	if (nla_put_u16(skb, MPTCP_PM_ADDR_ATTR_FAMILY, addr->family))
142		goto nla_put_failure;
143	if (nla_put_u16(skb, MPTCP_PM_ADDR_ATTR_PORT, ntohs(addr->port)))
144		goto nla_put_failure;
145	if (nla_put_u8(skb, MPTCP_PM_ADDR_ATTR_ID, addr->id))
146		goto nla_put_failure;
147	if (nla_put_u32(skb, MPTCP_PM_ADDR_ATTR_FLAGS, entry->flags))
148		goto nla_put_failure;
149	if (entry->ifindex &&
150	    nla_put_s32(skb, MPTCP_PM_ADDR_ATTR_IF_IDX, entry->ifindex))
151		goto nla_put_failure;
152
153	if (addr->family == AF_INET &&
154	    nla_put_in_addr(skb, MPTCP_PM_ADDR_ATTR_ADDR4,
155			    addr->addr.s_addr))
156		goto nla_put_failure;
157#if IS_ENABLED(CONFIG_MPTCP_IPV6)
158	else if (addr->family == AF_INET6 &&
159		 nla_put_in6_addr(skb, MPTCP_PM_ADDR_ATTR_ADDR6, &addr->addr6))
160		goto nla_put_failure;
161#endif
162	nla_nest_end(skb, attr);
163	return 0;
164
165nla_put_failure:
166	nla_nest_cancel(skb, attr);
167	return -EMSGSIZE;
168}
169
170static int mptcp_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
171			     struct genl_info *info)
172{
173	if (info->attrs[MPTCP_PM_ATTR_TOKEN])
174		return mptcp_userspace_pm_get_addr(id, addr, info);
175	return mptcp_pm_nl_get_addr(id, addr, info);
176}
177
178int mptcp_pm_nl_get_addr_doit(struct sk_buff *skb, struct genl_info *info)
179{
180	struct mptcp_pm_addr_entry addr;
181	struct nlattr *attr;
182	struct sk_buff *msg;
183	void *reply;
184	int ret;
185
186	if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ENDPOINT_ADDR))
187		return -EINVAL;
188
189	attr = info->attrs[MPTCP_PM_ENDPOINT_ADDR];
190	ret = mptcp_pm_parse_entry(attr, info, false, &addr);
191	if (ret < 0)
192		return ret;
193
194	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
195	if (!msg)
196		return -ENOMEM;
197
198	reply = genlmsg_put_reply(msg, info, &mptcp_genl_family, 0,
199				  info->genlhdr->cmd);
200	if (!reply) {
201		GENL_SET_ERR_MSG(info, "not enough space in Netlink message");
202		ret = -EMSGSIZE;
203		goto fail;
204	}
205
206	ret = mptcp_pm_get_addr(addr.addr.id, &addr, info);
207	if (ret) {
208		NL_SET_ERR_MSG_ATTR(info->extack, attr, "address not found");
209		goto fail;
210	}
211
212	ret = mptcp_nl_fill_addr(msg, &addr);
213	if (ret)
214		goto fail;
215
216	genlmsg_end(msg, reply);
217	ret = genlmsg_reply(msg, info);
218	return ret;
219
220fail:
221	nlmsg_free(msg);
222	return ret;
223}
224
225int mptcp_pm_genl_fill_addr(struct sk_buff *msg,
226			    struct netlink_callback *cb,
227			    struct mptcp_pm_addr_entry *entry)
228{
229	void *hdr;
230
231	hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid,
232			  cb->nlh->nlmsg_seq, &mptcp_genl_family,
233			  NLM_F_MULTI, MPTCP_PM_CMD_GET_ADDR);
234	if (!hdr)
235		return -EINVAL;
236
237	if (mptcp_nl_fill_addr(msg, entry) < 0) {
238		genlmsg_cancel(msg, hdr);
239		return -EINVAL;
240	}
241
242	genlmsg_end(msg, hdr);
243	return 0;
244}
245
246static int mptcp_pm_dump_addr(struct sk_buff *msg, struct netlink_callback *cb)
247{
248	const struct genl_info *info = genl_info_dump(cb);
249
250	if (info->attrs[MPTCP_PM_ATTR_TOKEN])
251		return mptcp_userspace_pm_dump_addr(msg, cb);
252	return mptcp_pm_nl_dump_addr(msg, cb);
253}
254
255int mptcp_pm_nl_get_addr_dumpit(struct sk_buff *msg,
256				struct netlink_callback *cb)
257{
258	return mptcp_pm_dump_addr(msg, cb);
259}
260
261static int mptcp_pm_set_flags(struct genl_info *info)
262{
263	struct mptcp_pm_addr_entry loc = { .addr = { .family = AF_UNSPEC }, };
264	struct nlattr *attr_loc;
265	int ret = -EINVAL;
266
267	if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_ADDR))
268		return ret;
269
270	attr_loc = info->attrs[MPTCP_PM_ATTR_ADDR];
271	ret = mptcp_pm_parse_entry(attr_loc, info, false, &loc);
272	if (ret < 0)
273		return ret;
274
275	if (info->attrs[MPTCP_PM_ATTR_TOKEN])
276		return mptcp_userspace_pm_set_flags(&loc, info);
277	return mptcp_pm_nl_set_flags(&loc, info);
278}
279
280int mptcp_pm_nl_set_flags_doit(struct sk_buff *skb, struct genl_info *info)
281{
282	return mptcp_pm_set_flags(info);
283}
284
285static void mptcp_nl_mcast_send(struct net *net, struct sk_buff *nlskb, gfp_t gfp)
286{
287	genlmsg_multicast_netns(&mptcp_genl_family, net,
288				nlskb, 0, MPTCP_PM_EV_GRP_OFFSET, gfp);
289}
290
291bool mptcp_userspace_pm_active(const struct mptcp_sock *msk)
292{
293	return genl_has_listeners(&mptcp_genl_family,
294				  sock_net((const struct sock *)msk),
295				  MPTCP_PM_EV_GRP_OFFSET);
296}
297
298static int mptcp_event_add_subflow(struct sk_buff *skb, const struct sock *ssk)
299{
300	const struct inet_sock *issk = inet_sk(ssk);
301	const struct mptcp_subflow_context *sf;
302
303	if (nla_put_u16(skb, MPTCP_ATTR_FAMILY, ssk->sk_family))
304		return -EMSGSIZE;
305
306	switch (ssk->sk_family) {
307	case AF_INET:
308		if (nla_put_in_addr(skb, MPTCP_ATTR_SADDR4, issk->inet_saddr))
309			return -EMSGSIZE;
310		if (nla_put_in_addr(skb, MPTCP_ATTR_DADDR4, issk->inet_daddr))
311			return -EMSGSIZE;
312		break;
313#if IS_ENABLED(CONFIG_MPTCP_IPV6)
314	case AF_INET6: {
315		if (nla_put_in6_addr(skb, MPTCP_ATTR_SADDR6, &issk->pinet6->saddr))
316			return -EMSGSIZE;
317		if (nla_put_in6_addr(skb, MPTCP_ATTR_DADDR6, &ssk->sk_v6_daddr))
318			return -EMSGSIZE;
319		break;
320	}
321#endif
322	default:
323		WARN_ON_ONCE(1);
324		return -EMSGSIZE;
325	}
326
327	if (nla_put_be16(skb, MPTCP_ATTR_SPORT, issk->inet_sport))
328		return -EMSGSIZE;
329	if (nla_put_be16(skb, MPTCP_ATTR_DPORT, issk->inet_dport))
330		return -EMSGSIZE;
331
332	sf = mptcp_subflow_ctx(ssk);
333	if (WARN_ON_ONCE(!sf))
334		return -EINVAL;
335
336	if (nla_put_u8(skb, MPTCP_ATTR_LOC_ID, subflow_get_local_id(sf)))
337		return -EMSGSIZE;
338
339	if (nla_put_u8(skb, MPTCP_ATTR_REM_ID, sf->remote_id))
340		return -EMSGSIZE;
341
342	return 0;
343}
344
345static int mptcp_event_put_token_and_ssk(struct sk_buff *skb,
346					 const struct mptcp_sock *msk,
347					 const struct sock *ssk)
348{
349	const struct sock *sk = (const struct sock *)msk;
350	const struct mptcp_subflow_context *sf;
351	u8 sk_err;
352
353	if (nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token)))
354		return -EMSGSIZE;
355
356	if (mptcp_event_add_subflow(skb, ssk))
357		return -EMSGSIZE;
358
359	sf = mptcp_subflow_ctx(ssk);
360	if (WARN_ON_ONCE(!sf))
361		return -EINVAL;
362
363	if (nla_put_u8(skb, MPTCP_ATTR_BACKUP, sf->backup))
364		return -EMSGSIZE;
365
366	if (ssk->sk_bound_dev_if &&
367	    nla_put_s32(skb, MPTCP_ATTR_IF_IDX, ssk->sk_bound_dev_if))
368		return -EMSGSIZE;
369
370	sk_err = READ_ONCE(ssk->sk_err);
371	if (sk_err && sk->sk_state == TCP_ESTABLISHED &&
372	    nla_put_u8(skb, MPTCP_ATTR_ERROR, sk_err))
373		return -EMSGSIZE;
374
375	return 0;
376}
377
378static int mptcp_event_sub_established(struct sk_buff *skb,
379				       const struct mptcp_sock *msk,
380				       const struct sock *ssk)
381{
382	return mptcp_event_put_token_and_ssk(skb, msk, ssk);
383}
384
385static int mptcp_event_sub_closed(struct sk_buff *skb,
386				  const struct mptcp_sock *msk,
387				  const struct sock *ssk)
388{
389	const struct mptcp_subflow_context *sf;
390
391	if (mptcp_event_put_token_and_ssk(skb, msk, ssk))
392		return -EMSGSIZE;
393
394	sf = mptcp_subflow_ctx(ssk);
395	if (!sf->reset_seen)
396		return 0;
397
398	if (nla_put_u32(skb, MPTCP_ATTR_RESET_REASON, sf->reset_reason))
399		return -EMSGSIZE;
400
401	if (nla_put_u32(skb, MPTCP_ATTR_RESET_FLAGS, sf->reset_transient))
402		return -EMSGSIZE;
403
404	return 0;
405}
406
407static int mptcp_event_created(struct sk_buff *skb,
408			       const struct mptcp_sock *msk,
409			       const struct sock *ssk)
410{
411	int err = nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token));
412	u16 flags = 0;
413
414	if (err)
415		return err;
416
417	if (READ_ONCE(msk->pm.server_side)) {
418		flags |= MPTCP_PM_EV_FLAG_SERVER_SIDE;
419
420		/* Deprecated, and only set when it is the server side */
421		if (nla_put_u8(skb, MPTCP_ATTR_SERVER_SIDE, 1))
422			return -EMSGSIZE;
423	}
424
425	if (READ_ONCE(msk->pm.remote_deny_join_id0))
426		flags |= MPTCP_PM_EV_FLAG_DENY_JOIN_ID0;
427
428	if (flags && nla_put_u16(skb, MPTCP_ATTR_FLAGS, flags))
429		return -EMSGSIZE;
430
431	return mptcp_event_add_subflow(skb, ssk);
432}
433
434void mptcp_event_addr_removed(const struct mptcp_sock *msk, uint8_t id)
435{
436	struct net *net = sock_net((const struct sock *)msk);
437	struct nlmsghdr *nlh;
438	struct sk_buff *skb;
439
440	if (!genl_has_listeners(&mptcp_genl_family, net, MPTCP_PM_EV_GRP_OFFSET))
441		return;
442
443	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
444	if (!skb)
445		return;
446
447	nlh = genlmsg_put(skb, 0, 0, &mptcp_genl_family, 0, MPTCP_EVENT_REMOVED);
448	if (!nlh)
449		goto nla_put_failure;
450
451	if (nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token)))
452		goto nla_put_failure;
453
454	if (nla_put_u8(skb, MPTCP_ATTR_REM_ID, id))
455		goto nla_put_failure;
456
457	genlmsg_end(skb, nlh);
458	mptcp_nl_mcast_send(net, skb, GFP_ATOMIC);
459	return;
460
461nla_put_failure:
462	nlmsg_free(skb);
463}
464
465void mptcp_event_addr_announced(const struct sock *ssk,
466				const struct mptcp_addr_info *info)
467{
468	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
469	struct mptcp_sock *msk = mptcp_sk(subflow->conn);
470	struct net *net = sock_net(ssk);
471	struct nlmsghdr *nlh;
472	struct sk_buff *skb;
473
474	if (!genl_has_listeners(&mptcp_genl_family, net, MPTCP_PM_EV_GRP_OFFSET))
475		return;
476
477	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
478	if (!skb)
479		return;
480
481	nlh = genlmsg_put(skb, 0, 0, &mptcp_genl_family, 0,
482			  MPTCP_EVENT_ANNOUNCED);
483	if (!nlh)
484		goto nla_put_failure;
485
486	if (nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token)))
487		goto nla_put_failure;
488
489	if (nla_put_u8(skb, MPTCP_ATTR_REM_ID, info->id))
490		goto nla_put_failure;
491
492	if (nla_put_be16(skb, MPTCP_ATTR_DPORT,
493			 info->port == 0 ?
494			 inet_sk(ssk)->inet_dport :
495			 info->port))
496		goto nla_put_failure;
497
498	switch (info->family) {
499	case AF_INET:
500		if (nla_put_in_addr(skb, MPTCP_ATTR_DADDR4, info->addr.s_addr))
501			goto nla_put_failure;
502		break;
503#if IS_ENABLED(CONFIG_MPTCP_IPV6)
504	case AF_INET6:
505		if (nla_put_in6_addr(skb, MPTCP_ATTR_DADDR6, &info->addr6))
506			goto nla_put_failure;
507		break;
508#endif
509	default:
510		WARN_ON_ONCE(1);
511		goto nla_put_failure;
512	}
513
514	genlmsg_end(skb, nlh);
515	mptcp_nl_mcast_send(net, skb, GFP_ATOMIC);
516	return;
517
518nla_put_failure:
519	nlmsg_free(skb);
520}
521
522void mptcp_event_pm_listener(const struct sock *ssk,
523			     enum mptcp_event_type event)
524{
525	const struct inet_sock *issk = inet_sk(ssk);
526	struct net *net = sock_net(ssk);
527	struct nlmsghdr *nlh;
528	struct sk_buff *skb;
529
530	if (!genl_has_listeners(&mptcp_genl_family, net, MPTCP_PM_EV_GRP_OFFSET))
531		return;
532
533	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
534	if (!skb)
535		return;
536
537	nlh = genlmsg_put(skb, 0, 0, &mptcp_genl_family, 0, event);
538	if (!nlh)
539		goto nla_put_failure;
540
541	if (nla_put_u16(skb, MPTCP_ATTR_FAMILY, ssk->sk_family))
542		goto nla_put_failure;
543
544	if (nla_put_be16(skb, MPTCP_ATTR_SPORT, issk->inet_sport))
545		goto nla_put_failure;
546
547	switch (ssk->sk_family) {
548	case AF_INET:
549		if (nla_put_in_addr(skb, MPTCP_ATTR_SADDR4, issk->inet_saddr))
550			goto nla_put_failure;
551		break;
552#if IS_ENABLED(CONFIG_MPTCP_IPV6)
553	case AF_INET6: {
554		if (nla_put_in6_addr(skb, MPTCP_ATTR_SADDR6, &issk->pinet6->saddr))
555			goto nla_put_failure;
556		break;
557	}
558#endif
559	default:
560		WARN_ON_ONCE(1);
561		goto nla_put_failure;
562	}
563
564	genlmsg_end(skb, nlh);
565	mptcp_nl_mcast_send(net, skb, GFP_KERNEL);
566	return;
567
568nla_put_failure:
569	nlmsg_free(skb);
570}
571
572void mptcp_event(enum mptcp_event_type type, const struct mptcp_sock *msk,
573		 const struct sock *ssk, gfp_t gfp)
574{
575	struct net *net = sock_net((const struct sock *)msk);
576	struct nlmsghdr *nlh;
577	struct sk_buff *skb;
578
579	if (!genl_has_listeners(&mptcp_genl_family, net, MPTCP_PM_EV_GRP_OFFSET))
580		return;
581
582	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
583	if (!skb)
584		return;
585
586	nlh = genlmsg_put(skb, 0, 0, &mptcp_genl_family, 0, type);
587	if (!nlh)
588		goto nla_put_failure;
589
590	switch (type) {
591	case MPTCP_EVENT_UNSPEC:
592		WARN_ON_ONCE(1);
593		break;
594	case MPTCP_EVENT_CREATED:
595	case MPTCP_EVENT_ESTABLISHED:
596		if (mptcp_event_created(skb, msk, ssk) < 0)
597			goto nla_put_failure;
598		break;
599	case MPTCP_EVENT_CLOSED:
600		if (nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token)) < 0)
601			goto nla_put_failure;
602		break;
603	case MPTCP_EVENT_ANNOUNCED:
604	case MPTCP_EVENT_REMOVED:
605		/* call mptcp_event_addr_announced()/removed instead */
606		WARN_ON_ONCE(1);
607		break;
608	case MPTCP_EVENT_SUB_ESTABLISHED:
609	case MPTCP_EVENT_SUB_PRIORITY:
610		if (mptcp_event_sub_established(skb, msk, ssk) < 0)
611			goto nla_put_failure;
612		break;
613	case MPTCP_EVENT_SUB_CLOSED:
614		if (mptcp_event_sub_closed(skb, msk, ssk) < 0)
615			goto nla_put_failure;
616		break;
617	case MPTCP_EVENT_LISTENER_CREATED:
618	case MPTCP_EVENT_LISTENER_CLOSED:
619		break;
620	}
621
622	genlmsg_end(skb, nlh);
623	mptcp_nl_mcast_send(net, skb, gfp);
624	return;
625
626nla_put_failure:
627	nlmsg_free(skb);
628}
629
630struct genl_family mptcp_genl_family __ro_after_init = {
631	.name		= MPTCP_PM_NAME,
632	.version	= MPTCP_PM_VER,
633	.netnsok	= true,
634	.module		= THIS_MODULE,
635	.ops		= mptcp_pm_nl_ops,
636	.n_ops		= ARRAY_SIZE(mptcp_pm_nl_ops),
637	.resv_start_op	= MPTCP_PM_CMD_SUBFLOW_DESTROY + 1,
638	.mcgrps		= mptcp_pm_mcgrps,
639	.n_mcgrps	= ARRAY_SIZE(mptcp_pm_mcgrps),
640};
641
642void __init mptcp_pm_nl_init(void)
643{
644	if (genl_register_family(&mptcp_genl_family))
645		panic("Failed to register MPTCP PM netlink family\n");
646}
~/ Read-only file preview.