aboutsummaryrefslogtreecommitdiffstats
path: root/net/l2tp
diff options
context:
space:
mode:
authorJames Chapman <jchapman@katalix.com>2010-04-02 02:19:10 -0400
committerDavid S. Miller <davem@davemloft.net>2010-04-03 17:56:05 -0400
commit309795f4bec2d69cd507a631f82065c2198a0825 (patch)
treeb3676be9a8f65f0d828a07e3bd6906bf7cd7b664 /net/l2tp
parentf408e0ce40270559ef80f231843c93baa9947bc5 (diff)
l2tp: Add netlink control API for L2TP
In L2TPv3, we need to create/delete/modify/query L2TP tunnel and session contexts. The number of parameters is significant. So let's use netlink. Userspace uses this API to control L2TP tunnel/session contexts in the kernel. The previous pppol2tp driver was managed using [gs]etsockopt(). This API is retained for backwards compatibility. Unlike L2TPv2 which carries only PPP frames, L2TPv3 can carry raw ethernet frames or other frame types and these do not always have an associated socket family. Therefore, we need a way to use L2TP sessions that doesn't require a socket type for each supported frame type. Hence netlink is used. Signed-off-by: James Chapman <jchapman@katalix.com> Reviewed-by: Randy Dunlap <randy.dunlap@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/l2tp')
-rw-r--r--net/l2tp/Makefile1
-rw-r--r--net/l2tp/l2tp_core.c61
-rw-r--r--net/l2tp/l2tp_core.h34
-rw-r--r--net/l2tp/l2tp_netlink.c830
-rw-r--r--net/l2tp/l2tp_ppp.c162
5 files changed, 1044 insertions, 44 deletions
diff --git a/net/l2tp/Makefile b/net/l2tp/Makefile
index ef28b16f7d6a..2c4a14b673ab 100644
--- a/net/l2tp/Makefile
+++ b/net/l2tp/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_L2TP) += l2tp_core.o
7# Build l2tp as modules if L2TP is M 7# Build l2tp as modules if L2TP is M
8obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_PPPOL2TP)) += l2tp_ppp.o 8obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_PPPOL2TP)) += l2tp_ppp.o
9obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_IP)) += l2tp_ip.o 9obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_IP)) += l2tp_ip.o
10obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_V3)) += l2tp_netlink.o
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index 1739d04367e4..fbd1f2119fe9 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -49,6 +49,7 @@
49#include <net/dst.h> 49#include <net/dst.h>
50#include <net/ip.h> 50#include <net/ip.h>
51#include <net/udp.h> 51#include <net/udp.h>
52#include <net/inet_common.h>
52#include <net/xfrm.h> 53#include <net/xfrm.h>
53#include <net/protocol.h> 54#include <net/protocol.h>
54 55
@@ -214,6 +215,32 @@ struct l2tp_session *l2tp_session_find_nth(struct l2tp_tunnel *tunnel, int nth)
214} 215}
215EXPORT_SYMBOL_GPL(l2tp_session_find_nth); 216EXPORT_SYMBOL_GPL(l2tp_session_find_nth);
216 217
218/* Lookup a session by interface name.
219 * This is very inefficient but is only used by management interfaces.
220 */
221struct l2tp_session *l2tp_session_find_by_ifname(struct net *net, char *ifname)
222{
223 struct l2tp_net *pn = l2tp_pernet(net);
224 int hash;
225 struct hlist_node *walk;
226 struct l2tp_session *session;
227
228 read_lock_bh(&pn->l2tp_session_hlist_lock);
229 for (hash = 0; hash < L2TP_HASH_SIZE_2; hash++) {
230 hlist_for_each_entry(session, walk, &pn->l2tp_session_hlist[hash], global_hlist) {
231 if (!strcmp(session->ifname, ifname)) {
232 read_unlock_bh(&pn->l2tp_session_hlist_lock);
233 return session;
234 }
235 }
236 }
237
238 read_unlock_bh(&pn->l2tp_session_hlist_lock);
239
240 return NULL;
241}
242EXPORT_SYMBOL_GPL(l2tp_session_find_by_ifname);
243
217/* Lookup a tunnel by id 244/* Lookup a tunnel by id
218 */ 245 */
219struct l2tp_tunnel *l2tp_tunnel_find(struct net *net, u32 tunnel_id) 246struct l2tp_tunnel *l2tp_tunnel_find(struct net *net, u32 tunnel_id)
@@ -758,7 +785,7 @@ int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb,
758 785
759 /* Find the session context */ 786 /* Find the session context */
760 session = l2tp_session_find(tunnel->l2tp_net, tunnel, session_id); 787 session = l2tp_session_find(tunnel->l2tp_net, tunnel, session_id);
761 if (!session) { 788 if (!session || !session->recv_skb) {
762 /* Not found? Pass to userspace to deal with */ 789 /* Not found? Pass to userspace to deal with */
763 PRINTK(tunnel->debug, L2TP_MSG_DATA, KERN_INFO, 790 PRINTK(tunnel->debug, L2TP_MSG_DATA, KERN_INFO,
764 "%s: no session found (%u/%u). Passing up.\n", 791 "%s: no session found (%u/%u). Passing up.\n",
@@ -1305,6 +1332,23 @@ err:
1305} 1332}
1306EXPORT_SYMBOL_GPL(l2tp_tunnel_create); 1333EXPORT_SYMBOL_GPL(l2tp_tunnel_create);
1307 1334
1335/* This function is used by the netlink TUNNEL_DELETE command.
1336 */
1337int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel)
1338{
1339 int err = 0;
1340
1341 /* Force the tunnel socket to close. This will eventually
1342 * cause the tunnel to be deleted via the normal socket close
1343 * mechanisms when userspace closes the tunnel socket.
1344 */
1345 if ((tunnel->sock != NULL) && (tunnel->sock->sk_socket != NULL))
1346 err = inet_shutdown(tunnel->sock->sk_socket, 2);
1347
1348 return err;
1349}
1350EXPORT_SYMBOL_GPL(l2tp_tunnel_delete);
1351
1308/* Really kill the session. 1352/* Really kill the session.
1309 */ 1353 */
1310void l2tp_session_free(struct l2tp_session *session) 1354void l2tp_session_free(struct l2tp_session *session)
@@ -1349,6 +1393,21 @@ void l2tp_session_free(struct l2tp_session *session)
1349} 1393}
1350EXPORT_SYMBOL_GPL(l2tp_session_free); 1394EXPORT_SYMBOL_GPL(l2tp_session_free);
1351 1395
1396/* This function is used by the netlink SESSION_DELETE command and by
1397 pseudowire modules.
1398 */
1399int l2tp_session_delete(struct l2tp_session *session)
1400{
1401 if (session->session_close != NULL)
1402 (*session->session_close)(session);
1403
1404 l2tp_session_dec_refcount(session);
1405
1406 return 0;
1407}
1408EXPORT_SYMBOL_GPL(l2tp_session_delete);
1409
1410
1352/* We come here whenever a session's send_seq, cookie_len or 1411/* We come here whenever a session's send_seq, cookie_len or
1353 * l2specific_len parameters are set. 1412 * l2specific_len parameters are set.
1354 */ 1413 */
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
index d2395984645e..2974d9ade167 100644
--- a/net/l2tp/l2tp_core.h
+++ b/net/l2tp/l2tp_core.h
@@ -33,26 +33,6 @@ enum {
33 L2TP_MSG_DATA = (1 << 3), /* data packets */ 33 L2TP_MSG_DATA = (1 << 3), /* data packets */
34}; 34};
35 35
36enum l2tp_pwtype {
37 L2TP_PWTYPE_NONE = 0x0000,
38 L2TP_PWTYPE_ETH_VLAN = 0x0004,
39 L2TP_PWTYPE_ETH = 0x0005,
40 L2TP_PWTYPE_PPP = 0x0007,
41 L2TP_PWTYPE_PPP_AC = 0x0008,
42 L2TP_PWTYPE_IP = 0x000b,
43 __L2TP_PWTYPE_MAX
44};
45
46enum l2tp_l2spec_type {
47 L2TP_L2SPECTYPE_NONE,
48 L2TP_L2SPECTYPE_DEFAULT,
49};
50
51enum l2tp_encap_type {
52 L2TP_ENCAPTYPE_UDP,
53 L2TP_ENCAPTYPE_IP,
54};
55
56struct sk_buff; 36struct sk_buff;
57 37
58struct l2tp_stats { 38struct l2tp_stats {
@@ -87,6 +67,7 @@ struct l2tp_session_cfg {
87 * control of LNS. */ 67 * control of LNS. */
88 int debug; /* bitmask of debug message 68 int debug; /* bitmask of debug message
89 * categories */ 69 * categories */
70 u16 vlan_id; /* VLAN pseudowire only */
90 u16 offset; /* offset to payload */ 71 u16 offset; /* offset to payload */
91 u16 l2specific_len; /* Layer 2 specific length */ 72 u16 l2specific_len; /* Layer 2 specific length */
92 u16 l2specific_type; /* Layer 2 specific type */ 73 u16 l2specific_type; /* Layer 2 specific type */
@@ -98,6 +79,7 @@ struct l2tp_session_cfg {
98 * (in jiffies) */ 79 * (in jiffies) */
99 int mtu; 80 int mtu;
100 int mru; 81 int mru;
82 char *ifname;
101}; 83};
102 84
103struct l2tp_session { 85struct l2tp_session {
@@ -124,6 +106,7 @@ struct l2tp_session {
124 atomic_t ref_count; 106 atomic_t ref_count;
125 107
126 char name[32]; /* for logging */ 108 char name[32]; /* for logging */
109 char ifname[IFNAMSIZ];
127 unsigned data_seq:2; /* data sequencing level 110 unsigned data_seq:2; /* data sequencing level
128 * 0 => none, 1 => IP only, 111 * 0 => none, 1 => IP only,
129 * 2 => all 112 * 2 => all
@@ -192,6 +175,11 @@ struct l2tp_tunnel {
192 uint8_t priv[0]; /* private data */ 175 uint8_t priv[0]; /* private data */
193}; 176};
194 177
178struct l2tp_nl_cmd_ops {
179 int (*session_create)(struct net *net, u32 tunnel_id, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg);
180 int (*session_delete)(struct l2tp_session *session);
181};
182
195static inline void *l2tp_tunnel_priv(struct l2tp_tunnel *tunnel) 183static inline void *l2tp_tunnel_priv(struct l2tp_tunnel *tunnel)
196{ 184{
197 return &tunnel->priv[0]; 185 return &tunnel->priv[0];
@@ -224,11 +212,14 @@ out:
224 212
225extern struct l2tp_session *l2tp_session_find(struct net *net, struct l2tp_tunnel *tunnel, u32 session_id); 213extern struct l2tp_session *l2tp_session_find(struct net *net, struct l2tp_tunnel *tunnel, u32 session_id);
226extern struct l2tp_session *l2tp_session_find_nth(struct l2tp_tunnel *tunnel, int nth); 214extern struct l2tp_session *l2tp_session_find_nth(struct l2tp_tunnel *tunnel, int nth);
215extern struct l2tp_session *l2tp_session_find_by_ifname(struct net *net, char *ifname);
227extern struct l2tp_tunnel *l2tp_tunnel_find(struct net *net, u32 tunnel_id); 216extern struct l2tp_tunnel *l2tp_tunnel_find(struct net *net, u32 tunnel_id);
228extern struct l2tp_tunnel *l2tp_tunnel_find_nth(struct net *net, int nth); 217extern struct l2tp_tunnel *l2tp_tunnel_find_nth(struct net *net, int nth);
229 218
230extern int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 peer_tunnel_id, struct l2tp_tunnel_cfg *cfg, struct l2tp_tunnel **tunnelp); 219extern int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 peer_tunnel_id, struct l2tp_tunnel_cfg *cfg, struct l2tp_tunnel **tunnelp);
220extern int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel);
231extern struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunnel, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg); 221extern struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunnel, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg);
222extern int l2tp_session_delete(struct l2tp_session *session);
232extern void l2tp_tunnel_free(struct l2tp_tunnel *tunnel); 223extern void l2tp_tunnel_free(struct l2tp_tunnel *tunnel);
233extern void l2tp_session_free(struct l2tp_session *session); 224extern void l2tp_session_free(struct l2tp_session *session);
234extern void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, unsigned char *ptr, unsigned char *optr, u16 hdrflags, int length, int (*payload_hook)(struct sk_buff *skb)); 225extern void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, unsigned char *ptr, unsigned char *optr, u16 hdrflags, int length, int (*payload_hook)(struct sk_buff *skb));
@@ -241,6 +232,9 @@ extern void l2tp_tunnel_destruct(struct sock *sk);
241extern void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel); 232extern void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel);
242extern void l2tp_session_set_header_len(struct l2tp_session *session, int version); 233extern void l2tp_session_set_header_len(struct l2tp_session *session, int version);
243 234
235extern int l2tp_nl_register_ops(enum l2tp_pwtype pw_type, const struct l2tp_nl_cmd_ops *ops);
236extern void l2tp_nl_unregister_ops(enum l2tp_pwtype pw_type);
237
244/* Tunnel reference counts. Incremented per session that is added to 238/* Tunnel reference counts. Incremented per session that is added to
245 * the tunnel. 239 * the tunnel.
246 */ 240 */
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
new file mode 100644
index 000000000000..3d0f7f6f7488
--- /dev/null
+++ b/net/l2tp/l2tp_netlink.c
@@ -0,0 +1,830 @@
1/*
2 * L2TP netlink layer, for management
3 *
4 * Copyright (c) 2008,2009,2010 Katalix Systems Ltd
5 *
6 * Partly based on the IrDA nelink implementation
7 * (see net/irda/irnetlink.c) which is:
8 * Copyright (c) 2007 Samuel Ortiz <samuel@sortiz.org>
9 * which is in turn partly based on the wireless netlink code:
10 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#include <net/sock.h>
18#include <net/genetlink.h>
19#include <net/udp.h>
20#include <linux/in.h>
21#include <linux/udp.h>
22#include <linux/socket.h>
23#include <linux/module.h>
24#include <linux/list.h>
25#include <net/net_namespace.h>
26
27#include <linux/l2tp.h>
28
29#include "l2tp_core.h"
30
31
32static struct genl_family l2tp_nl_family = {
33 .id = GENL_ID_GENERATE,
34 .name = L2TP_GENL_NAME,
35 .version = L2TP_GENL_VERSION,
36 .hdrsize = 0,
37 .maxattr = L2TP_ATTR_MAX,
38};
39
40/* Accessed under genl lock */
41static const struct l2tp_nl_cmd_ops *l2tp_nl_cmd_ops[__L2TP_PWTYPE_MAX];
42
43static struct l2tp_session *l2tp_nl_session_find(struct genl_info *info)
44{
45 u32 tunnel_id;
46 u32 session_id;
47 char *ifname;
48 struct l2tp_tunnel *tunnel;
49 struct l2tp_session *session = NULL;
50 struct net *net = genl_info_net(info);
51
52 if (info->attrs[L2TP_ATTR_IFNAME]) {
53 ifname = nla_data(info->attrs[L2TP_ATTR_IFNAME]);
54 session = l2tp_session_find_by_ifname(net, ifname);
55 } else if ((info->attrs[L2TP_ATTR_SESSION_ID]) &&
56 (info->attrs[L2TP_ATTR_CONN_ID])) {
57 tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
58 session_id = nla_get_u32(info->attrs[L2TP_ATTR_SESSION_ID]);
59 tunnel = l2tp_tunnel_find(net, tunnel_id);
60 if (tunnel)
61 session = l2tp_session_find(net, tunnel, session_id);
62 }
63
64 return session;
65}
66
67static int l2tp_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info)
68{
69 struct sk_buff *msg;
70 void *hdr;
71 int ret = -ENOBUFS;
72
73 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
74 if (!msg) {
75 ret = -ENOMEM;
76 goto out;
77 }
78
79 hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq,
80 &l2tp_nl_family, 0, L2TP_CMD_NOOP);
81 if (IS_ERR(hdr)) {
82 ret = PTR_ERR(hdr);
83 goto err_out;
84 }
85
86 genlmsg_end(msg, hdr);
87
88 return genlmsg_unicast(genl_info_net(info), msg, info->snd_pid);
89
90err_out:
91 nlmsg_free(msg);
92
93out:
94 return ret;
95}
96
97static int l2tp_nl_cmd_tunnel_create(struct sk_buff *skb, struct genl_info *info)
98{
99 u32 tunnel_id;
100 u32 peer_tunnel_id;
101 int proto_version;
102 int fd;
103 int ret = 0;
104 struct l2tp_tunnel_cfg cfg = { 0, };
105 struct l2tp_tunnel *tunnel;
106 struct net *net = genl_info_net(info);
107
108 if (!info->attrs[L2TP_ATTR_CONN_ID]) {
109 ret = -EINVAL;
110 goto out;
111 }
112 tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
113
114 if (!info->attrs[L2TP_ATTR_PEER_CONN_ID]) {
115 ret = -EINVAL;
116 goto out;
117 }
118 peer_tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_PEER_CONN_ID]);
119
120 if (!info->attrs[L2TP_ATTR_PROTO_VERSION]) {
121 ret = -EINVAL;
122 goto out;
123 }
124 proto_version = nla_get_u8(info->attrs[L2TP_ATTR_PROTO_VERSION]);
125
126 if (!info->attrs[L2TP_ATTR_ENCAP_TYPE]) {
127 ret = -EINVAL;
128 goto out;
129 }
130 cfg.encap = nla_get_u16(info->attrs[L2TP_ATTR_ENCAP_TYPE]);
131
132 if (!info->attrs[L2TP_ATTR_FD]) {
133 ret = -EINVAL;
134 goto out;
135 }
136 fd = nla_get_u32(info->attrs[L2TP_ATTR_FD]);
137
138 if (info->attrs[L2TP_ATTR_DEBUG])
139 cfg.debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]);
140
141 tunnel = l2tp_tunnel_find(net, tunnel_id);
142 if (tunnel != NULL) {
143 ret = -EEXIST;
144 goto out;
145 }
146
147 ret = -EINVAL;
148 switch (cfg.encap) {
149 case L2TP_ENCAPTYPE_UDP:
150 case L2TP_ENCAPTYPE_IP:
151 ret = l2tp_tunnel_create(net, fd, proto_version, tunnel_id,
152 peer_tunnel_id, &cfg, &tunnel);
153 break;
154 }
155
156out:
157 return ret;
158}
159
160static int l2tp_nl_cmd_tunnel_delete(struct sk_buff *skb, struct genl_info *info)
161{
162 struct l2tp_tunnel *tunnel;
163 u32 tunnel_id;
164 int ret = 0;
165 struct net *net = genl_info_net(info);
166
167 if (!info->attrs[L2TP_ATTR_CONN_ID]) {
168 ret = -EINVAL;
169 goto out;
170 }
171 tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
172
173 tunnel = l2tp_tunnel_find(net, tunnel_id);
174 if (tunnel == NULL) {
175 ret = -ENODEV;
176 goto out;
177 }
178
179 (void) l2tp_tunnel_delete(tunnel);
180
181out:
182 return ret;
183}
184
185static int l2tp_nl_cmd_tunnel_modify(struct sk_buff *skb, struct genl_info *info)
186{
187 struct l2tp_tunnel *tunnel;
188 u32 tunnel_id;
189 int ret = 0;
190 struct net *net = genl_info_net(info);
191
192 if (!info->attrs[L2TP_ATTR_CONN_ID]) {
193 ret = -EINVAL;
194 goto out;
195 }
196 tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
197
198 tunnel = l2tp_tunnel_find(net, tunnel_id);
199 if (tunnel == NULL) {
200 ret = -ENODEV;
201 goto out;
202 }
203
204 if (info->attrs[L2TP_ATTR_DEBUG])
205 tunnel->debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]);
206
207out:
208 return ret;
209}
210
211static int l2tp_nl_tunnel_send(struct sk_buff *skb, u32 pid, u32 seq, int flags,
212 struct l2tp_tunnel *tunnel)
213{
214 void *hdr;
215 struct nlattr *nest;
216 struct sock *sk = NULL;
217 struct inet_sock *inet;
218
219 hdr = genlmsg_put(skb, pid, seq, &l2tp_nl_family, flags,
220 L2TP_CMD_TUNNEL_GET);
221 if (IS_ERR(hdr))
222 return PTR_ERR(hdr);
223
224 NLA_PUT_U8(skb, L2TP_ATTR_PROTO_VERSION, tunnel->version);
225 NLA_PUT_U32(skb, L2TP_ATTR_CONN_ID, tunnel->tunnel_id);
226 NLA_PUT_U32(skb, L2TP_ATTR_PEER_CONN_ID, tunnel->peer_tunnel_id);
227 NLA_PUT_U32(skb, L2TP_ATTR_DEBUG, tunnel->debug);
228 NLA_PUT_U16(skb, L2TP_ATTR_ENCAP_TYPE, tunnel->encap);
229
230 nest = nla_nest_start(skb, L2TP_ATTR_STATS);
231 if (nest == NULL)
232 goto nla_put_failure;
233
234 NLA_PUT_U64(skb, L2TP_ATTR_TX_PACKETS, tunnel->stats.tx_packets);
235 NLA_PUT_U64(skb, L2TP_ATTR_TX_BYTES, tunnel->stats.tx_bytes);
236 NLA_PUT_U64(skb, L2TP_ATTR_TX_ERRORS, tunnel->stats.tx_errors);
237 NLA_PUT_U64(skb, L2TP_ATTR_RX_PACKETS, tunnel->stats.rx_packets);
238 NLA_PUT_U64(skb, L2TP_ATTR_RX_BYTES, tunnel->stats.rx_bytes);
239 NLA_PUT_U64(skb, L2TP_ATTR_RX_SEQ_DISCARDS, tunnel->stats.rx_seq_discards);
240 NLA_PUT_U64(skb, L2TP_ATTR_RX_OOS_PACKETS, tunnel->stats.rx_oos_packets);
241 NLA_PUT_U64(skb, L2TP_ATTR_RX_ERRORS, tunnel->stats.rx_errors);
242 nla_nest_end(skb, nest);
243
244 sk = tunnel->sock;
245 if (!sk)
246 goto out;
247
248 inet = inet_sk(sk);
249
250 switch (tunnel->encap) {
251 case L2TP_ENCAPTYPE_UDP:
252 NLA_PUT_U16(skb, L2TP_ATTR_UDP_SPORT, ntohs(inet->inet_sport));
253 NLA_PUT_U16(skb, L2TP_ATTR_UDP_DPORT, ntohs(inet->inet_dport));
254 NLA_PUT_U8(skb, L2TP_ATTR_UDP_CSUM, (sk->sk_no_check != UDP_CSUM_NOXMIT));
255 /* NOBREAK */
256 case L2TP_ENCAPTYPE_IP:
257 NLA_PUT_BE32(skb, L2TP_ATTR_IP_SADDR, inet->inet_saddr);
258 NLA_PUT_BE32(skb, L2TP_ATTR_IP_DADDR, inet->inet_daddr);
259 break;
260 }
261
262out:
263 return genlmsg_end(skb, hdr);
264
265nla_put_failure:
266 genlmsg_cancel(skb, hdr);
267 return -1;
268}
269
270static int l2tp_nl_cmd_tunnel_get(struct sk_buff *skb, struct genl_info *info)
271{
272 struct l2tp_tunnel *tunnel;
273 struct sk_buff *msg;
274 u32 tunnel_id;
275 int ret = -ENOBUFS;
276 struct net *net = genl_info_net(info);
277
278 if (!info->attrs[L2TP_ATTR_CONN_ID]) {
279 ret = -EINVAL;
280 goto out;
281 }
282
283 tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
284
285 tunnel = l2tp_tunnel_find(net, tunnel_id);
286 if (tunnel == NULL) {
287 ret = -ENODEV;
288 goto out;
289 }
290
291 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
292 if (!msg) {
293 ret = -ENOMEM;
294 goto out;
295 }
296
297 ret = l2tp_nl_tunnel_send(msg, info->snd_pid, info->snd_seq,
298 NLM_F_ACK, tunnel);
299 if (ret < 0)
300 goto err_out;
301
302 return genlmsg_unicast(net, msg, info->snd_pid);
303
304err_out:
305 nlmsg_free(msg);
306
307out:
308 return ret;
309}
310
311static int l2tp_nl_cmd_tunnel_dump(struct sk_buff *skb, struct netlink_callback *cb)
312{
313 int ti = cb->args[0];
314 struct l2tp_tunnel *tunnel;
315 struct net *net = sock_net(skb->sk);
316
317 for (;;) {
318 tunnel = l2tp_tunnel_find_nth(net, ti);
319 if (tunnel == NULL)
320 goto out;
321
322 if (l2tp_nl_tunnel_send(skb, NETLINK_CB(cb->skb).pid,
323 cb->nlh->nlmsg_seq, NLM_F_MULTI,
324 tunnel) <= 0)
325 goto out;
326
327 ti++;
328 }
329
330out:
331 cb->args[0] = ti;
332
333 return skb->len;
334}
335
336static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *info)
337{
338 u32 tunnel_id = 0;
339 u32 session_id;
340 u32 peer_session_id;
341 int ret = 0;
342 struct l2tp_tunnel *tunnel;
343 struct l2tp_session *session;
344 struct l2tp_session_cfg cfg = { 0, };
345 struct net *net = genl_info_net(info);
346
347 if (!info->attrs[L2TP_ATTR_CONN_ID]) {
348 ret = -EINVAL;
349 goto out;
350 }
351 tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
352 tunnel = l2tp_tunnel_find(net, tunnel_id);
353 if (!tunnel) {
354 ret = -ENODEV;
355 goto out;
356 }
357
358 if (!info->attrs[L2TP_ATTR_SESSION_ID]) {
359 ret = -EINVAL;
360 goto out;
361 }
362 session_id = nla_get_u32(info->attrs[L2TP_ATTR_SESSION_ID]);
363 session = l2tp_session_find(net, tunnel, session_id);
364 if (session) {
365 ret = -EEXIST;
366 goto out;
367 }
368
369 if (!info->attrs[L2TP_ATTR_PEER_SESSION_ID]) {
370 ret = -EINVAL;
371 goto out;
372 }
373 peer_session_id = nla_get_u32(info->attrs[L2TP_ATTR_PEER_SESSION_ID]);
374
375 if (!info->attrs[L2TP_ATTR_PW_TYPE]) {
376 ret = -EINVAL;
377 goto out;
378 }
379 cfg.pw_type = nla_get_u16(info->attrs[L2TP_ATTR_PW_TYPE]);
380 if (cfg.pw_type >= __L2TP_PWTYPE_MAX) {
381 ret = -EINVAL;
382 goto out;
383 }
384
385 if (tunnel->version > 2) {
386 if (info->attrs[L2TP_ATTR_OFFSET])
387 cfg.offset = nla_get_u16(info->attrs[L2TP_ATTR_OFFSET]);
388
389 if (info->attrs[L2TP_ATTR_DATA_SEQ])
390 cfg.data_seq = nla_get_u8(info->attrs[L2TP_ATTR_DATA_SEQ]);
391
392 cfg.l2specific_type = L2TP_L2SPECTYPE_DEFAULT;
393 if (info->attrs[L2TP_ATTR_L2SPEC_TYPE])
394 cfg.l2specific_type = nla_get_u8(info->attrs[L2TP_ATTR_L2SPEC_TYPE]);
395
396 cfg.l2specific_len = 4;
397 if (info->attrs[L2TP_ATTR_L2SPEC_LEN])
398 cfg.l2specific_len = nla_get_u8(info->attrs[L2TP_ATTR_L2SPEC_LEN]);
399
400 if (info->attrs[L2TP_ATTR_COOKIE]) {
401 u16 len = nla_len(info->attrs[L2TP_ATTR_COOKIE]);
402 if (len > 8) {
403 ret = -EINVAL;
404 goto out;
405 }
406 cfg.cookie_len = len;
407 memcpy(&cfg.cookie[0], nla_data(info->attrs[L2TP_ATTR_COOKIE]), len);
408 }
409 if (info->attrs[L2TP_ATTR_PEER_COOKIE]) {
410 u16 len = nla_len(info->attrs[L2TP_ATTR_PEER_COOKIE]);
411 if (len > 8) {
412 ret = -EINVAL;
413 goto out;
414 }
415 cfg.peer_cookie_len = len;
416 memcpy(&cfg.peer_cookie[0], nla_data(info->attrs[L2TP_ATTR_PEER_COOKIE]), len);
417 }
418 if (info->attrs[L2TP_ATTR_IFNAME])
419 cfg.ifname = nla_data(info->attrs[L2TP_ATTR_IFNAME]);
420
421 if (info->attrs[L2TP_ATTR_VLAN_ID])
422 cfg.vlan_id = nla_get_u16(info->attrs[L2TP_ATTR_VLAN_ID]);
423 }
424
425 if (info->attrs[L2TP_ATTR_DEBUG])
426 cfg.debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]);
427
428 if (info->attrs[L2TP_ATTR_RECV_SEQ])
429 cfg.recv_seq = nla_get_u8(info->attrs[L2TP_ATTR_RECV_SEQ]);
430
431 if (info->attrs[L2TP_ATTR_SEND_SEQ])
432 cfg.send_seq = nla_get_u8(info->attrs[L2TP_ATTR_SEND_SEQ]);
433
434 if (info->attrs[L2TP_ATTR_LNS_MODE])
435 cfg.lns_mode = nla_get_u8(info->attrs[L2TP_ATTR_LNS_MODE]);
436
437 if (info->attrs[L2TP_ATTR_RECV_TIMEOUT])
438 cfg.reorder_timeout = nla_get_msecs(info->attrs[L2TP_ATTR_RECV_TIMEOUT]);
439
440 if (info->attrs[L2TP_ATTR_MTU])
441 cfg.mtu = nla_get_u16(info->attrs[L2TP_ATTR_MTU]);
442
443 if (info->attrs[L2TP_ATTR_MRU])
444 cfg.mru = nla_get_u16(info->attrs[L2TP_ATTR_MRU]);
445
446 if ((l2tp_nl_cmd_ops[cfg.pw_type] == NULL) ||
447 (l2tp_nl_cmd_ops[cfg.pw_type]->session_create == NULL)) {
448 ret = -EPROTONOSUPPORT;
449 goto out;
450 }
451
452 /* Check that pseudowire-specific params are present */
453 switch (cfg.pw_type) {
454 case L2TP_PWTYPE_NONE:
455 break;
456 case L2TP_PWTYPE_ETH_VLAN:
457 if (!info->attrs[L2TP_ATTR_VLAN_ID]) {
458 ret = -EINVAL;
459 goto out;
460 }
461 break;
462 case L2TP_PWTYPE_ETH:
463 break;
464 case L2TP_PWTYPE_PPP:
465 case L2TP_PWTYPE_PPP_AC:
466 break;
467 case L2TP_PWTYPE_IP:
468 default:
469 ret = -EPROTONOSUPPORT;
470 break;
471 }
472
473 ret = -EPROTONOSUPPORT;
474 if (l2tp_nl_cmd_ops[cfg.pw_type]->session_create)
475 ret = (*l2tp_nl_cmd_ops[cfg.pw_type]->session_create)(net, tunnel_id,
476 session_id, peer_session_id, &cfg);
477
478out:
479 return ret;
480}
481
482static int l2tp_nl_cmd_session_delete(struct sk_buff *skb, struct genl_info *info)
483{
484 int ret = 0;
485 struct l2tp_session *session;
486 u16 pw_type;
487
488 session = l2tp_nl_session_find(info);
489 if (session == NULL) {
490 ret = -ENODEV;
491 goto out;
492 }
493
494 pw_type = session->pwtype;
495 if (pw_type < __L2TP_PWTYPE_MAX)
496 if (l2tp_nl_cmd_ops[pw_type] && l2tp_nl_cmd_ops[pw_type]->session_delete)
497 ret = (*l2tp_nl_cmd_ops[pw_type]->session_delete)(session);
498
499out:
500 return ret;
501}
502
503static int l2tp_nl_cmd_session_modify(struct sk_buff *skb, struct genl_info *info)
504{
505 int ret = 0;
506 struct l2tp_session *session;
507
508 session = l2tp_nl_session_find(info);
509 if (session == NULL) {
510 ret = -ENODEV;
511 goto out;
512 }
513
514 if (info->attrs[L2TP_ATTR_DEBUG])
515 session->debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]);
516
517 if (info->attrs[L2TP_ATTR_DATA_SEQ])
518 session->data_seq = nla_get_u8(info->attrs[L2TP_ATTR_DATA_SEQ]);
519
520 if (info->attrs[L2TP_ATTR_RECV_SEQ])
521 session->recv_seq = nla_get_u8(info->attrs[L2TP_ATTR_RECV_SEQ]);
522
523 if (info->attrs[L2TP_ATTR_SEND_SEQ])
524 session->send_seq = nla_get_u8(info->attrs[L2TP_ATTR_SEND_SEQ]);
525
526 if (info->attrs[L2TP_ATTR_LNS_MODE])
527 session->lns_mode = nla_get_u8(info->attrs[L2TP_ATTR_LNS_MODE]);
528
529 if (info->attrs[L2TP_ATTR_RECV_TIMEOUT])
530 session->reorder_timeout = nla_get_msecs(info->attrs[L2TP_ATTR_RECV_TIMEOUT]);
531
532 if (info->attrs[L2TP_ATTR_MTU])
533 session->mtu = nla_get_u16(info->attrs[L2TP_ATTR_MTU]);
534
535 if (info->attrs[L2TP_ATTR_MRU])
536 session->mru = nla_get_u16(info->attrs[L2TP_ATTR_MRU]);
537
538out:
539 return ret;
540}
541
542static int l2tp_nl_session_send(struct sk_buff *skb, u32 pid, u32 seq, int flags,
543 struct l2tp_session *session)
544{
545 void *hdr;
546 struct nlattr *nest;
547 struct l2tp_tunnel *tunnel = session->tunnel;
548 struct sock *sk = NULL;
549
550 sk = tunnel->sock;
551
552 hdr = genlmsg_put(skb, pid, seq, &l2tp_nl_family, flags, L2TP_CMD_SESSION_GET);
553 if (IS_ERR(hdr))
554 return PTR_ERR(hdr);
555
556 NLA_PUT_U32(skb, L2TP_ATTR_CONN_ID, tunnel->tunnel_id);
557 NLA_PUT_U32(skb, L2TP_ATTR_SESSION_ID, session->session_id);
558 NLA_PUT_U32(skb, L2TP_ATTR_PEER_CONN_ID, tunnel->peer_tunnel_id);
559 NLA_PUT_U32(skb, L2TP_ATTR_PEER_SESSION_ID, session->peer_session_id);
560 NLA_PUT_U32(skb, L2TP_ATTR_DEBUG, session->debug);
561 NLA_PUT_U16(skb, L2TP_ATTR_PW_TYPE, session->pwtype);
562 NLA_PUT_U16(skb, L2TP_ATTR_MTU, session->mtu);
563 if (session->mru)
564 NLA_PUT_U16(skb, L2TP_ATTR_MRU, session->mru);
565
566 if (session->ifname && session->ifname[0])
567 NLA_PUT_STRING(skb, L2TP_ATTR_IFNAME, session->ifname);
568 if (session->cookie_len)
569 NLA_PUT(skb, L2TP_ATTR_COOKIE, session->cookie_len, &session->cookie[0]);
570 if (session->peer_cookie_len)
571 NLA_PUT(skb, L2TP_ATTR_PEER_COOKIE, session->peer_cookie_len, &session->peer_cookie[0]);
572 NLA_PUT_U8(skb, L2TP_ATTR_RECV_SEQ, session->recv_seq);
573 NLA_PUT_U8(skb, L2TP_ATTR_SEND_SEQ, session->send_seq);
574 NLA_PUT_U8(skb, L2TP_ATTR_LNS_MODE, session->lns_mode);
575#ifdef CONFIG_XFRM
576 if ((sk) && (sk->sk_policy[0] || sk->sk_policy[1]))
577 NLA_PUT_U8(skb, L2TP_ATTR_USING_IPSEC, 1);
578#endif
579 if (session->reorder_timeout)
580 NLA_PUT_MSECS(skb, L2TP_ATTR_RECV_TIMEOUT, session->reorder_timeout);
581
582 nest = nla_nest_start(skb, L2TP_ATTR_STATS);
583 if (nest == NULL)
584 goto nla_put_failure;
585 NLA_PUT_U64(skb, L2TP_ATTR_TX_PACKETS, session->stats.tx_packets);
586 NLA_PUT_U64(skb, L2TP_ATTR_TX_BYTES, session->stats.tx_bytes);
587 NLA_PUT_U64(skb, L2TP_ATTR_TX_ERRORS, session->stats.tx_errors);
588 NLA_PUT_U64(skb, L2TP_ATTR_RX_PACKETS, session->stats.rx_packets);
589 NLA_PUT_U64(skb, L2TP_ATTR_RX_BYTES, session->stats.rx_bytes);
590 NLA_PUT_U64(skb, L2TP_ATTR_RX_SEQ_DISCARDS, session->stats.rx_seq_discards);
591 NLA_PUT_U64(skb, L2TP_ATTR_RX_OOS_PACKETS, session->stats.rx_oos_packets);
592 NLA_PUT_U64(skb, L2TP_ATTR_RX_ERRORS, session->stats.rx_errors);
593 nla_nest_end(skb, nest);
594
595 return genlmsg_end(skb, hdr);
596
597 nla_put_failure:
598 genlmsg_cancel(skb, hdr);
599 return -1;
600}
601
602static int l2tp_nl_cmd_session_get(struct sk_buff *skb, struct genl_info *info)
603{
604 struct l2tp_session *session;
605 struct sk_buff *msg;
606 int ret;
607
608 session = l2tp_nl_session_find(info);
609 if (session == NULL) {
610 ret = -ENODEV;
611 goto out;
612 }
613
614 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
615 if (!msg) {
616 ret = -ENOMEM;
617 goto out;
618 }
619
620 ret = l2tp_nl_session_send(msg, info->snd_pid, info->snd_seq,
621 0, session);
622 if (ret < 0)
623 goto err_out;
624
625 return genlmsg_unicast(genl_info_net(info), msg, info->snd_pid);
626
627err_out:
628 nlmsg_free(msg);
629
630out:
631 return ret;
632}
633
634static int l2tp_nl_cmd_session_dump(struct sk_buff *skb, struct netlink_callback *cb)
635{
636 struct net *net = sock_net(skb->sk);
637 struct l2tp_session *session;
638 struct l2tp_tunnel *tunnel = NULL;
639 int ti = cb->args[0];
640 int si = cb->args[1];
641
642 for (;;) {
643 if (tunnel == NULL) {
644 tunnel = l2tp_tunnel_find_nth(net, ti);
645 if (tunnel == NULL)
646 goto out;
647 }
648
649 session = l2tp_session_find_nth(tunnel, si);
650 if (session == NULL) {
651 ti++;
652 tunnel = NULL;
653 si = 0;
654 continue;
655 }
656
657 if (l2tp_nl_session_send(skb, NETLINK_CB(cb->skb).pid,
658 cb->nlh->nlmsg_seq, NLM_F_MULTI,
659 session) <= 0)
660 break;
661
662 si++;
663 }
664
665out:
666 cb->args[0] = ti;
667 cb->args[1] = si;
668
669 return skb->len;
670}
671
672static struct nla_policy l2tp_nl_policy[L2TP_ATTR_MAX + 1] = {
673 [L2TP_ATTR_NONE] = { .type = NLA_UNSPEC, },
674 [L2TP_ATTR_PW_TYPE] = { .type = NLA_U16, },
675 [L2TP_ATTR_ENCAP_TYPE] = { .type = NLA_U16, },
676 [L2TP_ATTR_OFFSET] = { .type = NLA_U16, },
677 [L2TP_ATTR_DATA_SEQ] = { .type = NLA_U8, },
678 [L2TP_ATTR_L2SPEC_TYPE] = { .type = NLA_U8, },
679 [L2TP_ATTR_L2SPEC_LEN] = { .type = NLA_U8, },
680 [L2TP_ATTR_PROTO_VERSION] = { .type = NLA_U8, },
681 [L2TP_ATTR_CONN_ID] = { .type = NLA_U32, },
682 [L2TP_ATTR_PEER_CONN_ID] = { .type = NLA_U32, },
683 [L2TP_ATTR_SESSION_ID] = { .type = NLA_U32, },
684 [L2TP_ATTR_PEER_SESSION_ID] = { .type = NLA_U32, },
685 [L2TP_ATTR_UDP_CSUM] = { .type = NLA_U8, },
686 [L2TP_ATTR_VLAN_ID] = { .type = NLA_U16, },
687 [L2TP_ATTR_DEBUG] = { .type = NLA_U32, },
688 [L2TP_ATTR_RECV_SEQ] = { .type = NLA_U8, },
689 [L2TP_ATTR_SEND_SEQ] = { .type = NLA_U8, },
690 [L2TP_ATTR_LNS_MODE] = { .type = NLA_U8, },
691 [L2TP_ATTR_USING_IPSEC] = { .type = NLA_U8, },
692 [L2TP_ATTR_RECV_TIMEOUT] = { .type = NLA_MSECS, },
693 [L2TP_ATTR_FD] = { .type = NLA_U32, },
694 [L2TP_ATTR_IP_SADDR] = { .type = NLA_U32, },
695 [L2TP_ATTR_IP_DADDR] = { .type = NLA_U32, },
696 [L2TP_ATTR_UDP_SPORT] = { .type = NLA_U16, },
697 [L2TP_ATTR_UDP_DPORT] = { .type = NLA_U16, },
698 [L2TP_ATTR_MTU] = { .type = NLA_U16, },
699 [L2TP_ATTR_MRU] = { .type = NLA_U16, },
700 [L2TP_ATTR_STATS] = { .type = NLA_NESTED, },
701 [L2TP_ATTR_IFNAME] = {
702 .type = NLA_NUL_STRING,
703 .len = IFNAMSIZ - 1,
704 },
705 [L2TP_ATTR_COOKIE] = {
706 .type = NLA_BINARY,
707 .len = 8,
708 },
709 [L2TP_ATTR_PEER_COOKIE] = {
710 .type = NLA_BINARY,
711 .len = 8,
712 },
713};
714
715static struct genl_ops l2tp_nl_ops[] = {
716 {
717 .cmd = L2TP_CMD_NOOP,
718 .doit = l2tp_nl_cmd_noop,
719 .policy = l2tp_nl_policy,
720 /* can be retrieved by unprivileged users */
721 },
722 {
723 .cmd = L2TP_CMD_TUNNEL_CREATE,
724 .doit = l2tp_nl_cmd_tunnel_create,
725 .policy = l2tp_nl_policy,
726 .flags = GENL_ADMIN_PERM,
727 },
728 {
729 .cmd = L2TP_CMD_TUNNEL_DELETE,
730 .doit = l2tp_nl_cmd_tunnel_delete,
731 .policy = l2tp_nl_policy,
732 .flags = GENL_ADMIN_PERM,
733 },
734 {
735 .cmd = L2TP_CMD_TUNNEL_MODIFY,
736 .doit = l2tp_nl_cmd_tunnel_modify,
737 .policy = l2tp_nl_policy,
738 .flags = GENL_ADMIN_PERM,
739 },
740 {
741 .cmd = L2TP_CMD_TUNNEL_GET,
742 .doit = l2tp_nl_cmd_tunnel_get,
743 .dumpit = l2tp_nl_cmd_tunnel_dump,
744 .policy = l2tp_nl_policy,
745 .flags = GENL_ADMIN_PERM,
746 },
747 {
748 .cmd = L2TP_CMD_SESSION_CREATE,
749 .doit = l2tp_nl_cmd_session_create,
750 .policy = l2tp_nl_policy,
751 .flags = GENL_ADMIN_PERM,
752 },
753 {
754 .cmd = L2TP_CMD_SESSION_DELETE,
755 .doit = l2tp_nl_cmd_session_delete,
756 .policy = l2tp_nl_policy,
757 .flags = GENL_ADMIN_PERM,
758 },
759 {
760 .cmd = L2TP_CMD_SESSION_MODIFY,
761 .doit = l2tp_nl_cmd_session_modify,
762 .policy = l2tp_nl_policy,
763 .flags = GENL_ADMIN_PERM,
764 },
765 {
766 .cmd = L2TP_CMD_SESSION_GET,
767 .doit = l2tp_nl_cmd_session_get,
768 .dumpit = l2tp_nl_cmd_session_dump,
769 .policy = l2tp_nl_policy,
770 .flags = GENL_ADMIN_PERM,
771 },
772};
773
774int l2tp_nl_register_ops(enum l2tp_pwtype pw_type, const struct l2tp_nl_cmd_ops *ops)
775{
776 int ret;
777
778 ret = -EINVAL;
779 if (pw_type >= __L2TP_PWTYPE_MAX)
780 goto err;
781
782 genl_lock();
783 ret = -EBUSY;
784 if (l2tp_nl_cmd_ops[pw_type])
785 goto out;
786
787 l2tp_nl_cmd_ops[pw_type] = ops;
788
789out:
790 genl_unlock();
791err:
792 return 0;
793}
794EXPORT_SYMBOL_GPL(l2tp_nl_register_ops);
795
796void l2tp_nl_unregister_ops(enum l2tp_pwtype pw_type)
797{
798 if (pw_type < __L2TP_PWTYPE_MAX) {
799 genl_lock();
800 l2tp_nl_cmd_ops[pw_type] = NULL;
801 genl_unlock();
802 }
803}
804EXPORT_SYMBOL_GPL(l2tp_nl_unregister_ops);
805
806static int l2tp_nl_init(void)
807{
808 int err;
809
810 printk(KERN_INFO "L2TP netlink interface\n");
811 err = genl_register_family_with_ops(&l2tp_nl_family, l2tp_nl_ops,
812 ARRAY_SIZE(l2tp_nl_ops));
813
814 return err;
815}
816
817static void l2tp_nl_cleanup(void)
818{
819 genl_unregister_family(&l2tp_nl_family);
820}
821
822module_init(l2tp_nl_init);
823module_exit(l2tp_nl_cleanup);
824
825MODULE_AUTHOR("James Chapman <jchapman@katalix.com>");
826MODULE_DESCRIPTION("L2TP netlink");
827MODULE_LICENSE("GPL");
828MODULE_VERSION("1.0");
829MODULE_ALIAS("net-pf-" __stringify(PF_NETLINK) "-proto-" \
830 __stringify(NETLINK_GENERIC) "-type-" "l2tp")
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index 63fc62baeeb9..d64f081f2b1c 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -87,6 +87,7 @@
87#include <linux/hash.h> 87#include <linux/hash.h>
88#include <linux/sort.h> 88#include <linux/sort.h>
89#include <linux/proc_fs.h> 89#include <linux/proc_fs.h>
90#include <linux/l2tp.h>
90#include <linux/nsproxy.h> 91#include <linux/nsproxy.h>
91#include <net/net_namespace.h> 92#include <net/net_namespace.h>
92#include <net/netns/generic.h> 93#include <net/netns/generic.h>
@@ -656,17 +657,23 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
656 if (tunnel_id == 0) 657 if (tunnel_id == 0)
657 goto end; 658 goto end;
658 659
660 tunnel = l2tp_tunnel_find(sock_net(sk), tunnel_id);
661
659 /* Special case: create tunnel context if session_id and 662 /* Special case: create tunnel context if session_id and
660 * peer_session_id is 0. Otherwise look up tunnel using supplied 663 * peer_session_id is 0. Otherwise look up tunnel using supplied
661 * tunnel id. 664 * tunnel id.
662 */ 665 */
663 if ((session_id == 0) && (peer_session_id == 0)) { 666 if ((session_id == 0) && (peer_session_id == 0)) {
664 error = l2tp_tunnel_create(sock_net(sk), fd, ver, tunnel_id, peer_tunnel_id, NULL, &tunnel); 667 if (tunnel == NULL) {
665 if (error < 0) 668 struct l2tp_tunnel_cfg tcfg = {
666 goto end; 669 .encap = L2TP_ENCAPTYPE_UDP,
670 .debug = 0,
671 };
672 error = l2tp_tunnel_create(sock_net(sk), fd, ver, tunnel_id, peer_tunnel_id, &tcfg, &tunnel);
673 if (error < 0)
674 goto end;
675 }
667 } else { 676 } else {
668 tunnel = l2tp_tunnel_find(sock_net(sk), tunnel_id);
669
670 /* Error if we can't find the tunnel */ 677 /* Error if we can't find the tunnel */
671 error = -ENOENT; 678 error = -ENOENT;
672 if (tunnel == NULL) 679 if (tunnel == NULL)
@@ -680,28 +687,46 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
680 if (tunnel->recv_payload_hook == NULL) 687 if (tunnel->recv_payload_hook == NULL)
681 tunnel->recv_payload_hook = pppol2tp_recv_payload_hook; 688 tunnel->recv_payload_hook = pppol2tp_recv_payload_hook;
682 689
683 /* Check that this session doesn't already exist */ 690 if (tunnel->peer_tunnel_id == 0) {
684 error = -EEXIST; 691 if (ver == 2)
685 session = l2tp_session_find(sock_net(sk), tunnel, session_id); 692 tunnel->peer_tunnel_id = sp->pppol2tp.d_tunnel;
686 if (session != NULL) 693 else
687 goto end; 694 tunnel->peer_tunnel_id = sp3->pppol2tp.d_tunnel;
688 695 }
689 /* Default MTU values. */
690 if (cfg.mtu == 0)
691 cfg.mtu = 1500 - PPPOL2TP_HEADER_OVERHEAD;
692 if (cfg.mru == 0)
693 cfg.mru = cfg.mtu;
694 cfg.debug = tunnel->debug;
695 696
696 /* Allocate and initialize a new session context. */ 697 /* Create session if it doesn't already exist. We handle the
697 session = l2tp_session_create(sizeof(struct pppol2tp_session), 698 * case where a session was previously created by the netlink
698 tunnel, session_id, 699 * interface by checking that the session doesn't already have
699 peer_session_id, &cfg); 700 * a socket and its tunnel socket are what we expect. If any
701 * of those checks fail, return EEXIST to the caller.
702 */
703 session = l2tp_session_find(sock_net(sk), tunnel, session_id);
700 if (session == NULL) { 704 if (session == NULL) {
701 error = -ENOMEM; 705 /* Default MTU must allow space for UDP/L2TP/PPP
702 goto end; 706 * headers.
707 */
708 cfg.mtu = cfg.mru = 1500 - PPPOL2TP_HEADER_OVERHEAD;
709
710 /* Allocate and initialize a new session context. */
711 session = l2tp_session_create(sizeof(struct pppol2tp_session),
712 tunnel, session_id,
713 peer_session_id, &cfg);
714 if (session == NULL) {
715 error = -ENOMEM;
716 goto end;
717 }
718 } else {
719 ps = l2tp_session_priv(session);
720 error = -EEXIST;
721 if (ps->sock != NULL)
722 goto end;
723
724 /* consistency checks */
725 if (ps->tunnel_sock != tunnel->sock)
726 goto end;
703 } 727 }
704 728
729 /* Associate session with its PPPoL2TP socket */
705 ps = l2tp_session_priv(session); 730 ps = l2tp_session_priv(session);
706 ps->owner = current->pid; 731 ps->owner = current->pid;
707 ps->sock = sk; 732 ps->sock = sk;
@@ -764,6 +789,74 @@ end:
764 return error; 789 return error;
765} 790}
766 791
792#ifdef CONFIG_L2TP_V3
793
794/* Called when creating sessions via the netlink interface.
795 */
796static int pppol2tp_session_create(struct net *net, u32 tunnel_id, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg)
797{
798 int error;
799 struct l2tp_tunnel *tunnel;
800 struct l2tp_session *session;
801 struct pppol2tp_session *ps;
802
803 tunnel = l2tp_tunnel_find(net, tunnel_id);
804
805 /* Error if we can't find the tunnel */
806 error = -ENOENT;
807 if (tunnel == NULL)
808 goto out;
809
810 /* Error if tunnel socket is not prepped */
811 if (tunnel->sock == NULL)
812 goto out;
813
814 /* Check that this session doesn't already exist */
815 error = -EEXIST;
816 session = l2tp_session_find(net, tunnel, session_id);
817 if (session != NULL)
818 goto out;
819
820 /* Default MTU values. */
821 if (cfg->mtu == 0)
822 cfg->mtu = 1500 - PPPOL2TP_HEADER_OVERHEAD;
823 if (cfg->mru == 0)
824 cfg->mru = cfg->mtu;
825
826 /* Allocate and initialize a new session context. */
827 error = -ENOMEM;
828 session = l2tp_session_create(sizeof(struct pppol2tp_session),
829 tunnel, session_id,
830 peer_session_id, cfg);
831 if (session == NULL)
832 goto out;
833
834 ps = l2tp_session_priv(session);
835 ps->tunnel_sock = tunnel->sock;
836
837 PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
838 "%s: created\n", session->name);
839
840 error = 0;
841
842out:
843 return error;
844}
845
846/* Called when deleting sessions via the netlink interface.
847 */
848static int pppol2tp_session_delete(struct l2tp_session *session)
849{
850 struct pppol2tp_session *ps = l2tp_session_priv(session);
851
852 if (ps->sock == NULL)
853 l2tp_session_dec_refcount(session);
854
855 return 0;
856}
857
858#endif /* CONFIG_L2TP_V3 */
859
767/* getname() support. 860/* getname() support.
768 */ 861 */
769static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr, 862static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr,
@@ -1660,6 +1753,15 @@ static struct pppox_proto pppol2tp_proto = {
1660 .ioctl = pppol2tp_ioctl 1753 .ioctl = pppol2tp_ioctl
1661}; 1754};
1662 1755
1756#ifdef CONFIG_L2TP_V3
1757
1758static const struct l2tp_nl_cmd_ops pppol2tp_nl_cmd_ops = {
1759 .session_create = pppol2tp_session_create,
1760 .session_delete = pppol2tp_session_delete,
1761};
1762
1763#endif /* CONFIG_L2TP_V3 */
1764
1663static int __init pppol2tp_init(void) 1765static int __init pppol2tp_init(void)
1664{ 1766{
1665 int err; 1767 int err;
@@ -1676,11 +1778,22 @@ static int __init pppol2tp_init(void)
1676 if (err) 1778 if (err)
1677 goto out_unregister_pppol2tp_proto; 1779 goto out_unregister_pppol2tp_proto;
1678 1780
1781#ifdef CONFIG_L2TP_V3
1782 err = l2tp_nl_register_ops(L2TP_PWTYPE_PPP, &pppol2tp_nl_cmd_ops);
1783 if (err)
1784 goto out_unregister_pppox;
1785#endif
1786
1679 printk(KERN_INFO "PPPoL2TP kernel driver, %s\n", 1787 printk(KERN_INFO "PPPoL2TP kernel driver, %s\n",
1680 PPPOL2TP_DRV_VERSION); 1788 PPPOL2TP_DRV_VERSION);
1681 1789
1682out: 1790out:
1683 return err; 1791 return err;
1792
1793#ifdef CONFIG_L2TP_V3
1794out_unregister_pppox:
1795 unregister_pppox_proto(PX_PROTO_OL2TP);
1796#endif
1684out_unregister_pppol2tp_proto: 1797out_unregister_pppol2tp_proto:
1685 proto_unregister(&pppol2tp_sk_proto); 1798 proto_unregister(&pppol2tp_sk_proto);
1686out_unregister_pppol2tp_pernet: 1799out_unregister_pppol2tp_pernet:
@@ -1690,6 +1803,9 @@ out_unregister_pppol2tp_pernet:
1690 1803
1691static void __exit pppol2tp_exit(void) 1804static void __exit pppol2tp_exit(void)
1692{ 1805{
1806#ifdef CONFIG_L2TP_V3
1807 l2tp_nl_unregister_ops(L2TP_PWTYPE_PPP);
1808#endif
1693 unregister_pppox_proto(PX_PROTO_OL2TP); 1809 unregister_pppox_proto(PX_PROTO_OL2TP);
1694 proto_unregister(&pppol2tp_sk_proto); 1810 proto_unregister(&pppol2tp_sk_proto);
1695 unregister_pernet_device(&pppol2tp_net_ops); 1811 unregister_pernet_device(&pppol2tp_net_ops);