Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

l2tp: Add netlink control API for L2TP

In L2TPv3, we need to create/delete/modify/query L2TP tunnel and
session contexts. The number of parameters is significant. So let's
use netlink. Userspace uses this API to control L2TP tunnel/session
contexts in the kernel.

The previous pppol2tp driver was managed using [gs]etsockopt(). This
API is retained for backwards compatibility. Unlike L2TPv2 which
carries only PPP frames, L2TPv3 can carry raw ethernet frames or other
frame types and these do not always have an associated socket
family. Therefore, we need a way to use L2TP sessions that doesn't
require a socket type for each supported frame type. Hence netlink is
used.

Signed-off-by: James Chapman <jchapman@katalix.com>
Reviewed-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

James Chapman and committed by
David S. Miller
309795f4 f408e0ce

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