diff options
Diffstat (limited to 'net/bridge')
-rw-r--r-- | net/bridge/br_forward.c | 8 | ||||
-rw-r--r-- | net/bridge/br_input.c | 3 | ||||
-rw-r--r-- | net/bridge/br_netfilter.c | 13 | ||||
-rw-r--r-- | net/bridge/netfilter/ebtables.c | 38 |
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; |