Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/net/mptcp/pm_netlink.c
51911 views
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
15
static 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
22
static 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
31
static 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
92
int 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
102
int 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
131
static 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
165
nla_put_failure:
166
nla_nest_cancel(skb, attr);
167
return -EMSGSIZE;
168
}
169
170
static 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
178
int 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
220
fail:
221
nlmsg_free(msg);
222
return ret;
223
}
224
225
int 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
246
static 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
255
int 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
261
static 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
280
int mptcp_pm_nl_set_flags_doit(struct sk_buff *skb, struct genl_info *info)
281
{
282
return mptcp_pm_set_flags(info);
283
}
284
285
static 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
291
bool 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
298
static 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
345
static 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
378
static 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
385
static 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
407
static 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
434
void 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
461
nla_put_failure:
462
nlmsg_free(skb);
463
}
464
465
void 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
518
nla_put_failure:
519
nlmsg_free(skb);
520
}
521
522
void 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
568
nla_put_failure:
569
nlmsg_free(skb);
570
}
571
572
void 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
626
nla_put_failure:
627
nlmsg_free(skb);
628
}
629
630
struct 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
642
void __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
}
647
648