Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/net/mptcp/pm_netlink.c
26278 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
u32 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
124
if (tb[MPTCP_PM_ADDR_ATTR_PORT])
125
entry->addr.port = htons(nla_get_u16(tb[MPTCP_PM_ADDR_ATTR_PORT]));
126
127
return 0;
128
}
129
130
static int mptcp_nl_fill_addr(struct sk_buff *skb,
131
struct mptcp_pm_addr_entry *entry)
132
{
133
struct mptcp_addr_info *addr = &entry->addr;
134
struct nlattr *attr;
135
136
attr = nla_nest_start(skb, MPTCP_PM_ATTR_ADDR);
137
if (!attr)
138
return -EMSGSIZE;
139
140
if (nla_put_u16(skb, MPTCP_PM_ADDR_ATTR_FAMILY, addr->family))
141
goto nla_put_failure;
142
if (nla_put_u16(skb, MPTCP_PM_ADDR_ATTR_PORT, ntohs(addr->port)))
143
goto nla_put_failure;
144
if (nla_put_u8(skb, MPTCP_PM_ADDR_ATTR_ID, addr->id))
145
goto nla_put_failure;
146
if (nla_put_u32(skb, MPTCP_PM_ADDR_ATTR_FLAGS, entry->flags))
147
goto nla_put_failure;
148
if (entry->ifindex &&
149
nla_put_s32(skb, MPTCP_PM_ADDR_ATTR_IF_IDX, entry->ifindex))
150
goto nla_put_failure;
151
152
if (addr->family == AF_INET &&
153
nla_put_in_addr(skb, MPTCP_PM_ADDR_ATTR_ADDR4,
154
addr->addr.s_addr))
155
goto nla_put_failure;
156
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
157
else if (addr->family == AF_INET6 &&
158
nla_put_in6_addr(skb, MPTCP_PM_ADDR_ATTR_ADDR6, &addr->addr6))
159
goto nla_put_failure;
160
#endif
161
nla_nest_end(skb, attr);
162
return 0;
163
164
nla_put_failure:
165
nla_nest_cancel(skb, attr);
166
return -EMSGSIZE;
167
}
168
169
static int mptcp_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
170
struct genl_info *info)
171
{
172
if (info->attrs[MPTCP_PM_ATTR_TOKEN])
173
return mptcp_userspace_pm_get_addr(id, addr, info);
174
return mptcp_pm_nl_get_addr(id, addr, info);
175
}
176
177
int mptcp_pm_nl_get_addr_doit(struct sk_buff *skb, struct genl_info *info)
178
{
179
struct mptcp_pm_addr_entry addr;
180
struct nlattr *attr;
181
struct sk_buff *msg;
182
void *reply;
183
int ret;
184
185
if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ENDPOINT_ADDR))
186
return -EINVAL;
187
188
attr = info->attrs[MPTCP_PM_ENDPOINT_ADDR];
189
ret = mptcp_pm_parse_entry(attr, info, false, &addr);
190
if (ret < 0)
191
return ret;
192
193
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
194
if (!msg)
195
return -ENOMEM;
196
197
reply = genlmsg_put_reply(msg, info, &mptcp_genl_family, 0,
198
info->genlhdr->cmd);
199
if (!reply) {
200
GENL_SET_ERR_MSG(info, "not enough space in Netlink message");
201
ret = -EMSGSIZE;
202
goto fail;
203
}
204
205
ret = mptcp_pm_get_addr(addr.addr.id, &addr, info);
206
if (ret) {
207
NL_SET_ERR_MSG_ATTR(info->extack, attr, "address not found");
208
goto fail;
209
}
210
211
ret = mptcp_nl_fill_addr(msg, &addr);
212
if (ret)
213
goto fail;
214
215
genlmsg_end(msg, reply);
216
ret = genlmsg_reply(msg, info);
217
return ret;
218
219
fail:
220
nlmsg_free(msg);
221
return ret;
222
}
223
224
int mptcp_pm_genl_fill_addr(struct sk_buff *msg,
225
struct netlink_callback *cb,
226
struct mptcp_pm_addr_entry *entry)
227
{
228
void *hdr;
229
230
hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid,
231
cb->nlh->nlmsg_seq, &mptcp_genl_family,
232
NLM_F_MULTI, MPTCP_PM_CMD_GET_ADDR);
233
if (!hdr)
234
return -EINVAL;
235
236
if (mptcp_nl_fill_addr(msg, entry) < 0) {
237
genlmsg_cancel(msg, hdr);
238
return -EINVAL;
239
}
240
241
genlmsg_end(msg, hdr);
242
return 0;
243
}
244
245
static int mptcp_pm_dump_addr(struct sk_buff *msg, struct netlink_callback *cb)
246
{
247
const struct genl_info *info = genl_info_dump(cb);
248
249
if (info->attrs[MPTCP_PM_ATTR_TOKEN])
250
return mptcp_userspace_pm_dump_addr(msg, cb);
251
return mptcp_pm_nl_dump_addr(msg, cb);
252
}
253
254
int mptcp_pm_nl_get_addr_dumpit(struct sk_buff *msg,
255
struct netlink_callback *cb)
256
{
257
return mptcp_pm_dump_addr(msg, cb);
258
}
259
260
static int mptcp_pm_set_flags(struct genl_info *info)
261
{
262
struct mptcp_pm_addr_entry loc = { .addr = { .family = AF_UNSPEC }, };
263
struct nlattr *attr_loc;
264
int ret = -EINVAL;
265
266
if (GENL_REQ_ATTR_CHECK(info, MPTCP_PM_ATTR_ADDR))
267
return ret;
268
269
attr_loc = info->attrs[MPTCP_PM_ATTR_ADDR];
270
ret = mptcp_pm_parse_entry(attr_loc, info, false, &loc);
271
if (ret < 0)
272
return ret;
273
274
if (info->attrs[MPTCP_PM_ATTR_TOKEN])
275
return mptcp_userspace_pm_set_flags(&loc, info);
276
return mptcp_pm_nl_set_flags(&loc, info);
277
}
278
279
int mptcp_pm_nl_set_flags_doit(struct sk_buff *skb, struct genl_info *info)
280
{
281
return mptcp_pm_set_flags(info);
282
}
283
284
static void mptcp_nl_mcast_send(struct net *net, struct sk_buff *nlskb, gfp_t gfp)
285
{
286
genlmsg_multicast_netns(&mptcp_genl_family, net,
287
nlskb, 0, MPTCP_PM_EV_GRP_OFFSET, gfp);
288
}
289
290
bool mptcp_userspace_pm_active(const struct mptcp_sock *msk)
291
{
292
return genl_has_listeners(&mptcp_genl_family,
293
sock_net((const struct sock *)msk),
294
MPTCP_PM_EV_GRP_OFFSET);
295
}
296
297
static int mptcp_event_add_subflow(struct sk_buff *skb, const struct sock *ssk)
298
{
299
const struct inet_sock *issk = inet_sk(ssk);
300
const struct mptcp_subflow_context *sf;
301
302
if (nla_put_u16(skb, MPTCP_ATTR_FAMILY, ssk->sk_family))
303
return -EMSGSIZE;
304
305
switch (ssk->sk_family) {
306
case AF_INET:
307
if (nla_put_in_addr(skb, MPTCP_ATTR_SADDR4, issk->inet_saddr))
308
return -EMSGSIZE;
309
if (nla_put_in_addr(skb, MPTCP_ATTR_DADDR4, issk->inet_daddr))
310
return -EMSGSIZE;
311
break;
312
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
313
case AF_INET6: {
314
if (nla_put_in6_addr(skb, MPTCP_ATTR_SADDR6, &issk->pinet6->saddr))
315
return -EMSGSIZE;
316
if (nla_put_in6_addr(skb, MPTCP_ATTR_DADDR6, &ssk->sk_v6_daddr))
317
return -EMSGSIZE;
318
break;
319
}
320
#endif
321
default:
322
WARN_ON_ONCE(1);
323
return -EMSGSIZE;
324
}
325
326
if (nla_put_be16(skb, MPTCP_ATTR_SPORT, issk->inet_sport))
327
return -EMSGSIZE;
328
if (nla_put_be16(skb, MPTCP_ATTR_DPORT, issk->inet_dport))
329
return -EMSGSIZE;
330
331
sf = mptcp_subflow_ctx(ssk);
332
if (WARN_ON_ONCE(!sf))
333
return -EINVAL;
334
335
if (nla_put_u8(skb, MPTCP_ATTR_LOC_ID, subflow_get_local_id(sf)))
336
return -EMSGSIZE;
337
338
if (nla_put_u8(skb, MPTCP_ATTR_REM_ID, sf->remote_id))
339
return -EMSGSIZE;
340
341
return 0;
342
}
343
344
static int mptcp_event_put_token_and_ssk(struct sk_buff *skb,
345
const struct mptcp_sock *msk,
346
const struct sock *ssk)
347
{
348
const struct sock *sk = (const struct sock *)msk;
349
const struct mptcp_subflow_context *sf;
350
u8 sk_err;
351
352
if (nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token)))
353
return -EMSGSIZE;
354
355
if (mptcp_event_add_subflow(skb, ssk))
356
return -EMSGSIZE;
357
358
sf = mptcp_subflow_ctx(ssk);
359
if (WARN_ON_ONCE(!sf))
360
return -EINVAL;
361
362
if (nla_put_u8(skb, MPTCP_ATTR_BACKUP, sf->backup))
363
return -EMSGSIZE;
364
365
if (ssk->sk_bound_dev_if &&
366
nla_put_s32(skb, MPTCP_ATTR_IF_IDX, ssk->sk_bound_dev_if))
367
return -EMSGSIZE;
368
369
sk_err = READ_ONCE(ssk->sk_err);
370
if (sk_err && sk->sk_state == TCP_ESTABLISHED &&
371
nla_put_u8(skb, MPTCP_ATTR_ERROR, sk_err))
372
return -EMSGSIZE;
373
374
return 0;
375
}
376
377
static int mptcp_event_sub_established(struct sk_buff *skb,
378
const struct mptcp_sock *msk,
379
const struct sock *ssk)
380
{
381
return mptcp_event_put_token_and_ssk(skb, msk, ssk);
382
}
383
384
static int mptcp_event_sub_closed(struct sk_buff *skb,
385
const struct mptcp_sock *msk,
386
const struct sock *ssk)
387
{
388
const struct mptcp_subflow_context *sf;
389
390
if (mptcp_event_put_token_and_ssk(skb, msk, ssk))
391
return -EMSGSIZE;
392
393
sf = mptcp_subflow_ctx(ssk);
394
if (!sf->reset_seen)
395
return 0;
396
397
if (nla_put_u32(skb, MPTCP_ATTR_RESET_REASON, sf->reset_reason))
398
return -EMSGSIZE;
399
400
if (nla_put_u32(skb, MPTCP_ATTR_RESET_FLAGS, sf->reset_transient))
401
return -EMSGSIZE;
402
403
return 0;
404
}
405
406
static int mptcp_event_created(struct sk_buff *skb,
407
const struct mptcp_sock *msk,
408
const struct sock *ssk)
409
{
410
int err = nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token));
411
412
if (err)
413
return err;
414
415
if (nla_put_u8(skb, MPTCP_ATTR_SERVER_SIDE, READ_ONCE(msk->pm.server_side)))
416
return -EMSGSIZE;
417
418
return mptcp_event_add_subflow(skb, ssk);
419
}
420
421
void mptcp_event_addr_removed(const struct mptcp_sock *msk, uint8_t id)
422
{
423
struct net *net = sock_net((const struct sock *)msk);
424
struct nlmsghdr *nlh;
425
struct sk_buff *skb;
426
427
if (!genl_has_listeners(&mptcp_genl_family, net, MPTCP_PM_EV_GRP_OFFSET))
428
return;
429
430
skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
431
if (!skb)
432
return;
433
434
nlh = genlmsg_put(skb, 0, 0, &mptcp_genl_family, 0, MPTCP_EVENT_REMOVED);
435
if (!nlh)
436
goto nla_put_failure;
437
438
if (nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token)))
439
goto nla_put_failure;
440
441
if (nla_put_u8(skb, MPTCP_ATTR_REM_ID, id))
442
goto nla_put_failure;
443
444
genlmsg_end(skb, nlh);
445
mptcp_nl_mcast_send(net, skb, GFP_ATOMIC);
446
return;
447
448
nla_put_failure:
449
nlmsg_free(skb);
450
}
451
452
void mptcp_event_addr_announced(const struct sock *ssk,
453
const struct mptcp_addr_info *info)
454
{
455
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
456
struct mptcp_sock *msk = mptcp_sk(subflow->conn);
457
struct net *net = sock_net(ssk);
458
struct nlmsghdr *nlh;
459
struct sk_buff *skb;
460
461
if (!genl_has_listeners(&mptcp_genl_family, net, MPTCP_PM_EV_GRP_OFFSET))
462
return;
463
464
skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
465
if (!skb)
466
return;
467
468
nlh = genlmsg_put(skb, 0, 0, &mptcp_genl_family, 0,
469
MPTCP_EVENT_ANNOUNCED);
470
if (!nlh)
471
goto nla_put_failure;
472
473
if (nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token)))
474
goto nla_put_failure;
475
476
if (nla_put_u8(skb, MPTCP_ATTR_REM_ID, info->id))
477
goto nla_put_failure;
478
479
if (nla_put_be16(skb, MPTCP_ATTR_DPORT,
480
info->port == 0 ?
481
inet_sk(ssk)->inet_dport :
482
info->port))
483
goto nla_put_failure;
484
485
switch (info->family) {
486
case AF_INET:
487
if (nla_put_in_addr(skb, MPTCP_ATTR_DADDR4, info->addr.s_addr))
488
goto nla_put_failure;
489
break;
490
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
491
case AF_INET6:
492
if (nla_put_in6_addr(skb, MPTCP_ATTR_DADDR6, &info->addr6))
493
goto nla_put_failure;
494
break;
495
#endif
496
default:
497
WARN_ON_ONCE(1);
498
goto nla_put_failure;
499
}
500
501
genlmsg_end(skb, nlh);
502
mptcp_nl_mcast_send(net, skb, GFP_ATOMIC);
503
return;
504
505
nla_put_failure:
506
nlmsg_free(skb);
507
}
508
509
void mptcp_event_pm_listener(const struct sock *ssk,
510
enum mptcp_event_type event)
511
{
512
const struct inet_sock *issk = inet_sk(ssk);
513
struct net *net = sock_net(ssk);
514
struct nlmsghdr *nlh;
515
struct sk_buff *skb;
516
517
if (!genl_has_listeners(&mptcp_genl_family, net, MPTCP_PM_EV_GRP_OFFSET))
518
return;
519
520
skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
521
if (!skb)
522
return;
523
524
nlh = genlmsg_put(skb, 0, 0, &mptcp_genl_family, 0, event);
525
if (!nlh)
526
goto nla_put_failure;
527
528
if (nla_put_u16(skb, MPTCP_ATTR_FAMILY, ssk->sk_family))
529
goto nla_put_failure;
530
531
if (nla_put_be16(skb, MPTCP_ATTR_SPORT, issk->inet_sport))
532
goto nla_put_failure;
533
534
switch (ssk->sk_family) {
535
case AF_INET:
536
if (nla_put_in_addr(skb, MPTCP_ATTR_SADDR4, issk->inet_saddr))
537
goto nla_put_failure;
538
break;
539
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
540
case AF_INET6: {
541
if (nla_put_in6_addr(skb, MPTCP_ATTR_SADDR6, &issk->pinet6->saddr))
542
goto nla_put_failure;
543
break;
544
}
545
#endif
546
default:
547
WARN_ON_ONCE(1);
548
goto nla_put_failure;
549
}
550
551
genlmsg_end(skb, nlh);
552
mptcp_nl_mcast_send(net, skb, GFP_KERNEL);
553
return;
554
555
nla_put_failure:
556
nlmsg_free(skb);
557
}
558
559
void mptcp_event(enum mptcp_event_type type, const struct mptcp_sock *msk,
560
const struct sock *ssk, gfp_t gfp)
561
{
562
struct net *net = sock_net((const struct sock *)msk);
563
struct nlmsghdr *nlh;
564
struct sk_buff *skb;
565
566
if (!genl_has_listeners(&mptcp_genl_family, net, MPTCP_PM_EV_GRP_OFFSET))
567
return;
568
569
skb = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
570
if (!skb)
571
return;
572
573
nlh = genlmsg_put(skb, 0, 0, &mptcp_genl_family, 0, type);
574
if (!nlh)
575
goto nla_put_failure;
576
577
switch (type) {
578
case MPTCP_EVENT_UNSPEC:
579
WARN_ON_ONCE(1);
580
break;
581
case MPTCP_EVENT_CREATED:
582
case MPTCP_EVENT_ESTABLISHED:
583
if (mptcp_event_created(skb, msk, ssk) < 0)
584
goto nla_put_failure;
585
break;
586
case MPTCP_EVENT_CLOSED:
587
if (nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token)) < 0)
588
goto nla_put_failure;
589
break;
590
case MPTCP_EVENT_ANNOUNCED:
591
case MPTCP_EVENT_REMOVED:
592
/* call mptcp_event_addr_announced()/removed instead */
593
WARN_ON_ONCE(1);
594
break;
595
case MPTCP_EVENT_SUB_ESTABLISHED:
596
case MPTCP_EVENT_SUB_PRIORITY:
597
if (mptcp_event_sub_established(skb, msk, ssk) < 0)
598
goto nla_put_failure;
599
break;
600
case MPTCP_EVENT_SUB_CLOSED:
601
if (mptcp_event_sub_closed(skb, msk, ssk) < 0)
602
goto nla_put_failure;
603
break;
604
case MPTCP_EVENT_LISTENER_CREATED:
605
case MPTCP_EVENT_LISTENER_CLOSED:
606
break;
607
}
608
609
genlmsg_end(skb, nlh);
610
mptcp_nl_mcast_send(net, skb, gfp);
611
return;
612
613
nla_put_failure:
614
nlmsg_free(skb);
615
}
616
617
struct genl_family mptcp_genl_family __ro_after_init = {
618
.name = MPTCP_PM_NAME,
619
.version = MPTCP_PM_VER,
620
.netnsok = true,
621
.module = THIS_MODULE,
622
.ops = mptcp_pm_nl_ops,
623
.n_ops = ARRAY_SIZE(mptcp_pm_nl_ops),
624
.resv_start_op = MPTCP_PM_CMD_SUBFLOW_DESTROY + 1,
625
.mcgrps = mptcp_pm_mcgrps,
626
.n_mcgrps = ARRAY_SIZE(mptcp_pm_mcgrps),
627
};
628
629
void __init mptcp_pm_nl_init(void)
630
{
631
if (genl_register_family(&mptcp_genl_family))
632
panic("Failed to register MPTCP PM netlink family\n");
633
}
634
635