Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 193944
b: refs/heads/master
c: 309795f
h: refs/heads/master
v: v3
  • Loading branch information
James Chapman authored and David S. Miller committed Apr 3, 2010
1 parent 9b1be2c commit d93c87f
Show file tree
Hide file tree
Showing 7 changed files with 1,170 additions and 45 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f408e0ce40270559ef80f231843c93baa9947bc5
refs/heads/master: 309795f4bec2d69cd507a631f82065c2198a0825
125 changes: 125 additions & 0 deletions trunk/include/linux/l2tp.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#ifdef __KERNEL__
#include <linux/socket.h>
#include <linux/in.h>
#else
#include <netinet/in.h>
#endif

#define IPPROTO_L2TP 115
Expand All @@ -21,6 +23,7 @@
* @l2tp_addr: protocol specific address information
* @l2tp_conn_id: connection id of tunnel
*/
#define __SOCK_SIZE__ 16 /* sizeof(struct sockaddr) */
struct sockaddr_l2tpip {
/* The first fields must match struct sockaddr_in */
sa_family_t l2tp_family; /* AF_INET */
Expand All @@ -35,4 +38,126 @@ struct sockaddr_l2tpip {
sizeof(__u32)];
};

/*****************************************************************************
* NETLINK_GENERIC netlink family.
*****************************************************************************/

/*
* Commands.
* Valid TLVs of each command are:-
* TUNNEL_CREATE - CONN_ID, pw_type, netns, ifname, ipinfo, udpinfo, udpcsum, vlanid
* TUNNEL_DELETE - CONN_ID
* TUNNEL_MODIFY - CONN_ID, udpcsum
* TUNNEL_GETSTATS - CONN_ID, (stats)
* TUNNEL_GET - CONN_ID, (...)
* SESSION_CREATE - SESSION_ID, PW_TYPE, offset, data_seq, cookie, peer_cookie, offset, l2spec
* SESSION_DELETE - SESSION_ID
* SESSION_MODIFY - SESSION_ID, data_seq
* SESSION_GET - SESSION_ID, (...)
* SESSION_GETSTATS - SESSION_ID, (stats)
*
*/
enum {
L2TP_CMD_NOOP,
L2TP_CMD_TUNNEL_CREATE,
L2TP_CMD_TUNNEL_DELETE,
L2TP_CMD_TUNNEL_MODIFY,
L2TP_CMD_TUNNEL_GET,
L2TP_CMD_SESSION_CREATE,
L2TP_CMD_SESSION_DELETE,
L2TP_CMD_SESSION_MODIFY,
L2TP_CMD_SESSION_GET,
__L2TP_CMD_MAX,
};

#define L2TP_CMD_MAX (__L2TP_CMD_MAX - 1)

/*
* ATTR types defined for L2TP
*/
enum {
L2TP_ATTR_NONE, /* no data */
L2TP_ATTR_PW_TYPE, /* u16, enum l2tp_pwtype */
L2TP_ATTR_ENCAP_TYPE, /* u16, enum l2tp_encap_type */
L2TP_ATTR_OFFSET, /* u16 */
L2TP_ATTR_DATA_SEQ, /* u16 */
L2TP_ATTR_L2SPEC_TYPE, /* u8, enum l2tp_l2spec_type */
L2TP_ATTR_L2SPEC_LEN, /* u8, enum l2tp_l2spec_type */
L2TP_ATTR_PROTO_VERSION, /* u8 */
L2TP_ATTR_IFNAME, /* string */
L2TP_ATTR_CONN_ID, /* u32 */
L2TP_ATTR_PEER_CONN_ID, /* u32 */
L2TP_ATTR_SESSION_ID, /* u32 */
L2TP_ATTR_PEER_SESSION_ID, /* u32 */
L2TP_ATTR_UDP_CSUM, /* u8 */
L2TP_ATTR_VLAN_ID, /* u16 */
L2TP_ATTR_COOKIE, /* 0, 4 or 8 bytes */
L2TP_ATTR_PEER_COOKIE, /* 0, 4 or 8 bytes */
L2TP_ATTR_DEBUG, /* u32 */
L2TP_ATTR_RECV_SEQ, /* u8 */
L2TP_ATTR_SEND_SEQ, /* u8 */
L2TP_ATTR_LNS_MODE, /* u8 */
L2TP_ATTR_USING_IPSEC, /* u8 */
L2TP_ATTR_RECV_TIMEOUT, /* msec */
L2TP_ATTR_FD, /* int */
L2TP_ATTR_IP_SADDR, /* u32 */
L2TP_ATTR_IP_DADDR, /* u32 */
L2TP_ATTR_UDP_SPORT, /* u16 */
L2TP_ATTR_UDP_DPORT, /* u16 */
L2TP_ATTR_MTU, /* u16 */
L2TP_ATTR_MRU, /* u16 */
L2TP_ATTR_STATS, /* nested */
__L2TP_ATTR_MAX,
};

