KEYS: add missing permission check for request_key() destination
[linux/fpc-iii.git] / net / l2tp / l2tp_netlink.c
blob0fc9e31d1edcdb95da875789fb3359bc38af2ac1
1 /*
2 * L2TP netlink layer, for management
4 * Copyright (c) 2008,2009,2010 Katalix Systems Ltd
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>
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.
17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19 #include <net/sock.h>
20 #include <net/genetlink.h>
21 #include <net/udp.h>
22 #include <linux/in.h>
23 #include <linux/udp.h>
24 #include <linux/socket.h>
25 #include <linux/module.h>
26 #include <linux/list.h>
27 #include <net/net_namespace.h>
29 #include <linux/l2tp.h>
31 #include "l2tp_core.h"
34 static struct genl_family l2tp_nl_family = {
35 .id = GENL_ID_GENERATE,
36 .name = L2TP_GENL_NAME,
37 .version = L2TP_GENL_VERSION,
38 .hdrsize = 0,
39 .maxattr = L2TP_ATTR_MAX,
40 .netnsok = true,
43 /* Accessed under genl lock */
44 static const struct l2tp_nl_cmd_ops *l2tp_nl_cmd_ops[__L2TP_PWTYPE_MAX];
46 static struct l2tp_session *l2tp_nl_session_get(struct genl_info *info,
47 bool do_ref)
49 u32 tunnel_id;
50 u32 session_id;
51 char *ifname;
52 struct l2tp_tunnel *tunnel;
53 struct l2tp_session *session = NULL;
54 struct net *net = genl_info_net(info);
56 if (info->attrs[L2TP_ATTR_IFNAME]) {
57 ifname = nla_data(info->attrs[L2TP_ATTR_IFNAME]);
58 session = l2tp_session_get_by_ifname(net, ifname, do_ref);
59 } else if ((info->attrs[L2TP_ATTR_SESSION_ID]) &&
60 (info->attrs[L2TP_ATTR_CONN_ID])) {
61 tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
62 session_id = nla_get_u32(info->attrs[L2TP_ATTR_SESSION_ID]);
63 tunnel = l2tp_tunnel_get(net, tunnel_id);
64 if (tunnel) {
65 session = l2tp_session_get(net, tunnel, session_id,
66 do_ref);
67 l2tp_tunnel_dec_refcount(tunnel);
71 return session;
74 static int l2tp_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info)
76 struct sk_buff *msg;
77 void *hdr;
78 int ret = -ENOBUFS;
80 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
81 if (!msg) {
82 ret = -ENOMEM;
83 goto out;
86 hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq,
87 &l2tp_nl_family, 0, L2TP_CMD_NOOP);
88 if (!hdr) {
89 ret = -EMSGSIZE;
90 goto err_out;
93 genlmsg_end(msg, hdr);
95 return genlmsg_unicast(genl_info_net(info), msg, info->snd_portid);
97 err_out:
98 nlmsg_free(msg);
100 out:
101 return ret;
104 static int l2tp_nl_cmd_tunnel_create(struct sk_buff *skb, struct genl_info *info)
106 u32 tunnel_id;
107 u32 peer_tunnel_id;
108 int proto_version;
109 int fd;
110 int ret = 0;
111 struct l2tp_tunnel_cfg cfg = { 0, };
112 struct l2tp_tunnel *tunnel;
113 struct net *net = genl_info_net(info);
115 if (!info->attrs[L2TP_ATTR_CONN_ID]) {
116 ret = -EINVAL;
117 goto out;
119 tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
121 if (!info->attrs[L2TP_ATTR_PEER_CONN_ID]) {
122 ret = -EINVAL;
123 goto out;
125 peer_tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_PEER_CONN_ID]);
127 if (!info->attrs[L2TP_ATTR_PROTO_VERSION]) {
128 ret = -EINVAL;
129 goto out;
131 proto_version = nla_get_u8(info->attrs[L2TP_ATTR_PROTO_VERSION]);
133 if (!info->attrs[L2TP_ATTR_ENCAP_TYPE]) {
134 ret = -EINVAL;
135 goto out;
137 cfg.encap = nla_get_u16(info->attrs[L2TP_ATTR_ENCAP_TYPE]);
139 fd = -1;
140 if (info->attrs[L2TP_ATTR_FD]) {
141 fd = nla_get_u32(info->attrs[L2TP_ATTR_FD]);
142 } else {
143 #if IS_ENABLED(CONFIG_IPV6)
144 if (info->attrs[L2TP_ATTR_IP6_SADDR] &&
145 info->attrs[L2TP_ATTR_IP6_DADDR]) {
146 cfg.local_ip6 = nla_data(
147 info->attrs[L2TP_ATTR_IP6_SADDR]);
148 cfg.peer_ip6 = nla_data(
149 info->attrs[L2TP_ATTR_IP6_DADDR]);
150 } else
151 #endif
152 if (info->attrs[L2TP_ATTR_IP_SADDR] &&
153 info->attrs[L2TP_ATTR_IP_DADDR]) {
154 cfg.local_ip.s_addr = nla_get_be32(
155 info->attrs[L2TP_ATTR_IP_SADDR]);
156 cfg.peer_ip.s_addr = nla_get_be32(
157 info->attrs[L2TP_ATTR_IP_DADDR]);
158 } else {
159 ret = -EINVAL;
160 goto out;
162 if (info->attrs[L2TP_ATTR_UDP_SPORT])
163 cfg.local_udp_port = nla_get_u16(info->attrs[L2TP_ATTR_UDP_SPORT]);
164 if (info->attrs[L2TP_ATTR_UDP_DPORT])
165 cfg.peer_udp_port = nla_get_u16(info->attrs[L2TP_ATTR_UDP_DPORT]);
166 if (info->attrs[L2TP_ATTR_UDP_CSUM])
167 cfg.use_udp_checksums = nla_get_flag(info->attrs[L2TP_ATTR_UDP_CSUM]);
169 #if IS_ENABLED(CONFIG_IPV6)
170 if (info->attrs[L2TP_ATTR_UDP_ZERO_CSUM6_TX])
171 cfg.udp6_zero_tx_checksums = nla_get_flag(info->attrs[L2TP_ATTR_UDP_ZERO_CSUM6_TX]);
172 if (info->attrs[L2TP_ATTR_UDP_ZERO_CSUM6_RX])
173 cfg.udp6_zero_rx_checksums = nla_get_flag(info->attrs[L2TP_ATTR_UDP_ZERO_CSUM6_RX]);
174 #endif
177 if (info->attrs[L2TP_ATTR_DEBUG])
178 cfg.debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]);
180 tunnel = l2tp_tunnel_find(net, tunnel_id);
181 if (tunnel != NULL) {
182 ret = -EEXIST;
183 goto out;
186 ret = -EINVAL;
187 switch (cfg.encap) {
188 case L2TP_ENCAPTYPE_UDP:
189 case L2TP_ENCAPTYPE_IP:
190 ret = l2tp_tunnel_create(net, fd, proto_version, tunnel_id,
191 peer_tunnel_id, &cfg, &tunnel);
192 break;
195 out:
196 return ret;
199 static int l2tp_nl_cmd_tunnel_delete(struct sk_buff *skb, struct genl_info *info)
201 struct l2tp_tunnel *tunnel;
202 u32 tunnel_id;
203 int ret = 0;
204 struct net *net = genl_info_net(info);
206 if (!info->attrs[L2TP_ATTR_CONN_ID]) {
207 ret = -EINVAL;
208 goto out;
210 tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
212 tunnel = l2tp_tunnel_get(net, tunnel_id);
213 if (!tunnel) {
214 ret = -ENODEV;
215 goto out;
218 (void) l2tp_tunnel_delete(tunnel);
220 l2tp_tunnel_dec_refcount(tunnel);
222 out:
223 return ret;
226 static int l2tp_nl_cmd_tunnel_modify(struct sk_buff *skb, struct genl_info *info)
228 struct l2tp_tunnel *tunnel;
229 u32 tunnel_id;
230 int ret = 0;
231 struct net *net = genl_info_net(info);
233 if (!info->attrs[L2TP_ATTR_CONN_ID]) {
234 ret = -EINVAL;
235 goto out;
237 tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
239 tunnel = l2tp_tunnel_get(net, tunnel_id);
240 if (!tunnel) {
241 ret = -ENODEV;
242 goto out;
245 if (info->attrs[L2TP_ATTR_DEBUG])
246 tunnel->debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]);
248 l2tp_tunnel_dec_refcount(tunnel);
250 out:
251 return ret;
254 static int l2tp_nl_tunnel_send(struct sk_buff *skb, u32 portid, u32 seq, int flags,
255 struct l2tp_tunnel *tunnel)
257 void *hdr;
258 struct nlattr *nest;
259 struct sock *sk = NULL;
260 struct inet_sock *inet;
261 #if IS_ENABLED(CONFIG_IPV6)
262 struct ipv6_pinfo *np = NULL;
263 #endif
265 hdr = genlmsg_put(skb, portid, seq, &l2tp_nl_family, flags,
266 L2TP_CMD_TUNNEL_GET);
267 if (!hdr)
268 return -EMSGSIZE;
270 if (nla_put_u8(skb, L2TP_ATTR_PROTO_VERSION, tunnel->version) ||
271 nla_put_u32(skb, L2TP_ATTR_CONN_ID, tunnel->tunnel_id) ||
272 nla_put_u32(skb, L2TP_ATTR_PEER_CONN_ID, tunnel->peer_tunnel_id) ||
273 nla_put_u32(skb, L2TP_ATTR_DEBUG, tunnel->debug) ||
274 nla_put_u16(skb, L2TP_ATTR_ENCAP_TYPE, tunnel->encap))
275 goto nla_put_failure;
277 nest = nla_nest_start(skb, L2TP_ATTR_STATS);
278 if (nest == NULL)
279 goto nla_put_failure;
281 if (nla_put_u64(skb, L2TP_ATTR_TX_PACKETS,
282 atomic_long_read(&tunnel->stats.tx_packets)) ||
283 nla_put_u64(skb, L2TP_ATTR_TX_BYTES,
284 atomic_long_read(&tunnel->stats.tx_bytes)) ||
285 nla_put_u64(skb, L2TP_ATTR_TX_ERRORS,
286 atomic_long_read(&tunnel->stats.tx_errors)) ||
287 nla_put_u64(skb, L2TP_ATTR_RX_PACKETS,
288 atomic_long_read(&tunnel->stats.rx_packets)) ||
289 nla_put_u64(skb, L2TP_ATTR_RX_BYTES,
290 atomic_long_read(&tunnel->stats.rx_bytes)) ||
291 nla_put_u64(skb, L2TP_ATTR_RX_SEQ_DISCARDS,
292 atomic_long_read(&tunnel->stats.rx_seq_discards)) ||
293 nla_put_u64(skb, L2TP_ATTR_RX_OOS_PACKETS,
294 atomic_long_read(&tunnel->stats.rx_oos_packets)) ||
295 nla_put_u64(skb, L2TP_ATTR_RX_ERRORS,
296 atomic_long_read(&tunnel->stats.rx_errors)))
297 goto nla_put_failure;
298 nla_nest_end(skb, nest);
300 sk = tunnel->sock;
301 if (!sk)
302 goto out;
304 #if IS_ENABLED(CONFIG_IPV6)
305 if (sk->sk_family == AF_INET6)
306 np = inet6_sk(sk);
307 #endif
309 inet = inet_sk(sk);
311 switch (tunnel->encap) {
312 case L2TP_ENCAPTYPE_UDP:
313 if (nla_put_u16(skb, L2TP_ATTR_UDP_SPORT, ntohs(inet->inet_sport)) ||
314 nla_put_u16(skb, L2TP_ATTR_UDP_DPORT, ntohs(inet->inet_dport)) ||
315 nla_put_u8(skb, L2TP_ATTR_UDP_CSUM, !sk->sk_no_check_tx))
316 goto nla_put_failure;
317 /* NOBREAK */
318 case L2TP_ENCAPTYPE_IP:
319 #if IS_ENABLED(CONFIG_IPV6)
320 if (np) {
321 if (nla_put(skb, L2TP_ATTR_IP6_SADDR, sizeof(np->saddr),
322 &np->saddr) ||
323 nla_put(skb, L2TP_ATTR_IP6_DADDR, sizeof(sk->sk_v6_daddr),
324 &sk->sk_v6_daddr))
325 goto nla_put_failure;
326 } else
327 #endif
328 if (nla_put_be32(skb, L2TP_ATTR_IP_SADDR, inet->inet_saddr) ||
329 nla_put_be32(skb, L2TP_ATTR_IP_DADDR, inet->inet_daddr))
330 goto nla_put_failure;
331 break;
334 out:
335 return genlmsg_end(skb, hdr);
337 nla_put_failure:
338 genlmsg_cancel(skb, hdr);
339 return -1;
342 static int l2tp_nl_cmd_tunnel_get(struct sk_buff *skb, struct genl_info *info)
344 struct l2tp_tunnel *tunnel;
345 struct sk_buff *msg;
346 u32 tunnel_id;
347 int ret = -ENOBUFS;
348 struct net *net = genl_info_net(info);
350 if (!info->attrs[L2TP_ATTR_CONN_ID]) {
351 ret = -EINVAL;
352 goto err;
355 tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
357 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
358 if (!msg) {
359 ret = -ENOMEM;
360 goto err;
363 tunnel = l2tp_tunnel_get(net, tunnel_id);
364 if (!tunnel) {
365 ret = -ENODEV;
366 goto err_nlmsg;
369 ret = l2tp_nl_tunnel_send(msg, info->snd_portid, info->snd_seq,
370 NLM_F_ACK, tunnel);
371 if (ret < 0)
372 goto err_nlmsg_tunnel;
374 l2tp_tunnel_dec_refcount(tunnel);
376 return genlmsg_unicast(net, msg, info->snd_portid);
378 err_nlmsg_tunnel:
379 l2tp_tunnel_dec_refcount(tunnel);
380 err_nlmsg:
381 nlmsg_free(msg);
382 err:
383 return ret;
386 static int l2tp_nl_cmd_tunnel_dump(struct sk_buff *skb, struct netlink_callback *cb)
388 int ti = cb->args[0];
389 struct l2tp_tunnel *tunnel;
390 struct net *net = sock_net(skb->sk);
392 for (;;) {
393 tunnel = l2tp_tunnel_find_nth(net, ti);
394 if (tunnel == NULL)
395 goto out;
397 if (l2tp_nl_tunnel_send(skb, NETLINK_CB(cb->skb).portid,
398 cb->nlh->nlmsg_seq, NLM_F_MULTI,
399 tunnel) <= 0)
400 goto out;
402 ti++;
405 out:
406 cb->args[0] = ti;
408 return skb->len;
411 static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *info)
413 u32 tunnel_id = 0;
414 u32 session_id;
415 u32 peer_session_id;
416 int ret = 0;
417 struct l2tp_tunnel *tunnel;
418 struct l2tp_session_cfg cfg = { 0, };
419 struct net *net = genl_info_net(info);
421 if (!info->attrs[L2TP_ATTR_CONN_ID]) {
422 ret = -EINVAL;
423 goto out;
426 tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
427 tunnel = l2tp_tunnel_get(net, tunnel_id);
428 if (!tunnel) {
429 ret = -ENODEV;
430 goto out;
433 if (!info->attrs[L2TP_ATTR_SESSION_ID]) {
434 ret = -EINVAL;
435 goto out_tunnel;
437 session_id = nla_get_u32(info->attrs[L2TP_ATTR_SESSION_ID]);
439 if (!info->attrs[L2TP_ATTR_PEER_SESSION_ID]) {
440 ret = -EINVAL;
441 goto out_tunnel;
443 peer_session_id = nla_get_u32(info->attrs[L2TP_ATTR_PEER_SESSION_ID]);
445 if (!info->attrs[L2TP_ATTR_PW_TYPE]) {
446 ret = -EINVAL;
447 goto out_tunnel;
449 cfg.pw_type = nla_get_u16(info->attrs[L2TP_ATTR_PW_TYPE]);
450 if (cfg.pw_type >= __L2TP_PWTYPE_MAX) {
451 ret = -EINVAL;
452 goto out_tunnel;
455 if (tunnel->version > 2) {
456 if (info->attrs[L2TP_ATTR_OFFSET])
457 cfg.offset = nla_get_u16(info->attrs[L2TP_ATTR_OFFSET]);
459 if (info->attrs[L2TP_ATTR_DATA_SEQ])
460 cfg.data_seq = nla_get_u8(info->attrs[L2TP_ATTR_DATA_SEQ]);
462 cfg.l2specific_type = L2TP_L2SPECTYPE_DEFAULT;
463 if (info->attrs[L2TP_ATTR_L2SPEC_TYPE])
464 cfg.l2specific_type = nla_get_u8(info->attrs[L2TP_ATTR_L2SPEC_TYPE]);
466 cfg.l2specific_len = 4;
467 if (info->attrs[L2TP_ATTR_L2SPEC_LEN])
468 cfg.l2specific_len = nla_get_u8(info->attrs[L2TP_ATTR_L2SPEC_LEN]);
470 if (info->attrs[L2TP_ATTR_COOKIE]) {
471 u16 len = nla_len(info->attrs[L2TP_ATTR_COOKIE]);
472 if (len > 8) {
473 ret = -EINVAL;
474 goto out_tunnel;
476 cfg.cookie_len = len;
477 memcpy(&cfg.cookie[0], nla_data(info->attrs[L2TP_ATTR_COOKIE]), len);
479 if (info->attrs[L2TP_ATTR_PEER_COOKIE]) {
480 u16 len = nla_len(info->attrs[L2TP_ATTR_PEER_COOKIE]);
481 if (len > 8) {
482 ret = -EINVAL;
483 goto out_tunnel;
485 cfg.peer_cookie_len = len;
486 memcpy(&cfg.peer_cookie[0], nla_data(info->attrs[L2TP_ATTR_PEER_COOKIE]), len);
488 if (info->attrs[L2TP_ATTR_IFNAME])
489 cfg.ifname = nla_data(info->attrs[L2TP_ATTR_IFNAME]);
491 if (info->attrs[L2TP_ATTR_VLAN_ID])
492 cfg.vlan_id = nla_get_u16(info->attrs[L2TP_ATTR_VLAN_ID]);
495 if (info->attrs[L2TP_ATTR_DEBUG])
496 cfg.debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]);
498 if (info->attrs[L2TP_ATTR_RECV_SEQ])
499 cfg.recv_seq = nla_get_u8(info->attrs[L2TP_ATTR_RECV_SEQ]);
501 if (info->attrs[L2TP_ATTR_SEND_SEQ])
502 cfg.send_seq = nla_get_u8(info->attrs[L2TP_ATTR_SEND_SEQ]);
504 if (info->attrs[L2TP_ATTR_LNS_MODE])
505 cfg.lns_mode = nla_get_u8(info->attrs[L2TP_ATTR_LNS_MODE]);
507 if (info->attrs[L2TP_ATTR_RECV_TIMEOUT])
508 cfg.reorder_timeout = nla_get_msecs(info->attrs[L2TP_ATTR_RECV_TIMEOUT]);
510 if (info->attrs[L2TP_ATTR_MTU])
511 cfg.mtu = nla_get_u16(info->attrs[L2TP_ATTR_MTU]);
513 if (info->attrs[L2TP_ATTR_MRU])
514 cfg.mru = nla_get_u16(info->attrs[L2TP_ATTR_MRU]);
516 if ((l2tp_nl_cmd_ops[cfg.pw_type] == NULL) ||
517 (l2tp_nl_cmd_ops[cfg.pw_type]->session_create == NULL)) {
518 ret = -EPROTONOSUPPORT;
519 goto out_tunnel;
522 /* Check that pseudowire-specific params are present */
523 switch (cfg.pw_type) {
524 case L2TP_PWTYPE_NONE:
525 break;
526 case L2TP_PWTYPE_ETH_VLAN:
527 if (!info->attrs[L2TP_ATTR_VLAN_ID]) {
528 ret = -EINVAL;
529 goto out_tunnel;
531 break;
532 case L2TP_PWTYPE_ETH:
533 break;
534 case L2TP_PWTYPE_PPP:
535 case L2TP_PWTYPE_PPP_AC:
536 break;
537 case L2TP_PWTYPE_IP:
538 default:
539 ret = -EPROTONOSUPPORT;
540 break;
543 ret = l2tp_nl_cmd_ops[cfg.pw_type]->session_create(net, tunnel,
544 session_id,
545 peer_session_id,
546 &cfg);
548 out_tunnel:
549 l2tp_tunnel_dec_refcount(tunnel);
550 out:
551 return ret;
554 static int l2tp_nl_cmd_session_delete(struct sk_buff *skb, struct genl_info *info)
556 int ret = 0;
557 struct l2tp_session *session;
558 u16 pw_type;
560 session = l2tp_nl_session_get(info, true);
561 if (session == NULL) {
562 ret = -ENODEV;
563 goto out;
566 pw_type = session->pwtype;
567 if (pw_type < __L2TP_PWTYPE_MAX)
568 if (l2tp_nl_cmd_ops[pw_type] && l2tp_nl_cmd_ops[pw_type]->session_delete)
569 ret = (*l2tp_nl_cmd_ops[pw_type]->session_delete)(session);
571 if (session->deref)
572 session->deref(session);
573 l2tp_session_dec_refcount(session);
575 out:
576 return ret;
579 static int l2tp_nl_cmd_session_modify(struct sk_buff *skb, struct genl_info *info)
581 int ret = 0;
582 struct l2tp_session *session;
584 session = l2tp_nl_session_get(info, false);
585 if (session == NULL) {
586 ret = -ENODEV;
587 goto out;
590 if (info->attrs[L2TP_ATTR_DEBUG])
591 session->debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]);
593 if (info->attrs[L2TP_ATTR_DATA_SEQ])
594 session->data_seq = nla_get_u8(info->attrs[L2TP_ATTR_DATA_SEQ]);
596 if (info->attrs[L2TP_ATTR_RECV_SEQ])
597 session->recv_seq = nla_get_u8(info->attrs[L2TP_ATTR_RECV_SEQ]);
599 if (info->attrs[L2TP_ATTR_SEND_SEQ]) {
600 session->send_seq = nla_get_u8(info->attrs[L2TP_ATTR_SEND_SEQ]);
601 l2tp_session_set_header_len(session, session->tunnel->version);
604 if (info->attrs[L2TP_ATTR_LNS_MODE])
605 session->lns_mode = nla_get_u8(info->attrs[L2TP_ATTR_LNS_MODE]);
607 if (info->attrs[L2TP_ATTR_RECV_TIMEOUT])
608 session->reorder_timeout = nla_get_msecs(info->attrs[L2TP_ATTR_RECV_TIMEOUT]);
610 if (info->attrs[L2TP_ATTR_MTU])
611 session->mtu = nla_get_u16(info->attrs[L2TP_ATTR_MTU]);
613 if (info->attrs[L2TP_ATTR_MRU])
614 session->mru = nla_get_u16(info->attrs[L2TP_ATTR_MRU]);
616 l2tp_session_dec_refcount(session);
618 out:
619 return ret;
622 static int l2tp_nl_session_send(struct sk_buff *skb, u32 portid, u32 seq, int flags,
623 struct l2tp_session *session)
625 void *hdr;
626 struct nlattr *nest;
627 struct l2tp_tunnel *tunnel = session->tunnel;
628 struct sock *sk = NULL;
630 sk = tunnel->sock;
632 hdr = genlmsg_put(skb, portid, seq, &l2tp_nl_family, flags, L2TP_CMD_SESSION_GET);
633 if (!hdr)
634 return -EMSGSIZE;
636 if (nla_put_u32(skb, L2TP_ATTR_CONN_ID, tunnel->tunnel_id) ||
637 nla_put_u32(skb, L2TP_ATTR_SESSION_ID, session->session_id) ||
638 nla_put_u32(skb, L2TP_ATTR_PEER_CONN_ID, tunnel->peer_tunnel_id) ||
639 nla_put_u32(skb, L2TP_ATTR_PEER_SESSION_ID,
640 session->peer_session_id) ||
641 nla_put_u32(skb, L2TP_ATTR_DEBUG, session->debug) ||
642 nla_put_u16(skb, L2TP_ATTR_PW_TYPE, session->pwtype) ||
643 nla_put_u16(skb, L2TP_ATTR_MTU, session->mtu) ||
644 (session->mru &&
645 nla_put_u16(skb, L2TP_ATTR_MRU, session->mru)))
646 goto nla_put_failure;
648 if ((session->ifname[0] &&
649 nla_put_string(skb, L2TP_ATTR_IFNAME, session->ifname)) ||
650 (session->cookie_len &&
651 nla_put(skb, L2TP_ATTR_COOKIE, session->cookie_len,
652 &session->cookie[0])) ||
653 (session->peer_cookie_len &&
654 nla_put(skb, L2TP_ATTR_PEER_COOKIE, session->peer_cookie_len,
655 &session->peer_cookie[0])) ||
656 nla_put_u8(skb, L2TP_ATTR_RECV_SEQ, session->recv_seq) ||
657 nla_put_u8(skb, L2TP_ATTR_SEND_SEQ, session->send_seq) ||
658 nla_put_u8(skb, L2TP_ATTR_LNS_MODE, session->lns_mode) ||
659 #ifdef CONFIG_XFRM
660 (((sk) && (sk->sk_policy[0] || sk->sk_policy[1])) &&
661 nla_put_u8(skb, L2TP_ATTR_USING_IPSEC, 1)) ||
662 #endif
663 (session->reorder_timeout &&
664 nla_put_msecs(skb, L2TP_ATTR_RECV_TIMEOUT, session->reorder_timeout)))
665 goto nla_put_failure;
667 nest = nla_nest_start(skb, L2TP_ATTR_STATS);
668 if (nest == NULL)
669 goto nla_put_failure;
671 if (nla_put_u64(skb, L2TP_ATTR_TX_PACKETS,
672 atomic_long_read(&session->stats.tx_packets)) ||
673 nla_put_u64(skb, L2TP_ATTR_TX_BYTES,
674 atomic_long_read(&session->stats.tx_bytes)) ||
675 nla_put_u64(skb, L2TP_ATTR_TX_ERRORS,
676 atomic_long_read(&session->stats.tx_errors)) ||
677 nla_put_u64(skb, L2TP_ATTR_RX_PACKETS,
678 atomic_long_read(&session->stats.rx_packets)) ||
679 nla_put_u64(skb, L2TP_ATTR_RX_BYTES,
680 atomic_long_read(&session->stats.rx_bytes)) ||
681 nla_put_u64(skb, L2TP_ATTR_RX_SEQ_DISCARDS,
682 atomic_long_read(&session->stats.rx_seq_discards)) ||
683 nla_put_u64(skb, L2TP_ATTR_RX_OOS_PACKETS,
684 atomic_long_read(&session->stats.rx_oos_packets)) ||
685 nla_put_u64(skb, L2TP_ATTR_RX_ERRORS,
686 atomic_long_read(&session->stats.rx_errors)))
687 goto nla_put_failure;
688 nla_nest_end(skb, nest);
690 return genlmsg_end(skb, hdr);
692 nla_put_failure:
693 genlmsg_cancel(skb, hdr);
694 return -1;
697 static int l2tp_nl_cmd_session_get(struct sk_buff *skb, struct genl_info *info)
699 struct l2tp_session *session;
700 struct sk_buff *msg;
701 int ret;
703 session = l2tp_nl_session_get(info, false);
704 if (session == NULL) {
705 ret = -ENODEV;
706 goto err;
709 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
710 if (!msg) {
711 ret = -ENOMEM;
712 goto err_ref;
715 ret = l2tp_nl_session_send(msg, info->snd_portid, info->snd_seq,
716 0, session);
717 if (ret < 0)
718 goto err_ref_msg;
720 ret = genlmsg_unicast(genl_info_net(info), msg, info->snd_portid);
722 l2tp_session_dec_refcount(session);
724 return ret;
726 err_ref_msg:
727 nlmsg_free(msg);
728 err_ref:
729 l2tp_session_dec_refcount(session);
730 err:
731 return ret;
734 static int l2tp_nl_cmd_session_dump(struct sk_buff *skb, struct netlink_callback *cb)
736 struct net *net = sock_net(skb->sk);
737 struct l2tp_session *session;
738 struct l2tp_tunnel *tunnel = NULL;
739 int ti = cb->args[0];
740 int si = cb->args[1];
742 for (;;) {
743 if (tunnel == NULL) {
744 tunnel = l2tp_tunnel_find_nth(net, ti);
745 if (tunnel == NULL)
746 goto out;
749 session = l2tp_session_get_nth(tunnel, si, false);
750 if (session == NULL) {
751 ti++;
752 tunnel = NULL;
753 si = 0;
754 continue;
757 if (l2tp_nl_session_send(skb, NETLINK_CB(cb->skb).portid,
758 cb->nlh->nlmsg_seq, NLM_F_MULTI,
759 session) <= 0) {
760 l2tp_session_dec_refcount(session);
761 break;
763 l2tp_session_dec_refcount(session);
765 si++;
768 out:
769 cb->args[0] = ti;
770 cb->args[1] = si;
772 return skb->len;
775 static struct nla_policy l2tp_nl_policy[L2TP_ATTR_MAX + 1] = {
776 [L2TP_ATTR_NONE] = { .type = NLA_UNSPEC, },
777 [L2TP_ATTR_PW_TYPE] = { .type = NLA_U16, },
778 [L2TP_ATTR_ENCAP_TYPE] = { .type = NLA_U16, },
779 [L2TP_ATTR_OFFSET] = { .type = NLA_U16, },
780 [L2TP_ATTR_DATA_SEQ] = { .type = NLA_U8, },
781 [L2TP_ATTR_L2SPEC_TYPE] = { .type = NLA_U8, },
782 [L2TP_ATTR_L2SPEC_LEN] = { .type = NLA_U8, },
783 [L2TP_ATTR_PROTO_VERSION] = { .type = NLA_U8, },
784 [L2TP_ATTR_CONN_ID] = { .type = NLA_U32, },
785 [L2TP_ATTR_PEER_CONN_ID] = { .type = NLA_U32, },
786 [L2TP_ATTR_SESSION_ID] = { .type = NLA_U32, },
787 [L2TP_ATTR_PEER_SESSION_ID] = { .type = NLA_U32, },
788 [L2TP_ATTR_UDP_CSUM] = { .type = NLA_U8, },
789 [L2TP_ATTR_VLAN_ID] = { .type = NLA_U16, },
790 [L2TP_ATTR_DEBUG] = { .type = NLA_U32, },
791 [L2TP_ATTR_RECV_SEQ] = { .type = NLA_U8, },
792 [L2TP_ATTR_SEND_SEQ] = { .type = NLA_U8, },
793 [L2TP_ATTR_LNS_MODE] = { .type = NLA_U8, },
794 [L2TP_ATTR_USING_IPSEC] = { .type = NLA_U8, },
795 [L2TP_ATTR_RECV_TIMEOUT] = { .type = NLA_MSECS, },
796 [L2TP_ATTR_FD] = { .type = NLA_U32, },
797 [L2TP_ATTR_IP_SADDR] = { .type = NLA_U32, },
798 [L2TP_ATTR_IP_DADDR] = { .type = NLA_U32, },
799 [L2TP_ATTR_UDP_SPORT] = { .type = NLA_U16, },
800 [L2TP_ATTR_UDP_DPORT] = { .type = NLA_U16, },
801 [L2TP_ATTR_MTU] = { .type = NLA_U16, },
802 [L2TP_ATTR_MRU] = { .type = NLA_U16, },
803 [L2TP_ATTR_STATS] = { .type = NLA_NESTED, },
804 [L2TP_ATTR_IP6_SADDR] = {
805 .type = NLA_BINARY,
806 .len = sizeof(struct in6_addr),
808 [L2TP_ATTR_IP6_DADDR] = {
809 .type = NLA_BINARY,
810 .len = sizeof(struct in6_addr),
812 [L2TP_ATTR_IFNAME] = {
813 .type = NLA_NUL_STRING,
814 .len = IFNAMSIZ - 1,
816 [L2TP_ATTR_COOKIE] = {
817 .type = NLA_BINARY,
818 .len = 8,
820 [L2TP_ATTR_PEER_COOKIE] = {
821 .type = NLA_BINARY,
822 .len = 8,
826 static const struct genl_ops l2tp_nl_ops[] = {
828 .cmd = L2TP_CMD_NOOP,
829 .doit = l2tp_nl_cmd_noop,
830 .policy = l2tp_nl_policy,
831 /* can be retrieved by unprivileged users */
834 .cmd = L2TP_CMD_TUNNEL_CREATE,
835 .doit = l2tp_nl_cmd_tunnel_create,
836 .policy = l2tp_nl_policy,
837 .flags = GENL_ADMIN_PERM,
840 .cmd = L2TP_CMD_TUNNEL_DELETE,
841 .doit = l2tp_nl_cmd_tunnel_delete,
842 .policy = l2tp_nl_policy,
843 .flags = GENL_ADMIN_PERM,
846 .cmd = L2TP_CMD_TUNNEL_MODIFY,
847 .doit = l2tp_nl_cmd_tunnel_modify,
848 .policy = l2tp_nl_policy,
849 .flags = GENL_ADMIN_PERM,
852 .cmd = L2TP_CMD_TUNNEL_GET,
853 .doit = l2tp_nl_cmd_tunnel_get,
854 .dumpit = l2tp_nl_cmd_tunnel_dump,
855 .policy = l2tp_nl_policy,
856 .flags = GENL_ADMIN_PERM,
859 .cmd = L2TP_CMD_SESSION_CREATE,
860 .doit = l2tp_nl_cmd_session_create,
861 .policy = l2tp_nl_policy,
862 .flags = GENL_ADMIN_PERM,
865 .cmd = L2TP_CMD_SESSION_DELETE,
866 .doit = l2tp_nl_cmd_session_delete,
867 .policy = l2tp_nl_policy,
868 .flags = GENL_ADMIN_PERM,
871 .cmd = L2TP_CMD_SESSION_MODIFY,
872 .doit = l2tp_nl_cmd_session_modify,
873 .policy = l2tp_nl_policy,
874 .flags = GENL_ADMIN_PERM,
877 .cmd = L2TP_CMD_SESSION_GET,
878 .doit = l2tp_nl_cmd_session_get,
879 .dumpit = l2tp_nl_cmd_session_dump,
880 .policy = l2tp_nl_policy,
881 .flags = GENL_ADMIN_PERM,
885 int l2tp_nl_register_ops(enum l2tp_pwtype pw_type, const struct l2tp_nl_cmd_ops *ops)
887 int ret;
889 ret = -EINVAL;
890 if (pw_type >= __L2TP_PWTYPE_MAX)
891 goto err;
893 genl_lock();
894 ret = -EBUSY;
895 if (l2tp_nl_cmd_ops[pw_type])
896 goto out;
898 l2tp_nl_cmd_ops[pw_type] = ops;
899 ret = 0;
901 out:
902 genl_unlock();
903 err:
904 return ret;
906 EXPORT_SYMBOL_GPL(l2tp_nl_register_ops);
908 void l2tp_nl_unregister_ops(enum l2tp_pwtype pw_type)
910 if (pw_type < __L2TP_PWTYPE_MAX) {
911 genl_lock();
912 l2tp_nl_cmd_ops[pw_type] = NULL;
913 genl_unlock();
916 EXPORT_SYMBOL_GPL(l2tp_nl_unregister_ops);
918 static int l2tp_nl_init(void)
920 pr_info("L2TP netlink interface\n");
921 return genl_register_family_with_ops(&l2tp_nl_family, l2tp_nl_ops);
924 static void l2tp_nl_cleanup(void)
926 genl_unregister_family(&l2tp_nl_family);
929 module_init(l2tp_nl_init);
930 module_exit(l2tp_nl_cleanup);
932 MODULE_AUTHOR("James Chapman <jchapman@katalix.com>");
933 MODULE_DESCRIPTION("L2TP netlink");
934 MODULE_LICENSE("GPL");
935 MODULE_VERSION("1.0");
936 MODULE_ALIAS_GENL_FAMILY("l2tp");