linux/net/l2tp/l2tp_netlink.c
<<
>>
Prefs
   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        fd = -1;
 133        if (info->attrs[L2TP_ATTR_FD]) {
 134                fd = nla_get_u32(info->attrs[L2TP_ATTR_FD]);
 135        } else {
 136                if (info->attrs[L2TP_ATTR_IP_SADDR])
 137                        cfg.local_ip.s_addr = nla_get_be32(info->attrs[L2TP_ATTR_IP_SADDR]);
 138                if (info->attrs[L2TP_ATTR_IP_DADDR])
 139                        cfg.peer_ip.s_addr = nla_get_be32(info->attrs[L2TP_ATTR_IP_DADDR]);
 140                if (info->attrs[L2TP_ATTR_UDP_SPORT])
 141                        cfg.local_udp_port = nla_get_u16(info->attrs[L2TP_ATTR_UDP_SPORT]);
 142                if (info->attrs[L2TP_ATTR_UDP_DPORT])
 143                        cfg.peer_udp_port = nla_get_u16(info->attrs[L2TP_ATTR_UDP_DPORT]);
 144                if (info->attrs[L2TP_ATTR_UDP_CSUM])
 145                        cfg.use_udp_checksums = nla_get_flag(info->attrs[L2TP_ATTR_UDP_CSUM]);
 146        }
 147
 148        if (info->attrs[L2TP_ATTR_DEBUG])
 149                cfg.debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]);
 150
 151        tunnel = l2tp_tunnel_find(net, tunnel_id);
 152        if (tunnel != NULL) {
 153                ret = -EEXIST;
 154                goto out;
 155        }
 156
 157        ret = -EINVAL;
 158        switch (cfg.encap) {
 159        case L2TP_ENCAPTYPE_UDP:
 160        case L2TP_ENCAPTYPE_IP:
 161                ret = l2tp_tunnel_create(net, fd, proto_version, tunnel_id,
 162                                         peer_tunnel_id, &cfg, &tunnel);
 163                break;
 164        }
 165
 166out:
 167        return ret;
 168}
 169
 170static int l2tp_nl_cmd_tunnel_delete(struct sk_buff *skb, struct genl_info *info)
 171{
 172        struct l2tp_tunnel *tunnel;
 173        u32 tunnel_id;
 174        int ret = 0;
 175        struct net *net = genl_info_net(info);
 176
 177        if (!info->attrs[L2TP_ATTR_CONN_ID]) {
 178                ret = -EINVAL;
 179                goto out;
 180        }
 181        tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
 182
 183        tunnel = l2tp_tunnel_find(net, tunnel_id);
 184        if (tunnel == NULL) {
 185                ret = -ENODEV;
 186                goto out;
 187        }
 188
 189        (void) l2tp_tunnel_delete(tunnel);
 190
 191out:
 192        return ret;
 193}
 194
 195static int l2tp_nl_cmd_tunnel_modify(struct sk_buff *skb, struct genl_info *info)
 196{
 197        struct l2tp_tunnel *tunnel;
 198        u32 tunnel_id;
 199        int ret = 0;
 200        struct net *net = genl_info_net(info);
 201
 202        if (!info->attrs[L2TP_ATTR_CONN_ID]) {
 203                ret = -EINVAL;
 204                goto out;
 205        }
 206        tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
 207
 208        tunnel = l2tp_tunnel_find(net, tunnel_id);
 209        if (tunnel == NULL) {
 210                ret = -ENODEV;
 211                goto out;
 212        }
 213
 214        if (info->attrs[L2TP_ATTR_DEBUG])
 215                tunnel->debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]);
 216
 217out:
 218        return ret;
 219}
 220
 221static int l2tp_nl_tunnel_send(struct sk_buff *skb, u32 pid, u32 seq, int flags,
 222                               struct l2tp_tunnel *tunnel)
 223{
 224        void *hdr;
 225        struct nlattr *nest;
 226        struct sock *sk = NULL;
 227        struct inet_sock *inet;
 228
 229        hdr = genlmsg_put(skb, pid, seq, &l2tp_nl_family, flags,
 230                          L2TP_CMD_TUNNEL_GET);
 231        if (IS_ERR(hdr))
 232                return PTR_ERR(hdr);
 233
 234        NLA_PUT_U8(skb, L2TP_ATTR_PROTO_VERSION, tunnel->version);
 235        NLA_PUT_U32(skb, L2TP_ATTR_CONN_ID, tunnel->tunnel_id);
 236        NLA_PUT_U32(skb, L2TP_ATTR_PEER_CONN_ID, tunnel->peer_tunnel_id);
 237        NLA_PUT_U32(skb, L2TP_ATTR_DEBUG, tunnel->debug);
 238        NLA_PUT_U16(skb, L2TP_ATTR_ENCAP_TYPE, tunnel->encap);
 239
 240        nest = nla_nest_start(skb, L2TP_ATTR_STATS);
 241        if (nest == NULL)
 242                goto nla_put_failure;
 243
 244        NLA_PUT_U64(skb, L2TP_ATTR_TX_PACKETS, tunnel->stats.tx_packets);
 245        NLA_PUT_U64(skb, L2TP_ATTR_TX_BYTES, tunnel->stats.tx_bytes);
 246        NLA_PUT_U64(skb, L2TP_ATTR_TX_ERRORS, tunnel->stats.tx_errors);
 247        NLA_PUT_U64(skb, L2TP_ATTR_RX_PACKETS, tunnel->stats.rx_packets);
 248        NLA_PUT_U64(skb, L2TP_ATTR_RX_BYTES, tunnel->stats.rx_bytes);
 249        NLA_PUT_U64(skb, L2TP_ATTR_RX_SEQ_DISCARDS, tunnel->stats.rx_seq_discards);
 250        NLA_PUT_U64(skb, L2TP_ATTR_RX_OOS_PACKETS, tunnel->stats.rx_oos_packets);
 251        NLA_PUT_U64(skb, L2TP_ATTR_RX_ERRORS, tunnel->stats.rx_errors);
 252        nla_nest_end(skb, nest);
 253
 254        sk = tunnel->sock;
 255        if (!sk)
 256                goto out;
 257
 258        inet = inet_sk(sk);
 259
 260        switch (tunnel->encap) {
 261        case L2TP_ENCAPTYPE_UDP:
 262                NLA_PUT_U16(skb, L2TP_ATTR_UDP_SPORT, ntohs(inet->inet_sport));
 263                NLA_PUT_U16(skb, L2TP_ATTR_UDP_DPORT, ntohs(inet->inet_dport));
 264                NLA_PUT_U8(skb, L2TP_ATTR_UDP_CSUM, (sk->sk_no_check != UDP_CSUM_NOXMIT));
 265                /* NOBREAK */
 266        case L2TP_ENCAPTYPE_IP:
 267                NLA_PUT_BE32(skb, L2TP_ATTR_IP_SADDR, inet->inet_saddr);
 268                NLA_PUT_BE32(skb, L2TP_ATTR_IP_DADDR, inet->inet_daddr);
 269                break;
 270        }
 271
 272out:
 273        return genlmsg_end(skb, hdr);
 274
 275nla_put_failure:
 276        genlmsg_cancel(skb, hdr);
 277        return -1;
 278}
 279
 280static int l2tp_nl_cmd_tunnel_get(struct sk_buff *skb, struct genl_info *info)
 281{
 282        struct l2tp_tunnel *tunnel;
 283        struct sk_buff *msg;
 284        u32 tunnel_id;
 285        int ret = -ENOBUFS;
 286        struct net *net = genl_info_net(info);
 287
 288        if (!info->attrs[L2TP_ATTR_CONN_ID]) {
 289                ret = -EINVAL;
 290                goto out;
 291        }
 292
 293        tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
 294
 295        tunnel = l2tp_tunnel_find(net, tunnel_id);
 296        if (tunnel == NULL) {
 297                ret = -ENODEV;
 298                goto out;
 299        }
 300
 301        msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
 302        if (!msg) {
 303                ret = -ENOMEM;
 304                goto out;
 305        }
 306
 307        ret = l2tp_nl_tunnel_send(msg, info->snd_pid, info->snd_seq,
 308                                  NLM_F_ACK, tunnel);
 309        if (ret < 0)
 310                goto err_out;
 311
 312        return genlmsg_unicast(net, msg, info->snd_pid);
 313
 314err_out:
 315        nlmsg_free(msg);
 316
 317out:
 318        return ret;
 319}
 320
 321static int l2tp_nl_cmd_tunnel_dump(struct sk_buff *skb, struct netlink_callback *cb)
 322{
 323        int ti = cb->args[0];
 324        struct l2tp_tunnel *tunnel;
 325        struct net *net = sock_net(skb->sk);
 326
 327        for (;;) {
 328                tunnel = l2tp_tunnel_find_nth(net, ti);
 329                if (tunnel == NULL)
 330                        goto out;
 331
 332                if (l2tp_nl_tunnel_send(skb, NETLINK_CB(cb->skb).pid,
 333                                        cb->nlh->nlmsg_seq, NLM_F_MULTI,
 334                                        tunnel) <= 0)
 335                        goto out;
 336
 337                ti++;
 338        }
 339
 340out:
 341        cb->args[0] = ti;
 342
 343        return skb->len;
 344}
 345
 346static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *info)
 347{
 348        u32 tunnel_id = 0;
 349        u32 session_id;
 350        u32 peer_session_id;
 351        int ret = 0;
 352        struct l2tp_tunnel *tunnel;
 353        struct l2tp_session *session;
 354        struct l2tp_session_cfg cfg = { 0, };
 355        struct net *net = genl_info_net(info);
 356
 357        if (!info->attrs[L2TP_ATTR_CONN_ID]) {
 358                ret = -EINVAL;
 359                goto out;
 360        }
 361        tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
 362        tunnel = l2tp_tunnel_find(net, tunnel_id);
 363        if (!tunnel) {
 364                ret = -ENODEV;
 365                goto out;
 366        }
 367
 368        if (!info->attrs[L2TP_ATTR_SESSION_ID]) {
 369                ret = -EINVAL;
 370                goto out;
 371        }
 372        session_id = nla_get_u32(info->attrs[L2TP_ATTR_SESSION_ID]);
 373        session = l2tp_session_find(net, tunnel, session_id);
 374        if (session) {
 375                ret = -EEXIST;
 376                goto out;
 377        }
 378
 379        if (!info->attrs[L2TP_ATTR_PEER_SESSION_ID]) {
 380                ret = -EINVAL;
 381                goto out;
 382        }
 383        peer_session_id = nla_get_u32(info->attrs[L2TP_ATTR_PEER_SESSION_ID]);
 384
 385        if (!info->attrs[L2TP_ATTR_PW_TYPE]) {
 386                ret = -EINVAL;
 387                goto out;
 388        }
 389        cfg.pw_type = nla_get_u16(info->attrs[L2TP_ATTR_PW_TYPE]);
 390        if (cfg.pw_type >= __L2TP_PWTYPE_MAX) {
 391                ret = -EINVAL;
 392                goto out;
 393        }
 394
 395        if (tunnel->version > 2) {
 396                if (info->attrs[L2TP_ATTR_OFFSET])
 397                        cfg.offset = nla_get_u16(info->attrs[L2TP_ATTR_OFFSET]);
 398
 399                if (info->attrs[L2TP_ATTR_DATA_SEQ])
 400                        cfg.data_seq = nla_get_u8(info->attrs[L2TP_ATTR_DATA_SEQ]);
 401
 402                cfg.l2specific_type = L2TP_L2SPECTYPE_DEFAULT;
 403                if (info->attrs[L2TP_ATTR_L2SPEC_TYPE])
 404                        cfg.l2specific_type = nla_get_u8(info->attrs[L2TP_ATTR_L2SPEC_TYPE]);
 405
 406                cfg.l2specific_len = 4;
 407                if (info->attrs[L2TP_ATTR_L2SPEC_LEN])
 408                        cfg.l2specific_len = nla_get_u8(info->attrs[L2TP_ATTR_L2SPEC_LEN]);
 409
 410                if (info->attrs[L2TP_ATTR_COOKIE]) {
 411                        u16 len = nla_len(info->attrs[L2TP_ATTR_COOKIE]);
 412                        if (len > 8) {
 413                                ret = -EINVAL;
 414                                goto out;
 415                        }
 416                        cfg.cookie_len = len;
 417                        memcpy(&cfg.cookie[0], nla_data(info->attrs[L2TP_ATTR_COOKIE]), len);
 418                }
 419                if (info->attrs[L2TP_ATTR_PEER_COOKIE]) {
 420                        u16 len = nla_len(info->attrs[L2TP_ATTR_PEER_COOKIE]);
 421                        if (len > 8) {
 422                                ret = -EINVAL;
 423                                goto out;
 424                        }
 425                        cfg.peer_cookie_len = len;
 426                        memcpy(&cfg.peer_cookie[0], nla_data(info->attrs[L2TP_ATTR_PEER_COOKIE]), len);
 427                }
 428                if (info->attrs[L2TP_ATTR_IFNAME])
 429                        cfg.ifname = nla_data(info->attrs[L2TP_ATTR_IFNAME]);
 430
 431                if (info->attrs[L2TP_ATTR_VLAN_ID])
 432                        cfg.vlan_id = nla_get_u16(info->attrs[L2TP_ATTR_VLAN_ID]);
 433        }
 434
 435        if (info->attrs[L2TP_ATTR_DEBUG])
 436                cfg.debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]);
 437
 438        if (info->attrs[L2TP_ATTR_RECV_SEQ])
 439                cfg.recv_seq = nla_get_u8(info->attrs[L2TP_ATTR_RECV_SEQ]);
 440
 441        if (info->attrs[L2TP_ATTR_SEND_SEQ])
 442                cfg.send_seq = nla_get_u8(info->attrs[L2TP_ATTR_SEND_SEQ]);
 443
 444        if (info->attrs[L2TP_ATTR_LNS_MODE])
 445                cfg.lns_mode = nla_get_u8(info->attrs[L2TP_ATTR_LNS_MODE]);
 446
 447        if (info->attrs[L2TP_ATTR_RECV_TIMEOUT])
 448                cfg.reorder_timeout = nla_get_msecs(info->attrs[L2TP_ATTR_RECV_TIMEOUT]);
 449
 450        if (info->attrs[L2TP_ATTR_MTU])
 451                cfg.mtu = nla_get_u16(info->attrs[L2TP_ATTR_MTU]);
 452
 453        if (info->attrs[L2TP_ATTR_MRU])
 454                cfg.mru = nla_get_u16(info->attrs[L2TP_ATTR_MRU]);
 455
 456        if ((l2tp_nl_cmd_ops[cfg.pw_type] == NULL) ||
 457            (l2tp_nl_cmd_ops[cfg.pw_type]->session_create == NULL)) {
 458                ret = -EPROTONOSUPPORT;
 459                goto out;
 460        }
 461
 462        /* Check that pseudowire-specific params are present */
 463        switch (cfg.pw_type) {
 464        case L2TP_PWTYPE_NONE:
 465                break;
 466        case L2TP_PWTYPE_ETH_VLAN:
 467                if (!info->attrs[L2TP_ATTR_VLAN_ID]) {
 468                        ret = -EINVAL;
 469                        goto out;
 470                }
 471                break;
 472        case L2TP_PWTYPE_ETH:
 473                break;
 474        case L2TP_PWTYPE_PPP:
 475        case L2TP_PWTYPE_PPP_AC:
 476                break;
 477        case L2TP_PWTYPE_IP:
 478        default:
 479                ret = -EPROTONOSUPPORT;
 480                break;
 481        }
 482
 483        ret = -EPROTONOSUPPORT;
 484        if (l2tp_nl_cmd_ops[cfg.pw_type]->session_create)
 485                ret = (*l2tp_nl_cmd_ops[cfg.pw_type]->session_create)(net, tunnel_id,
 486                        session_id, peer_session_id, &cfg);
 487
 488out:
 489        return ret;
 490}
 491
 492static int l2tp_nl_cmd_session_delete(struct sk_buff *skb, struct genl_info *info)
 493{
 494        int ret = 0;
 495        struct l2tp_session *session;
 496        u16 pw_type;
 497
 498        session = l2tp_nl_session_find(info);
 499        if (session == NULL) {
 500                ret = -ENODEV;
 501                goto out;
 502        }
 503
 504        pw_type = session->pwtype;
 505        if (pw_type < __L2TP_PWTYPE_MAX)
 506                if (l2tp_nl_cmd_ops[pw_type] && l2tp_nl_cmd_ops[pw_type]->session_delete)
 507                        ret = (*l2tp_nl_cmd_ops[pw_type]->session_delete)(session);
 508
 509out:
 510        return ret;
 511}
 512
 513static int l2tp_nl_cmd_session_modify(struct sk_buff *skb, struct genl_info *info)
 514{
 515        int ret = 0;
 516        struct l2tp_session *session;
 517
 518        session = l2tp_nl_session_find(info);
 519        if (session == NULL) {
 520                ret = -ENODEV;
 521                goto out;
 522        }
 523
 524        if (info->attrs[L2TP_ATTR_DEBUG])
 525                session->debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]);
 526
 527        if (info->attrs[L2TP_ATTR_DATA_SEQ])
 528                session->data_seq = nla_get_u8(info->attrs[L2TP_ATTR_DATA_SEQ]);
 529
 530        if (info->attrs[L2TP_ATTR_RECV_SEQ])
 531                session->recv_seq = nla_get_u8(info->attrs[L2TP_ATTR_RECV_SEQ]);
 532
 533        if (info->attrs[L2TP_ATTR_SEND_SEQ])
 534                session->send_seq = nla_get_u8(info->attrs[L2TP_ATTR_SEND_SEQ]);
 535
 536        if (info->attrs[L2TP_ATTR_LNS_MODE])
 537                session->lns_mode = nla_get_u8(info->attrs[L2TP_ATTR_LNS_MODE]);
 538
 539        if (info->attrs[L2TP_ATTR_RECV_TIMEOUT])
 540                session->reorder_timeout = nla_get_msecs(info->attrs[L2TP_ATTR_RECV_TIMEOUT]);
 541
 542        if (info->attrs[L2TP_ATTR_MTU])
 543                session->mtu = nla_get_u16(info->attrs[L2TP_ATTR_MTU]);
 544
 545        if (info->attrs[L2TP_ATTR_MRU])
 546                session->mru = nla_get_u16(info->attrs[L2TP_ATTR_MRU]);
 547
 548out:
 549        return ret;
 550}
 551
 552static int l2tp_nl_session_send(struct sk_buff *skb, u32 pid, u32 seq, int flags,
 553                                struct l2tp_session *session)
 554{
 555        void *hdr;
 556        struct nlattr *nest;
 557        struct l2tp_tunnel *tunnel = session->tunnel;
 558        struct sock *sk = NULL;
 559
 560        sk = tunnel->sock;
 561
 562        hdr = genlmsg_put(skb, pid, seq, &l2tp_nl_family, flags, L2TP_CMD_SESSION_GET);
 563        if (IS_ERR(hdr))
 564                return PTR_ERR(hdr);
 565
 566        NLA_PUT_U32(skb, L2TP_ATTR_CONN_ID, tunnel->tunnel_id);
 567        NLA_PUT_U32(skb, L2TP_ATTR_SESSION_ID, session->session_id);
 568        NLA_PUT_U32(skb, L2TP_ATTR_PEER_CONN_ID, tunnel->peer_tunnel_id);
 569        NLA_PUT_U32(skb, L2TP_ATTR_PEER_SESSION_ID, session->peer_session_id);
 570        NLA_PUT_U32(skb, L2TP_ATTR_DEBUG, session->debug);
 571        NLA_PUT_U16(skb, L2TP_ATTR_PW_TYPE, session->pwtype);
 572        NLA_PUT_U16(skb, L2TP_ATTR_MTU, session->mtu);
 573        if (session->mru)
 574                NLA_PUT_U16(skb, L2TP_ATTR_MRU, session->mru);
 575
 576        if (session->ifname && session->ifname[0])
 577                NLA_PUT_STRING(skb, L2TP_ATTR_IFNAME, session->ifname);
 578        if (session->cookie_len)
 579                NLA_PUT(skb, L2TP_ATTR_COOKIE, session->cookie_len, &session->cookie[0]);
 580        if (session->peer_cookie_len)
 581                NLA_PUT(skb, L2TP_ATTR_PEER_COOKIE, session->peer_cookie_len, &session->peer_cookie[0]);
 582        NLA_PUT_U8(skb, L2TP_ATTR_RECV_SEQ, session->recv_seq);
 583        NLA_PUT_U8(skb, L2TP_ATTR_SEND_SEQ, session->send_seq);
 584        NLA_PUT_U8(skb, L2TP_ATTR_LNS_MODE, session->lns_mode);
 585#ifdef CONFIG_XFRM
 586        if ((sk) && (sk->sk_policy[0] || sk->sk_policy[1]))
 587                NLA_PUT_U8(skb, L2TP_ATTR_USING_IPSEC, 1);
 588#endif
 589        if (session->reorder_timeout)
 590                NLA_PUT_MSECS(skb, L2TP_ATTR_RECV_TIMEOUT, session->reorder_timeout);
 591
 592        nest = nla_nest_start(skb, L2TP_ATTR_STATS);
 593        if (nest == NULL)
 594                goto nla_put_failure;
 595        NLA_PUT_U64(skb, L2TP_ATTR_TX_PACKETS, session->stats.tx_packets);
 596        NLA_PUT_U64(skb, L2TP_ATTR_TX_BYTES, session->stats.tx_bytes);
 597        NLA_PUT_U64(skb, L2TP_ATTR_TX_ERRORS, session->stats.tx_errors);
 598        NLA_PUT_U64(skb, L2TP_ATTR_RX_PACKETS, session->stats.rx_packets);
 599        NLA_PUT_U64(skb, L2TP_ATTR_RX_BYTES, session->stats.rx_bytes);
 600        NLA_PUT_U64(skb, L2TP_ATTR_RX_SEQ_DISCARDS, session->stats.rx_seq_discards);
 601        NLA_PUT_U64(skb, L2TP_ATTR_RX_OOS_PACKETS, session->stats.rx_oos_packets);
 602        NLA_PUT_U64(skb, L2TP_ATTR_RX_ERRORS, session->stats.rx_errors);
 603        nla_nest_end(skb, nest);
 604
 605        return genlmsg_end(skb, hdr);
 606
 607 nla_put_failure:
 608        genlmsg_cancel(skb, hdr);
 609        return -1;
 610}
 611
 612static int l2tp_nl_cmd_session_get(struct sk_buff *skb, struct genl_info *info)
 613{
 614        struct l2tp_session *session;
 615        struct sk_buff *msg;
 616        int ret;
 617
 618        session = l2tp_nl_session_find(info);
 619        if (session == NULL) {
 620                ret = -ENODEV;
 621                goto out;
 622        }
 623
 624        msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
 625        if (!msg) {
 626                ret = -ENOMEM;
 627                goto out;
 628        }
 629
 630        ret = l2tp_nl_session_send(msg, info->snd_pid, info->snd_seq,
 631                                   0, session);
 632        if (ret < 0)
 633                goto err_out;
 634
 635        return genlmsg_unicast(genl_info_net(info), msg, info->snd_pid);
 636
 637err_out:
 638        nlmsg_free(msg);
 639
 640out:
 641        return ret;
 642}
 643
 644static int l2tp_nl_cmd_session_dump(struct sk_buff *skb, struct netlink_callback *cb)
 645{
 646        struct net *net = sock_net(skb->sk);
 647        struct l2tp_session *session;
 648        struct l2tp_tunnel *tunnel = NULL;
 649        int ti = cb->args[0];
 650        int si = cb->args[1];
 651
 652        for (;;) {
 653                if (tunnel == NULL) {
 654                        tunnel = l2tp_tunnel_find_nth(net, ti);
 655                        if (tunnel == NULL)
 656                                goto out;
 657                }
 658
 659                session = l2tp_session_find_nth(tunnel, si);
 660                if (session == NULL) {
 661                        ti++;
 662                        tunnel = NULL;
 663                        si = 0;
 664                        continue;
 665                }
 666
 667                if (l2tp_nl_session_send(skb, NETLINK_CB(cb->skb).pid,
 668                                         cb->nlh->nlmsg_seq, NLM_F_MULTI,
 669                                         session) <= 0)
 670                        break;
 671
 672                si++;
 673        }
 674
 675out:
 676        cb->args[0] = ti;
 677        cb->args[1] = si;
 678
 679        return skb->len;
 680}
 681
 682static struct nla_policy l2tp_nl_policy[L2TP_ATTR_MAX + 1] = {
 683        [L2TP_ATTR_NONE]                = { .type = NLA_UNSPEC, },
 684        [L2TP_ATTR_PW_TYPE]             = { .type = NLA_U16, },
 685        [L2TP_ATTR_ENCAP_TYPE]          = { .type = NLA_U16, },
 686        [L2TP_ATTR_OFFSET]              = { .type = NLA_U16, },
 687        [L2TP_ATTR_DATA_SEQ]            = { .type = NLA_U8, },
 688        [L2TP_ATTR_L2SPEC_TYPE]         = { .type = NLA_U8, },
 689        [L2TP_ATTR_L2SPEC_LEN]          = { .type = NLA_U8, },
 690        [L2TP_ATTR_PROTO_VERSION]       = { .type = NLA_U8, },
 691        [L2TP_ATTR_CONN_ID]             = { .type = NLA_U32, },
 692        [L2TP_ATTR_PEER_CONN_ID]        = { .type = NLA_U32, },
 693        [L2TP_ATTR_SESSION_ID]          = { .type = NLA_U32, },
 694        [L2TP_ATTR_PEER_SESSION_ID]     = { .type = NLA_U32, },
 695        [L2TP_ATTR_UDP_CSUM]            = { .type = NLA_U8, },
 696        [L2TP_ATTR_VLAN_ID]             = { .type = NLA_U16, },
 697        [L2TP_ATTR_DEBUG]               = { .type = NLA_U32, },
 698        [L2TP_ATTR_RECV_SEQ]            = { .type = NLA_U8, },
 699        [L2TP_ATTR_SEND_SEQ]            = { .type = NLA_U8, },
 700        [L2TP_ATTR_LNS_MODE]            = { .type = NLA_U8, },
 701        [L2TP_ATTR_USING_IPSEC]         = { .type = NLA_U8, },
 702        [L2TP_ATTR_RECV_TIMEOUT]        = { .type = NLA_MSECS, },
 703        [L2TP_ATTR_FD]                  = { .type = NLA_U32, },
 704        [L2TP_ATTR_IP_SADDR]            = { .type = NLA_U32, },
 705        [L2TP_ATTR_IP_DADDR]            = { .type = NLA_U32, },
 706        [L2TP_ATTR_UDP_SPORT]           = { .type = NLA_U16, },
 707        [L2TP_ATTR_UDP_DPORT]           = { .type = NLA_U16, },
 708        [L2TP_ATTR_MTU]                 = { .type = NLA_U16, },
 709        [L2TP_ATTR_MRU]                 = { .type = NLA_U16, },
 710        [L2TP_ATTR_STATS]               = { .type = NLA_NESTED, },
 711        [L2TP_ATTR_IFNAME] = {
 712                .type = NLA_NUL_STRING,
 713                .len = IFNAMSIZ - 1,
 714        },
 715        [L2TP_ATTR_COOKIE] = {
 716                .type = NLA_BINARY,
 717                .len = 8,
 718        },
 719        [L2TP_ATTR_PEER_COOKIE] = {
 720                .type = NLA_BINARY,
 721                .len = 8,
 722        },
 723};
 724
 725static struct genl_ops l2tp_nl_ops[] = {
 726        {
 727                .cmd = L2TP_CMD_NOOP,
 728                .doit = l2tp_nl_cmd_noop,
 729                .policy = l2tp_nl_policy,
 730                /* can be retrieved by unprivileged users */
 731        },
 732        {
 733                .cmd = L2TP_CMD_TUNNEL_CREATE,
 734                .doit = l2tp_nl_cmd_tunnel_create,
 735                .policy = l2tp_nl_policy,
 736                .flags = GENL_ADMIN_PERM,
 737        },
 738        {
 739                .cmd = L2TP_CMD_TUNNEL_DELETE,
 740                .doit = l2tp_nl_cmd_tunnel_delete,
 741                .policy = l2tp_nl_policy,
 742                .flags = GENL_ADMIN_PERM,
 743        },
 744        {
 745                .cmd = L2TP_CMD_TUNNEL_MODIFY,
 746                .doit = l2tp_nl_cmd_tunnel_modify,
 747                .policy = l2tp_nl_policy,
 748                .flags = GENL_ADMIN_PERM,
 749        },
 750        {
 751                .cmd = L2TP_CMD_TUNNEL_GET,
 752                .doit = l2tp_nl_cmd_tunnel_get,
 753                .dumpit = l2tp_nl_cmd_tunnel_dump,
 754                .policy = l2tp_nl_policy,
 755                .flags = GENL_ADMIN_PERM,
 756        },
 757        {
 758                .cmd = L2TP_CMD_SESSION_CREATE,
 759                .doit = l2tp_nl_cmd_session_create,
 760                .policy = l2tp_nl_policy,
 761                .flags = GENL_ADMIN_PERM,
 762        },
 763        {
 764                .cmd = L2TP_CMD_SESSION_DELETE,
 765                .doit = l2tp_nl_cmd_session_delete,
 766                .policy = l2tp_nl_policy,
 767                .flags = GENL_ADMIN_PERM,
 768        },
 769        {
 770                .cmd = L2TP_CMD_SESSION_MODIFY,
 771                .doit = l2tp_nl_cmd_session_modify,
 772                .policy = l2tp_nl_policy,
 773                .flags = GENL_ADMIN_PERM,
 774        },
 775        {
 776                .cmd = L2TP_CMD_SESSION_GET,
 777                .doit = l2tp_nl_cmd_session_get,
 778                .dumpit = l2tp_nl_cmd_session_dump,
 779                .policy = l2tp_nl_policy,
 780                .flags = GENL_ADMIN_PERM,
 781        },
 782};
 783
 784int l2tp_nl_register_ops(enum l2tp_pwtype pw_type, const struct l2tp_nl_cmd_ops *ops)
 785{
 786        int ret;
 787
 788        ret = -EINVAL;
 789        if (pw_type >= __L2TP_PWTYPE_MAX)
 790                goto err;
 791
 792        genl_lock();
 793        ret = -EBUSY;
 794        if (l2tp_nl_cmd_ops[pw_type])
 795                goto out;
 796
 797        l2tp_nl_cmd_ops[pw_type] = ops;
 798        ret = 0;
 799
 800out:
 801        genl_unlock();
 802err:
 803        return ret;
 804}
 805EXPORT_SYMBOL_GPL(l2tp_nl_register_ops);
 806
 807void l2tp_nl_unregister_ops(enum l2tp_pwtype pw_type)
 808{
 809        if (pw_type < __L2TP_PWTYPE_MAX) {
 810                genl_lock();
 811                l2tp_nl_cmd_ops[pw_type] = NULL;
 812                genl_unlock();
 813        }
 814}
 815EXPORT_SYMBOL_GPL(l2tp_nl_unregister_ops);
 816
 817static int l2tp_nl_init(void)
 818{
 819        int err;
 820
 821        printk(KERN_INFO "L2TP netlink interface\n");
 822        err = genl_register_family_with_ops(&l2tp_nl_family, l2tp_nl_ops,
 823                                            ARRAY_SIZE(l2tp_nl_ops));
 824
 825        return err;
 826}
 827
 828static void l2tp_nl_cleanup(void)
 829{
 830        genl_unregister_family(&l2tp_nl_family);
 831}
 832
 833module_init(l2tp_nl_init);
 834module_exit(l2tp_nl_cleanup);
 835
 836MODULE_AUTHOR("James Chapman <jchapman@katalix.com>");
 837MODULE_DESCRIPTION("L2TP netlink");
 838MODULE_LICENSE("GPL");
 839MODULE_VERSION("1.0");
 840MODULE_ALIAS("net-pf-" __stringify(PF_NETLINK) "-proto-" \
 841             __stringify(NETLINK_GENERIC) "-type-" "l2tp");
 842
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.