From: Felix Fietkau Date: Tue, 17 Jan 2006 16:05:09 +0000 (+0000) Subject: rename br2684 atm routing patch X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fsvn-archive%2Farchive.git;a=commitdiff_plain;hb=353597dede026b14d8fad6aa6484ddc15fbe1b96 rename br2684 atm routing patch SVN-Revision: 3006 --- diff --git a/openwrt/target/linux/generic-2.4/patches/225-atm_br2684.patch b/openwrt/target/linux/generic-2.4/patches/225-atm_br2684.patch deleted file mode 100644 index 3b01533cd1..0000000000 --- a/openwrt/target/linux/generic-2.4/patches/225-atm_br2684.patch +++ /dev/null @@ -1,600 +0,0 @@ -diff -Nur linux.old/net/atm/br2684.c linux.new/net/atm/br2684.c ---- linux.old/net/atm/br2684.c 2004-08-08 01:26:06.000000000 +0200 -+++ linux.new/net/atm/br2684.c 2005-11-13 00:04:15.000000000 +0100 -@@ -16,12 +16,9 @@ - #include - #include - #include --#include --#include - - #include - --#include "common.h" - #include "ipcommon.h" - - /* -@@ -55,36 +52,57 @@ - #define skb_debug(skb) do {} while (0) - #endif - -+#define BR2684_LLC_LEN 3 -+#define BR2684_SNAP_LEN 3 -+#define BR2684_ETHERTYPE_LEN 2 -+#define BR2684_PID_LEN 2 -+#define BR2684_PAD_LEN 2 -+ -+static unsigned char llc_common[] = { 0xaa, 0xaa, 0x03 }; -+static unsigned char snap_bridged[] = { 0x00, 0x80, 0xc2 }; -+static unsigned char snap_routed[] = { 0x00, 0x00, 0x00 }; -+static unsigned char pid_ipv4[] = { 0x00, 0x07 }; -+static unsigned char ethertype_ipv4[] = { 0x08, 0x00 }; -+static unsigned char ethertype_ipv6[] = { 0x86, 0xdd }; -+static unsigned char pad_bridged[] = { 0x00, 0x00 }; -+ - static unsigned char llc_oui_pid_pad[] = - { 0xAA, 0xAA, 0x03, 0x00, 0x80, 0xC2, 0x00, 0x07, 0x00, 0x00 }; -+static unsigned char llc_oui_ipv6[] = -+ { 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xdd }; -+static unsigned char llc_oui_ipv4[] = -+ { 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00 }; - #define PADLEN (2) - - enum br2684_encaps { -- e_vc = BR2684_ENCAPS_VC, -+ e_vc = BR2684_ENCAPS_VC, - e_llc = BR2684_ENCAPS_LLC, - }; - -+ -+ - struct br2684_vcc { -- struct atm_vcc *atmvcc; -+ struct atm_vcc *atmvcc; - struct br2684_dev *brdev; - /* keep old push,pop functions for chaining */ -- void (*old_push)(struct atm_vcc *vcc,struct sk_buff *skb); -+ void (*old_push) (struct atm_vcc * vcc, struct sk_buff * skb); - /* void (*old_pop)(struct atm_vcc *vcc,struct sk_buff *skb); */ - enum br2684_encaps encaps; -+ enum br2684_payload payload; - struct list_head brvccs; - #ifdef CONFIG_ATM_BR2684_IPFILTER - struct br2684_filter filter; --#endif /* CONFIG_ATM_BR2684_IPFILTER */ -+#endif /* CONFIG_ATM_BR2684_IPFILTER */ - #ifndef FASTER_VERSION - unsigned copies_needed, copies_failed; --#endif /* FASTER_VERSION */ -+#endif /* FASTER_VERSION */ - }; - - struct br2684_dev { - struct net_device net_dev; - struct list_head br2684_devs; - int number; -- struct list_head brvccs; /* one device <=> one vcc (before xmas) */ -+ struct list_head brvccs; /* one device <=> one vcc (before xmas) */ - struct net_device_stats stats; - int mac_was_set; - }; -@@ -173,24 +197,84 @@ - } - skb = skb2; - } -- skb_push(skb, minheadroom); -- if (brvcc->encaps == e_llc) -- memcpy(skb->data, llc_oui_pid_pad, 10); -- else -- memset(skb->data, 0, 2); --#endif /* FASTER_VERSION */ -+ -+ /* This skb_push is a problem: routed packets need less headroom than -+ * bridged packets. -+ */ -+ -+/* skb_push(skb, minheadroom); */ -+ if (brvcc->encaps == e_llc) { -+ int offset = 0; -+ int actual_headroom; -+ -+ actual_headroom = -+ BR2684_LLC_LEN + -+ BR2684_SNAP_LEN + -+ ((brvcc->payload == p_bridged) ? -+ (BR2684_PID_LEN + BR2684_PAD_LEN) : -+ BR2684_ETHERTYPE_LEN); -+ -+ skb_push(skb, actual_headroom); -+ memcpy(skb->data, llc_common, BR2684_LLC_LEN); -+ offset += BR2684_LLC_LEN; -+ -+ if (brvcc->payload == p_bridged) { -+ memcpy(skb->data + offset, snap_bridged, -+ BR2684_SNAP_LEN); -+ offset += BR2684_SNAP_LEN; -+ /* pid_ipv4 is poorly named. should probably be -+ * pid_ethernet -+ */ -+ memcpy(skb->data + offset, pid_ipv4, -+ BR2684_PID_LEN); -+ offset += BR2684_PID_LEN; -+ memcpy(skb->data + offset, pad_bridged, -+ BR2684_PAD_LEN); -+ offset += BR2684_PAD_LEN; -+ } else if (brvcc->payload == p_routed) { -+ unsigned short prot = -+ __constant_ntohs(skb->protocol); -+ memcpy(skb->data + offset, snap_routed, -+ BR2684_SNAP_LEN); -+ offset += BR2684_SNAP_LEN; -+ -+ switch (prot) { -+ case ETH_P_IP: -+ memcpy(skb->data + offset, -+ ethertype_ipv4, -+ BR2684_ETHERTYPE_LEN); -+ break; -+ case ETH_P_IPV6: -+ memcpy(skb->data + offset, -+ ethertype_ipv6, -+ BR2684_ETHERTYPE_LEN); -+ break; -+ default: -+ dev_kfree_skb(skb); -+ return 0; -+ } -+ offset += BR2684_ETHERTYPE_LEN; -+ -+ } -+ } else { -+ skb_push(skb, 2); -+ if (brvcc->payload == p_bridged) -+ memset(skb->data, 0, 2); -+ } -+#endif /* FASTER_VERSION */ - skb_debug(skb); - - ATM_SKB(skb)->vcc = atmvcc = brvcc->atmvcc; -- DPRINTK("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, atmvcc, atmvcc->dev); -+ DPRINTK("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, atmvcc, -+ atmvcc->dev); - if (!atm_may_send(atmvcc, skb->truesize)) { - /* we free this here for now, because we cannot know in a higher -- layer whether the skb point it supplied wasn't freed yet. -- now, it always is. -- */ -+ layer whether the skb point it supplied wasn't freed yet. -+ now, it always is. -+ */ - dev_kfree_skb(skb); - return 0; -- } -+ } - atomic_add(skb->truesize, &atmvcc->sk->wmem_alloc); - ATM_SKB(skb)->atm_options = atmvcc->atm_options; - brdev->stats.tx_packets++; -@@ -428,18 +512,39 @@ - atm_return(atmvcc, skb->truesize); - DPRINTK("skb from brdev %p\n", brdev); - if (brvcc->encaps == e_llc) { -+ /* accept packets that have "ipv[46]" in the snap header */ -+ /* 8 - 2 == sizeof(llc_oui_ipv6) - BR2684_ETHERTYPE_LEN */ -+ if (memcmp(skb->data, llc_oui_ipv6, 8 - 2) == 0) { -+ plen = sizeof(llc_oui_ipv6); -+ -+ if (memcmp(skb->data + 6, ethertype_ipv6, 2) == 0) -+ skb->protocol = -+ __constant_htons(ETH_P_IPV6); -+ else if (memcmp(skb->data + 6, ethertype_ipv4, 2) -+ == 0) -+ skb->protocol = __constant_htons(ETH_P_IP); -+ else { -+ brdev->stats.rx_errors++; -+ dev_kfree_skb(skb); -+ return; -+ } -+ skb_pull(skb, plen); -+ skb->nh.raw = skb->data; -+ skb->pkt_type = PACKET_HOST; -+ } -+ - /* let us waste some time for checking the encapsulation. - Note, that only 7 char is checked so frames with a valid FCS - are also accepted (but FCS is not checked of course) */ -- if (memcmp(skb->data, llc_oui_pid_pad, 7)) { -+ else if (memcmp(skb->data, llc_oui_pid_pad, 7) == 0) { -+ skb_pull(skb, plen - ETH_HLEN); -+ skb->protocol = -+ eth_type_trans(skb, &brdev->net_dev); -+ } else { - brdev->stats.rx_errors++; - dev_kfree_skb(skb); - return; - } -- -- /* Strip FCS if present */ -- if (skb->len > 7 && skb->data[7] == 0x01) -- __skb_trim(skb, skb->len - 4); - } else { - plen = PADLEN + ETH_HLEN; /* pad, dstmac,srcmac, ethtype */ - /* first 2 chars should be 0 */ -@@ -448,13 +553,14 @@ - dev_kfree_skb(skb); - return; - } -+ skb_pull(skb, plen - ETH_HLEN); -+ skb->protocol = eth_type_trans(skb, &brdev->net_dev); - } - if (skb->len < plen) { - brdev->stats.rx_errors++; - dev_kfree_skb(skb); /* dev_ not needed? */ - return; - } -- - #ifdef FASTER_VERSION - /* FIXME: tcpdump shows that pointer to mac header is 2 bytes earlier, - than should be. What else should I set? */ -@@ -465,30 +571,29 @@ - skb->protocol = ((u16 *) skb->data)[-1]; - #else /* some protocols might require this: */ - skb->protocol = br_type_trans(skb, &brdev->net_dev); --#endif /* CONFIG_BR2684_FAST_TRANS */ -+#endif /* CONFIG_BR2684_FAST_TRANS */ - #else -- skb_pull(skb, plen - ETH_HLEN); -- skb->protocol = eth_type_trans(skb, &brdev->net_dev); --#endif /* FASTER_VERSION */ -+ /* skb_pull(skb, plen - ETH_HLEN); */ -+ /* skb->protocol = eth_type_trans(skb, &brdev->net_dev); */ -+#endif /* FASTER_VERSION */ - #ifdef CONFIG_ATM_BR2684_IPFILTER - if (packet_fails_filter(skb->protocol, brvcc, skb)) { - brdev->stats.rx_dropped++; - dev_kfree_skb(skb); - return; - } --#endif /* CONFIG_ATM_BR2684_IPFILTER */ -+#endif /* CONFIG_ATM_BR2684_IPFILTER */ - skb->dev = &brdev->net_dev; -- ATM_SKB(skb)->vcc = atmvcc; /* needed ? */ -+ /* ATM_SKB(skb)->vcc = atmvcc; *//* needed ? */ - DPRINTK("received packet's protocol: %x\n", ntohs(skb->protocol)); - skb_debug(skb); -- if (!(brdev->net_dev.flags & IFF_UP)) { /* sigh, interface is down */ -+ if (!(brdev->net_dev.flags & IFF_UP)) { /* sigh, interface is down */ - brdev->stats.rx_dropped++; - dev_kfree_skb(skb); - return; - } - brdev->stats.rx_packets++; - brdev->stats.rx_bytes += skb->len; -- memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data)); - netif_rx(skb); - } - -@@ -525,10 +630,10 @@ - err = -EEXIST; - goto error; - } -- if (be.fcs_in != BR2684_FCSIN_NO || be.fcs_out != BR2684_FCSOUT_NO || -- be.fcs_auto || be.has_vpiid || be.send_padding || (be.encaps != -- BR2684_ENCAPS_VC && be.encaps != BR2684_ENCAPS_LLC) || -- be.min_size != 0) { -+ if (be.fcs_in != BR2684_FCSIN_NO || be.fcs_out != BR2684_FCSOUT_NO -+ || be.fcs_auto || be.has_vpiid || be.send_padding -+ || (be.encaps != BR2684_ENCAPS_VC -+ && be.encaps != BR2684_ENCAPS_LLC) || be.min_size != 0) { - err = -EINVAL; - goto error; - } -@@ -554,18 +659,21 @@ - brvcc->atmvcc = atmvcc; - atmvcc->user_back = brvcc; - brvcc->encaps = (enum br2684_encaps) be.encaps; -+ brvcc->payload = (enum br2684_payload) be.payload; - brvcc->old_push = atmvcc->push; - barrier(); - atmvcc->push = br2684_push; - skb_queue_head_init(©); - skb_migrate(&atmvcc->sk->receive_queue, ©); - while ((skb = skb_dequeue(©))) { -+#ifdef notdef - BRPRIV(skb->dev)->stats.rx_bytes -= skb->len; - BRPRIV(skb->dev)->stats.rx_packets--; -+#endif - br2684_push(atmvcc, skb); - } - return 0; -- error: -+ error: - write_unlock_irq(&devs_lock); - MOD_DEC_USE_COUNT; - return err; -@@ -608,12 +717,25 @@ - - if (ni.ifname[0] != '\0') { - memcpy(brdev->net_dev.name, ni.ifname, -- sizeof(brdev->net_dev.name)); -- brdev->net_dev.name[sizeof(brdev->net_dev.name) - 1] = '\0'; -+ sizeof(brdev->net_dev.name)); -+ brdev->net_dev.name[sizeof(brdev->net_dev.name) - 1] = -+ '\0'; - } else - sprintf(brdev->net_dev.name, "nas%d", brdev->number); - DPRINTK("registered netdev %s\n", brdev->net_dev.name); -- ether_setup(&brdev->net_dev); -+ if (ni.payload == p_routed) { -+ brdev->net_dev.hard_header_len = 0; -+ brdev->net_dev.addr_len = 0; -+ brdev->net_dev.mtu = 1500; -+ -+ /* Type PPP seems most suitable */ -+ brdev->net_dev.type = ARPHRD_PPP; -+ brdev->net_dev.flags = -+ IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST; -+ brdev->net_dev.tx_queue_len = 100; -+ } else { -+ ether_setup(&brdev->net_dev); -+ } - brdev->mac_was_set = 0; - #ifdef FASTER_VERSION - my_eth_header = brdev->net_dev.hard_header; -@@ -677,12 +799,11 @@ - err = br2684_setfilt(atmvcc, arg); - MOD_DEC_USE_COUNT; - return err; --#endif /* CONFIG_ATM_BR2684_IPFILTER */ -+#endif /* CONFIG_ATM_BR2684_IPFILTER */ - } - return -ENOIOCTLCMD; - } - --#ifdef CONFIG_PROC_FS - /* Never put more than 256 bytes in at once */ - static int br2684_proc_engine(loff_t pos, char *buf) - { -@@ -692,52 +813,62 @@ - list_for_each(lhd, &br2684_devs) { - brdev = list_entry_brdev(lhd); - if (pos-- == 0) -- return sprintf(buf, "dev %.16s: num=%d, mac=%02X:%02X:" -- "%02X:%02X:%02X:%02X (%s)\n", brdev->net_dev.name, -- brdev->number, -- brdev->net_dev.dev_addr[0], -- brdev->net_dev.dev_addr[1], -- brdev->net_dev.dev_addr[2], -- brdev->net_dev.dev_addr[3], -- brdev->net_dev.dev_addr[4], -- brdev->net_dev.dev_addr[5], -- brdev->mac_was_set ? "set" : "auto"); -+ return sprintf(buf, -+ "dev %.16s: num=%d, mac=%02X:%02X:" -+ "%02X:%02X:%02X:%02X (%s)\n", -+ brdev->net_dev.name, brdev->number, -+ brdev->net_dev.dev_addr[0], -+ brdev->net_dev.dev_addr[1], -+ brdev->net_dev.dev_addr[2], -+ brdev->net_dev.dev_addr[3], -+ brdev->net_dev.dev_addr[4], -+ brdev->net_dev.dev_addr[5], -+ brdev-> -+ mac_was_set ? "set" : "auto"); - list_for_each(lhc, &brdev->brvccs) { - brvcc = list_entry_brvcc(lhc); - if (pos-- == 0) -- return sprintf(buf, " vcc %d.%d.%d: encaps=%s" -+ return sprintf(buf, -+ " vcc %d.%d.%d: encaps=%s" -+ ", payload=%s" - #ifndef FASTER_VERSION -- ", failed copies %u/%u" --#endif /* FASTER_VERSION */ -- "\n", brvcc->atmvcc->dev->number, -- brvcc->atmvcc->vpi, brvcc->atmvcc->vci, -- (brvcc->encaps == e_llc) ? "LLC" : "VC" -+ ", failed copies %u/%u" -+#endif /* FASTER_VERSION */ -+ "\n", -+ brvcc->atmvcc->dev->number, -+ brvcc->atmvcc->vpi, -+ brvcc->atmvcc->vci, -+ (brvcc->encaps == -+ e_llc) ? "LLC" : "VC", -+ (brvcc->payload == -+ p_bridged) ? "bridged" : -+ "routed" - #ifndef FASTER_VERSION -- , brvcc->copies_failed -- , brvcc->copies_needed --#endif /* FASTER_VERSION */ -+ , brvcc->copies_failed, -+ brvcc->copies_needed -+#endif /* FASTER_VERSION */ - ); - #ifdef CONFIG_ATM_BR2684_IPFILTER - #define b1(var, byte) ((u8 *) &brvcc->filter.var)[byte] - #define bs(var) b1(var, 0), b1(var, 1), b1(var, 2), b1(var, 3) - if (brvcc->filter.netmask != 0 && pos-- == 0) -- return sprintf(buf, " filter=%d.%d.%d.%d/" -- "%d.%d.%d.%d\n", bs(prefix), bs(netmask)); -+ return sprintf(buf, -+ " filter=%d.%d.%d.%d/" -+ "%d.%d.%d.%d\n", bs(prefix), -+ bs(netmask)); - #undef bs - #undef b1 --#endif /* CONFIG_ATM_BR2684_IPFILTER */ -+#endif /* CONFIG_ATM_BR2684_IPFILTER */ - } - } - return 0; - } - - static ssize_t br2684_proc_read(struct file *file, char *buf, size_t count, -- loff_t *pos) -+ loff_t * pos) - { - unsigned long page; - int len = 0, x, left; -- loff_t n = *pos; -- - page = get_free_page(GFP_KERNEL); - if (!page) - return -ENOMEM; -@@ -746,7 +877,7 @@ - left = count; - read_lock(&devs_lock); - for (;;) { -- x = br2684_proc_engine(n, &((char *) page)[len]); -+ x = br2684_proc_engine(*pos, &((char *) page)[len]); - if (x == 0) - break; - if (x > left) -@@ -761,12 +892,11 @@ - } - len += x; - left -= x; -- n++; -+ (*pos)++; - if (left < 256) - break; - } - read_unlock(&devs_lock); -- *pos = n; - if (len > 0 && copy_to_user(buf, (char *) page, len)) - len = -EFAULT; - free_page(page); -@@ -774,34 +904,32 @@ - } - - static struct file_operations br2684_proc_operations = { -- read: br2684_proc_read, -+ read:br2684_proc_read, - }; - - extern struct proc_dir_entry *atm_proc_root; /* from proc.c */ --#endif /* CONFIG_PROC_FS */ -+ -+extern int (*br2684_ioctl_hook) (struct atm_vcc *, unsigned int, -+ unsigned long); - - /* the following avoids some spurious warnings from the compiler */ - #define UNUSED __attribute__((unused)) - - static int __init UNUSED br2684_init(void) - { --#ifdef CONFIG_PROC_FS - struct proc_dir_entry *p; - if ((p = create_proc_entry("br2684", 0, atm_proc_root)) == NULL) - return -ENOMEM; - p->proc_fops = &br2684_proc_operations; --#endif /* CONFIG_PROC_FS */ -- br2684_ioctl_set(br2684_ioctl); -+ br2684_ioctl_hook = br2684_ioctl; - return 0; - } - - static void __exit UNUSED br2684_exit(void) - { - struct br2684_dev *brdev; -- br2684_ioctl_set(NULL); --#ifdef CONFIG_PROC_FS -+ br2684_ioctl_hook = NULL; - remove_proc_entry("br2684", atm_proc_root); --#endif /* CONFIG_PROC_FS */ - while (!list_empty(&br2684_devs)) { - brdev = list_entry_brdev(br2684_devs.next); - unregister_netdev(&brdev->net_dev); -diff -Nur linux.old/net/atm/common.c linux.new/net/atm/common.c ---- linux.old/net/atm/common.c 2004-02-18 14:36:32.000000000 +0100 -+++ linux.new/net/atm/common.c 2005-11-13 00:46:11.000000000 +0100 -@@ -158,6 +158,7 @@ - } - #ifdef CONFIG_ATM_BR2684_MODULE - EXPORT_SYMBOL(br2684_ioctl_set); -+EXPORT_SYMBOL(br2684_ioctl_hook); - #endif - #endif - -diff -Nur linux.old/include/linux/atmbr2684.h linux.new/include/linux/atmbr2684.h ---- linux.old/include/linux/atmbr2684.h 2005-11-13 00:28:19.000000000 +0100 -+++ linux.new/include/linux/atmbr2684.h 2005-11-13 00:06:42.000000000 +0100 -@@ -3,6 +3,7 @@ - - #include - #include /* For IFNAMSIZ */ -+#include /* ETH_P_* */ - - /* - * Type of media we're bridging (ethernet, token ring, etc) Currently only -@@ -36,15 +37,24 @@ - #define BR2684_ENCAPS_AUTODETECT (2) /* Unsuported */ - - /* -+ * Is this VC bridged or routed? -+ */ -+ -+#define BR2684_PAYLOAD_ROUTED (0) -+#define BR2684_PAYLOAD_BRIDGED (1) -+ -+ -+/* - * This is for the ATM_NEWBACKENDIF call - these are like socket families: - * the first element of the structure is the backend number and the rest - * is per-backend specific - */ - struct atm_newif_br2684 { -- atm_backend_t backend_num; /* ATM_BACKEND_BR2684 */ -- int media; /* BR2684_MEDIA_* */ -- char ifname[IFNAMSIZ]; -- int mtu; -+ atm_backend_t backend_num; /* ATM_BACKEND_BR2684 */ -+ int media; /* BR2684_MEDIA_* */ -+ char ifname[IFNAMSIZ]; -+ int mtu; -+ int payload; /* bridged or routed */ - }; - - /* -@@ -68,16 +78,17 @@ - * is per-backend specific - */ - struct atm_backend_br2684 { -- atm_backend_t backend_num; /* ATM_BACKEND_BR2684 */ -+ atm_backend_t backend_num; /* ATM_BACKEND_BR2684 */ - struct br2684_if_spec ifspec; -- int fcs_in; /* BR2684_FCSIN_* */ -- int fcs_out; /* BR2684_FCSOUT_* */ -- int fcs_auto; /* 1: fcs_{in,out} disabled if no FCS rx'ed */ -- int encaps; /* BR2684_ENCAPS_* */ -- int has_vpiid; /* 1: use vpn_id - Unsupported */ -- __u8 vpn_id[7]; -- int send_padding; /* unsupported */ -- int min_size; /* we will pad smaller packets than this */ -+ int fcs_in; /* BR2684_FCSIN_* */ -+ int fcs_out; /* BR2684_FCSOUT_* */ -+ int fcs_auto; /* 1: fcs_{in,out} disabled if no FCS rx'ed */ -+ int encaps; /* BR2684_ENCAPS_* */ -+ int payload; /* BR2684_PAYLOAD_* */ -+ int has_vpiid; /* 1: use vpn_id - Unsupported */ -+ __u8 vpn_id[7]; -+ int send_padding; /* unsupported */ -+ int min_size; /* we will pad smaller packets than this */ - }; - - /* -@@ -95,7 +106,12 @@ - struct br2684_filter filter; - }; - -+enum br2684_payload { -+ p_routed = BR2684_PAYLOAD_ROUTED, -+ p_bridged = BR2684_PAYLOAD_BRIDGED, -+}; -+ - #define BR2684_SETFILT _IOW( 'a', ATMIOC_BACKEND + 0, \ - struct br2684_filter_set) - --#endif /* _LINUX_ATMBR2684_H */ -+#endif /* _LINUX_ATMBR2684_H */ diff --git a/openwrt/target/linux/generic-2.4/patches/226-atm_br2684.patch b/openwrt/target/linux/generic-2.4/patches/226-atm_br2684.patch new file mode 100644 index 0000000000..3b01533cd1 --- /dev/null +++ b/openwrt/target/linux/generic-2.4/patches/226-atm_br2684.patch @@ -0,0 +1,600 @@ +diff -Nur linux.old/net/atm/br2684.c linux.new/net/atm/br2684.c +--- linux.old/net/atm/br2684.c 2004-08-08 01:26:06.000000000 +0200 ++++ linux.new/net/atm/br2684.c 2005-11-13 00:04:15.000000000 +0100 +@@ -16,12 +16,9 @@ + #include + #include + #include +-#include +-#include + + #include + +-#include "common.h" + #include "ipcommon.h" + + /* +@@ -55,36 +52,57 @@ + #define skb_debug(skb) do {} while (0) + #endif + ++#define BR2684_LLC_LEN 3 ++#define BR2684_SNAP_LEN 3 ++#define BR2684_ETHERTYPE_LEN 2 ++#define BR2684_PID_LEN 2 ++#define BR2684_PAD_LEN 2 ++ ++static unsigned char llc_common[] = { 0xaa, 0xaa, 0x03 }; ++static unsigned char snap_bridged[] = { 0x00, 0x80, 0xc2 }; ++static unsigned char snap_routed[] = { 0x00, 0x00, 0x00 }; ++static unsigned char pid_ipv4[] = { 0x00, 0x07 }; ++static unsigned char ethertype_ipv4[] = { 0x08, 0x00 }; ++static unsigned char ethertype_ipv6[] = { 0x86, 0xdd }; ++static unsigned char pad_bridged[] = { 0x00, 0x00 }; ++ + static unsigned char llc_oui_pid_pad[] = + { 0xAA, 0xAA, 0x03, 0x00, 0x80, 0xC2, 0x00, 0x07, 0x00, 0x00 }; ++static unsigned char llc_oui_ipv6[] = ++ { 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xdd }; ++static unsigned char llc_oui_ipv4[] = ++ { 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00 }; + #define PADLEN (2) + + enum br2684_encaps { +- e_vc = BR2684_ENCAPS_VC, ++ e_vc = BR2684_ENCAPS_VC, + e_llc = BR2684_ENCAPS_LLC, + }; + ++ ++ + struct br2684_vcc { +- struct atm_vcc *atmvcc; ++ struct atm_vcc *atmvcc; + struct br2684_dev *brdev; + /* keep old push,pop functions for chaining */ +- void (*old_push)(struct atm_vcc *vcc,struct sk_buff *skb); ++ void (*old_push) (struct atm_vcc * vcc, struct sk_buff * skb); + /* void (*old_pop)(struct atm_vcc *vcc,struct sk_buff *skb); */ + enum br2684_encaps encaps; ++ enum br2684_payload payload; + struct list_head brvccs; + #ifdef CONFIG_ATM_BR2684_IPFILTER + struct br2684_filter filter; +-#endif /* CONFIG_ATM_BR2684_IPFILTER */ ++#endif /* CONFIG_ATM_BR2684_IPFILTER */ + #ifndef FASTER_VERSION + unsigned copies_needed, copies_failed; +-#endif /* FASTER_VERSION */ ++#endif /* FASTER_VERSION */ + }; + + struct br2684_dev { + struct net_device net_dev; + struct list_head br2684_devs; + int number; +- struct list_head brvccs; /* one device <=> one vcc (before xmas) */ ++ struct list_head brvccs; /* one device <=> one vcc (before xmas) */ + struct net_device_stats stats; + int mac_was_set; + }; +@@ -173,24 +197,84 @@ + } + skb = skb2; + } +- skb_push(skb, minheadroom); +- if (brvcc->encaps == e_llc) +- memcpy(skb->data, llc_oui_pid_pad, 10); +- else +- memset(skb->data, 0, 2); +-#endif /* FASTER_VERSION */ ++ ++ /* This skb_push is a problem: routed packets need less headroom than ++ * bridged packets. ++ */ ++ ++/* skb_push(skb, minheadroom); */ ++ if (brvcc->encaps == e_llc) { ++ int offset = 0; ++ int actual_headroom; ++ ++ actual_headroom = ++ BR2684_LLC_LEN + ++ BR2684_SNAP_LEN + ++ ((brvcc->payload == p_bridged) ? ++ (BR2684_PID_LEN + BR2684_PAD_LEN) : ++ BR2684_ETHERTYPE_LEN); ++ ++ skb_push(skb, actual_headroom); ++ memcpy(skb->data, llc_common, BR2684_LLC_LEN); ++ offset += BR2684_LLC_LEN; ++ ++ if (brvcc->payload == p_bridged) { ++ memcpy(skb->data + offset, snap_bridged, ++ BR2684_SNAP_LEN); ++ offset += BR2684_SNAP_LEN; ++ /* pid_ipv4 is poorly named. should probably be ++ * pid_ethernet ++ */ ++ memcpy(skb->data + offset, pid_ipv4, ++ BR2684_PID_LEN); ++ offset += BR2684_PID_LEN; ++ memcpy(skb->data + offset, pad_bridged, ++ BR2684_PAD_LEN); ++ offset += BR2684_PAD_LEN; ++ } else if (brvcc->payload == p_routed) { ++ unsigned short prot = ++ __constant_ntohs(skb->protocol); ++ memcpy(skb->data + offset, snap_routed, ++ BR2684_SNAP_LEN); ++ offset += BR2684_SNAP_LEN; ++ ++ switch (prot) { ++ case ETH_P_IP: ++ memcpy(skb->data + offset, ++ ethertype_ipv4, ++ BR2684_ETHERTYPE_LEN); ++ break; ++ case ETH_P_IPV6: ++ memcpy(skb->data + offset, ++ ethertype_ipv6, ++ BR2684_ETHERTYPE_LEN); ++ break; ++ default: ++ dev_kfree_skb(skb); ++ return 0; ++ } ++ offset += BR2684_ETHERTYPE_LEN; ++ ++ } ++ } else { ++ skb_push(skb, 2); ++ if (brvcc->payload == p_bridged) ++ memset(skb->data, 0, 2); ++ } ++#endif /* FASTER_VERSION */ + skb_debug(skb); + + ATM_SKB(skb)->vcc = atmvcc = brvcc->atmvcc; +- DPRINTK("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, atmvcc, atmvcc->dev); ++ DPRINTK("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, atmvcc, ++ atmvcc->dev); + if (!atm_may_send(atmvcc, skb->truesize)) { + /* we free this here for now, because we cannot know in a higher +- layer whether the skb point it supplied wasn't freed yet. +- now, it always is. +- */ ++ layer whether the skb point it supplied wasn't freed yet. ++ now, it always is. ++ */ + dev_kfree_skb(skb); + return 0; +- } ++ } + atomic_add(skb->truesize, &atmvcc->sk->wmem_alloc); + ATM_SKB(skb)->atm_options = atmvcc->atm_options; + brdev->stats.tx_packets++; +@@ -428,18 +512,39 @@ + atm_return(atmvcc, skb->truesize); + DPRINTK("skb from brdev %p\n", brdev); + if (brvcc->encaps == e_llc) { ++ /* accept packets that have "ipv[46]" in the snap header */ ++ /* 8 - 2 == sizeof(llc_oui_ipv6) - BR2684_ETHERTYPE_LEN */ ++ if (memcmp(skb->data, llc_oui_ipv6, 8 - 2) == 0) { ++ plen = sizeof(llc_oui_ipv6); ++ ++ if (memcmp(skb->data + 6, ethertype_ipv6, 2) == 0) ++ skb->protocol = ++ __constant_htons(ETH_P_IPV6); ++ else if (memcmp(skb->data + 6, ethertype_ipv4, 2) ++ == 0) ++ skb->protocol = __constant_htons(ETH_P_IP); ++ else { ++ brdev->stats.rx_errors++; ++ dev_kfree_skb(skb); ++ return; ++ } ++ skb_pull(skb, plen); ++ skb->nh.raw = skb->data; ++ skb->pkt_type = PACKET_HOST; ++ } ++ + /* let us waste some time for checking the encapsulation. + Note, that only 7 char is checked so frames with a valid FCS + are also accepted (but FCS is not checked of course) */ +- if (memcmp(skb->data, llc_oui_pid_pad, 7)) { ++ else if (memcmp(skb->data, llc_oui_pid_pad, 7) == 0) { ++ skb_pull(skb, plen - ETH_HLEN); ++ skb->protocol = ++ eth_type_trans(skb, &brdev->net_dev); ++ } else { + brdev->stats.rx_errors++; + dev_kfree_skb(skb); + return; + } +- +- /* Strip FCS if present */ +- if (skb->len > 7 && skb->data[7] == 0x01) +- __skb_trim(skb, skb->len - 4); + } else { + plen = PADLEN + ETH_HLEN; /* pad, dstmac,srcmac, ethtype */ + /* first 2 chars should be 0 */ +@@ -448,13 +553,14 @@ + dev_kfree_skb(skb); + return; + } ++ skb_pull(skb, plen - ETH_HLEN); ++ skb->protocol = eth_type_trans(skb, &brdev->net_dev); + } + if (skb->len < plen) { + brdev->stats.rx_errors++; + dev_kfree_skb(skb); /* dev_ not needed? */ + return; + } +- + #ifdef FASTER_VERSION + /* FIXME: tcpdump shows that pointer to mac header is 2 bytes earlier, + than should be. What else should I set? */ +@@ -465,30 +571,29 @@ + skb->protocol = ((u16 *) skb->data)[-1]; + #else /* some protocols might require this: */ + skb->protocol = br_type_trans(skb, &brdev->net_dev); +-#endif /* CONFIG_BR2684_FAST_TRANS */ ++#endif /* CONFIG_BR2684_FAST_TRANS */ + #else +- skb_pull(skb, plen - ETH_HLEN); +- skb->protocol = eth_type_trans(skb, &brdev->net_dev); +-#endif /* FASTER_VERSION */ ++ /* skb_pull(skb, plen - ETH_HLEN); */ ++ /* skb->protocol = eth_type_trans(skb, &brdev->net_dev); */ ++#endif /* FASTER_VERSION */ + #ifdef CONFIG_ATM_BR2684_IPFILTER + if (packet_fails_filter(skb->protocol, brvcc, skb)) { + brdev->stats.rx_dropped++; + dev_kfree_skb(skb); + return; + } +-#endif /* CONFIG_ATM_BR2684_IPFILTER */ ++#endif /* CONFIG_ATM_BR2684_IPFILTER */ + skb->dev = &brdev->net_dev; +- ATM_SKB(skb)->vcc = atmvcc; /* needed ? */ ++ /* ATM_SKB(skb)->vcc = atmvcc; *//* needed ? */ + DPRINTK("received packet's protocol: %x\n", ntohs(skb->protocol)); + skb_debug(skb); +- if (!(brdev->net_dev.flags & IFF_UP)) { /* sigh, interface is down */ ++ if (!(brdev->net_dev.flags & IFF_UP)) { /* sigh, interface is down */ + brdev->stats.rx_dropped++; + dev_kfree_skb(skb); + return; + } + brdev->stats.rx_packets++; + brdev->stats.rx_bytes += skb->len; +- memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data)); + netif_rx(skb); + } + +@@ -525,10 +630,10 @@ + err = -EEXIST; + goto error; + } +- if (be.fcs_in != BR2684_FCSIN_NO || be.fcs_out != BR2684_FCSOUT_NO || +- be.fcs_auto || be.has_vpiid || be.send_padding || (be.encaps != +- BR2684_ENCAPS_VC && be.encaps != BR2684_ENCAPS_LLC) || +- be.min_size != 0) { ++ if (be.fcs_in != BR2684_FCSIN_NO || be.fcs_out != BR2684_FCSOUT_NO ++ || be.fcs_auto || be.has_vpiid || be.send_padding ++ || (be.encaps != BR2684_ENCAPS_VC ++ && be.encaps != BR2684_ENCAPS_LLC) || be.min_size != 0) { + err = -EINVAL; + goto error; + } +@@ -554,18 +659,21 @@ + brvcc->atmvcc = atmvcc; + atmvcc->user_back = brvcc; + brvcc->encaps = (enum br2684_encaps) be.encaps; ++ brvcc->payload = (enum br2684_payload) be.payload; + brvcc->old_push = atmvcc->push; + barrier(); + atmvcc->push = br2684_push; + skb_queue_head_init(©); + skb_migrate(&atmvcc->sk->receive_queue, ©); + while ((skb = skb_dequeue(©))) { ++#ifdef notdef + BRPRIV(skb->dev)->stats.rx_bytes -= skb->len; + BRPRIV(skb->dev)->stats.rx_packets--; ++#endif + br2684_push(atmvcc, skb); + } + return 0; +- error: ++ error: + write_unlock_irq(&devs_lock); + MOD_DEC_USE_COUNT; + return err; +@@ -608,12 +717,25 @@ + + if (ni.ifname[0] != '\0') { + memcpy(brdev->net_dev.name, ni.ifname, +- sizeof(brdev->net_dev.name)); +- brdev->net_dev.name[sizeof(brdev->net_dev.name) - 1] = '\0'; ++ sizeof(brdev->net_dev.name)); ++ brdev->net_dev.name[sizeof(brdev->net_dev.name) - 1] = ++ '\0'; + } else + sprintf(brdev->net_dev.name, "nas%d", brdev->number); + DPRINTK("registered netdev %s\n", brdev->net_dev.name); +- ether_setup(&brdev->net_dev); ++ if (ni.payload == p_routed) { ++ brdev->net_dev.hard_header_len = 0; ++ brdev->net_dev.addr_len = 0; ++ brdev->net_dev.mtu = 1500; ++ ++ /* Type PPP seems most suitable */ ++ brdev->net_dev.type = ARPHRD_PPP; ++ brdev->net_dev.flags = ++ IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST; ++ brdev->net_dev.tx_queue_len = 100; ++ } else { ++ ether_setup(&brdev->net_dev); ++ } + brdev->mac_was_set = 0; + #ifdef FASTER_VERSION + my_eth_header = brdev->net_dev.hard_header; +@@ -677,12 +799,11 @@ + err = br2684_setfilt(atmvcc, arg); + MOD_DEC_USE_COUNT; + return err; +-#endif /* CONFIG_ATM_BR2684_IPFILTER */ ++#endif /* CONFIG_ATM_BR2684_IPFILTER */ + } + return -ENOIOCTLCMD; + } + +-#ifdef CONFIG_PROC_FS + /* Never put more than 256 bytes in at once */ + static int br2684_proc_engine(loff_t pos, char *buf) + { +@@ -692,52 +813,62 @@ + list_for_each(lhd, &br2684_devs) { + brdev = list_entry_brdev(lhd); + if (pos-- == 0) +- return sprintf(buf, "dev %.16s: num=%d, mac=%02X:%02X:" +- "%02X:%02X:%02X:%02X (%s)\n", brdev->net_dev.name, +- brdev->number, +- brdev->net_dev.dev_addr[0], +- brdev->net_dev.dev_addr[1], +- brdev->net_dev.dev_addr[2], +- brdev->net_dev.dev_addr[3], +- brdev->net_dev.dev_addr[4], +- brdev->net_dev.dev_addr[5], +- brdev->mac_was_set ? "set" : "auto"); ++ return sprintf(buf, ++ "dev %.16s: num=%d, mac=%02X:%02X:" ++ "%02X:%02X:%02X:%02X (%s)\n", ++ brdev->net_dev.name, brdev->number, ++ brdev->net_dev.dev_addr[0], ++ brdev->net_dev.dev_addr[1], ++ brdev->net_dev.dev_addr[2], ++ brdev->net_dev.dev_addr[3], ++ brdev->net_dev.dev_addr[4], ++ brdev->net_dev.dev_addr[5], ++ brdev-> ++ mac_was_set ? "set" : "auto"); + list_for_each(lhc, &brdev->brvccs) { + brvcc = list_entry_brvcc(lhc); + if (pos-- == 0) +- return sprintf(buf, " vcc %d.%d.%d: encaps=%s" ++ return sprintf(buf, ++ " vcc %d.%d.%d: encaps=%s" ++ ", payload=%s" + #ifndef FASTER_VERSION +- ", failed copies %u/%u" +-#endif /* FASTER_VERSION */ +- "\n", brvcc->atmvcc->dev->number, +- brvcc->atmvcc->vpi, brvcc->atmvcc->vci, +- (brvcc->encaps == e_llc) ? "LLC" : "VC" ++ ", failed copies %u/%u" ++#endif /* FASTER_VERSION */ ++ "\n", ++ brvcc->atmvcc->dev->number, ++ brvcc->atmvcc->vpi, ++ brvcc->atmvcc->vci, ++ (brvcc->encaps == ++ e_llc) ? "LLC" : "VC", ++ (brvcc->payload == ++ p_bridged) ? "bridged" : ++ "routed" + #ifndef FASTER_VERSION +- , brvcc->copies_failed +- , brvcc->copies_needed +-#endif /* FASTER_VERSION */ ++ , brvcc->copies_failed, ++ brvcc->copies_needed ++#endif /* FASTER_VERSION */ + ); + #ifdef CONFIG_ATM_BR2684_IPFILTER + #define b1(var, byte) ((u8 *) &brvcc->filter.var)[byte] + #define bs(var) b1(var, 0), b1(var, 1), b1(var, 2), b1(var, 3) + if (brvcc->filter.netmask != 0 && pos-- == 0) +- return sprintf(buf, " filter=%d.%d.%d.%d/" +- "%d.%d.%d.%d\n", bs(prefix), bs(netmask)); ++ return sprintf(buf, ++ " filter=%d.%d.%d.%d/" ++ "%d.%d.%d.%d\n", bs(prefix), ++ bs(netmask)); + #undef bs + #undef b1 +-#endif /* CONFIG_ATM_BR2684_IPFILTER */ ++#endif /* CONFIG_ATM_BR2684_IPFILTER */ + } + } + return 0; + } + + static ssize_t br2684_proc_read(struct file *file, char *buf, size_t count, +- loff_t *pos) ++ loff_t * pos) + { + unsigned long page; + int len = 0, x, left; +- loff_t n = *pos; +- + page = get_free_page(GFP_KERNEL); + if (!page) + return -ENOMEM; +@@ -746,7 +877,7 @@ + left = count; + read_lock(&devs_lock); + for (;;) { +- x = br2684_proc_engine(n, &((char *) page)[len]); ++ x = br2684_proc_engine(*pos, &((char *) page)[len]); + if (x == 0) + break; + if (x > left) +@@ -761,12 +892,11 @@ + } + len += x; + left -= x; +- n++; ++ (*pos)++; + if (left < 256) + break; + } + read_unlock(&devs_lock); +- *pos = n; + if (len > 0 && copy_to_user(buf, (char *) page, len)) + len = -EFAULT; + free_page(page); +@@ -774,34 +904,32 @@ + } + + static struct file_operations br2684_proc_operations = { +- read: br2684_proc_read, ++ read:br2684_proc_read, + }; + + extern struct proc_dir_entry *atm_proc_root; /* from proc.c */ +-#endif /* CONFIG_PROC_FS */ ++ ++extern int (*br2684_ioctl_hook) (struct atm_vcc *, unsigned int, ++ unsigned long); + + /* the following avoids some spurious warnings from the compiler */ + #define UNUSED __attribute__((unused)) + + static int __init UNUSED br2684_init(void) + { +-#ifdef CONFIG_PROC_FS + struct proc_dir_entry *p; + if ((p = create_proc_entry("br2684", 0, atm_proc_root)) == NULL) + return -ENOMEM; + p->proc_fops = &br2684_proc_operations; +-#endif /* CONFIG_PROC_FS */ +- br2684_ioctl_set(br2684_ioctl); ++ br2684_ioctl_hook = br2684_ioctl; + return 0; + } + + static void __exit UNUSED br2684_exit(void) + { + struct br2684_dev *brdev; +- br2684_ioctl_set(NULL); +-#ifdef CONFIG_PROC_FS ++ br2684_ioctl_hook = NULL; + remove_proc_entry("br2684", atm_proc_root); +-#endif /* CONFIG_PROC_FS */ + while (!list_empty(&br2684_devs)) { + brdev = list_entry_brdev(br2684_devs.next); + unregister_netdev(&brdev->net_dev); +diff -Nur linux.old/net/atm/common.c linux.new/net/atm/common.c +--- linux.old/net/atm/common.c 2004-02-18 14:36:32.000000000 +0100 ++++ linux.new/net/atm/common.c 2005-11-13 00:46:11.000000000 +0100 +@@ -158,6 +158,7 @@ + } + #ifdef CONFIG_ATM_BR2684_MODULE + EXPORT_SYMBOL(br2684_ioctl_set); ++EXPORT_SYMBOL(br2684_ioctl_hook); + #endif + #endif + +diff -Nur linux.old/include/linux/atmbr2684.h linux.new/include/linux/atmbr2684.h +--- linux.old/include/linux/atmbr2684.h 2005-11-13 00:28:19.000000000 +0100 ++++ linux.new/include/linux/atmbr2684.h 2005-11-13 00:06:42.000000000 +0100 +@@ -3,6 +3,7 @@ + + #include + #include /* For IFNAMSIZ */ ++#include /* ETH_P_* */ + + /* + * Type of media we're bridging (ethernet, token ring, etc) Currently only +@@ -36,15 +37,24 @@ + #define BR2684_ENCAPS_AUTODETECT (2) /* Unsuported */ + + /* ++ * Is this VC bridged or routed? ++ */ ++ ++#define BR2684_PAYLOAD_ROUTED (0) ++#define BR2684_PAYLOAD_BRIDGED (1) ++ ++ ++/* + * This is for the ATM_NEWBACKENDIF call - these are like socket families: + * the first element of the structure is the backend number and the rest + * is per-backend specific + */ + struct atm_newif_br2684 { +- atm_backend_t backend_num; /* ATM_BACKEND_BR2684 */ +- int media; /* BR2684_MEDIA_* */ +- char ifname[IFNAMSIZ]; +- int mtu; ++ atm_backend_t backend_num; /* ATM_BACKEND_BR2684 */ ++ int media; /* BR2684_MEDIA_* */ ++ char ifname[IFNAMSIZ]; ++ int mtu; ++ int payload; /* bridged or routed */ + }; + + /* +@@ -68,16 +78,17 @@ + * is per-backend specific + */ + struct atm_backend_br2684 { +- atm_backend_t backend_num; /* ATM_BACKEND_BR2684 */ ++ atm_backend_t backend_num; /* ATM_BACKEND_BR2684 */ + struct br2684_if_spec ifspec; +- int fcs_in; /* BR2684_FCSIN_* */ +- int fcs_out; /* BR2684_FCSOUT_* */ +- int fcs_auto; /* 1: fcs_{in,out} disabled if no FCS rx'ed */ +- int encaps; /* BR2684_ENCAPS_* */ +- int has_vpiid; /* 1: use vpn_id - Unsupported */ +- __u8 vpn_id[7]; +- int send_padding; /* unsupported */ +- int min_size; /* we will pad smaller packets than this */ ++ int fcs_in; /* BR2684_FCSIN_* */ ++ int fcs_out; /* BR2684_FCSOUT_* */ ++ int fcs_auto; /* 1: fcs_{in,out} disabled if no FCS rx'ed */ ++ int encaps; /* BR2684_ENCAPS_* */ ++ int payload; /* BR2684_PAYLOAD_* */ ++ int has_vpiid; /* 1: use vpn_id - Unsupported */ ++ __u8 vpn_id[7]; ++ int send_padding; /* unsupported */ ++ int min_size; /* we will pad smaller packets than this */ + }; + + /* +@@ -95,7 +106,12 @@ + struct br2684_filter filter; + }; + ++enum br2684_payload { ++ p_routed = BR2684_PAYLOAD_ROUTED, ++ p_bridged = BR2684_PAYLOAD_BRIDGED, ++}; ++ + #define BR2684_SETFILT _IOW( 'a', ATMIOC_BACKEND + 0, \ + struct br2684_filter_set) + +-#endif /* _LINUX_ATMBR2684_H */ ++#endif /* _LINUX_ATMBR2684_H */