#define L2TP_ATTR_MAX (__L2TP_ATTR_MAX - 1)

/* Nested in L2TP_ATTR_STATS */
enum {
L2TP_ATTR_STATS_NONE, /* no data */
L2TP_ATTR_TX_PACKETS, /* u64 */
L2TP_ATTR_TX_BYTES, /* u64 */
L2TP_ATTR_TX_ERRORS, /* u64 */
L2TP_ATTR_RX_PACKETS, /* u64 */
L2TP_ATTR_RX_BYTES, /* u64 */
L2TP_ATTR_RX_SEQ_DISCARDS, /* u64 */
L2TP_ATTR_RX_OOS_PACKETS, /* u64 */
L2TP_ATTR_RX_ERRORS, /* u64 */
__L2TP_ATTR_STATS_MAX,
};

#define L2TP_ATTR_STATS_MAX (__L2TP_ATTR_STATS_MAX - 1)

enum l2tp_pwtype {
L2TP_PWTYPE_NONE = 0x0000,
L2TP_PWTYPE_ETH_VLAN = 0x0004,
L2TP_PWTYPE_ETH = 0x0005,
L2TP_PWTYPE_PPP = 0x0007,
L2TP_PWTYPE_PPP_AC = 0x0008,
L2TP_PWTYPE_IP = 0x000b,
__L2TP_PWTYPE_MAX
};

enum l2tp_l2spec_type {
L2TP_L2SPECTYPE_NONE,
L2TP_L2SPECTYPE_DEFAULT,
};

enum l2tp_encap_type {
L2TP_ENCAPTYPE_UDP,
L2TP_ENCAPTYPE_IP,
};

enum l2tp_seqmode {
L2TP_SEQ_NONE = 0,
L2TP_SEQ_IP = 1,
L2TP_SEQ_ALL = 2,
};

/*
* NETLINK_GENERIC related info
*/
#define L2TP_GENL_NAME "l2tp"
#define L2TP_GENL_VERSION 0x1

#endif
1 change: 1 addition & 0 deletions trunk/net/l2tp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ obj-$(CONFIG_L2TP) += l2tp_core.o
# Build l2tp as modules if L2TP is M
obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_PPPOL2TP)) += l2tp_ppp.o
obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_IP)) += l2tp_ip.o
obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_V3)) += l2tp_netlink.o
61 changes: 60 additions & 1 deletion trunk/net/l2tp/l2tp_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include <net/dst.h>
#include <net/ip.h>
#include <net/udp.h>
#include <net/inet_common.h>
#include <net/xfrm.h>
#include <net/protocol.h>

Expand Down Expand Up @@ -214,6 +215,32 @@ struct l2tp_session *l2tp_session_find_nth(struct l2tp_tunnel *tunnel, int nth)
}
EXPORT_SYMBOL_GPL(l2tp_session_find_nth);

/* Lookup a session by interface name.
* This is very inefficient but is only used by management interfaces.
*/
struct l2tp_session *l2tp_session_find_by_ifname(struct net *net, char *ifname)
{
struct l2tp_net *pn = l2tp_pernet(net);
int hash;
struct hlist_node *walk;
struct l2tp_session *session;

read_lock_bh(&pn->l2tp_session_hlist_lock);
for (hash = 0; hash < L2TP_HASH_SIZE_2; hash++) {
hlist_for_each_entry(session, walk, &pn->l2tp_session_hlist[hash], global_hlist) {
if (!strcmp(session->ifname, ifname)) {
read_unlock_bh(&pn->l2tp_session_hlist_lock);
return session;
}
}
}

read_unlock_bh(&pn->l2tp_session_hlist_lock);

return NULL;
}
EXPORT_SYMBOL_GPL(l2tp_session_find_by_ifname);

/* Lookup a tunnel by id
*/
struct l2tp_tunnel *l2tp_tunnel_find(struct net *net, u32 tunnel_id)
Expand Down Expand Up @@ -758,7 +785,7 @@ int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb,

/* Find the session context */
session = l2tp_session_find(tunnel->l2tp_net, tunnel, session_id);
if (!session) {
if (!session || !session->recv_skb) {
/* Not found? Pass to userspace to deal with */
PRINTK(tunnel->debug, L2TP_MSG_DATA, KERN_INFO,
"%s: no session found (%u/%u). Passing up.\n",
Expand Down Expand Up @@ -1305,6 +1332,23 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
}
EXPORT_SYMBOL_GPL(l2tp_tunnel_create);

/* This function is used by the netlink TUNNEL_DELETE command.
*/
int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel)
{
int err = 0;

/* Force the tunnel socket to close. This will eventually
* cause the tunnel to be deleted via the normal socket close
* mechanisms when userspace closes the tunnel socket.
*/
if ((tunnel->sock != NULL) && (tunnel->sock->sk_socket != NULL))
err = inet_shutdown(tunnel->sock->sk_socket, 2);

return err;
}
EXPORT_SYMBOL_GPL(l2tp_tunnel_delete);

/* Really kill the session.
*/
void l2tp_session_free(struct l2tp_session *session)
Expand Down Expand Up @@ -1349,6 +1393,21 @@ void l2tp_session_free(struct l2tp_session *session)
}
EXPORT_SYMBOL_GPL(l2tp_session_free);

