[kernel] generic-2.6/2.6.24: refresh patches
[openwrt/svn-archive/archive.git] / target / linux / generic-2.6 / patches-2.6.24 / 601-br2684-routed-support.patch
1 --- a/include/linux/atmbr2684.h
2 +++ b/include/linux/atmbr2684.h
3 @@ -14,6 +14,9 @@
4 #define BR2684_MEDIA_FDDI (3)
5 #define BR2684_MEDIA_802_6 (4) /* 802.6 */
6
7 + /* used only at device creation: */
8 +#define BR2684_FLAG_ROUTED (1<<16) /* payload is routed, not bridged */
9 +
10 /*
11 * Is there FCS inbound on this VC? This currently isn't supported.
12 */
13 @@ -36,15 +39,22 @@
14 #define BR2684_ENCAPS_AUTODETECT (2) /* Unsuported */
15
16 /*
17 + * Is this VC bridged or routed?
18 + */
19 +
20 +#define BR2684_PAYLOAD_ROUTED (0)
21 +#define BR2684_PAYLOAD_BRIDGED (1)
22 +
23 +/*
24 * This is for the ATM_NEWBACKENDIF call - these are like socket families:
25 * the first element of the structure is the backend number and the rest
26 * is per-backend specific
27 */
28 struct atm_newif_br2684 {
29 - atm_backend_t backend_num; /* ATM_BACKEND_BR2684 */
30 - int media; /* BR2684_MEDIA_* */
31 - char ifname[IFNAMSIZ];
32 - int mtu;
33 + atm_backend_t backend_num; /* ATM_BACKEND_BR2684 */
34 + int media; /* BR2684_MEDIA_*, flags in upper bits */
35 + char ifname[IFNAMSIZ];
36 + int mtu;
37 };
38
39 /*
40 @@ -55,10 +65,10 @@ struct atm_newif_br2684 {
41 #define BR2684_FIND_BYNUM (1)
42 #define BR2684_FIND_BYIFNAME (2)
43 struct br2684_if_spec {
44 - int method; /* BR2684_FIND_* */
45 + int method; /* BR2684_FIND_* */
46 union {
47 - char ifname[IFNAMSIZ];
48 - int devnum;
49 + char ifname[IFNAMSIZ];
50 + int devnum;
51 } spec;
52 };
53
54 @@ -68,16 +78,16 @@ struct br2684_if_spec {
55 * is per-backend specific
56 */
57 struct atm_backend_br2684 {
58 - atm_backend_t backend_num; /* ATM_BACKEND_BR2684 */
59 + atm_backend_t backend_num; /* ATM_BACKEND_BR2684 */
60 struct br2684_if_spec ifspec;
61 - int fcs_in; /* BR2684_FCSIN_* */
62 - int fcs_out; /* BR2684_FCSOUT_* */
63 - int fcs_auto; /* 1: fcs_{in,out} disabled if no FCS rx'ed */
64 - int encaps; /* BR2684_ENCAPS_* */
65 - int has_vpiid; /* 1: use vpn_id - Unsupported */
66 - __u8 vpn_id[7];
67 - int send_padding; /* unsupported */
68 - int min_size; /* we will pad smaller packets than this */
69 + int fcs_in; /* BR2684_FCSIN_* */
70 + int fcs_out; /* BR2684_FCSOUT_* */
71 + int fcs_auto; /* 1: fcs_{in,out} disabled if no FCS rx'ed */
72 + int encaps; /* BR2684_ENCAPS_* */
73 + int has_vpiid; /* 1: use vpn_id - Unsupported */
74 + __u8 vpn_id[7];
75 + int send_padding; /* unsupported */
76 + int min_size; /* we will pad smaller packets than this */
77 };
78
79 /*
80 @@ -86,8 +96,8 @@ struct atm_backend_br2684 {
81 * efficient per-if in/out filters, this support will be removed
82 */
83 struct br2684_filter {
84 - __be32 prefix; /* network byte order */
85 - __be32 netmask; /* 0 = disable filter */
86 + __be32 prefix; /* network byte order */
87 + __be32 netmask; /* 0 = disable filter */
88 };
89
90 struct br2684_filter_set {
91 @@ -95,7 +105,13 @@ struct br2684_filter_set {
92 struct br2684_filter filter;
93 };
94
95 +enum br2684_payload {
96 + p_routed = BR2684_PAYLOAD_ROUTED,
97 + p_bridged = BR2684_PAYLOAD_BRIDGED,
98 +};
99 +
100 #define BR2684_SETFILT _IOW( 'a', ATMIOC_BACKEND + 0, \
101 struct br2684_filter_set)
102
103 #endif /* _LINUX_ATMBR2684_H */
104 +
105 --- a/net/atm/br2684.c
106 +++ b/net/atm/br2684.c
107 @@ -1,8 +1,10 @@
108 /*
109 -Experimental ethernet netdevice using ATM AAL5 as underlying carrier
110 -(RFC1483 obsoleted by RFC2684) for Linux 2.4
111 -Author: Marcell GAL, 2000, XDSL Ltd, Hungary
112 -*/
113 + * Ethernet netdevice using ATM AAL5 as underlying carrier
114 + * (RFC1483 obsoleted by RFC2684) for Linux
115 + *
116 + * Authors: Marcell GAL, 2000, XDSL Ltd, Hungary
117 + * Eric Kinzie, 2006-2007, US Naval Research Laboratory
118 + */
119
120 #include <linux/module.h>
121 #include <linux/init.h>
122 @@ -39,21 +41,35 @@ static void skb_debug(const struct sk_bu
123 #define skb_debug(skb) do {} while (0)
124 #endif
125
126 +#define BR2684_ETHERTYPE_LEN 2
127 +#define BR2684_PAD_LEN 2
128 +
129 +#define LLC 0xaa, 0xaa, 0x03
130 +#define SNAP_BRIDGED 0x00, 0x80, 0xc2
131 +#define SNAP_ROUTED 0x00, 0x00, 0x00
132 +#define PID_ETHERNET 0x00, 0x07
133 +#define ETHERTYPE_IPV4 0x08, 0x00
134 +#define ETHERTYPE_IPV6 0x86, 0xdd
135 +#define PAD_BRIDGED 0x00, 0x00
136 +
137 +static unsigned char ethertype_ipv4[] = { ETHERTYPE_IPV4 };
138 +static unsigned char ethertype_ipv6[] = { ETHERTYPE_IPV6 };
139 static unsigned char llc_oui_pid_pad[] =
140 - { 0xAA, 0xAA, 0x03, 0x00, 0x80, 0xC2, 0x00, 0x07, 0x00, 0x00 };
141 -#define PADLEN (2)
142 + { LLC, SNAP_BRIDGED, PID_ETHERNET, PAD_BRIDGED };
143 +static unsigned char llc_oui_ipv4[] = { LLC, SNAP_ROUTED, ETHERTYPE_IPV4 };
144 +static unsigned char llc_oui_ipv6[] = { LLC, SNAP_ROUTED, ETHERTYPE_IPV6 };
145
146 enum br2684_encaps {
147 - e_vc = BR2684_ENCAPS_VC,
148 + e_vc = BR2684_ENCAPS_VC,
149 e_llc = BR2684_ENCAPS_LLC,
150 };
151
152 struct br2684_vcc {
153 - struct atm_vcc *atmvcc;
154 + struct atm_vcc *atmvcc;
155 struct net_device *device;
156 - /* keep old push,pop functions for chaining */
157 - void (*old_push)(struct atm_vcc *vcc,struct sk_buff *skb);
158 - /* void (*old_pop)(struct atm_vcc *vcc,struct sk_buff *skb); */
159 + /* keep old push, pop functions for chaining */
160 + void (*old_push) (struct atm_vcc * vcc, struct sk_buff * skb);
161 + /* void (*old_pop)(struct atm_vcc *vcc, struct sk_buff *skb); */
162 enum br2684_encaps encaps;
163 struct list_head brvccs;
164 #ifdef CONFIG_ATM_BR2684_IPFILTER
165 @@ -66,9 +82,10 @@ struct br2684_dev {
166 struct net_device *net_dev;
167 struct list_head br2684_devs;
168 int number;
169 - struct list_head brvccs; /* one device <=> one vcc (before xmas) */
170 + struct list_head brvccs; /* one device <=> one vcc (before xmas) */
171 struct net_device_stats stats;
172 int mac_was_set;
173 + enum br2684_payload payload;
174 };
175
176 /*
177 @@ -84,7 +101,7 @@ static LIST_HEAD(br2684_devs);
178
179 static inline struct br2684_dev *BRPRIV(const struct net_device *net_dev)
180 {
181 - return (struct br2684_dev *) net_dev->priv;
182 + return (struct br2684_dev *)net_dev->priv;
183 }
184
185 static inline struct net_device *list_entry_brdev(const struct list_head *le)
186 @@ -94,7 +111,7 @@ static inline struct net_device *list_en
187
188 static inline struct br2684_vcc *BR2684_VCC(const struct atm_vcc *atmvcc)
189 {
190 - return (struct br2684_vcc *) (atmvcc->user_back);
191 + return (struct br2684_vcc *)(atmvcc->user_back);
192 }
193
194 static inline struct br2684_vcc *list_entry_brvcc(const struct list_head *le)
195 @@ -132,10 +149,11 @@ static struct net_device *br2684_find_de
196 * otherwise false
197 */
198 static int br2684_xmit_vcc(struct sk_buff *skb, struct br2684_dev *brdev,
199 - struct br2684_vcc *brvcc)
200 + struct br2684_vcc *brvcc)
201 {
202 struct atm_vcc *atmvcc;
203 int minheadroom = (brvcc->encaps == e_llc) ? 10 : 2;
204 +
205 if (skb_headroom(skb) < minheadroom) {
206 struct sk_buff *skb2 = skb_realloc_headroom(skb, minheadroom);
207 brvcc->copies_needed++;
208 @@ -146,23 +164,48 @@ static int br2684_xmit_vcc(struct sk_buf
209 }
210 skb = skb2;
211 }
212 - skb_push(skb, minheadroom);
213 - if (brvcc->encaps == e_llc)
214 - skb_copy_to_linear_data(skb, llc_oui_pid_pad, 10);
215 - else
216 - memset(skb->data, 0, 2);
217 +
218 + if (brvcc->encaps == e_llc) {
219 + if (brdev->payload == p_bridged) {
220 + skb_push(skb, sizeof(llc_oui_pid_pad));
221 + skb_copy_to_linear_data(skb, llc_oui_pid_pad,
222 + sizeof(llc_oui_pid_pad));
223 + } else if (brdev->payload == p_routed) {
224 + unsigned short prot = ntohs(skb->protocol);
225 +
226 + skb_push(skb, sizeof(llc_oui_ipv4));
227 + switch (prot) {
228 + case ETH_P_IP:
229 + skb_copy_to_linear_data(skb, llc_oui_ipv4,
230 + sizeof(llc_oui_ipv4));
231 + break;
232 + case ETH_P_IPV6:
233 + skb_copy_to_linear_data(skb, llc_oui_ipv6,
234 + sizeof(llc_oui_ipv6));
235 + break;
236 + default:
237 + dev_kfree_skb(skb);
238 + return 0;
239 + }
240 + }
241 + } else {
242 + skb_push(skb, 2);
243 + if (brdev->payload == p_bridged)
244 + memset(skb->data, 0, 2);
245 + }
246 skb_debug(skb);
247
248 ATM_SKB(skb)->vcc = atmvcc = brvcc->atmvcc;
249 pr_debug("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, atmvcc, atmvcc->dev);
250 if (!atm_may_send(atmvcc, skb->truesize)) {
251 - /* we free this here for now, because we cannot know in a higher
252 - layer whether the skb point it supplied wasn't freed yet.
253 - now, it always is.
254 - */
255 + /*
256 + * We free this here for now, because we cannot know in a higher
257 + * layer whether the skb pointer it supplied wasn't freed yet.
258 + * Now, it always is.
259 + */
260 dev_kfree_skb(skb);
261 return 0;
262 - }
263 + }
264 atomic_add(skb->truesize, &sk_atm(atmvcc)->sk_wmem_alloc);
265 ATM_SKB(skb)->atm_options = atmvcc->atm_options;
266 brdev->stats.tx_packets++;
267 @@ -172,10 +215,9 @@ static int br2684_xmit_vcc(struct sk_buf
268 }
269
270 static inline struct br2684_vcc *pick_outgoing_vcc(struct sk_buff *skb,
271 - struct br2684_dev *brdev)
272 + struct br2684_dev *brdev)
273 {
274 - return list_empty(&brdev->brvccs) ? NULL :
275 - list_entry_brvcc(brdev->brvccs.next); /* 1 vcc/dev right now */
276 + return list_empty(&brdev->brvccs) ? NULL : list_entry_brvcc(brdev->brvccs.next); /* 1 vcc/dev right now */
277 }
278
279 static int br2684_start_xmit(struct sk_buff *skb, struct net_device *dev)
280 @@ -199,11 +241,10 @@ static int br2684_start_xmit(struct sk_b
281 /*
282 * We should probably use netif_*_queue() here, but that
283 * involves added complication. We need to walk before
284 - * we can run
285 + * we can run.
286 + *
287 + * Don't free here! this pointer might be no longer valid!
288 */
289 - /* don't free here! this pointer might be no longer valid!
290 - dev_kfree_skb(skb);
291 - */
292 brdev->stats.tx_errors++;
293 brdev->stats.tx_fifo_errors++;
294 }
295 @@ -217,12 +258,11 @@ static struct net_device_stats *br2684_g
296 return &BRPRIV(dev)->stats;
297 }
298
299 -
300 /*
301 * We remember when the MAC gets set, so we don't override it later with
302 * the ESI of the ATM card of the first VC
303 */
304 -static int (*my_eth_mac_addr)(struct net_device *, void *);
305 +static int (*my_eth_mac_addr) (struct net_device *, void *);
306 static int br2684_mac_addr(struct net_device *dev, void *p)
307 {
308 int err = my_eth_mac_addr(dev, p);
309 @@ -233,7 +273,7 @@ static int br2684_mac_addr(struct net_de
310
311 #ifdef CONFIG_ATM_BR2684_IPFILTER
312 /* this IOCTL is experimental. */
313 -static int br2684_setfilt(struct atm_vcc *atmvcc, void __user *arg)
314 +static int br2684_setfilt(struct atm_vcc *atmvcc, void __user * arg)
315 {
316 struct br2684_vcc *brvcc;
317 struct br2684_filter_set fs;
318 @@ -243,13 +283,12 @@ static int br2684_setfilt(struct atm_vcc
319 if (fs.ifspec.method != BR2684_FIND_BYNOTHING) {
320 /*
321 * This is really a per-vcc thing, but we can also search
322 - * by device
323 + * by device.
324 */
325 struct br2684_dev *brdev;
326 read_lock(&devs_lock);
327 brdev = BRPRIV(br2684_find_dev(&fs.ifspec));
328 - if (brdev == NULL || list_empty(&brdev->brvccs) ||
329 - brdev->brvccs.next != brdev->brvccs.prev) /* >1 VCC */
330 + if (brdev == NULL || list_empty(&brdev->brvccs) || brdev->brvccs.next != brdev->brvccs.prev) /* >1 VCC */
331 brvcc = NULL;
332 else
333 brvcc = list_entry_brvcc(brdev->brvccs.next);
334 @@ -267,15 +306,16 @@ static inline int
335 packet_fails_filter(__be16 type, struct br2684_vcc *brvcc, struct sk_buff *skb)
336 {
337 if (brvcc->filter.netmask == 0)
338 - return 0; /* no filter in place */
339 + return 0; /* no filter in place */
340 if (type == htons(ETH_P_IP) &&
341 - (((struct iphdr *) (skb->data))->daddr & brvcc->filter.
342 + (((struct iphdr *)(skb->data))->daddr & brvcc->filter.
343 netmask) == brvcc->filter.prefix)
344 return 0;
345 if (type == htons(ETH_P_ARP))
346 return 0;
347 - /* TODO: we should probably filter ARPs too.. don't want to have
348 - * them returning values that don't make sense, or is that ok?
349 + /*
350 + * TODO: we should probably filter ARPs too.. don't want to have
351 + * them returning values that don't make sense, or is that ok?
352 */
353 return 1; /* drop */
354 }
355 @@ -299,7 +339,6 @@ static void br2684_push(struct atm_vcc *
356 struct br2684_vcc *brvcc = BR2684_VCC(atmvcc);
357 struct net_device *net_dev = brvcc->device;
358 struct br2684_dev *brdev = BRPRIV(net_dev);
359 - int plen = sizeof(llc_oui_pid_pad) + ETH_HLEN;
360
361 pr_debug("br2684_push\n");
362
363 @@ -320,35 +359,58 @@ static void br2684_push(struct atm_vcc *
364 atm_return(atmvcc, skb->truesize);
365 pr_debug("skb from brdev %p\n", brdev);
366 if (brvcc->encaps == e_llc) {
367 - /* let us waste some time for checking the encapsulation.
368 - Note, that only 7 char is checked so frames with a valid FCS
369 - are also accepted (but FCS is not checked of course) */
370 - if (memcmp(skb->data, llc_oui_pid_pad, 7)) {
371 +
372 + if (skb->len > 7 && skb->data[7] == 0x01)
373 + __skb_trim(skb, skb->len - 4);
374 +
375 + /* accept packets that have "ipv[46]" in the snap header */
376 + if ((skb->len >= (sizeof(llc_oui_ipv4)))
377 + &&
378 + (memcmp
379 + (skb->data, llc_oui_ipv4,
380 + sizeof(llc_oui_ipv4) - BR2684_ETHERTYPE_LEN) == 0)) {
381 + if (memcmp
382 + (skb->data + 6, ethertype_ipv6,
383 + sizeof(ethertype_ipv6)) == 0)
384 + skb->protocol = __constant_htons(ETH_P_IPV6);
385 + else if (memcmp
386 + (skb->data + 6, ethertype_ipv4,
387 + sizeof(ethertype_ipv4)) == 0)
388 + skb->protocol = __constant_htons(ETH_P_IP);
389 + else {
390 + brdev->stats.rx_errors++;
391 + dev_kfree_skb(skb);
392 + return;
393 + }
394 + skb_pull(skb, sizeof(llc_oui_ipv4));
395 + skb_reset_network_header(skb);
396 + skb->pkt_type = PACKET_HOST;
397 + /*
398 + * Let us waste some time for checking the encapsulation.
399 + * Note, that only 7 char is checked so frames with a valid FCS
400 + * are also accepted (but FCS is not checked of course).
401 + */
402 + } else if ((skb->len >= sizeof(llc_oui_pid_pad)) &&
403 + (memcmp(skb->data, llc_oui_pid_pad, 7) == 0)) {
404 + skb_pull(skb, sizeof(llc_oui_pid_pad));
405 + skb->protocol = eth_type_trans(skb, net_dev);
406 + } else {
407 brdev->stats.rx_errors++;
408 dev_kfree_skb(skb);
409 return;
410 }
411
412 - /* Strip FCS if present */
413 - if (skb->len > 7 && skb->data[7] == 0x01)
414 - __skb_trim(skb, skb->len - 4);
415 } else {
416 - plen = PADLEN + ETH_HLEN; /* pad, dstmac,srcmac, ethtype */
417 /* first 2 chars should be 0 */
418 if (*((u16 *) (skb->data)) != 0) {
419 brdev->stats.rx_errors++;
420 dev_kfree_skb(skb);
421 return;
422 }
423 - }
424 - if (skb->len < plen) {
425 - brdev->stats.rx_errors++;
426 - dev_kfree_skb(skb); /* dev_ not needed? */
427 - return;
428 + skb_pull(skb, BR2684_PAD_LEN + ETH_HLEN); /* pad, dstmac, srcmac, ethtype */
429 + skb->protocol = eth_type_trans(skb, net_dev);
430 }
431
432 - skb_pull(skb, plen - ETH_HLEN);
433 - skb->protocol = eth_type_trans(skb, net_dev);
434 #ifdef CONFIG_ATM_BR2684_IPFILTER
435 if (unlikely(packet_fails_filter(skb->protocol, brvcc, skb))) {
436 brdev->stats.rx_dropped++;
437 @@ -372,11 +434,12 @@ static void br2684_push(struct atm_vcc *
438 netif_rx(skb);
439 }
440
441 -static int br2684_regvcc(struct atm_vcc *atmvcc, void __user *arg)
442 +/*
443 + * Assign a vcc to a dev
444 + * Note: we do not have explicit unassign, but look at _push()
445 + */
446 +static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
447 {
448 -/* assign a vcc to a dev
449 -Note: we do not have explicit unassign, but look at _push()
450 -*/
451 int err;
452 struct br2684_vcc *brvcc;
453 struct sk_buff *skb;
454 @@ -395,7 +458,7 @@ Note: we do not have explicit unassign,
455 net_dev = br2684_find_dev(&be.ifspec);
456 if (net_dev == NULL) {
457 printk(KERN_ERR
458 - "br2684: tried to attach to non-existant device\n");
459 + "br2684: tried to attach to non-existant device\n");
460 err = -ENXIO;
461 goto error;
462 }
463 @@ -411,13 +474,15 @@ Note: we do not have explicit unassign,
464 }
465 if (be.fcs_in != BR2684_FCSIN_NO || be.fcs_out != BR2684_FCSOUT_NO ||
466 be.fcs_auto || be.has_vpiid || be.send_padding || (be.encaps !=
467 - BR2684_ENCAPS_VC && be.encaps != BR2684_ENCAPS_LLC) ||
468 - be.min_size != 0) {
469 + BR2684_ENCAPS_VC
470 + && be.encaps !=
471 + BR2684_ENCAPS_LLC)
472 + || be.min_size != 0) {
473 err = -EINVAL;
474 goto error;
475 }
476 - pr_debug("br2684_regvcc vcc=%p, encaps=%d, brvcc=%p\n", atmvcc, be.encaps,
477 - brvcc);
478 + pr_debug("br2684_regvcc vcc=%p, encaps=%d, brvcc=%p\n", atmvcc,
479 + be.encaps, brvcc);
480 if (list_empty(&brdev->brvccs) && !brdev->mac_was_set) {
481 unsigned char *esi = atmvcc->dev->esi;
482 if (esi[0] | esi[1] | esi[2] | esi[3] | esi[4] | esi[5])
483 @@ -430,7 +495,7 @@ Note: we do not have explicit unassign,
484 brvcc->device = net_dev;
485 brvcc->atmvcc = atmvcc;
486 atmvcc->user_back = brvcc;
487 - brvcc->encaps = (enum br2684_encaps) be.encaps;
488 + brvcc->encaps = (enum br2684_encaps)be.encaps;
489 brvcc->old_push = atmvcc->push;
490 barrier();
491 atmvcc->push = br2684_push;
492 @@ -461,7 +526,7 @@ Note: we do not have explicit unassign,
493 }
494 __module_get(THIS_MODULE);
495 return 0;
496 - error:
497 + error:
498 write_unlock_irq(&devs_lock);
499 kfree(brvcc);
500 return err;
501 @@ -482,25 +547,52 @@ static void br2684_setup(struct net_devi
502 INIT_LIST_HEAD(&brdev->brvccs);
503 }
504
505 -static int br2684_create(void __user *arg)
506 +static void br2684_setup_routed(struct net_device *netdev)
507 +{
508 + struct br2684_dev *brdev = BRPRIV(netdev);
509 + brdev->net_dev = netdev;
510 +
511 + netdev->hard_header_len = 0;
512 + my_eth_mac_addr = netdev->set_mac_address;
513 + netdev->set_mac_address = br2684_mac_addr;
514 + netdev->hard_start_xmit = br2684_start_xmit;
515 + netdev->get_stats = br2684_get_stats;
516 + netdev->addr_len = 0;
517 + netdev->mtu = 1500;
518 + netdev->type = ARPHRD_PPP;
519 + netdev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
520 + netdev->tx_queue_len = 100;
521 + INIT_LIST_HEAD(&brdev->brvccs);
522 +}
523 +
524 +static int br2684_create(void __user * arg)
525 {
526 int err;
527 struct net_device *netdev;
528 struct br2684_dev *brdev;
529 struct atm_newif_br2684 ni;
530 + enum br2684_payload payload;
531
532 pr_debug("br2684_create\n");
533
534 if (copy_from_user(&ni, arg, sizeof ni)) {
535 return -EFAULT;
536 }
537 +
538 + if (ni.media & BR2684_FLAG_ROUTED)
539 + payload = p_routed;
540 + else
541 + payload = p_bridged;
542 + ni.media &= 0xffff; /* strip flags */
543 +
544 if (ni.media != BR2684_MEDIA_ETHERNET || ni.mtu != 1500) {
545 return -EINVAL;
546 }
547
548 netdev = alloc_netdev(sizeof(struct br2684_dev),
549 ni.ifname[0] ? ni.ifname : "nas%d",
550 - br2684_setup);
551 + (payload == p_routed) ?
552 + br2684_setup_routed : br2684_setup);
553 if (!netdev)
554 return -ENOMEM;
555
556 @@ -516,6 +608,7 @@ static int br2684_create(void __user *ar
557 }
558
559 write_lock_irq(&devs_lock);
560 + brdev->payload = payload;
561 brdev->number = list_empty(&br2684_devs) ? 1 :
562 BRPRIV(list_entry_brdev(br2684_devs.prev))->number + 1;
563 list_add_tail(&brdev->br2684_devs, &br2684_devs);
564 @@ -528,16 +621,16 @@ static int br2684_create(void __user *ar
565 * -ENOIOCTLCMD for any unrecognized ioctl
566 */
567 static int br2684_ioctl(struct socket *sock, unsigned int cmd,
568 - unsigned long arg)
569 + unsigned long arg)
570 {
571 struct atm_vcc *atmvcc = ATM_SD(sock);
572 void __user *argp = (void __user *)arg;
573 + atm_backend_t b;
574
575 int err;
576 - switch(cmd) {
577 + switch (cmd) {
578 case ATM_SETBACKEND:
579 - case ATM_NEWBACKENDIF: {
580 - atm_backend_t b;
581 + case ATM_NEWBACKENDIF:
582 err = get_user(b, (atm_backend_t __user *) argp);
583 if (err)
584 return -EFAULT;
585 @@ -549,7 +642,6 @@ static int br2684_ioctl(struct socket *s
586 return br2684_regvcc(atmvcc, argp);
587 else
588 return br2684_create(argp);
589 - }
590 #ifdef CONFIG_ATM_BR2684_IPFILTER
591 case BR2684_SETFILT:
592 if (atmvcc->push != br2684_push)
593 @@ -557,6 +649,7 @@ static int br2684_ioctl(struct socket *s
594 if (!capable(CAP_NET_ADMIN))
595 return -EPERM;
596 err = br2684_setfilt(atmvcc, argp);
597 +
598 return err;
599 #endif /* CONFIG_ATM_BR2684_IPFILTER */
600 }
601 @@ -564,24 +657,25 @@ static int br2684_ioctl(struct socket *s
602 }
603
604 static struct atm_ioctl br2684_ioctl_ops = {
605 - .owner = THIS_MODULE,
606 - .ioctl = br2684_ioctl,
607 + .owner = THIS_MODULE,
608 + .ioctl = br2684_ioctl,
609 };
610
611 -
612 #ifdef CONFIG_PROC_FS
613 -static void *br2684_seq_start(struct seq_file *seq, loff_t *pos)
614 +static void *br2684_seq_start(struct seq_file *seq, loff_t * pos)
615 + __acquires(devs_lock)
616 {
617 read_lock(&devs_lock);
618 return seq_list_start(&br2684_devs, *pos);
619 }
620
621 -static void *br2684_seq_next(struct seq_file *seq, void *v, loff_t *pos)
622 +static void *br2684_seq_next(struct seq_file *seq, void *v, loff_t * pos)
623 {
624 return seq_list_next(v, &br2684_devs, pos);
625 }
626
627 static void br2684_seq_stop(struct seq_file *seq, void *v)
628 + __releases(devs_lock)
629 {
630 read_unlock(&devs_lock);
631 }
632 @@ -589,7 +683,7 @@ static void br2684_seq_stop(struct seq_f
633 static int br2684_seq_show(struct seq_file *seq, void *v)
634 {
635 const struct br2684_dev *brdev = list_entry(v, struct br2684_dev,
636 - br2684_devs);
637 + br2684_devs);
638 const struct net_device *net_dev = brdev->net_dev;
639 const struct br2684_vcc *brvcc;
640 DECLARE_MAC_BUF(mac);
641 @@ -601,21 +695,19 @@ static int br2684_seq_show(struct seq_fi
642 brdev->mac_was_set ? "set" : "auto");
643
644 list_for_each_entry(brvcc, &brdev->brvccs, brvccs) {
645 - seq_printf(seq, " vcc %d.%d.%d: encaps=%s"
646 - ", failed copies %u/%u"
647 - "\n", brvcc->atmvcc->dev->number,
648 - brvcc->atmvcc->vpi, brvcc->atmvcc->vci,
649 - (brvcc->encaps == e_llc) ? "LLC" : "VC"
650 - , brvcc->copies_failed
651 - , brvcc->copies_needed
652 - );
653 + seq_printf(seq, " vcc %d.%d.%d: encaps=%s payload=%s"
654 + ", failed copies %u/%u"
655 + "\n", brvcc->atmvcc->dev->number,
656 + brvcc->atmvcc->vpi, brvcc->atmvcc->vci,
657 + (brvcc->encaps == e_llc) ? "LLC" : "VC",
658 + (brdev->payload == p_bridged) ? "bridged" : "routed",
659 + brvcc->copies_failed, brvcc->copies_needed);
660 #ifdef CONFIG_ATM_BR2684_IPFILTER
661 #define b1(var, byte) ((u8 *) &brvcc->filter.var)[byte]
662 #define bs(var) b1(var, 0), b1(var, 1), b1(var, 2), b1(var, 3)
663 - if (brvcc->filter.netmask != 0)
664 - seq_printf(seq, " filter=%d.%d.%d.%d/"
665 - "%d.%d.%d.%d\n",
666 - bs(prefix), bs(netmask));
667 + if (brvcc->filter.netmask != 0)
668 + seq_printf(seq, " filter=%d.%d.%d.%d/"
669 + "%d.%d.%d.%d\n", bs(prefix), bs(netmask));
670 #undef bs
671 #undef b1
672 #endif /* CONFIG_ATM_BR2684_IPFILTER */
673 @@ -625,9 +717,9 @@ static int br2684_seq_show(struct seq_fi
674
675 static const struct seq_operations br2684_seq_ops = {
676 .start = br2684_seq_start,
677 - .next = br2684_seq_next,
678 - .stop = br2684_seq_stop,
679 - .show = br2684_seq_show,
680 + .next = br2684_seq_next,
681 + .stop = br2684_seq_stop,
682 + .show = br2684_seq_show,
683 };
684
685 static int br2684_proc_open(struct inode *inode, struct file *file)
686 @@ -636,26 +728,28 @@ static int br2684_proc_open(struct inode
687 }
688
689 static const struct file_operations br2684_proc_ops = {
690 - .owner = THIS_MODULE,
691 - .open = br2684_proc_open,
692 - .read = seq_read,
693 - .llseek = seq_lseek,
694 + .owner = THIS_MODULE,
695 + .open = br2684_proc_open,
696 + .read = seq_read,
697 + .llseek = seq_lseek,
698 .release = seq_release,
699 };
700
701 extern struct proc_dir_entry *atm_proc_root; /* from proc.c */
702 -#endif
703 +#endif /* CONFIG_PROC_FS */
704
705 static int __init br2684_init(void)
706 {
707 #ifdef CONFIG_PROC_FS
708 struct proc_dir_entry *p;
709 +
710 if ((p = create_proc_entry("br2684", 0, atm_proc_root)) == NULL)
711 - return -ENOMEM;
712 - p->proc_fops = &br2684_proc_ops;
713 + return -ENOMEM;
714 + p->proc_fops = &br2684_proc_ops;
715 #endif
716 - register_atm_ioctl(&br2684_ioctl_ops);
717 - return 0;
718 + register_atm_ioctl(&br2684_ioctl_ops);
719 + return 0;
720 +
721 }
722
723 static void __exit br2684_exit(void)
724 @@ -689,3 +783,4 @@ module_exit(br2684_exit);
725 MODULE_AUTHOR("Marcell GAL");
726 MODULE_DESCRIPTION("RFC2684 bridged protocols over ATM/AAL5");
727 MODULE_LICENSE("GPL");
728 +