[kernel] generic-2.6: remove remaining ipp2p patches
[openwrt.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 +