diff options
author | James Chapman <jchapman@katalix.com> | 2010-04-02 02:18:49 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-04-03 17:56:03 -0400 |
commit | f7faffa3ff8ef6ae712ef16312b8a2aa7a1c95fe (patch) | |
tree | 2b9d1bd7ed08767a02cd282a876970b34241f7af /net/l2tp/l2tp_ppp.c | |
parent | 9345471bca96d00d4196b3dcc4a5625f1bfae247 (diff) |
l2tp: Add L2TPv3 protocol support
The L2TPv3 protocol changes the layout of the L2TP packet
header. Tunnel and session ids change from 16-bit to 32-bit values,
data sequence numbers change from 16-bit to 24-bit values and PPP-specific
fields are moved into protocol-specific subheaders.
Although this patch introduces L2TPv3 protocol support, there are no
userspace interfaces to create L2TPv3 sessions yet.
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>
Diffstat (limited to 'net/l2tp/l2tp_ppp.c')
-rw-r--r-- | net/l2tp/l2tp_ppp.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index 3ad290dd830a..bee5b1413ec0 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c | |||
@@ -670,7 +670,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, | |||
670 | 670 | ||
671 | /* Check that this session doesn't already exist */ | 671 | /* Check that this session doesn't already exist */ |
672 | error = -EEXIST; | 672 | error = -EEXIST; |
673 | session = l2tp_session_find(tunnel, sp->pppol2tp.s_session); | 673 | session = l2tp_session_find(sock_net(sk), tunnel, sp->pppol2tp.s_session); |
674 | if (session != NULL) | 674 | if (session != NULL) |
675 | goto end; | 675 | goto end; |
676 | 676 | ||
@@ -678,7 +678,6 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, | |||
678 | * headers. | 678 | * headers. |
679 | */ | 679 | */ |
680 | cfg.mtu = cfg.mru = 1500 - PPPOL2TP_HEADER_OVERHEAD; | 680 | cfg.mtu = cfg.mru = 1500 - PPPOL2TP_HEADER_OVERHEAD; |
681 | cfg.hdr_len = PPPOL2TP_L2TP_HDR_SIZE_NOSEQ; | ||
682 | cfg.debug = tunnel->debug; | 681 | cfg.debug = tunnel->debug; |
683 | 682 | ||
684 | /* Allocate and initialize a new session context. */ | 683 | /* Allocate and initialize a new session context. */ |
@@ -999,7 +998,7 @@ static int pppol2tp_tunnel_ioctl(struct l2tp_tunnel *tunnel, | |||
999 | if (stats.session_id != 0) { | 998 | if (stats.session_id != 0) { |
1000 | /* resend to session ioctl handler */ | 999 | /* resend to session ioctl handler */ |
1001 | struct l2tp_session *session = | 1000 | struct l2tp_session *session = |
1002 | l2tp_session_find(tunnel, stats.session_id); | 1001 | l2tp_session_find(sock_net(sk), tunnel, stats.session_id); |
1003 | if (session != NULL) | 1002 | if (session != NULL) |
1004 | err = pppol2tp_session_ioctl(session, cmd, arg); | 1003 | err = pppol2tp_session_ioctl(session, cmd, arg); |
1005 | else | 1004 | else |
@@ -1375,6 +1374,8 @@ end: | |||
1375 | 1374 | ||
1376 | /***************************************************************************** | 1375 | /***************************************************************************** |
1377 | * /proc filesystem for debug | 1376 | * /proc filesystem for debug |
1377 | * Since the original pppol2tp driver provided /proc/net/pppol2tp for | ||
1378 | * L2TPv2, we dump only L2TPv2 tunnels and sessions here. | ||
1378 | *****************************************************************************/ | 1379 | *****************************************************************************/ |
1379 | 1380 | ||
1380 | static unsigned int pppol2tp_net_id; | 1381 | static unsigned int pppol2tp_net_id; |
@@ -1391,14 +1392,24 @@ struct pppol2tp_seq_data { | |||
1391 | 1392 | ||
1392 | static void pppol2tp_next_tunnel(struct net *net, struct pppol2tp_seq_data *pd) | 1393 | static void pppol2tp_next_tunnel(struct net *net, struct pppol2tp_seq_data *pd) |
1393 | { | 1394 | { |
1394 | pd->tunnel = l2tp_tunnel_find_nth(net, pd->tunnel_idx); | 1395 | for (;;) { |
1395 | pd->tunnel_idx++; | 1396 | pd->tunnel = l2tp_tunnel_find_nth(net, pd->tunnel_idx); |
1397 | pd->tunnel_idx++; | ||
1398 | |||
1399 | if (pd->tunnel == NULL) | ||
1400 | break; | ||
1401 | |||
1402 | /* Ignore L2TPv3 tunnels */ | ||
1403 | if (pd->tunnel->version < 3) | ||
1404 | break; | ||
1405 | } | ||
1396 | } | 1406 | } |
1397 | 1407 | ||
1398 | static void pppol2tp_next_session(struct net *net, struct pppol2tp_seq_data *pd) | 1408 | static void pppol2tp_next_session(struct net *net, struct pppol2tp_seq_data *pd) |
1399 | { | 1409 | { |
1400 | pd->session = l2tp_session_find_nth(pd->tunnel, pd->session_idx); | 1410 | pd->session = l2tp_session_find_nth(pd->tunnel, pd->session_idx); |
1401 | pd->session_idx++; | 1411 | pd->session_idx++; |
1412 | |||
1402 | if (pd->session == NULL) { | 1413 | if (pd->session == NULL) { |
1403 | pd->session_idx = 0; | 1414 | pd->session_idx = 0; |
1404 | pppol2tp_next_tunnel(net, pd); | 1415 | pppol2tp_next_tunnel(net, pd); |