2121#include <linux/skbuff.h>
2222#include <net/x25device.h>
2323
24+ struct x25_state {
25+ x25_hdlc_proto settings ;
26+ };
27+
2428static int x25_ioctl (struct net_device * dev , struct ifreq * ifr );
2529
30+ static struct x25_state * state (hdlc_device * hdlc )
31+ {
32+ return hdlc -> state ;
33+ }
34+
2635/* These functions are callbacks called by LAPB layer */
2736
2837static void x25_connect_disconnect (struct net_device * dev , int reason , int code )
@@ -131,7 +140,6 @@ static netdev_tx_t x25_xmit(struct sk_buff *skb, struct net_device *dev)
131140
132141static int x25_open (struct net_device * dev )
133142{
134- int result ;
135143 static const struct lapb_register_struct cb = {
136144 .connect_confirmation = x25_connected ,
137145 .connect_indication = x25_connected ,
@@ -140,10 +148,33 @@ static int x25_open(struct net_device *dev)
140148 .data_indication = x25_data_indication ,
141149 .data_transmit = x25_data_transmit ,
142150 };
151+ hdlc_device * hdlc = dev_to_hdlc (dev );
152+ struct lapb_parms_struct params ;
153+ int result ;
143154
144155 result = lapb_register (dev , & cb );
145156 if (result != LAPB_OK )
146157 return result ;
158+
159+ result = lapb_getparms (dev , & params );
160+ if (result != LAPB_OK )
161+ return result ;
162+
163+ if (state (hdlc )-> settings .dce )
164+ params .mode = params .mode | LAPB_DCE ;
165+
166+ if (state (hdlc )-> settings .modulo == 128 )
167+ params .mode = params .mode | LAPB_EXTENDED ;
168+
169+ params .window = state (hdlc )-> settings .window ;
170+ params .t1 = state (hdlc )-> settings .t1 ;
171+ params .t2 = state (hdlc )-> settings .t2 ;
172+ params .n2 = state (hdlc )-> settings .n2 ;
173+
174+ result = lapb_setparms (dev , & params );
175+ if (result != LAPB_OK )
176+ return result ;
177+
147178 return 0 ;
148179}
149180
@@ -186,15 +217,24 @@ static struct hdlc_proto proto = {
186217
187218static int x25_ioctl (struct net_device * dev , struct ifreq * ifr )
188219{
220+ x25_hdlc_proto __user * x25_s = ifr -> ifr_settings .ifs_ifsu .x25 ;
221+ const size_t size = sizeof (x25_hdlc_proto );
189222 hdlc_device * hdlc = dev_to_hdlc (dev );
223+ x25_hdlc_proto new_settings ;
190224 int result ;
191225
192226 switch (ifr -> ifr_settings .type ) {
193227 case IF_GET_PROTO :
194228 if (dev_to_hdlc (dev )-> proto != & proto )
195229 return - EINVAL ;
196230 ifr -> ifr_settings .type = IF_PROTO_X25 ;
197- return 0 ; /* return protocol only, no settable parameters */
231+ if (ifr -> ifr_settings .size < size ) {
232+ ifr -> ifr_settings .size = size ; /* data size wanted */
233+ return - ENOBUFS ;
234+ }
235+ if (copy_to_user (x25_s , & state (hdlc )-> settings , size ))
236+ return - EFAULT ;
237+ return 0 ;
198238
199239 case IF_PROTO_X25 :
200240 if (!capable (CAP_NET_ADMIN ))
@@ -203,12 +243,46 @@ static int x25_ioctl(struct net_device *dev, struct ifreq *ifr)
203243 if (dev -> flags & IFF_UP )
204244 return - EBUSY ;
205245
246+ /* backward compatibility */
247+ if (ifr -> ifr_settings .size = 0 ) {
248+ new_settings .dce = 0 ;
249+ new_settings .modulo = 8 ;
250+ new_settings .window = 7 ;
251+ new_settings .t1 = 3 ;
252+ new_settings .t2 = 1 ;
253+ new_settings .n2 = 10 ;
254+ }
255+ else {
256+ if (copy_from_user (& new_settings , x25_s , size ))
257+ return - EFAULT ;
258+
259+ if ((new_settings .dce != 0 &&
260+ new_settings .dce != 1 ) ||
261+ (new_settings .modulo != 8 &&
262+ new_settings .modulo != 128 ) ||
263+ new_settings .window < 1 ||
264+ (new_settings .modulo == 8 &&
265+ new_settings .window > 7 ) ||
266+ (new_settings .modulo == 128 &&
267+ new_settings .window > 127 ) ||
268+ new_settings .t1 < 1 ||
269+ new_settings .t1 > 255 ||
270+ new_settings .t2 < 1 ||
271+ new_settings .t2 > 255 ||
272+ new_settings .n2 < 1 ||
273+ new_settings .n2 > 255 )
274+ return - EINVAL ;
275+ }
276+
206277 result = hdlc -> attach (dev , ENCODING_NRZ ,PARITY_CRC16_PR1_CCITT );
207278 if (result )
208279 return result ;
209280
210- if ((result = attach_hdlc_protocol (dev , & proto , 0 )))
281+ if ((result = attach_hdlc_protocol (dev , & proto ,
282+ sizeof (struct x25_state ))))
211283 return result ;
284+
285+ memcpy (& state (hdlc )-> settings , & new_settings , size );
212286 dev -> type = ARPHRD_X25 ;
213287 call_netdevice_notifiers (NETDEV_POST_TYPE_CHANGE , dev );
214288 netif_dormant_off (dev );
0 commit comments