aboutsummaryrefslogtreecommitdiff
path: root/net/bridge
diff options
context:
space:
mode:
Diffstat (limited to 'net/bridge')
-rw-r--r--net/bridge/br_forward.c8
-rw-r--r--net/bridge/br_input.c3
-rw-r--r--net/bridge/br_netfilter.c13
-rw-r--r--net/bridge/netfilter/ebtables.c38
4 files changed, 34 insertions, 28 deletions
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
index 2d24fb400e0..56f3aa47e75 100644
--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
+#include <linux/if_vlan.h>
#include <linux/netfilter_bridge.h>
#include "br_private.h"
@@ -29,10 +30,15 @@ static inline int should_deliver(const struct net_bridge_port *p,
return 1;
}
+static inline unsigned packet_length(const struct sk_buff *skb)
+{
+ return skb->len - (skb->protocol == htons(ETH_P_8021Q) ? VLAN_HLEN : 0);
+}
+
int br_dev_queue_push_xmit(struct sk_buff *skb)
{
/* drop mtu oversized packets except tso */
- if (skb->len > skb->dev->mtu && !skb_shinfo(skb)->tso_size)
+ if (packet_length(skb) > skb->dev->mtu && !skb_shinfo(skb)->tso_size)
kfree_skb(skb);
else {
#ifdef CONFIG_BRIDGE_NETFILTER
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index b7766562d72..b0b7f55c1ed 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -125,9 +125,6 @@ int br_handle_frame(struct net_bridge_port *p, struct sk_buff **pskb)
struct sk_buff *skb = *pskb;
const unsigned char *dest = eth_hdr(skb)->h_dest;
- if (p->state == BR_STATE_DISABLED)
- goto err;
-
if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
goto err;
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index f29450b788b..3da9264449f 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -765,6 +765,15 @@ out:
return NF_STOLEN;
}
+static int br_nf_dev_queue_xmit(struct sk_buff *skb)
+{
+ if (skb->protocol == htons(ETH_P_IP) &&
+ skb->len > skb->dev->mtu &&
+ !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
+ return ip_fragment(skb, br_dev_queue_push_xmit);
+ else
+ return br_dev_queue_push_xmit(skb);
+}
/* PF_BRIDGE/POST_ROUTING ********************************************/
static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb,
@@ -824,7 +833,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb,
realoutdev = nf_bridge->netoutdev;
#endif
NF_HOOK(pf, NF_IP_POST_ROUTING, skb, NULL, realoutdev,
- br_dev_queue_push_xmit);
+ br_nf_dev_queue_xmit);
return NF_STOLEN;
@@ -869,7 +878,7 @@ static unsigned int ip_sabotage_out(unsigned int hook, struct sk_buff **pskb,
if ((out->hard_start_xmit == br_dev_xmit &&
okfn != br_nf_forward_finish &&
- okfn != br_nf_local_out_finish && okfn != br_dev_queue_push_xmit)
+ okfn != br_nf_local_out_finish && okfn != br_nf_dev_queue_xmit)
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
|| ((out->priv_flags & IFF_802_1Q_VLAN) &&
VLAN_DEV_INFO(out)->real_dev->hard_start_xmit == br_dev_xmit)
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 01eae97c53d..3a13ed64345 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -824,14 +824,14 @@ static int translate_table(struct ebt_replace *repl,
if (udc_cnt) {
/* this will get free'd in do_replace()/ebt_register_table()
if an error occurs */
- newinfo->chainstack = (struct ebt_chainstack **)
- vmalloc((highest_possible_processor_id()+1)
- * sizeof(struct ebt_chainstack));
+ newinfo->chainstack =
+ vmalloc((highest_possible_processor_id()+1)
+ * sizeof(*(newinfo->chainstack)));
if (!newinfo->chainstack)
return -ENOMEM;
- for_each_cpu(i) {
+ for_each_possible_cpu(i) {
newinfo->chainstack[i] =
- vmalloc(udc_cnt * sizeof(struct ebt_chainstack));
+ vmalloc(udc_cnt * sizeof(*(newinfo->chainstack[0])));
if (!newinfo->chainstack[i]) {
while (i)
vfree(newinfo->chainstack[--i]);
@@ -841,8 +841,7 @@ static int translate_table(struct ebt_replace *repl,
}
}
- cl_s = (struct ebt_cl_stack *)
- vmalloc(udc_cnt * sizeof(struct ebt_cl_stack));
+ cl_s = vmalloc(udc_cnt * sizeof(*cl_s));
if (!cl_s)
return -ENOMEM;
i = 0; /* the i'th udc */
@@ -901,7 +900,7 @@ static void get_counters(struct ebt_counter *oldcounters,
sizeof(struct ebt_counter) * nentries);
/* add other counters to those of cpu 0 */
- for_each_cpu(cpu) {
+ for_each_possible_cpu(cpu) {
if (cpu == 0)
continue;
counter_base = COUNTER_BASE(oldcounters, nentries, cpu);
@@ -944,8 +943,7 @@ static int do_replace(void __user *user, unsigned int len)
countersize = COUNTER_OFFSET(tmp.nentries) *
(highest_possible_processor_id()+1);
- newinfo = (struct ebt_table_info *)
- vmalloc(sizeof(struct ebt_table_info) + countersize);
+ newinfo = vmalloc(sizeof(*newinfo) + countersize);
if (!newinfo)
return -ENOMEM;
@@ -967,8 +965,7 @@ static int do_replace(void __user *user, unsigned int len)
/* the user wants counters back
the check on the size is done later, when we have the lock */
if (tmp.num_counters) {
- counterstmp = (struct ebt_counter *)
- vmalloc(tmp.num_counters * sizeof(struct ebt_counter));
+ counterstmp = vmalloc(tmp.num_counters * sizeof(*counterstmp));
if (!counterstmp) {
ret = -ENOMEM;
goto free_entries;
@@ -1036,7 +1033,7 @@ static int do_replace(void __user *user, unsigned int len)
vfree(table->entries);
if (table->chainstack) {
- for_each_cpu(i)
+ for_each_possible_cpu(i)
vfree(table->chainstack[i]);
vfree(table->chainstack);
}
@@ -1054,7 +1051,7 @@ free_counterstmp:
vfree(counterstmp);
/* can be initialized in translate_table() */
if (newinfo->chainstack) {
- for_each_cpu(i)
+ for_each_possible_cpu(i)
vfree(newinfo->chainstack[i]);
vfree(newinfo->chainstack);
}
@@ -1148,8 +1145,7 @@ int ebt_register_table(struct ebt_table *table)
countersize = COUNTER_OFFSET(table->table->nentries) *
(highest_possible_processor_id()+1);
- newinfo = (struct ebt_table_info *)
- vmalloc(sizeof(struct ebt_table_info) + countersize);
+ newinfo = vmalloc(sizeof(*newinfo) + countersize);
ret = -ENOMEM;
if (!newinfo)
return -ENOMEM;
@@ -1201,7 +1197,7 @@ free_unlock:
mutex_unlock(&ebt_mutex);
free_chainstack:
if (newinfo->chainstack) {
- for_each_cpu(i)
+ for_each_possible_cpu(i)
vfree(newinfo->chainstack[i]);
vfree(newinfo->chainstack);
}
@@ -1224,7 +1220,7 @@ void ebt_unregister_table(struct ebt_table *table)
mutex_unlock(&ebt_mutex);
vfree(table->private->entries);
if (table->private->chainstack) {
- for_each_cpu(i)
+ for_each_possible_cpu(i)
vfree(table->private->chainstack[i]);
vfree(table->private->chainstack);
}
@@ -1247,8 +1243,7 @@ static int update_counters(void __user *user, unsigned int len)
if (hlp.num_counters == 0)
return -EINVAL;
- if ( !(tmp = (struct ebt_counter *)
- vmalloc(hlp.num_counters * sizeof(struct ebt_counter))) ){
+ if (!(tmp = vmalloc(hlp.num_counters * sizeof(*tmp)))) {
MEMPRINT("Update_counters && nomemory\n");
return -ENOMEM;
}
@@ -1377,8 +1372,7 @@ static int copy_everything_to_user(struct ebt_table *t, void __user *user,
BUGPRINT("Num_counters wrong\n");
return -EINVAL;
}
- counterstmp = (struct ebt_counter *)
- vmalloc(nentries * sizeof(struct ebt_counter));
+ counterstmp = vmalloc(nentries * sizeof(*counterstmp));
if (!counterstmp) {
MEMPRINT("Couldn't copy counters, out of memory\n");
return -ENOMEM;