aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge
diff options
context:
space:
mode:
Diffstat (limited to 'net/bridge')
-rw-r--r--net/bridge/Kconfig1
-rw-r--r--net/bridge/br_device.c45
-rw-r--r--net/bridge/br_forward.c18
-rw-r--r--net/bridge/br_if.c6
-rw-r--r--net/bridge/br_input.c10
-rw-r--r--net/bridge/br_multicast.c37
-rw-r--r--net/bridge/br_private.h20
-rw-r--r--net/bridge/br_sysfs_if.c2
-rw-r--r--net/bridge/netfilter/ebt_ip6.c3
9 files changed, 109 insertions, 33 deletions
diff --git a/net/bridge/Kconfig b/net/bridge/Kconfig
index 19a6b9629c51..d115d5cea5b6 100644
--- a/net/bridge/Kconfig
+++ b/net/bridge/Kconfig
@@ -35,6 +35,7 @@ config BRIDGE
35config BRIDGE_IGMP_SNOOPING 35config BRIDGE_IGMP_SNOOPING
36 bool "IGMP snooping" 36 bool "IGMP snooping"
37 depends on BRIDGE 37 depends on BRIDGE
38 depends on INET
38 default y 39 default y
39 ---help--- 40 ---help---
40 If you say Y here, then the Ethernet bridge will be able selectively 41 If you say Y here, then the Ethernet bridge will be able selectively
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index eb7062d2e9e5..5b8a6e73b02f 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -26,11 +26,12 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
26 const unsigned char *dest = skb->data; 26 const unsigned char *dest = skb->data;
27 struct net_bridge_fdb_entry *dst; 27 struct net_bridge_fdb_entry *dst;
28 struct net_bridge_mdb_entry *mdst; 28 struct net_bridge_mdb_entry *mdst;
29 struct br_cpu_netstats *brstats = this_cpu_ptr(br->stats);
29 30
30 BR_INPUT_SKB_CB(skb)->brdev = dev; 31 brstats->tx_packets++;
32 brstats->tx_bytes += skb->len;
31 33
32 dev->stats.tx_packets++; 34 BR_INPUT_SKB_CB(skb)->brdev = dev;
33 dev->stats.tx_bytes += skb->len;
34 35
35 skb_reset_mac_header(skb); 36 skb_reset_mac_header(skb);
36 skb_pull(skb, ETH_HLEN); 37 skb_pull(skb, ETH_HLEN);
@@ -40,7 +41,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
40 goto out; 41 goto out;
41 42
42 mdst = br_mdb_get(br, skb); 43 mdst = br_mdb_get(br, skb);
43 if (mdst || BR_INPUT_SKB_CB(skb)->mrouters_only) 44 if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb))
44 br_multicast_deliver(mdst, skb); 45 br_multicast_deliver(mdst, skb);
45 else 46 else
46 br_flood_deliver(br, skb); 47 br_flood_deliver(br, skb);
@@ -81,6 +82,31 @@ static int br_dev_stop(struct net_device *dev)
81 return 0; 82 return 0;
82} 83}
83 84
85static struct net_device_stats *br_get_stats(struct net_device *dev)
86{
87 struct net_bridge *br = netdev_priv(dev);
88 struct net_device_stats *stats = &dev->stats;
89 struct br_cpu_netstats sum = { 0 };
90 unsigned int cpu;
91
92 for_each_possible_cpu(cpu) {
93 const struct br_cpu_netstats *bstats
94 = per_cpu_ptr(br->stats, cpu);
95
96 sum.tx_bytes += bstats->tx_bytes;
97 sum.tx_packets += bstats->tx_packets;
98 sum.rx_bytes += bstats->rx_bytes;
99 sum.rx_packets += bstats->rx_packets;
100 }
101
102 stats->tx_bytes = sum.tx_bytes;
103 stats->tx_packets = sum.tx_packets;
104 stats->rx_bytes = sum.rx_bytes;
105 stats->rx_packets = sum.rx_packets;
106
107 return stats;
108}
109
84static int br_change_mtu(struct net_device *dev, int new_mtu) 110static int br_change_mtu(struct net_device *dev, int new_mtu)
85{ 111{
86 struct net_bridge *br = netdev_priv(dev); 112 struct net_bridge *br = netdev_priv(dev);
@@ -180,19 +206,28 @@ static const struct net_device_ops br_netdev_ops = {
180 .ndo_open = br_dev_open, 206 .ndo_open = br_dev_open,
181 .ndo_stop = br_dev_stop, 207 .ndo_stop = br_dev_stop,
182 .ndo_start_xmit = br_dev_xmit, 208 .ndo_start_xmit = br_dev_xmit,
209 .ndo_get_stats = br_get_stats,
183 .ndo_set_mac_address = br_set_mac_address, 210 .ndo_set_mac_address = br_set_mac_address,
184 .ndo_set_multicast_list = br_dev_set_multicast_list, 211 .ndo_set_multicast_list = br_dev_set_multicast_list,
185 .ndo_change_mtu = br_change_mtu, 212 .ndo_change_mtu = br_change_mtu,
186 .ndo_do_ioctl = br_dev_ioctl, 213 .ndo_do_ioctl = br_dev_ioctl,
187}; 214};
188 215
216static void br_dev_free(struct net_device *dev)
217{
218 struct net_bridge *br = netdev_priv(dev);
219
220 free_percpu(br->stats);
221 free_netdev(dev);
222}
223
189void br_dev_setup(struct net_device *dev) 224void br_dev_setup(struct net_device *dev)
190{ 225{
191 random_ether_addr(dev->dev_addr); 226 random_ether_addr(dev->dev_addr);
192 ether_setup(dev); 227 ether_setup(dev);
193 228
194 dev->netdev_ops = &br_netdev_ops; 229 dev->netdev_ops = &br_netdev_ops;
195 dev->destructor = free_netdev; 230 dev->destructor = br_dev_free;
196 SET_ETHTOOL_OPS(dev, &br_ethtool_ops); 231 SET_ETHTOOL_OPS(dev, &br_ethtool_ops);
197 dev->tx_queue_len = 0; 232 dev->tx_queue_len = 0;
198 dev->priv_flags = IFF_EBRIDGE; 233 dev->priv_flags = IFF_EBRIDGE;
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
index d61e6f741125..8dbec83e50ca 100644
--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
@@ -19,6 +19,11 @@
19#include <linux/netfilter_bridge.h> 19#include <linux/netfilter_bridge.h>
20#include "br_private.h" 20#include "br_private.h"
21 21
22static int deliver_clone(const struct net_bridge_port *prev,
23 struct sk_buff *skb,
24 void (*__packet_hook)(const struct net_bridge_port *p,
25 struct sk_buff *skb));
26
22/* Don't forward packets to originating port or forwarding diasabled */ 27/* Don't forward packets to originating port or forwarding diasabled */
23static inline int should_deliver(const struct net_bridge_port *p, 28static inline int should_deliver(const struct net_bridge_port *p,
24 const struct sk_buff *skb) 29 const struct sk_buff *skb)
@@ -94,17 +99,22 @@ void br_deliver(const struct net_bridge_port *to, struct sk_buff *skb)
94} 99}
95 100
96/* called with rcu_read_lock */ 101/* called with rcu_read_lock */
97void br_forward(const struct net_bridge_port *to, struct sk_buff *skb) 102void br_forward(const struct net_bridge_port *to, struct sk_buff *skb, struct sk_buff *skb0)
98{ 103{
99 if (should_deliver(to, skb)) { 104 if (should_deliver(to, skb)) {
100 __br_forward(to, skb); 105 if (skb0)
106 deliver_clone(to, skb, __br_forward);
107 else
108 __br_forward(to, skb);
101 return; 109 return;
102 } 110 }
103 111
104 kfree_skb(skb); 112 if (!skb0)
113 kfree_skb(skb);
105} 114}
106 115
107static int deliver_clone(struct net_bridge_port *prev, struct sk_buff *skb, 116static int deliver_clone(const struct net_bridge_port *prev,
117 struct sk_buff *skb,
108 void (*__packet_hook)(const struct net_bridge_port *p, 118 void (*__packet_hook)(const struct net_bridge_port *p,
109 struct sk_buff *skb)) 119 struct sk_buff *skb))
110{ 120{
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index b6a3872f5681..b7cdd2e98050 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -185,6 +185,12 @@ static struct net_device *new_bridge_dev(struct net *net, const char *name)
185 br = netdev_priv(dev); 185 br = netdev_priv(dev);
186 br->dev = dev; 186 br->dev = dev;
187 187
188 br->stats = alloc_percpu(struct br_cpu_netstats);
189 if (!br->stats) {
190 free_netdev(dev);
191 return NULL;
192 }
193
188 spin_lock_init(&br->lock); 194 spin_lock_init(&br->lock);
189 INIT_LIST_HEAD(&br->port_list); 195 INIT_LIST_HEAD(&br->port_list);
190 spin_lock_init(&br->hash_lock); 196 spin_lock_init(&br->hash_lock);
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 53b39851d87d..333dfb7c5886 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -23,9 +23,11 @@ const u8 br_group_address[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
23static int br_pass_frame_up(struct sk_buff *skb) 23static int br_pass_frame_up(struct sk_buff *skb)
24{ 24{
25 struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev; 25 struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev;
26 struct net_bridge *br = netdev_priv(brdev);
27 struct br_cpu_netstats *brstats = this_cpu_ptr(br->stats);
26 28
27 brdev->stats.rx_packets++; 29 brstats->rx_packets++;
28 brdev->stats.rx_bytes += skb->len; 30 brstats->rx_bytes += skb->len;
29 31
30 indev = skb->dev; 32 indev = skb->dev;
31 skb->dev = brdev; 33 skb->dev = brdev;
@@ -70,7 +72,7 @@ int br_handle_frame_finish(struct sk_buff *skb)
70 72
71 if (is_multicast_ether_addr(dest)) { 73 if (is_multicast_ether_addr(dest)) {
72 mdst = br_mdb_get(br, skb); 74 mdst = br_mdb_get(br, skb);
73 if (mdst || BR_INPUT_SKB_CB(skb)->mrouters_only) { 75 if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) {
74 if ((mdst && !hlist_unhashed(&mdst->mglist)) || 76 if ((mdst && !hlist_unhashed(&mdst->mglist)) ||
75 br_multicast_is_router(br)) 77 br_multicast_is_router(br))
76 skb2 = skb; 78 skb2 = skb;
@@ -90,7 +92,7 @@ int br_handle_frame_finish(struct sk_buff *skb)
90 92
91 if (skb) { 93 if (skb) {
92 if (dst) 94 if (dst)
93 br_forward(dst->dst, skb); 95 br_forward(dst->dst, skb, skb2);
94 else 96 else
95 br_flood_forward(br, skb, skb2); 97 br_flood_forward(br, skb, skb2);
96 } 98 }
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 2559fb539836..6980625537ca 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -38,7 +38,7 @@ static struct net_bridge_mdb_entry *__br_mdb_ip_get(
38 struct net_bridge_mdb_entry *mp; 38 struct net_bridge_mdb_entry *mp;
39 struct hlist_node *p; 39 struct hlist_node *p;
40 40
41 hlist_for_each_entry(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) { 41 hlist_for_each_entry_rcu(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) {
42 if (dst == mp->addr) 42 if (dst == mp->addr)
43 return mp; 43 return mp;
44 } 44 }
@@ -49,22 +49,23 @@ static struct net_bridge_mdb_entry *__br_mdb_ip_get(
49static struct net_bridge_mdb_entry *br_mdb_ip_get( 49static struct net_bridge_mdb_entry *br_mdb_ip_get(
50 struct net_bridge_mdb_htable *mdb, __be32 dst) 50 struct net_bridge_mdb_htable *mdb, __be32 dst)
51{ 51{
52 if (!mdb)
53 return NULL;
54
52 return __br_mdb_ip_get(mdb, dst, br_ip_hash(mdb, dst)); 55 return __br_mdb_ip_get(mdb, dst, br_ip_hash(mdb, dst));
53} 56}
54 57
55struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, 58struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
56 struct sk_buff *skb) 59 struct sk_buff *skb)
57{ 60{
58 struct net_bridge_mdb_htable *mdb = br->mdb; 61 if (br->multicast_disabled)
59
60 if (!mdb || br->multicast_disabled)
61 return NULL; 62 return NULL;
62 63
63 switch (skb->protocol) { 64 switch (skb->protocol) {
64 case htons(ETH_P_IP): 65 case htons(ETH_P_IP):
65 if (BR_INPUT_SKB_CB(skb)->igmp) 66 if (BR_INPUT_SKB_CB(skb)->igmp)
66 break; 67 break;
67 return br_mdb_ip_get(mdb, ip_hdr(skb)->daddr); 68 return br_mdb_ip_get(br->mdb, ip_hdr(skb)->daddr);
68 } 69 }
69 70
70 return NULL; 71 return NULL;
@@ -627,8 +628,8 @@ static void br_multicast_port_query_expired(unsigned long data)
627 struct net_bridge *br = port->br; 628 struct net_bridge *br = port->br;
628 629
629 spin_lock(&br->multicast_lock); 630 spin_lock(&br->multicast_lock);
630 if (port && (port->state == BR_STATE_DISABLED || 631 if (port->state == BR_STATE_DISABLED ||
631 port->state == BR_STATE_BLOCKING)) 632 port->state == BR_STATE_BLOCKING)
632 goto out; 633 goto out;
633 634
634 if (port->multicast_startup_queries_sent < 635 if (port->multicast_startup_queries_sent <
@@ -823,6 +824,7 @@ static int br_multicast_query(struct net_bridge *br,
823 unsigned long max_delay; 824 unsigned long max_delay;
824 unsigned long now = jiffies; 825 unsigned long now = jiffies;
825 __be32 group; 826 __be32 group;
827 int err = 0;
826 828
827 spin_lock(&br->multicast_lock); 829 spin_lock(&br->multicast_lock);
828 if (!netif_running(br->dev) || 830 if (!netif_running(br->dev) ||
@@ -841,15 +843,17 @@ static int br_multicast_query(struct net_bridge *br,
841 group = 0; 843 group = 0;
842 } 844 }
843 } else { 845 } else {
844 if (!pskb_may_pull(skb, sizeof(struct igmpv3_query))) 846 if (!pskb_may_pull(skb, sizeof(struct igmpv3_query))) {
845 return -EINVAL; 847 err = -EINVAL;
848 goto out;
849 }
846 850
847 ih3 = igmpv3_query_hdr(skb); 851 ih3 = igmpv3_query_hdr(skb);
848 if (ih3->nsrcs) 852 if (ih3->nsrcs)
849 return 0; 853 goto out;
850 854
851 max_delay = ih3->code ? 1 : 855 max_delay = ih3->code ?
852 IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE); 856 IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1;
853 } 857 }
854 858
855 if (!group) 859 if (!group)
@@ -876,7 +880,7 @@ static int br_multicast_query(struct net_bridge *br,
876 880
877out: 881out:
878 spin_unlock(&br->multicast_lock); 882 spin_unlock(&br->multicast_lock);
879 return 0; 883 return err;
880} 884}
881 885
882static void br_multicast_leave_group(struct net_bridge *br, 886static void br_multicast_leave_group(struct net_bridge *br,
@@ -987,7 +991,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
987 991
988 err = pskb_trim_rcsum(skb2, len); 992 err = pskb_trim_rcsum(skb2, len);
989 if (err) 993 if (err)
990 return err; 994 goto err_out;
991 } 995 }
992 996
993 len -= ip_hdrlen(skb2); 997 len -= ip_hdrlen(skb2);
@@ -1009,7 +1013,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
1009 case CHECKSUM_NONE: 1013 case CHECKSUM_NONE:
1010 skb2->csum = 0; 1014 skb2->csum = 0;
1011 if (skb_checksum_complete(skb2)) 1015 if (skb_checksum_complete(skb2))
1012 return -EINVAL; 1016 goto out;
1013 } 1017 }
1014 1018
1015 err = 0; 1019 err = 0;
@@ -1036,6 +1040,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
1036 1040
1037out: 1041out:
1038 __skb_push(skb2, offset); 1042 __skb_push(skb2, offset);
1043err_out:
1039 if (skb2 != skb) 1044 if (skb2 != skb)
1040 kfree_skb(skb2); 1045 kfree_skb(skb2);
1041 return err; 1046 return err;
@@ -1135,7 +1140,7 @@ void br_multicast_stop(struct net_bridge *br)
1135 1140
1136 if (mdb->old) { 1141 if (mdb->old) {
1137 spin_unlock_bh(&br->multicast_lock); 1142 spin_unlock_bh(&br->multicast_lock);
1138 synchronize_rcu_bh(); 1143 rcu_barrier_bh();
1139 spin_lock_bh(&br->multicast_lock); 1144 spin_lock_bh(&br->multicast_lock);
1140 WARN_ON(mdb->old); 1145 WARN_ON(mdb->old);
1141 } 1146 }
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 1cf2cef78584..791d4ab0fd4d 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -135,6 +135,14 @@ struct net_bridge
135 spinlock_t lock; 135 spinlock_t lock;
136 struct list_head port_list; 136 struct list_head port_list;
137 struct net_device *dev; 137 struct net_device *dev;
138
139 struct br_cpu_netstats __percpu {
140 unsigned long rx_packets;
141 unsigned long rx_bytes;
142 unsigned long tx_packets;
143 unsigned long tx_bytes;
144 } *stats;
145
138 spinlock_t hash_lock; 146 spinlock_t hash_lock;
139 struct hlist_head hash[BR_HASH_SIZE]; 147 struct hlist_head hash[BR_HASH_SIZE];
140 unsigned long feature_mask; 148 unsigned long feature_mask;
@@ -206,12 +214,20 @@ struct net_bridge
206 214
207struct br_input_skb_cb { 215struct br_input_skb_cb {
208 struct net_device *brdev; 216 struct net_device *brdev;
217#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
209 int igmp; 218 int igmp;
210 int mrouters_only; 219 int mrouters_only;
220#endif
211}; 221};
212 222
213#define BR_INPUT_SKB_CB(__skb) ((struct br_input_skb_cb *)(__skb)->cb) 223#define BR_INPUT_SKB_CB(__skb) ((struct br_input_skb_cb *)(__skb)->cb)
214 224
225#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
226# define BR_INPUT_SKB_CB_MROUTERS_ONLY(__skb) (BR_INPUT_SKB_CB(__skb)->mrouters_only)
227#else
228# define BR_INPUT_SKB_CB_MROUTERS_ONLY(__skb) (0)
229#endif
230
215extern struct notifier_block br_device_notifier; 231extern struct notifier_block br_device_notifier;
216extern const u8 br_group_address[ETH_ALEN]; 232extern const u8 br_group_address[ETH_ALEN];
217 233
@@ -252,7 +268,7 @@ extern void br_deliver(const struct net_bridge_port *to,
252 struct sk_buff *skb); 268 struct sk_buff *skb);
253extern int br_dev_queue_push_xmit(struct sk_buff *skb); 269extern int br_dev_queue_push_xmit(struct sk_buff *skb);
254extern void br_forward(const struct net_bridge_port *to, 270extern void br_forward(const struct net_bridge_port *to,
255 struct sk_buff *skb); 271 struct sk_buff *skb, struct sk_buff *skb0);
256extern int br_forward_finish(struct sk_buff *skb); 272extern int br_forward_finish(struct sk_buff *skb);
257extern void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb); 273extern void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb);
258extern void br_flood_forward(struct net_bridge *br, struct sk_buff *skb, 274extern void br_flood_forward(struct net_bridge *br, struct sk_buff *skb,
@@ -423,7 +439,7 @@ extern void br_ifinfo_notify(int event, struct net_bridge_port *port);
423 439
424#ifdef CONFIG_SYSFS 440#ifdef CONFIG_SYSFS
425/* br_sysfs_if.c */ 441/* br_sysfs_if.c */
426extern struct sysfs_ops brport_sysfs_ops; 442extern const struct sysfs_ops brport_sysfs_ops;
427extern int br_sysfs_addif(struct net_bridge_port *p); 443extern int br_sysfs_addif(struct net_bridge_port *p);
428 444
429/* br_sysfs_br.c */ 445/* br_sysfs_br.c */
diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c
index 696596cd3384..0b9916489d6b 100644
--- a/net/bridge/br_sysfs_if.c
+++ b/net/bridge/br_sysfs_if.c
@@ -238,7 +238,7 @@ static ssize_t brport_store(struct kobject * kobj,
238 return ret; 238 return ret;
239} 239}
240 240
241struct sysfs_ops brport_sysfs_ops = { 241const struct sysfs_ops brport_sysfs_ops = {
242 .show = brport_show, 242 .show = brport_show,
243 .store = brport_store, 243 .store = brport_store,
244}; 244};
diff --git a/net/bridge/netfilter/ebt_ip6.c b/net/bridge/netfilter/ebt_ip6.c
index 4644cc9c0579..63e3888d20cf 100644
--- a/net/bridge/netfilter/ebt_ip6.c
+++ b/net/bridge/netfilter/ebt_ip6.c
@@ -4,7 +4,7 @@
4 * Authors: 4 * Authors:
5 * Manohar Castelino <manohar.r.castelino@intel.com> 5 * Manohar Castelino <manohar.r.castelino@intel.com>
6 * Kuo-Lang Tseng <kuo-lang.tseng@intel.com> 6 * Kuo-Lang Tseng <kuo-lang.tseng@intel.com>
7 * Jan Engelhardt <jengelh@computergmbh.de> 7 * Jan Engelhardt <jengelh@medozas.de>
8 * 8 *
9 * Summary: 9 * Summary:
10 * This is just a modification of the IPv4 code written by 10 * This is just a modification of the IPv4 code written by
@@ -129,4 +129,5 @@ static void __exit ebt_ip6_fini(void)
129module_init(ebt_ip6_init); 129module_init(ebt_ip6_init);
130module_exit(ebt_ip6_fini); 130module_exit(ebt_ip6_fini);
131MODULE_DESCRIPTION("Ebtables: IPv6 protocol packet match"); 131MODULE_DESCRIPTION("Ebtables: IPv6 protocol packet match");
132MODULE_AUTHOR("Kuo-Lang Tseng <kuo-lang.tseng@intel.com>");
132MODULE_LICENSE("GPL"); 133MODULE_LICENSE("GPL");