aboutsummaryrefslogtreecommitdiffstats
path: root/net/l2tp/l2tp_ppp.c
diff options
context:
space:
mode:
authorJames Chapman <jchapman@katalix.com>2010-04-02 02:19:10 -0400
committerDavid S. Miller <davem@davemloft.net>2010-04-03 17:56:05 -0400
commit309795f4bec2d69cd507a631f82065c2198a0825 (patch)
treeb3676be9a8f65f0d828a07e3bd6906bf7cd7b664 /net/l2tp/l2tp_ppp.c
parentf408e0ce40270559ef80f231843c93baa9947bc5 (diff)
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>
Diffstat (limited to 'net/l2tp/l2tp_ppp.c')
-rw-r--r--net/l2tp/l2tp_ppp.c162
1 files changed, 139 insertions, 23 deletions
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index 63fc62baeeb9..d64f081f2b1c 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -87,6 +87,7 @@
87#include <linux/hash.h> 87#include <linux/hash.h>
88#include <linux/sort.h> 88#include <linux/sort.h>
89#include <linux/proc_fs.h> 89#include <linux/proc_fs.h>
90#include <linux/l2tp.h>
90#include <linux/nsproxy.h> 91#include <linux/nsproxy.h>
91#include <net/net_namespace.h> 92#include <net/net_namespace.h>
92#include <net/netns/generic.h> 93#include <net/netns/generic.h>
@@ -656,17 +657,23 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
656 if (tunnel_id == 0) 657 if (tunnel_id == 0)
657 goto end; 658 goto end;
658 659
660 tunnel = l2tp_tunnel_find(sock_net(sk), tunnel_id);
661
659 /* Special case: create tunnel context if session_id and 662 /* Special case: create tunnel context if session_id and
660 * peer_session_id is 0. Otherwise look up tunnel using supplied 663 * peer_session_id is 0. Otherwise look up tunnel using supplied
661 * tunnel id. 664 * tunnel id.
662 */ 665 */
663 if ((session_id == 0) && (peer_session_id == 0)) { 666 if ((session_id == 0) && (peer_session_id == 0)) {
664 error = l2tp_tunnel_create(sock_net(sk), fd, ver, tunnel_id, peer_tunnel_id, NULL, &tunnel); 667 if (tunnel == NULL) {
665 if (error < 0) 668 struct l2tp_tunnel_cfg tcfg = {
666 goto end; 669 .encap = L2TP_ENCAPTYPE_UDP,
670 .debug = 0,
671 };
672 error = l2tp_tunnel_create(sock_net(sk), fd, ver, tunnel_id, peer_tunnel_id, &tcfg, &tunnel);
673 if (error < 0)
674 goto end;
675 }
667 } else { 676 } else {
668 tunnel = l2tp_tunnel_find(sock_net(sk), tunnel_id);
669
670 /* Error if we can't find the tunnel */ 677 /* Error if we can't find the tunnel */
671 error = -ENOENT; 678 error = -ENOENT;
672 if (tunnel == NULL) 679 if (tunnel == NULL)
@@ -680,28 +687,46 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
680 if (tunnel->recv_payload_hook == NULL) 687 if (tunnel->recv_payload_hook == NULL)
681 tunnel->recv_payload_hook = pppol2tp_recv_payload_hook; 688 tunnel->recv_payload_hook = pppol2tp_recv_payload_hook;
682 689
683 /* Check that this session doesn't already exist */ 690 if (tunnel->peer_tunnel_id == 0) {
684 error = -EEXIST; 691 if (ver == 2)
685 session = l2tp_session_find(sock_net(sk), tunnel, session_id); 692 tunnel->peer_tunnel_id = sp->pppol2tp.d_tunnel;
686 if (session != NULL) 693 else
687 goto end; 694 tunnel->peer_tunnel_id = sp3->pppol2tp.d_tunnel;
688 695 }
689 /* Default MTU values. */
690 if (cfg.mtu == 0)
691 cfg.mtu = 1500 - PPPOL2TP_HEADER_OVERHEAD;
692 if (cfg.mru == 0)
693 cfg.mru = cfg.mtu;
694 cfg.debug = tunnel->debug;
695 696
696 /* Allocate and initialize a new session context. */ 697 /* Create session if it doesn't already exist. We handle the
697 session = l2tp_session_create(sizeof(struct pppol2tp_session), 698 * case where a session was previously created by the netlink
698 tunnel, session_id, 699 * interface by checking that the session doesn't already have
699 peer_session_id, &cfg); 700 * a socket and its tunnel socket are what we expect. If any
701 * of those checks fail, return EEXIST to the caller.
702 */
703 session = l2tp_session_find(sock_net(sk), tunnel, session_id);
700 if (session == NULL) { 704 if (session == NULL) {
701 error = -ENOMEM; 705 /* Default MTU must allow space for UDP/L2TP/PPP
702 goto end; 706 * headers.
707 */
708 cfg.mtu = cfg.mru = 1500 - PPPOL2TP_HEADER_OVERHEAD;
709
710 /* Allocate and initialize a new session context. */
711 session = l2tp_session_create(sizeof(struct pppol2tp_session),
712 tunnel, session_id,
713 peer_session_id, &cfg);
714 if (session == NULL) {
715 error = -ENOMEM;
716 goto end;
717 }
718 } else {
719 ps = l2tp_session_priv(session);
720 error = -EEXIST;
721 if (ps->sock != NULL)
722 goto end;
723
724 /* consistency checks */
725 if (ps->tunnel_sock != tunnel->sock)
726 goto end;
703 } 727 }
704 728
729 /* Associate session with its PPPoL2TP socket */
705 ps = l2tp_session_priv(session); 730 ps = l2tp_session_priv(session);
706 ps->owner = current->pid; 731 ps->owner = current->pid;
707 ps->sock = sk; 732 ps->sock = sk;
@@ -764,6 +789,74 @@ end:
764 return error; 789 return error;
765} 790}
766 791
792#ifdef CONFIG_L2TP_V3
793
794/* Called when creating sessions via the netlink interface.
795 */
796static int pppol2tp_session_create(struct net *net, u32 tunnel_id, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg)
797{
798 int error;
799 struct l2tp_tunnel *tunnel;
800 struct l2tp_session *session;
801 struct pppol2tp_session *ps;
802
803 tunnel = l2tp_tunnel_find(net, tunnel_id);
804
805 /* Error if we can't find the tunnel */
806 error = -ENOENT;
807 if (tunnel == NULL)
808 goto out;
809
810 /* Error if tunnel socket is not prepped */
811 if (tunnel->sock == NULL)
812 goto out;
813
814 /* Check that this session doesn't already exist */
815 error = -EEXIST;
816 session = l2tp_session_find(net, tunnel, session_id);
817 if (session != NULL)
818 goto out;
819
820 /* Default MTU values. */
821 if (cfg->mtu == 0)
822 cfg->mtu = 1500 - PPPOL2TP_HEADER_OVERHEAD;
823 if (cfg->mru == 0)
824 cfg->mru = cfg->mtu;
825
826 /* Allocate and initialize a new session context. */
827 error = -ENOMEM;
828 session = l2tp_session_create(sizeof(struct pppol2tp_session),
829 tunnel, session_id,
830 peer_session_id, cfg);
831 if (session == NULL)
832 goto out;
833
834 ps = l2tp_session_priv(session);
835 ps->tunnel_sock = tunnel->sock;
836
837 PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
838 "%s: created\n", session->name);
839
840 error = 0;
841
842out:
843 return error;
844}
845
846/* Called when deleting sessions via the netlink interface.
847 */
848static int pppol2tp_session_delete(struct l2tp_session *session)
849{
850 struct pppol2tp_session *ps = l2tp_session_priv(session);
851
852 if (ps->sock == NULL)
853 l2tp_session_dec_refcount(session);
854
855 return 0;
856}
857
858#endif /* CONFIG_L2TP_V3 */
859
767/* getname() support. 860/* getname() support.
768 */ 861 */
769static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr, 862static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr,
@@ -1660,6 +1753,15 @@ static struct pppox_proto pppol2tp_proto = {
1660 .ioctl = pppol2tp_ioctl 1753 .ioctl = pppol2tp_ioctl
1661}; 1754};
1662 1755
1756#ifdef CONFIG_L2TP_V3
1757
1758static const struct l2tp_nl_cmd_ops pppol2tp_nl_cmd_ops = {
1759 .session_create = pppol2tp_session_create,
1760 .session_delete = pppol2tp_session_delete,
1761};
1762
1763#endif /* CONFIG_L2TP_V3 */
1764
1663static int __init pppol2tp_init(void) 1765static int __init pppol2tp_init(void)
1664{ 1766{
1665 int err; 1767 int err;
@@ -1676,11 +1778,22 @@ static int __init pppol2tp_init(void)
1676 if (err) 1778 if (err)
1677 goto out_unregister_pppol2tp_proto; 1779 goto out_unregister_pppol2tp_proto;
1678 1780
1781#ifdef CONFIG_L2TP_V3
1782 err = l2tp_nl_register_ops(L2TP_PWTYPE_PPP, &pppol2tp_nl_cmd_ops);
1783 if (err)
1784 goto out_unregister_pppox;
1785#endif
1786
1679 printk(KERN_INFO "PPPoL2TP kernel driver, %s\n", 1787 printk(KERN_INFO "PPPoL2TP kernel driver, %s\n",
1680 PPPOL2TP_DRV_VERSION); 1788 PPPOL2TP_DRV_VERSION);
1681 1789
1682out: 1790out:
1683 return err; 1791 return err;
1792
1793#ifdef CONFIG_L2TP_V3
1794out_unregister_pppox:
1795 unregister_pppox_proto(PX_PROTO_OL2TP);
1796#endif
1684out_unregister_pppol2tp_proto: 1797out_unregister_pppol2tp_proto:
1685 proto_unregister(&pppol2tp_sk_proto); 1798 proto_unregister(&pppol2tp_sk_proto);
1686out_unregister_pppol2tp_pernet: 1799out_unregister_pppol2tp_pernet:
@@ -1690,6 +1803,9 @@ out_unregister_pppol2tp_pernet:
1690 1803
1691static void __exit pppol2tp_exit(void) 1804static void __exit pppol2tp_exit(void)
1692{ 1805{
1806#ifdef CONFIG_L2TP_V3
1807 l2tp_nl_unregister_ops(L2TP_PWTYPE_PPP);
1808#endif
1693 unregister_pppox_proto(PX_PROTO_OL2TP); 1809 unregister_pppox_proto(PX_PROTO_OL2TP);
1694 proto_unregister(&pppol2tp_sk_proto); 1810 proto_unregister(&pppol2tp_sk_proto);
1695 unregister_pernet_device(&pppol2tp_net_ops); 1811 unregister_pernet_device(&pppol2tp_net_ops);