diff options
author | Krzysztof Halasa <khc@pm.waw.pl> | 2006-09-26 17:23:45 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-09-26 17:40:24 -0400 |
commit | eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfb (patch) | |
tree | 1d910a9460b76fd85ed02e8b9131270e4977f6f7 /drivers/net/wan/hdlc_ppp.c | |
parent | c226951b93f7cd7c3a10b17384535b617bd43fd0 (diff) |
[PATCH] Modularize generic HDLC
This patch enables building of individual WAN protocol support
routines (parts of generic HDLC) as separate modules.
All protocol-private definitions are moved from hdlc.h file
to protocol drivers. User-space interface and interface
between generic HDLC and underlying low-level HDLC drivers
are unchanged.
Signed-off-by: Krzysztof Halasa <khc@pm.waw.pl>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/wan/hdlc_ppp.c')
-rw-r--r-- | drivers/net/wan/hdlc_ppp.c | 77 |
1 files changed, 61 insertions, 16 deletions
diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c index fbaab5bf71eb..e9f717070fde 100644 --- a/drivers/net/wan/hdlc_ppp.c +++ b/drivers/net/wan/hdlc_ppp.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Generic HDLC support routines for Linux | 2 | * Generic HDLC support routines for Linux |
3 | * Point-to-point protocol support | 3 | * Point-to-point protocol support |
4 | * | 4 | * |
5 | * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl> | 5 | * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms of version 2 of the GNU General Public License | 8 | * under the terms of version 2 of the GNU General Public License |
@@ -22,6 +22,21 @@ | |||
22 | #include <linux/lapb.h> | 22 | #include <linux/lapb.h> |
23 | #include <linux/rtnetlink.h> | 23 | #include <linux/rtnetlink.h> |
24 | #include <linux/hdlc.h> | 24 | #include <linux/hdlc.h> |
25 | #include <net/syncppp.h> | ||
26 | |||
27 | struct ppp_state { | ||
28 | struct ppp_device pppdev; | ||
29 | struct ppp_device *syncppp_ptr; | ||
30 | int (*old_change_mtu)(struct net_device *dev, int new_mtu); | ||
31 | }; | ||
32 | |||
33 | static int ppp_ioctl(struct net_device *dev, struct ifreq *ifr); | ||
34 | |||
35 | |||
36 | static inline struct ppp_state* state(hdlc_device *hdlc) | ||
37 | { | ||
38 | return(struct ppp_state *)(hdlc->state); | ||
39 | } | ||
25 | 40 | ||
26 | 41 | ||
27 | static int ppp_open(struct net_device *dev) | 42 | static int ppp_open(struct net_device *dev) |
@@ -30,16 +45,16 @@ static int ppp_open(struct net_device *dev) | |||
30 | void *old_ioctl; | 45 | void *old_ioctl; |
31 | int result; | 46 | int result; |
32 | 47 | ||
33 | dev->priv = &hdlc->state.ppp.syncppp_ptr; | 48 | dev->priv = &state(hdlc)->syncppp_ptr; |
34 | hdlc->state.ppp.syncppp_ptr = &hdlc->state.ppp.pppdev; | 49 | state(hdlc)->syncppp_ptr = &state(hdlc)->pppdev; |
35 | hdlc->state.ppp.pppdev.dev = dev; | 50 | state(hdlc)->pppdev.dev = dev; |
36 | 51 | ||
37 | old_ioctl = dev->do_ioctl; | 52 | old_ioctl = dev->do_ioctl; |
38 | hdlc->state.ppp.old_change_mtu = dev->change_mtu; | 53 | state(hdlc)->old_change_mtu = dev->change_mtu; |
39 | sppp_attach(&hdlc->state.ppp.pppdev); | 54 | sppp_attach(&state(hdlc)->pppdev); |
40 | /* sppp_attach nukes them. We don't need syncppp's ioctl */ | 55 | /* sppp_attach nukes them. We don't need syncppp's ioctl */ |
41 | dev->do_ioctl = old_ioctl; | 56 | dev->do_ioctl = old_ioctl; |
42 | hdlc->state.ppp.pppdev.sppp.pp_flags &= ~PP_CISCO; | 57 | state(hdlc)->pppdev.sppp.pp_flags &= ~PP_CISCO; |
43 | dev->type = ARPHRD_PPP; | 58 | dev->type = ARPHRD_PPP; |
44 | result = sppp_open(dev); | 59 | result = sppp_open(dev); |
45 | if (result) { | 60 | if (result) { |
@@ -59,7 +74,7 @@ static void ppp_close(struct net_device *dev) | |||
59 | sppp_close(dev); | 74 | sppp_close(dev); |
60 | sppp_detach(dev); | 75 | sppp_detach(dev); |
61 | dev->rebuild_header = NULL; | 76 | dev->rebuild_header = NULL; |
62 | dev->change_mtu = hdlc->state.ppp.old_change_mtu; | 77 | dev->change_mtu = state(hdlc)->old_change_mtu; |
63 | dev->mtu = HDLC_MAX_MTU; | 78 | dev->mtu = HDLC_MAX_MTU; |
64 | dev->hard_header_len = 16; | 79 | dev->hard_header_len = 16; |
65 | } | 80 | } |
@@ -73,13 +88,24 @@ static __be16 ppp_type_trans(struct sk_buff *skb, struct net_device *dev) | |||
73 | 88 | ||
74 | 89 | ||
75 | 90 | ||
76 | int hdlc_ppp_ioctl(struct net_device *dev, struct ifreq *ifr) | 91 | static struct hdlc_proto proto = { |
92 | .open = ppp_open, | ||
93 | .close = ppp_close, | ||
94 | .type_trans = ppp_type_trans, | ||
95 | .ioctl = ppp_ioctl, | ||
96 | .module = THIS_MODULE, | ||
97 | }; | ||
98 | |||
99 | |||
100 | static int ppp_ioctl(struct net_device *dev, struct ifreq *ifr) | ||
77 | { | 101 | { |
78 | hdlc_device *hdlc = dev_to_hdlc(dev); | 102 | hdlc_device *hdlc = dev_to_hdlc(dev); |
79 | int result; | 103 | int result; |
80 | 104 | ||
81 | switch (ifr->ifr_settings.type) { | 105 | switch (ifr->ifr_settings.type) { |
82 | case IF_GET_PROTO: | 106 | case IF_GET_PROTO: |
107 | if (dev_to_hdlc(dev)->proto != &proto) | ||
108 | return -EINVAL; | ||
83 | ifr->ifr_settings.type = IF_PROTO_PPP; | 109 | ifr->ifr_settings.type = IF_PROTO_PPP; |
84 | return 0; /* return protocol only, no settable parameters */ | 110 | return 0; /* return protocol only, no settable parameters */ |
85 | 111 | ||
@@ -96,13 +122,10 @@ int hdlc_ppp_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
96 | if (result) | 122 | if (result) |
97 | return result; | 123 | return result; |
98 | 124 | ||
99 | hdlc_proto_detach(hdlc); | 125 | result = attach_hdlc_protocol(dev, &proto, NULL, |
100 | memset(&hdlc->proto, 0, sizeof(hdlc->proto)); | 126 | sizeof(struct ppp_state)); |
101 | 127 | if (result) | |
102 | hdlc->proto.open = ppp_open; | 128 | return result; |
103 | hdlc->proto.close = ppp_close; | ||
104 | hdlc->proto.type_trans = ppp_type_trans; | ||
105 | hdlc->proto.id = IF_PROTO_PPP; | ||
106 | dev->hard_start_xmit = hdlc->xmit; | 129 | dev->hard_start_xmit = hdlc->xmit; |
107 | dev->hard_header = NULL; | 130 | dev->hard_header = NULL; |
108 | dev->type = ARPHRD_PPP; | 131 | dev->type = ARPHRD_PPP; |
@@ -113,3 +136,25 @@ int hdlc_ppp_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
113 | 136 | ||
114 | return -EINVAL; | 137 | return -EINVAL; |
115 | } | 138 | } |
139 | |||
140 | |||
141 | static int __init mod_init(void) | ||
142 | { | ||
143 | register_hdlc_protocol(&proto); | ||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | |||
148 | |||
149 | static void __exit mod_exit(void) | ||
150 | { | ||
151 | unregister_hdlc_protocol(&proto); | ||
152 | } | ||
153 | |||
154 | |||
155 | module_init(mod_init); | ||
156 | module_exit(mod_exit); | ||
157 | |||
158 | MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); | ||
159 | MODULE_DESCRIPTION("PPP protocol support for generic HDLC"); | ||
160 | MODULE_LICENSE("GPL v2"); | ||