diff options
Diffstat (limited to 'net/bridge')
-rw-r--r-- | net/bridge/br_netfilter.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 6fc9ecc4eb39..f29450b788be 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c | |||
@@ -113,6 +113,25 @@ static inline struct net_device *bridge_parent(const struct net_device *dev) | |||
113 | return port ? port->br->dev : NULL; | 113 | return port ? port->br->dev : NULL; |
114 | } | 114 | } |
115 | 115 | ||
116 | static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb) | ||
117 | { | ||
118 | skb->nf_bridge = kzalloc(sizeof(struct nf_bridge_info), GFP_ATOMIC); | ||
119 | if (likely(skb->nf_bridge)) | ||
120 | atomic_set(&(skb->nf_bridge->use), 1); | ||
121 | |||
122 | return skb->nf_bridge; | ||
123 | } | ||
124 | |||
125 | static inline void nf_bridge_save_header(struct sk_buff *skb) | ||
126 | { | ||
127 | int header_size = 16; | ||
128 | |||
129 | if (skb->protocol == htons(ETH_P_8021Q)) | ||
130 | header_size = 18; | ||
131 | |||
132 | memcpy(skb->nf_bridge->data, skb->data - header_size, header_size); | ||
133 | } | ||
134 | |||
116 | /* PF_BRIDGE/PRE_ROUTING *********************************************/ | 135 | /* PF_BRIDGE/PRE_ROUTING *********************************************/ |
117 | /* Undo the changes made for ip6tables PREROUTING and continue the | 136 | /* Undo the changes made for ip6tables PREROUTING and continue the |
118 | * bridge PRE_ROUTING hook. */ | 137 | * bridge PRE_ROUTING hook. */ |
@@ -371,7 +390,6 @@ static unsigned int br_nf_pre_routing_ipv6(unsigned int hook, | |||
371 | { | 390 | { |
372 | struct ipv6hdr *hdr; | 391 | struct ipv6hdr *hdr; |
373 | u32 pkt_len; | 392 | u32 pkt_len; |
374 | struct nf_bridge_info *nf_bridge; | ||
375 | 393 | ||
376 | if (skb->len < sizeof(struct ipv6hdr)) | 394 | if (skb->len < sizeof(struct ipv6hdr)) |
377 | goto inhdr_error; | 395 | goto inhdr_error; |
@@ -400,7 +418,7 @@ static unsigned int br_nf_pre_routing_ipv6(unsigned int hook, | |||
400 | goto inhdr_error; | 418 | goto inhdr_error; |
401 | 419 | ||
402 | nf_bridge_put(skb->nf_bridge); | 420 | nf_bridge_put(skb->nf_bridge); |
403 | if ((nf_bridge = nf_bridge_alloc(skb)) == NULL) | 421 | if (!nf_bridge_alloc(skb)) |
404 | return NF_DROP; | 422 | return NF_DROP; |
405 | if (!setup_pre_routing(skb)) | 423 | if (!setup_pre_routing(skb)) |
406 | return NF_DROP; | 424 | return NF_DROP; |
@@ -428,7 +446,6 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb, | |||
428 | struct iphdr *iph; | 446 | struct iphdr *iph; |
429 | __u32 len; | 447 | __u32 len; |
430 | struct sk_buff *skb = *pskb; | 448 | struct sk_buff *skb = *pskb; |
431 | struct nf_bridge_info *nf_bridge; | ||
432 | 449 | ||
433 | if (skb->protocol == htons(ETH_P_IPV6) || IS_VLAN_IPV6(skb)) { | 450 | if (skb->protocol == htons(ETH_P_IPV6) || IS_VLAN_IPV6(skb)) { |
434 | #ifdef CONFIG_SYSCTL | 451 | #ifdef CONFIG_SYSCTL |
@@ -485,7 +502,7 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb, | |||
485 | } | 502 | } |
486 | 503 | ||
487 | nf_bridge_put(skb->nf_bridge); | 504 | nf_bridge_put(skb->nf_bridge); |
488 | if ((nf_bridge = nf_bridge_alloc(skb)) == NULL) | 505 | if (!nf_bridge_alloc(skb)) |
489 | return NF_DROP; | 506 | return NF_DROP; |
490 | if (!setup_pre_routing(skb)) | 507 | if (!setup_pre_routing(skb)) |
491 | return NF_DROP; | 508 | return NF_DROP; |