Blame view
net/l2tp/l2tp_netlink.c
26.8 KB
309795f4b l2tp: Add netlink... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/* * L2TP netlink layer, for management * * Copyright (c) 2008,2009,2010 Katalix Systems Ltd * * Partly based on the IrDA nelink implementation * (see net/irda/irnetlink.c) which is: * Copyright (c) 2007 Samuel Ortiz <samuel@sortiz.org> * which is in turn partly based on the wireless netlink code: * Copyright 2006 Johannes Berg <johannes@sipsolutions.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ |
a4ca44fa5 net: l2tp: Standa... |
16 |
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
309795f4b l2tp: Add netlink... |
17 18 19 20 21 22 23 24 25 26 27 28 29 |
#include <net/sock.h> #include <net/genetlink.h> #include <net/udp.h> #include <linux/in.h> #include <linux/udp.h> #include <linux/socket.h> #include <linux/module.h> #include <linux/list.h> #include <net/net_namespace.h> #include <linux/l2tp.h> #include "l2tp_core.h" |
489111e5c genetlink: static... |
30 |
static struct genl_family l2tp_nl_family; |
309795f4b l2tp: Add netlink... |
31 |
|
33f72e6f0 l2tp : multicast ... |
32 33 34 35 36 37 38 39 40 41 42 |
static const struct genl_multicast_group l2tp_multicast_group[] = { { .name = L2TP_GENL_MCGROUP, }, }; static int l2tp_nl_tunnel_send(struct sk_buff *skb, u32 portid, u32 seq, int flags, struct l2tp_tunnel *tunnel, u8 cmd); static int l2tp_nl_session_send(struct sk_buff *skb, u32 portid, u32 seq, int flags, struct l2tp_session *session, u8 cmd); |
309795f4b l2tp: Add netlink... |
43 44 |
/* Accessed under genl lock */ static const struct l2tp_nl_cmd_ops *l2tp_nl_cmd_ops[__L2TP_PWTYPE_MAX]; |
2777e2ab5 l2tp: take a refe... |
45 46 |
static struct l2tp_session *l2tp_nl_session_get(struct genl_info *info, bool do_ref) |
309795f4b l2tp: Add netlink... |
47 48 49 50 51 52 53 54 55 56 |
{ u32 tunnel_id; u32 session_id; char *ifname; struct l2tp_tunnel *tunnel; struct l2tp_session *session = NULL; struct net *net = genl_info_net(info); if (info->attrs[L2TP_ATTR_IFNAME]) { ifname = nla_data(info->attrs[L2TP_ATTR_IFNAME]); |
2777e2ab5 l2tp: take a refe... |
57 |
session = l2tp_session_get_by_ifname(net, ifname, do_ref); |
309795f4b l2tp: Add netlink... |
58 59 60 61 |
} else if ((info->attrs[L2TP_ATTR_SESSION_ID]) && (info->attrs[L2TP_ATTR_CONN_ID])) { tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]); session_id = nla_get_u32(info->attrs[L2TP_ATTR_SESSION_ID]); |
54652eb12 l2tp: hold tunnel... |
62 63 |
tunnel = l2tp_tunnel_get(net, tunnel_id); if (tunnel) { |
2777e2ab5 l2tp: take a refe... |
64 65 |
session = l2tp_session_get(net, tunnel, session_id, do_ref); |
54652eb12 l2tp: hold tunnel... |
66 67 |
l2tp_tunnel_dec_refcount(tunnel); } |
309795f4b l2tp: Add netlink... |
68 69 70 71 72 73 74 75 76 77 |
} return session; } static int l2tp_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info) { struct sk_buff *msg; void *hdr; int ret = -ENOBUFS; |
58050fce3 net: Use NLMSG_DE... |
78 |
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
309795f4b l2tp: Add netlink... |
79 80 81 82 |
if (!msg) { ret = -ENOMEM; goto out; } |
15e473046 netlink: Rename p... |
83 |
hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, |
309795f4b l2tp: Add netlink... |
84 |
&l2tp_nl_family, 0, L2TP_CMD_NOOP); |
7f8436a12 l2tp: fix return ... |
85 86 |
if (!hdr) { ret = -EMSGSIZE; |
309795f4b l2tp: Add netlink... |
87 88 89 90 |
goto err_out; } genlmsg_end(msg, hdr); |
15e473046 netlink: Rename p... |
91 |
return genlmsg_unicast(genl_info_net(info), msg, info->snd_portid); |
309795f4b l2tp: Add netlink... |
92 93 94 95 96 97 98 |
err_out: nlmsg_free(msg); out: return ret; } |
33f72e6f0 l2tp : multicast ... |
99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
static int l2tp_tunnel_notify(struct genl_family *family, struct genl_info *info, struct l2tp_tunnel *tunnel, u8 cmd) { struct sk_buff *msg; int ret; msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) return -ENOMEM; ret = l2tp_nl_tunnel_send(msg, info->snd_portid, info->snd_seq, NLM_F_ACK, tunnel, cmd); |
853effc55 l2tp: Fix error c... |
113 114 115 116 117 118 119 |
if (ret >= 0) { ret = genlmsg_multicast_allns(family, msg, 0, 0, GFP_ATOMIC); /* We don't care if no one is listening */ if (ret == -ESRCH) ret = 0; return ret; } |
33f72e6f0 l2tp : multicast ... |
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
nlmsg_free(msg); return ret; } static int l2tp_session_notify(struct genl_family *family, struct genl_info *info, struct l2tp_session *session, u8 cmd) { struct sk_buff *msg; int ret; msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) return -ENOMEM; ret = l2tp_nl_session_send(msg, info->snd_portid, info->snd_seq, NLM_F_ACK, session, cmd); |
853effc55 l2tp: Fix error c... |
140 141 142 143 144 145 146 |
if (ret >= 0) { ret = genlmsg_multicast_allns(family, msg, 0, 0, GFP_ATOMIC); /* We don't care if no one is listening */ if (ret == -ESRCH) ret = 0; return ret; } |
33f72e6f0 l2tp : multicast ... |
147 148 149 150 151 |
nlmsg_free(msg); return ret; } |
309795f4b l2tp: Add netlink... |
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
static int l2tp_nl_cmd_tunnel_create(struct sk_buff *skb, struct genl_info *info) { u32 tunnel_id; u32 peer_tunnel_id; int proto_version; int fd; int ret = 0; struct l2tp_tunnel_cfg cfg = { 0, }; struct l2tp_tunnel *tunnel; struct net *net = genl_info_net(info); if (!info->attrs[L2TP_ATTR_CONN_ID]) { ret = -EINVAL; goto out; } tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]); if (!info->attrs[L2TP_ATTR_PEER_CONN_ID]) { ret = -EINVAL; goto out; } peer_tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_PEER_CONN_ID]); if (!info->attrs[L2TP_ATTR_PROTO_VERSION]) { ret = -EINVAL; goto out; } proto_version = nla_get_u8(info->attrs[L2TP_ATTR_PROTO_VERSION]); if (!info->attrs[L2TP_ATTR_ENCAP_TYPE]) { ret = -EINVAL; goto out; } cfg.encap = nla_get_u16(info->attrs[L2TP_ATTR_ENCAP_TYPE]); |
789a4a2c6 l2tp: Add support... |
186 187 188 189 |
fd = -1; if (info->attrs[L2TP_ATTR_FD]) { fd = nla_get_u32(info->attrs[L2TP_ATTR_FD]); } else { |
f9bac8df9 l2tp: netlink api... |
190 191 192 193 194 195 196 197 198 199 200 |
#if IS_ENABLED(CONFIG_IPV6) if (info->attrs[L2TP_ATTR_IP6_SADDR] && info->attrs[L2TP_ATTR_IP6_DADDR]) { cfg.local_ip6 = nla_data( info->attrs[L2TP_ATTR_IP6_SADDR]); cfg.peer_ip6 = nla_data( info->attrs[L2TP_ATTR_IP6_DADDR]); } else #endif if (info->attrs[L2TP_ATTR_IP_SADDR] && info->attrs[L2TP_ATTR_IP_DADDR]) { |
67b61f6c1 netlink: implemen... |
201 |
cfg.local_ip.s_addr = nla_get_in_addr( |
f9bac8df9 l2tp: netlink api... |
202 |
info->attrs[L2TP_ATTR_IP_SADDR]); |
67b61f6c1 netlink: implemen... |
203 |
cfg.peer_ip.s_addr = nla_get_in_addr( |
f9bac8df9 l2tp: netlink api... |
204 205 206 207 208 |
info->attrs[L2TP_ATTR_IP_DADDR]); } else { ret = -EINVAL; goto out; } |
789a4a2c6 l2tp: Add support... |
209 210 211 212 |
if (info->attrs[L2TP_ATTR_UDP_SPORT]) cfg.local_udp_port = nla_get_u16(info->attrs[L2TP_ATTR_UDP_SPORT]); if (info->attrs[L2TP_ATTR_UDP_DPORT]) cfg.peer_udp_port = nla_get_u16(info->attrs[L2TP_ATTR_UDP_DPORT]); |
57ceb8611 net: l2tp: cleanu... |
213 214 |
cfg.use_udp_checksums = nla_get_flag( info->attrs[L2TP_ATTR_UDP_CSUM]); |
6b649feaf l2tp: Add support... |
215 216 |
#if IS_ENABLED(CONFIG_IPV6) |
57ceb8611 net: l2tp: cleanu... |
217 218 219 220 |
cfg.udp6_zero_tx_checksums = nla_get_flag( info->attrs[L2TP_ATTR_UDP_ZERO_CSUM6_TX]); cfg.udp6_zero_rx_checksums = nla_get_flag( info->attrs[L2TP_ATTR_UDP_ZERO_CSUM6_RX]); |
6b649feaf l2tp: Add support... |
221 |
#endif |
309795f4b l2tp: Add netlink... |
222 |
} |
309795f4b l2tp: Add netlink... |
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
if (info->attrs[L2TP_ATTR_DEBUG]) cfg.debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]); tunnel = l2tp_tunnel_find(net, tunnel_id); if (tunnel != NULL) { ret = -EEXIST; goto out; } ret = -EINVAL; switch (cfg.encap) { case L2TP_ENCAPTYPE_UDP: case L2TP_ENCAPTYPE_IP: ret = l2tp_tunnel_create(net, fd, proto_version, tunnel_id, peer_tunnel_id, &cfg, &tunnel); break; } |
33f72e6f0 l2tp : multicast ... |
241 242 243 |
if (ret >= 0) ret = l2tp_tunnel_notify(&l2tp_nl_family, info, tunnel, L2TP_CMD_TUNNEL_CREATE); |
309795f4b l2tp: Add netlink... |
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
out: return ret; } static int l2tp_nl_cmd_tunnel_delete(struct sk_buff *skb, struct genl_info *info) { struct l2tp_tunnel *tunnel; u32 tunnel_id; int ret = 0; struct net *net = genl_info_net(info); if (!info->attrs[L2TP_ATTR_CONN_ID]) { ret = -EINVAL; goto out; } tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]); |
bb0a32ce4 l2tp: hold tunnel... |
260 261 |
tunnel = l2tp_tunnel_get(net, tunnel_id); if (!tunnel) { |
309795f4b l2tp: Add netlink... |
262 263 264 |
ret = -ENODEV; goto out; } |
33f72e6f0 l2tp : multicast ... |
265 266 |
l2tp_tunnel_notify(&l2tp_nl_family, info, tunnel, L2TP_CMD_TUNNEL_DELETE); |
ff62605e0 l2tp: cleanup l2t... |
267 |
l2tp_tunnel_delete(tunnel); |
309795f4b l2tp: Add netlink... |
268 |
|
bb0a32ce4 l2tp: hold tunnel... |
269 |
l2tp_tunnel_dec_refcount(tunnel); |
309795f4b l2tp: Add netlink... |
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 |
out: return ret; } static int l2tp_nl_cmd_tunnel_modify(struct sk_buff *skb, struct genl_info *info) { struct l2tp_tunnel *tunnel; u32 tunnel_id; int ret = 0; struct net *net = genl_info_net(info); if (!info->attrs[L2TP_ATTR_CONN_ID]) { ret = -EINVAL; goto out; } tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]); |
8c0e42152 l2tp: hold tunnel... |
286 287 |
tunnel = l2tp_tunnel_get(net, tunnel_id); if (!tunnel) { |
309795f4b l2tp: Add netlink... |
288 289 290 291 292 293 |
ret = -ENODEV; goto out; } if (info->attrs[L2TP_ATTR_DEBUG]) tunnel->debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]); |
33f72e6f0 l2tp : multicast ... |
294 295 |
ret = l2tp_tunnel_notify(&l2tp_nl_family, info, tunnel, L2TP_CMD_TUNNEL_MODIFY); |
8c0e42152 l2tp: hold tunnel... |
296 |
l2tp_tunnel_dec_refcount(tunnel); |
309795f4b l2tp: Add netlink... |
297 298 299 |
out: return ret; } |
15e473046 netlink: Rename p... |
300 |
static int l2tp_nl_tunnel_send(struct sk_buff *skb, u32 portid, u32 seq, int flags, |
33f72e6f0 l2tp : multicast ... |
301 |
struct l2tp_tunnel *tunnel, u8 cmd) |
309795f4b l2tp: Add netlink... |
302 303 304 305 306 |
{ void *hdr; struct nlattr *nest; struct sock *sk = NULL; struct inet_sock *inet; |
f9bac8df9 l2tp: netlink api... |
307 308 309 |
#if IS_ENABLED(CONFIG_IPV6) struct ipv6_pinfo *np = NULL; #endif |
309795f4b l2tp: Add netlink... |
310 |
|
33f72e6f0 l2tp : multicast ... |
311 |
hdr = genlmsg_put(skb, portid, seq, &l2tp_nl_family, flags, cmd); |
7f8436a12 l2tp: fix return ... |
312 313 |
if (!hdr) return -EMSGSIZE; |
309795f4b l2tp: Add netlink... |
314 |
|
60aed2abb l2tp: Stop using ... |
315 316 317 318 319 320 |
if (nla_put_u8(skb, L2TP_ATTR_PROTO_VERSION, tunnel->version) || nla_put_u32(skb, L2TP_ATTR_CONN_ID, tunnel->tunnel_id) || nla_put_u32(skb, L2TP_ATTR_PEER_CONN_ID, tunnel->peer_tunnel_id) || nla_put_u32(skb, L2TP_ATTR_DEBUG, tunnel->debug) || nla_put_u16(skb, L2TP_ATTR_ENCAP_TYPE, tunnel->encap)) goto nla_put_failure; |
309795f4b l2tp: Add netlink... |
321 322 323 324 |
nest = nla_nest_start(skb, L2TP_ATTR_STATS); if (nest == NULL) goto nla_put_failure; |
1c714a928 l2tp: use nla_put... |
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 |
if (nla_put_u64_64bit(skb, L2TP_ATTR_TX_PACKETS, atomic_long_read(&tunnel->stats.tx_packets), L2TP_ATTR_STATS_PAD) || nla_put_u64_64bit(skb, L2TP_ATTR_TX_BYTES, atomic_long_read(&tunnel->stats.tx_bytes), L2TP_ATTR_STATS_PAD) || nla_put_u64_64bit(skb, L2TP_ATTR_TX_ERRORS, atomic_long_read(&tunnel->stats.tx_errors), L2TP_ATTR_STATS_PAD) || nla_put_u64_64bit(skb, L2TP_ATTR_RX_PACKETS, atomic_long_read(&tunnel->stats.rx_packets), L2TP_ATTR_STATS_PAD) || nla_put_u64_64bit(skb, L2TP_ATTR_RX_BYTES, atomic_long_read(&tunnel->stats.rx_bytes), L2TP_ATTR_STATS_PAD) || nla_put_u64_64bit(skb, L2TP_ATTR_RX_SEQ_DISCARDS, atomic_long_read(&tunnel->stats.rx_seq_discards), L2TP_ATTR_STATS_PAD) || nla_put_u64_64bit(skb, L2TP_ATTR_RX_OOS_PACKETS, atomic_long_read(&tunnel->stats.rx_oos_packets), L2TP_ATTR_STATS_PAD) || nla_put_u64_64bit(skb, L2TP_ATTR_RX_ERRORS, atomic_long_read(&tunnel->stats.rx_errors), L2TP_ATTR_STATS_PAD)) |
60aed2abb l2tp: Stop using ... |
349 |
goto nla_put_failure; |
309795f4b l2tp: Add netlink... |
350 351 352 353 354 |
nla_nest_end(skb, nest); sk = tunnel->sock; if (!sk) goto out; |
f9bac8df9 l2tp: netlink api... |
355 356 357 358 |
#if IS_ENABLED(CONFIG_IPV6) if (sk->sk_family == AF_INET6) np = inet6_sk(sk); #endif |
309795f4b l2tp: Add netlink... |
359 360 361 362 |
inet = inet_sk(sk); switch (tunnel->encap) { case L2TP_ENCAPTYPE_UDP: |
7ff516ffe net: l2tp: only s... |
363 364 365 366 367 |
switch (sk->sk_family) { case AF_INET: if (nla_put_u8(skb, L2TP_ATTR_UDP_CSUM, !sk->sk_no_check_tx)) goto nla_put_failure; break; |
97b7af097 net: l2tp: netlin... |
368 369 370 371 372 373 374 375 376 377 |
#if IS_ENABLED(CONFIG_IPV6) case AF_INET6: if (udp_get_no_check6_tx(sk) && nla_put_flag(skb, L2TP_ATTR_UDP_ZERO_CSUM6_TX)) goto nla_put_failure; if (udp_get_no_check6_rx(sk) && nla_put_flag(skb, L2TP_ATTR_UDP_ZERO_CSUM6_RX)) goto nla_put_failure; break; #endif |
7ff516ffe net: l2tp: only s... |
378 |
} |
60aed2abb l2tp: Stop using ... |
379 |
if (nla_put_u16(skb, L2TP_ATTR_UDP_SPORT, ntohs(inet->inet_sport)) || |
7ff516ffe net: l2tp: only s... |
380 |
nla_put_u16(skb, L2TP_ATTR_UDP_DPORT, ntohs(inet->inet_dport))) |
60aed2abb l2tp: Stop using ... |
381 |
goto nla_put_failure; |
309795f4b l2tp: Add netlink... |
382 383 |
/* NOBREAK */ case L2TP_ENCAPTYPE_IP: |
f9bac8df9 l2tp: netlink api... |
384 385 |
#if IS_ENABLED(CONFIG_IPV6) if (np) { |
930345ea6 netlink: implemen... |
386 387 388 389 |
if (nla_put_in6_addr(skb, L2TP_ATTR_IP6_SADDR, &np->saddr) || nla_put_in6_addr(skb, L2TP_ATTR_IP6_DADDR, &sk->sk_v6_daddr)) |
f9bac8df9 l2tp: netlink api... |
390 391 392 |
goto nla_put_failure; } else #endif |
930345ea6 netlink: implemen... |
393 394 395 396 |
if (nla_put_in_addr(skb, L2TP_ATTR_IP_SADDR, inet->inet_saddr) || nla_put_in_addr(skb, L2TP_ATTR_IP_DADDR, inet->inet_daddr)) |
60aed2abb l2tp: Stop using ... |
397 |
goto nla_put_failure; |
309795f4b l2tp: Add netlink... |
398 399 400 401 |
break; } out: |
053c095a8 netlink: make nlm... |
402 403 |
genlmsg_end(skb, hdr); return 0; |
309795f4b l2tp: Add netlink... |
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 |
nla_put_failure: genlmsg_cancel(skb, hdr); return -1; } static int l2tp_nl_cmd_tunnel_get(struct sk_buff *skb, struct genl_info *info) { struct l2tp_tunnel *tunnel; struct sk_buff *msg; u32 tunnel_id; int ret = -ENOBUFS; struct net *net = genl_info_net(info); if (!info->attrs[L2TP_ATTR_CONN_ID]) { ret = -EINVAL; |
4e4b21da3 l2tp: hold tunnel... |
420 |
goto err; |
309795f4b l2tp: Add netlink... |
421 422 423 |
} tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]); |
58050fce3 net: Use NLMSG_DE... |
424 |
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
309795f4b l2tp: Add netlink... |
425 426 |
if (!msg) { ret = -ENOMEM; |
4e4b21da3 l2tp: hold tunnel... |
427 428 429 430 431 432 433 |
goto err; } tunnel = l2tp_tunnel_get(net, tunnel_id); if (!tunnel) { ret = -ENODEV; goto err_nlmsg; |
309795f4b l2tp: Add netlink... |
434 |
} |
15e473046 netlink: Rename p... |
435 |
ret = l2tp_nl_tunnel_send(msg, info->snd_portid, info->snd_seq, |
33f72e6f0 l2tp : multicast ... |
436 |
NLM_F_ACK, tunnel, L2TP_CMD_TUNNEL_GET); |
309795f4b l2tp: Add netlink... |
437 |
if (ret < 0) |
4e4b21da3 l2tp: hold tunnel... |
438 439 440 |
goto err_nlmsg_tunnel; l2tp_tunnel_dec_refcount(tunnel); |
309795f4b l2tp: Add netlink... |
441 |
|
15e473046 netlink: Rename p... |
442 |
return genlmsg_unicast(net, msg, info->snd_portid); |
309795f4b l2tp: Add netlink... |
443 |
|
4e4b21da3 l2tp: hold tunnel... |
444 445 446 |
err_nlmsg_tunnel: l2tp_tunnel_dec_refcount(tunnel); err_nlmsg: |
309795f4b l2tp: Add netlink... |
447 |
nlmsg_free(msg); |
4e4b21da3 l2tp: hold tunnel... |
448 |
err: |
309795f4b l2tp: Add netlink... |
449 450 451 452 453 454 455 456 457 458 459 460 461 |
return ret; } static int l2tp_nl_cmd_tunnel_dump(struct sk_buff *skb, struct netlink_callback *cb) { int ti = cb->args[0]; struct l2tp_tunnel *tunnel; struct net *net = sock_net(skb->sk); for (;;) { tunnel = l2tp_tunnel_find_nth(net, ti); if (tunnel == NULL) goto out; |
15e473046 netlink: Rename p... |
462 |
if (l2tp_nl_tunnel_send(skb, NETLINK_CB(cb->skb).portid, |
309795f4b l2tp: Add netlink... |
463 |
cb->nlh->nlmsg_seq, NLM_F_MULTI, |
053c095a8 netlink: make nlm... |
464 |
tunnel, L2TP_CMD_TUNNEL_GET) < 0) |
309795f4b l2tp: Add netlink... |
465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 |
goto out; ti++; } out: cb->args[0] = ti; return skb->len; } static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *info) { u32 tunnel_id = 0; u32 session_id; u32 peer_session_id; int ret = 0; struct l2tp_tunnel *tunnel; struct l2tp_session *session; struct l2tp_session_cfg cfg = { 0, }; struct net *net = genl_info_net(info); if (!info->attrs[L2TP_ATTR_CONN_ID]) { ret = -EINVAL; goto out; } |
e702c1204 l2tp: hold tunnel... |
491 |
|
309795f4b l2tp: Add netlink... |
492 |
tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]); |
e702c1204 l2tp: hold tunnel... |
493 |
tunnel = l2tp_tunnel_get(net, tunnel_id); |
309795f4b l2tp: Add netlink... |
494 495 496 497 498 499 500 |
if (!tunnel) { ret = -ENODEV; goto out; } if (!info->attrs[L2TP_ATTR_SESSION_ID]) { ret = -EINVAL; |
e702c1204 l2tp: hold tunnel... |
501 |
goto out_tunnel; |
309795f4b l2tp: Add netlink... |
502 503 |
} session_id = nla_get_u32(info->attrs[L2TP_ATTR_SESSION_ID]); |
309795f4b l2tp: Add netlink... |
504 505 506 |
if (!info->attrs[L2TP_ATTR_PEER_SESSION_ID]) { ret = -EINVAL; |
e702c1204 l2tp: hold tunnel... |
507 |
goto out_tunnel; |
309795f4b l2tp: Add netlink... |
508 509 510 511 512 |
} peer_session_id = nla_get_u32(info->attrs[L2TP_ATTR_PEER_SESSION_ID]); if (!info->attrs[L2TP_ATTR_PW_TYPE]) { ret = -EINVAL; |
e702c1204 l2tp: hold tunnel... |
513 |
goto out_tunnel; |
309795f4b l2tp: Add netlink... |
514 515 516 517 |
} cfg.pw_type = nla_get_u16(info->attrs[L2TP_ATTR_PW_TYPE]); if (cfg.pw_type >= __L2TP_PWTYPE_MAX) { ret = -EINVAL; |
e702c1204 l2tp: hold tunnel... |
518 |
goto out_tunnel; |
309795f4b l2tp: Add netlink... |
519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 |
} if (tunnel->version > 2) { if (info->attrs[L2TP_ATTR_OFFSET]) cfg.offset = nla_get_u16(info->attrs[L2TP_ATTR_OFFSET]); if (info->attrs[L2TP_ATTR_DATA_SEQ]) cfg.data_seq = nla_get_u8(info->attrs[L2TP_ATTR_DATA_SEQ]); cfg.l2specific_type = L2TP_L2SPECTYPE_DEFAULT; if (info->attrs[L2TP_ATTR_L2SPEC_TYPE]) cfg.l2specific_type = nla_get_u8(info->attrs[L2TP_ATTR_L2SPEC_TYPE]); cfg.l2specific_len = 4; if (info->attrs[L2TP_ATTR_L2SPEC_LEN]) cfg.l2specific_len = nla_get_u8(info->attrs[L2TP_ATTR_L2SPEC_LEN]); if (info->attrs[L2TP_ATTR_COOKIE]) { u16 len = nla_len(info->attrs[L2TP_ATTR_COOKIE]); if (len > 8) { ret = -EINVAL; |
e702c1204 l2tp: hold tunnel... |
540 |
goto out_tunnel; |
309795f4b l2tp: Add netlink... |
541 542 543 544 545 546 547 548 |
} cfg.cookie_len = len; memcpy(&cfg.cookie[0], nla_data(info->attrs[L2TP_ATTR_COOKIE]), len); } if (info->attrs[L2TP_ATTR_PEER_COOKIE]) { u16 len = nla_len(info->attrs[L2TP_ATTR_PEER_COOKIE]); if (len > 8) { ret = -EINVAL; |
e702c1204 l2tp: hold tunnel... |
549 |
goto out_tunnel; |
309795f4b l2tp: Add netlink... |
550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 |
} cfg.peer_cookie_len = len; memcpy(&cfg.peer_cookie[0], nla_data(info->attrs[L2TP_ATTR_PEER_COOKIE]), len); } if (info->attrs[L2TP_ATTR_IFNAME]) cfg.ifname = nla_data(info->attrs[L2TP_ATTR_IFNAME]); if (info->attrs[L2TP_ATTR_VLAN_ID]) cfg.vlan_id = nla_get_u16(info->attrs[L2TP_ATTR_VLAN_ID]); } if (info->attrs[L2TP_ATTR_DEBUG]) cfg.debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]); if (info->attrs[L2TP_ATTR_RECV_SEQ]) cfg.recv_seq = nla_get_u8(info->attrs[L2TP_ATTR_RECV_SEQ]); if (info->attrs[L2TP_ATTR_SEND_SEQ]) cfg.send_seq = nla_get_u8(info->attrs[L2TP_ATTR_SEND_SEQ]); if (info->attrs[L2TP_ATTR_LNS_MODE]) cfg.lns_mode = nla_get_u8(info->attrs[L2TP_ATTR_LNS_MODE]); if (info->attrs[L2TP_ATTR_RECV_TIMEOUT]) cfg.reorder_timeout = nla_get_msecs(info->attrs[L2TP_ATTR_RECV_TIMEOUT]); if (info->attrs[L2TP_ATTR_MTU]) cfg.mtu = nla_get_u16(info->attrs[L2TP_ATTR_MTU]); if (info->attrs[L2TP_ATTR_MRU]) cfg.mru = nla_get_u16(info->attrs[L2TP_ATTR_MRU]); |
f1f39f911 l2tp: auto load t... |
581 582 583 584 585 586 587 |
#ifdef CONFIG_MODULES if (l2tp_nl_cmd_ops[cfg.pw_type] == NULL) { genl_unlock(); request_module("net-l2tp-type-%u", cfg.pw_type); genl_lock(); } #endif |
309795f4b l2tp: Add netlink... |
588 589 590 |
if ((l2tp_nl_cmd_ops[cfg.pw_type] == NULL) || (l2tp_nl_cmd_ops[cfg.pw_type]->session_create == NULL)) { ret = -EPROTONOSUPPORT; |
e702c1204 l2tp: hold tunnel... |
591 |
goto out_tunnel; |
309795f4b l2tp: Add netlink... |
592 593 594 595 596 597 598 599 600 |
} /* Check that pseudowire-specific params are present */ switch (cfg.pw_type) { case L2TP_PWTYPE_NONE: break; case L2TP_PWTYPE_ETH_VLAN: if (!info->attrs[L2TP_ATTR_VLAN_ID]) { ret = -EINVAL; |
e702c1204 l2tp: hold tunnel... |
601 |
goto out_tunnel; |
309795f4b l2tp: Add netlink... |
602 603 604 605 606 607 608 609 610 611 612 613 |
} break; case L2TP_PWTYPE_ETH: break; case L2TP_PWTYPE_PPP: case L2TP_PWTYPE_PPP_AC: break; case L2TP_PWTYPE_IP: default: ret = -EPROTONOSUPPORT; break; } |
f026bc29a l2tp: pass tunnel... |
614 615 616 617 |
ret = l2tp_nl_cmd_ops[cfg.pw_type]->session_create(net, tunnel, session_id, peer_session_id, &cfg); |
309795f4b l2tp: Add netlink... |
618 |
|
33f72e6f0 l2tp : multicast ... |
619 |
if (ret >= 0) { |
5e6a9e5a3 l2tp: hold sessio... |
620 621 |
session = l2tp_session_get(net, tunnel, session_id, false); if (session) { |
33f72e6f0 l2tp : multicast ... |
622 623 |
ret = l2tp_session_notify(&l2tp_nl_family, info, session, L2TP_CMD_SESSION_CREATE); |
5e6a9e5a3 l2tp: hold sessio... |
624 625 |
l2tp_session_dec_refcount(session); } |
33f72e6f0 l2tp : multicast ... |
626 |
} |
e702c1204 l2tp: hold tunnel... |
627 628 |
out_tunnel: l2tp_tunnel_dec_refcount(tunnel); |
309795f4b l2tp: Add netlink... |
629 630 631 632 633 634 635 636 637 |
out: return ret; } static int l2tp_nl_cmd_session_delete(struct sk_buff *skb, struct genl_info *info) { int ret = 0; struct l2tp_session *session; u16 pw_type; |
2777e2ab5 l2tp: take a refe... |
638 |
session = l2tp_nl_session_get(info, true); |
309795f4b l2tp: Add netlink... |
639 640 641 642 |
if (session == NULL) { ret = -ENODEV; goto out; } |
33f72e6f0 l2tp : multicast ... |
643 644 |
l2tp_session_notify(&l2tp_nl_family, info, session, L2TP_CMD_SESSION_DELETE); |
309795f4b l2tp: Add netlink... |
645 646 647 648 |
pw_type = session->pwtype; if (pw_type < __L2TP_PWTYPE_MAX) if (l2tp_nl_cmd_ops[pw_type] && l2tp_nl_cmd_ops[pw_type]->session_delete) ret = (*l2tp_nl_cmd_ops[pw_type]->session_delete)(session); |
2777e2ab5 l2tp: take a refe... |
649 650 651 |
if (session->deref) session->deref(session); l2tp_session_dec_refcount(session); |
309795f4b l2tp: Add netlink... |
652 653 654 655 656 657 658 659 |
out: return ret; } static int l2tp_nl_cmd_session_modify(struct sk_buff *skb, struct genl_info *info) { int ret = 0; struct l2tp_session *session; |
2777e2ab5 l2tp: take a refe... |
660 |
session = l2tp_nl_session_get(info, false); |
309795f4b l2tp: Add netlink... |
661 662 663 664 665 666 667 668 669 670 671 672 673 |
if (session == NULL) { ret = -ENODEV; goto out; } if (info->attrs[L2TP_ATTR_DEBUG]) session->debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]); if (info->attrs[L2TP_ATTR_DATA_SEQ]) session->data_seq = nla_get_u8(info->attrs[L2TP_ATTR_DATA_SEQ]); if (info->attrs[L2TP_ATTR_RECV_SEQ]) session->recv_seq = nla_get_u8(info->attrs[L2TP_ATTR_RECV_SEQ]); |
bb5016eac l2tp: fix manual ... |
674 |
if (info->attrs[L2TP_ATTR_SEND_SEQ]) { |
309795f4b l2tp: Add netlink... |
675 |
session->send_seq = nla_get_u8(info->attrs[L2TP_ATTR_SEND_SEQ]); |
bb5016eac l2tp: fix manual ... |
676 677 |
l2tp_session_set_header_len(session, session->tunnel->version); } |
309795f4b l2tp: Add netlink... |
678 679 680 681 682 683 684 685 686 687 688 689 |
if (info->attrs[L2TP_ATTR_LNS_MODE]) session->lns_mode = nla_get_u8(info->attrs[L2TP_ATTR_LNS_MODE]); if (info->attrs[L2TP_ATTR_RECV_TIMEOUT]) session->reorder_timeout = nla_get_msecs(info->attrs[L2TP_ATTR_RECV_TIMEOUT]); if (info->attrs[L2TP_ATTR_MTU]) session->mtu = nla_get_u16(info->attrs[L2TP_ATTR_MTU]); if (info->attrs[L2TP_ATTR_MRU]) session->mru = nla_get_u16(info->attrs[L2TP_ATTR_MRU]); |
33f72e6f0 l2tp : multicast ... |
690 691 |
ret = l2tp_session_notify(&l2tp_nl_family, info, session, L2TP_CMD_SESSION_MODIFY); |
2777e2ab5 l2tp: take a refe... |
692 |
l2tp_session_dec_refcount(session); |
309795f4b l2tp: Add netlink... |
693 694 695 |
out: return ret; } |
15e473046 netlink: Rename p... |
696 |
static int l2tp_nl_session_send(struct sk_buff *skb, u32 portid, u32 seq, int flags, |
33f72e6f0 l2tp : multicast ... |
697 |
struct l2tp_session *session, u8 cmd) |
309795f4b l2tp: Add netlink... |
698 699 700 701 702 703 704 |
{ void *hdr; struct nlattr *nest; struct l2tp_tunnel *tunnel = session->tunnel; struct sock *sk = NULL; sk = tunnel->sock; |
33f72e6f0 l2tp : multicast ... |
705 |
hdr = genlmsg_put(skb, portid, seq, &l2tp_nl_family, flags, cmd); |
7f8436a12 l2tp: fix return ... |
706 707 |
if (!hdr) return -EMSGSIZE; |
309795f4b l2tp: Add netlink... |
708 |
|
60aed2abb l2tp: Stop using ... |
709 710 711 712 713 714 715 716 717 718 719 |
if (nla_put_u32(skb, L2TP_ATTR_CONN_ID, tunnel->tunnel_id) || nla_put_u32(skb, L2TP_ATTR_SESSION_ID, session->session_id) || nla_put_u32(skb, L2TP_ATTR_PEER_CONN_ID, tunnel->peer_tunnel_id) || nla_put_u32(skb, L2TP_ATTR_PEER_SESSION_ID, session->peer_session_id) || nla_put_u32(skb, L2TP_ATTR_DEBUG, session->debug) || nla_put_u16(skb, L2TP_ATTR_PW_TYPE, session->pwtype) || nla_put_u16(skb, L2TP_ATTR_MTU, session->mtu) || (session->mru && nla_put_u16(skb, L2TP_ATTR_MRU, session->mru))) goto nla_put_failure; |
e269ed26d l2tp: session is ... |
720 |
if ((session->ifname[0] && |
60aed2abb l2tp: Stop using ... |
721 722 723 724 725 726 727 728 729 730 |
nla_put_string(skb, L2TP_ATTR_IFNAME, session->ifname)) || (session->cookie_len && nla_put(skb, L2TP_ATTR_COOKIE, session->cookie_len, &session->cookie[0])) || (session->peer_cookie_len && nla_put(skb, L2TP_ATTR_PEER_COOKIE, session->peer_cookie_len, &session->peer_cookie[0])) || nla_put_u8(skb, L2TP_ATTR_RECV_SEQ, session->recv_seq) || nla_put_u8(skb, L2TP_ATTR_SEND_SEQ, session->send_seq) || nla_put_u8(skb, L2TP_ATTR_LNS_MODE, session->lns_mode) || |
309795f4b l2tp: Add netlink... |
731 |
#ifdef CONFIG_XFRM |
60aed2abb l2tp: Stop using ... |
732 733 |
(((sk) && (sk->sk_policy[0] || sk->sk_policy[1])) && nla_put_u8(skb, L2TP_ATTR_USING_IPSEC, 1)) || |
309795f4b l2tp: Add netlink... |
734 |
#endif |
60aed2abb l2tp: Stop using ... |
735 |
(session->reorder_timeout && |
2175d87cc libnl: nla_put_ms... |
736 737 |
nla_put_msecs(skb, L2TP_ATTR_RECV_TIMEOUT, session->reorder_timeout, L2TP_ATTR_PAD))) |
60aed2abb l2tp: Stop using ... |
738 |
goto nla_put_failure; |
5de7aee54 l2tp: fix locking... |
739 |
|
309795f4b l2tp: Add netlink... |
740 741 742 |
nest = nla_nest_start(skb, L2TP_ATTR_STATS); if (nest == NULL) goto nla_put_failure; |
5de7aee54 l2tp: fix locking... |
743 |
|
1c714a928 l2tp: use nla_put... |
744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 |
if (nla_put_u64_64bit(skb, L2TP_ATTR_TX_PACKETS, atomic_long_read(&session->stats.tx_packets), L2TP_ATTR_STATS_PAD) || nla_put_u64_64bit(skb, L2TP_ATTR_TX_BYTES, atomic_long_read(&session->stats.tx_bytes), L2TP_ATTR_STATS_PAD) || nla_put_u64_64bit(skb, L2TP_ATTR_TX_ERRORS, atomic_long_read(&session->stats.tx_errors), L2TP_ATTR_STATS_PAD) || nla_put_u64_64bit(skb, L2TP_ATTR_RX_PACKETS, atomic_long_read(&session->stats.rx_packets), L2TP_ATTR_STATS_PAD) || nla_put_u64_64bit(skb, L2TP_ATTR_RX_BYTES, atomic_long_read(&session->stats.rx_bytes), L2TP_ATTR_STATS_PAD) || nla_put_u64_64bit(skb, L2TP_ATTR_RX_SEQ_DISCARDS, atomic_long_read(&session->stats.rx_seq_discards), L2TP_ATTR_STATS_PAD) || nla_put_u64_64bit(skb, L2TP_ATTR_RX_OOS_PACKETS, atomic_long_read(&session->stats.rx_oos_packets), L2TP_ATTR_STATS_PAD) || nla_put_u64_64bit(skb, L2TP_ATTR_RX_ERRORS, atomic_long_read(&session->stats.rx_errors), L2TP_ATTR_STATS_PAD)) |
60aed2abb l2tp: Stop using ... |
768 |
goto nla_put_failure; |
309795f4b l2tp: Add netlink... |
769 |
nla_nest_end(skb, nest); |
053c095a8 netlink: make nlm... |
770 771 |
genlmsg_end(skb, hdr); return 0; |
309795f4b l2tp: Add netlink... |
772 773 774 775 776 777 778 779 780 781 782 |
nla_put_failure: genlmsg_cancel(skb, hdr); return -1; } static int l2tp_nl_cmd_session_get(struct sk_buff *skb, struct genl_info *info) { struct l2tp_session *session; struct sk_buff *msg; int ret; |
2777e2ab5 l2tp: take a refe... |
783 |
session = l2tp_nl_session_get(info, false); |
309795f4b l2tp: Add netlink... |
784 785 |
if (session == NULL) { ret = -ENODEV; |
2777e2ab5 l2tp: take a refe... |
786 |
goto err; |
309795f4b l2tp: Add netlink... |
787 |
} |
58050fce3 net: Use NLMSG_DE... |
788 |
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
309795f4b l2tp: Add netlink... |
789 790 |
if (!msg) { ret = -ENOMEM; |
2777e2ab5 l2tp: take a refe... |
791 |
goto err_ref; |
309795f4b l2tp: Add netlink... |
792 |
} |
15e473046 netlink: Rename p... |
793 |
ret = l2tp_nl_session_send(msg, info->snd_portid, info->snd_seq, |
33f72e6f0 l2tp : multicast ... |
794 |
0, session, L2TP_CMD_SESSION_GET); |
309795f4b l2tp: Add netlink... |
795 |
if (ret < 0) |
2777e2ab5 l2tp: take a refe... |
796 |
goto err_ref_msg; |
309795f4b l2tp: Add netlink... |
797 |
|
2777e2ab5 l2tp: take a refe... |
798 |
ret = genlmsg_unicast(genl_info_net(info), msg, info->snd_portid); |
309795f4b l2tp: Add netlink... |
799 |
|
2777e2ab5 l2tp: take a refe... |
800 |
l2tp_session_dec_refcount(session); |
309795f4b l2tp: Add netlink... |
801 |
|
2777e2ab5 l2tp: take a refe... |
802 803 804 805 806 807 808 |
return ret; err_ref_msg: nlmsg_free(msg); err_ref: l2tp_session_dec_refcount(session); err: |
309795f4b l2tp: Add netlink... |
809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 |
return ret; } static int l2tp_nl_cmd_session_dump(struct sk_buff *skb, struct netlink_callback *cb) { struct net *net = sock_net(skb->sk); struct l2tp_session *session; struct l2tp_tunnel *tunnel = NULL; int ti = cb->args[0]; int si = cb->args[1]; for (;;) { if (tunnel == NULL) { tunnel = l2tp_tunnel_find_nth(net, ti); if (tunnel == NULL) goto out; } |
e08293a4c l2tp: take refere... |
826 |
session = l2tp_session_get_nth(tunnel, si, false); |
309795f4b l2tp: Add netlink... |
827 828 829 830 831 832 |
if (session == NULL) { ti++; tunnel = NULL; si = 0; continue; } |
15e473046 netlink: Rename p... |
833 |
if (l2tp_nl_session_send(skb, NETLINK_CB(cb->skb).portid, |
309795f4b l2tp: Add netlink... |
834 |
cb->nlh->nlmsg_seq, NLM_F_MULTI, |
e08293a4c l2tp: take refere... |
835 836 |
session, L2TP_CMD_SESSION_GET) < 0) { l2tp_session_dec_refcount(session); |
309795f4b l2tp: Add netlink... |
837 |
break; |
e08293a4c l2tp: take refere... |
838 839 |
} l2tp_session_dec_refcount(session); |
309795f4b l2tp: Add netlink... |
840 841 842 843 844 845 846 847 848 849 |
si++; } out: cb->args[0] = ti; cb->args[1] = si; return skb->len; } |
f5bb341e1 l2tp: make nla_po... |
850 |
static const struct nla_policy l2tp_nl_policy[L2TP_ATTR_MAX + 1] = { |
309795f4b l2tp: Add netlink... |
851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 |
[L2TP_ATTR_NONE] = { .type = NLA_UNSPEC, }, [L2TP_ATTR_PW_TYPE] = { .type = NLA_U16, }, [L2TP_ATTR_ENCAP_TYPE] = { .type = NLA_U16, }, [L2TP_ATTR_OFFSET] = { .type = NLA_U16, }, [L2TP_ATTR_DATA_SEQ] = { .type = NLA_U8, }, [L2TP_ATTR_L2SPEC_TYPE] = { .type = NLA_U8, }, [L2TP_ATTR_L2SPEC_LEN] = { .type = NLA_U8, }, [L2TP_ATTR_PROTO_VERSION] = { .type = NLA_U8, }, [L2TP_ATTR_CONN_ID] = { .type = NLA_U32, }, [L2TP_ATTR_PEER_CONN_ID] = { .type = NLA_U32, }, [L2TP_ATTR_SESSION_ID] = { .type = NLA_U32, }, [L2TP_ATTR_PEER_SESSION_ID] = { .type = NLA_U32, }, [L2TP_ATTR_UDP_CSUM] = { .type = NLA_U8, }, [L2TP_ATTR_VLAN_ID] = { .type = NLA_U16, }, [L2TP_ATTR_DEBUG] = { .type = NLA_U32, }, [L2TP_ATTR_RECV_SEQ] = { .type = NLA_U8, }, [L2TP_ATTR_SEND_SEQ] = { .type = NLA_U8, }, [L2TP_ATTR_LNS_MODE] = { .type = NLA_U8, }, [L2TP_ATTR_USING_IPSEC] = { .type = NLA_U8, }, [L2TP_ATTR_RECV_TIMEOUT] = { .type = NLA_MSECS, }, [L2TP_ATTR_FD] = { .type = NLA_U32, }, [L2TP_ATTR_IP_SADDR] = { .type = NLA_U32, }, [L2TP_ATTR_IP_DADDR] = { .type = NLA_U32, }, [L2TP_ATTR_UDP_SPORT] = { .type = NLA_U16, }, [L2TP_ATTR_UDP_DPORT] = { .type = NLA_U16, }, [L2TP_ATTR_MTU] = { .type = NLA_U16, }, [L2TP_ATTR_MRU] = { .type = NLA_U16, }, [L2TP_ATTR_STATS] = { .type = NLA_NESTED, }, |
f9bac8df9 l2tp: netlink api... |
879 880 881 882 883 884 885 886 |
[L2TP_ATTR_IP6_SADDR] = { .type = NLA_BINARY, .len = sizeof(struct in6_addr), }, [L2TP_ATTR_IP6_DADDR] = { .type = NLA_BINARY, .len = sizeof(struct in6_addr), }, |
309795f4b l2tp: Add netlink... |
887 888 889 890 891 892 893 894 895 896 897 898 899 |
[L2TP_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ - 1, }, [L2TP_ATTR_COOKIE] = { .type = NLA_BINARY, .len = 8, }, [L2TP_ATTR_PEER_COOKIE] = { .type = NLA_BINARY, .len = 8, }, }; |
4534de830 genetlink: make a... |
900 |
static const struct genl_ops l2tp_nl_ops[] = { |
309795f4b l2tp: Add netlink... |
901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 |
{ .cmd = L2TP_CMD_NOOP, .doit = l2tp_nl_cmd_noop, .policy = l2tp_nl_policy, /* can be retrieved by unprivileged users */ }, { .cmd = L2TP_CMD_TUNNEL_CREATE, .doit = l2tp_nl_cmd_tunnel_create, .policy = l2tp_nl_policy, .flags = GENL_ADMIN_PERM, }, { .cmd = L2TP_CMD_TUNNEL_DELETE, .doit = l2tp_nl_cmd_tunnel_delete, .policy = l2tp_nl_policy, .flags = GENL_ADMIN_PERM, }, { .cmd = L2TP_CMD_TUNNEL_MODIFY, .doit = l2tp_nl_cmd_tunnel_modify, .policy = l2tp_nl_policy, .flags = GENL_ADMIN_PERM, }, { .cmd = L2TP_CMD_TUNNEL_GET, .doit = l2tp_nl_cmd_tunnel_get, .dumpit = l2tp_nl_cmd_tunnel_dump, .policy = l2tp_nl_policy, .flags = GENL_ADMIN_PERM, }, { .cmd = L2TP_CMD_SESSION_CREATE, .doit = l2tp_nl_cmd_session_create, .policy = l2tp_nl_policy, .flags = GENL_ADMIN_PERM, }, { .cmd = L2TP_CMD_SESSION_DELETE, .doit = l2tp_nl_cmd_session_delete, .policy = l2tp_nl_policy, .flags = GENL_ADMIN_PERM, }, { .cmd = L2TP_CMD_SESSION_MODIFY, .doit = l2tp_nl_cmd_session_modify, .policy = l2tp_nl_policy, .flags = GENL_ADMIN_PERM, }, { .cmd = L2TP_CMD_SESSION_GET, .doit = l2tp_nl_cmd_session_get, .dumpit = l2tp_nl_cmd_session_dump, .policy = l2tp_nl_policy, .flags = GENL_ADMIN_PERM, }, }; |
56989f6d8 genetlink: mark f... |
958 |
static struct genl_family l2tp_nl_family __ro_after_init = { |
489111e5c genetlink: static... |
959 960 961 962 963 964 965 966 967 968 969 |
.name = L2TP_GENL_NAME, .version = L2TP_GENL_VERSION, .hdrsize = 0, .maxattr = L2TP_ATTR_MAX, .netnsok = true, .module = THIS_MODULE, .ops = l2tp_nl_ops, .n_ops = ARRAY_SIZE(l2tp_nl_ops), .mcgrps = l2tp_multicast_group, .n_mcgrps = ARRAY_SIZE(l2tp_multicast_group), }; |
309795f4b l2tp: Add netlink... |
970 971 972 973 974 975 976 977 978 979 980 981 982 983 |
int l2tp_nl_register_ops(enum l2tp_pwtype pw_type, const struct l2tp_nl_cmd_ops *ops) { int ret; ret = -EINVAL; if (pw_type >= __L2TP_PWTYPE_MAX) goto err; genl_lock(); ret = -EBUSY; if (l2tp_nl_cmd_ops[pw_type]) goto out; l2tp_nl_cmd_ops[pw_type] = ops; |
8cb490144 l2tp: Fix set-but... |
984 |
ret = 0; |
309795f4b l2tp: Add netlink... |
985 986 987 988 |
out: genl_unlock(); err: |
8cb490144 l2tp: Fix set-but... |
989 |
return ret; |
309795f4b l2tp: Add netlink... |
990 991 992 993 994 995 996 997 998 999 1000 1001 |
} EXPORT_SYMBOL_GPL(l2tp_nl_register_ops); void l2tp_nl_unregister_ops(enum l2tp_pwtype pw_type) { if (pw_type < __L2TP_PWTYPE_MAX) { genl_lock(); l2tp_nl_cmd_ops[pw_type] = NULL; genl_unlock(); } } EXPORT_SYMBOL_GPL(l2tp_nl_unregister_ops); |
56989f6d8 genetlink: mark f... |
1002 |
static int __init l2tp_nl_init(void) |
309795f4b l2tp: Add netlink... |
1003 |
{ |
a4ca44fa5 net: l2tp: Standa... |
1004 1005 |
pr_info("L2TP netlink interface "); |
489111e5c genetlink: static... |
1006 |
return genl_register_family(&l2tp_nl_family); |
309795f4b l2tp: Add netlink... |
1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 |
} static void l2tp_nl_cleanup(void) { genl_unregister_family(&l2tp_nl_family); } module_init(l2tp_nl_init); module_exit(l2tp_nl_cleanup); MODULE_AUTHOR("James Chapman <jchapman@katalix.com>"); MODULE_DESCRIPTION("L2TP netlink"); MODULE_LICENSE("GPL"); MODULE_VERSION("1.0"); |
e9412c370 genetlink: Build ... |
1021 |
MODULE_ALIAS_GENL_FAMILY("l2tp"); |