1 // SPDX-License-Identifier: GPL-2.0
4 * Copyright (c) 2019, Tessares SA.
7 #include <linux/sysctl.h>
9 #include <net/net_namespace.h>
10 #include <net/netns/generic.h>
14 #define MPTCP_SYSCTL_PATH "net/mptcp"
16 static int mptcp_pernet_id
;
18 struct ctl_table_header
*ctl_table_hdr
;
23 static struct mptcp_pernet
*mptcp_get_pernet(struct net
*net
)
25 return net_generic(net
, mptcp_pernet_id
);
28 int mptcp_is_enabled(struct net
*net
)
30 return mptcp_get_pernet(net
)->mptcp_enabled
;
33 static struct ctl_table mptcp_sysctl_table
[] = {
35 .procname
= "enabled",
36 .maxlen
= sizeof(int),
38 /* users with CAP_NET_ADMIN or root (not and) can change this
39 * value, same as other sysctl or the 'net' tree.
41 .proc_handler
= proc_dointvec
,
46 static void mptcp_pernet_set_defaults(struct mptcp_pernet
*pernet
)
48 pernet
->mptcp_enabled
= 1;
51 static int mptcp_pernet_new_table(struct net
*net
, struct mptcp_pernet
*pernet
)
53 struct ctl_table_header
*hdr
;
54 struct ctl_table
*table
;
56 table
= mptcp_sysctl_table
;
57 if (!net_eq(net
, &init_net
)) {
58 table
= kmemdup(table
, sizeof(mptcp_sysctl_table
), GFP_KERNEL
);
63 table
[0].data
= &pernet
->mptcp_enabled
;
65 hdr
= register_net_sysctl(net
, MPTCP_SYSCTL_PATH
, table
);
69 pernet
->ctl_table_hdr
= hdr
;
74 if (!net_eq(net
, &init_net
))
80 static void mptcp_pernet_del_table(struct mptcp_pernet
*pernet
)
82 struct ctl_table
*table
= pernet
->ctl_table_hdr
->ctl_table_arg
;
84 unregister_net_sysctl_table(pernet
->ctl_table_hdr
);
89 static int __net_init
mptcp_net_init(struct net
*net
)
91 struct mptcp_pernet
*pernet
= mptcp_get_pernet(net
);
93 mptcp_pernet_set_defaults(pernet
);
95 return mptcp_pernet_new_table(net
, pernet
);
98 /* Note: the callback will only be called per extra netns */
99 static void __net_exit
mptcp_net_exit(struct net
*net
)
101 struct mptcp_pernet
*pernet
= mptcp_get_pernet(net
);
103 mptcp_pernet_del_table(pernet
);
106 static struct pernet_operations mptcp_pernet_ops
= {
107 .init
= mptcp_net_init
,
108 .exit
= mptcp_net_exit
,
109 .id
= &mptcp_pernet_id
,
110 .size
= sizeof(struct mptcp_pernet
),
113 void __init
mptcp_init(void)
117 if (register_pernet_subsys(&mptcp_pernet_ops
) < 0)
118 panic("Failed to register MPTCP pernet subsystem.\n");
121 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
122 int __init
mptcpv6_init(void)
126 err
= mptcp_proto_v6_init();