/* This function is used by the netlink SESSION_DELETE command and by
pseudowire modules.
*/
int l2tp_session_delete(struct l2tp_session *session)
{
if (session->session_close != NULL)
(*session->session_close)(session);

l2tp_session_dec_refcount(session);

return 0;
}
EXPORT_SYMBOL_GPL(l2tp_session_delete);


/* We come here whenever a session's send_seq, cookie_len or
* l2specific_len parameters are set.
*/
Expand Down
34 changes: 14 additions & 20 deletions trunk/net/l2tp/l2tp_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,26 +33,6 @@ enum {
L2TP_MSG_DATA = (1 << 3), /* data packets */
};

enum l2tp_pwtype {
L2TP_PWTYPE_NONE = 0x0000,
L2TP_PWTYPE_ETH_VLAN = 0x0004,
L2TP_PWTYPE_ETH = 0x0005,
L2TP_PWTYPE_PPP = 0x0007,
L2TP_PWTYPE_PPP_AC = 0x0008,
L2TP_PWTYPE_IP = 0x000b,
__L2TP_PWTYPE_MAX
};

enum l2tp_l2spec_type {
L2TP_L2SPECTYPE_NONE,
L2TP_L2SPECTYPE_DEFAULT,
};

enum l2tp_encap_type {
L2TP_ENCAPTYPE_UDP,
L2TP_ENCAPTYPE_IP,
};

struct sk_buff;

struct l2tp_stats {
Expand Down Expand Up @@ -87,6 +67,7 @@ struct l2tp_session_cfg {
* control of LNS. */
int debug; /* bitmask of debug message
* categories */
u16 vlan_id; /* VLAN pseudowire only */
u16 offset; /* offset to payload */
u16 l2specific_len; /* Layer 2 specific length */
u16 l2specific_type; /* Layer 2 specific type */
Expand All @@ -98,6 +79,7 @@ struct l2tp_session_cfg {
* (in jiffies) */
int mtu;
int mru;
char *ifname;
};

struct l2tp_session {
Expand All @@ -124,6 +106,7 @@ struct l2tp_session {
atomic_t ref_count;

char name[32]; /* for logging */
char ifname[IFNAMSIZ];
unsigned data_seq:2; /* data sequencing level
* 0 => none, 1 => IP only,
* 2 => all
Expand Down Expand Up @@ -192,6 +175,11 @@ struct l2tp_tunnel {
uint8_t priv[0]; /* private data */
};

struct l2tp_nl_cmd_ops {
int (*session_create)(struct net *net, u32 tunnel_id, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg);
int (*session_delete)(struct l2tp_session *session);
};

static inline void *l2tp_tunnel_priv(struct l2tp_tunnel *tunnel)
{
return &tunnel->priv[0];
Expand Down Expand Up @@ -224,11 +212,14 @@ static inline struct l2tp_tunnel *l2tp_sock_to_tunnel(struct sock *sk)

extern struct l2tp_session *l2tp_session_find(struct net *net, struct l2tp_tunnel *tunnel, u32 session_id);
extern struct l2tp_session *l2tp_session_find_nth(struct l2tp_tunnel *tunnel, int nth);
extern struct l2tp_session *l2tp_session_find_by_ifname(struct net *net, char *ifname);
extern struct l2tp_tunnel *l2tp_tunnel_find(struct net *net, u32 tunnel_id);
extern struct l2tp_tunnel *l2tp_tunnel_find_nth(struct net *net, int nth);

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);
extern int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel);
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);
extern int l2tp_session_delete(struct l2tp_session *session);
extern void l2tp_tunnel_free(struct l2tp_tunnel *tunnel);
extern void l2tp_session_free(struct l2tp_session *session);
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));
Expand All @@ -241,6 +232,9 @@ extern void l2tp_tunnel_destruct(struct sock *sk);
extern void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel);
extern void l2tp_session_set_header_len(struct l2tp_session *session, int version);

extern int l2tp_nl_register_ops(enum l2tp_pwtype pw_type, const struct l2tp_nl_cmd_ops *ops);
extern void l2tp_nl_unregister_ops(enum l2tp_pwtype pw_type);

/* Tunnel reference counts. Incremented per session that is added to
* the tunnel.
*/
Expand Down
Loading

0 comments on commit d93c87f

Please sign in to comment.