diff options
| -rw-r--r-- | include/linux/netfilter_bridge.h | 27 | ||||
| -rw-r--r-- | net/bridge/br_netfilter.c | 25 |
2 files changed, 21 insertions, 31 deletions
diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h index de4d397865ce..a75b84bb9a88 100644 --- a/include/linux/netfilter_bridge.h +++ b/include/linux/netfilter_bridge.h | |||
| @@ -47,22 +47,6 @@ enum nf_br_hook_priorities { | |||
| 47 | #define BRNF_BRIDGED 0x08 | 47 | #define BRNF_BRIDGED 0x08 |
| 48 | #define BRNF_NF_BRIDGE_PREROUTING 0x10 | 48 | #define BRNF_NF_BRIDGE_PREROUTING 0x10 |
| 49 | 49 | ||
| 50 | static inline | ||
| 51 | struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb) | ||
| 52 | { | ||
| 53 | struct nf_bridge_info **nf_bridge = &(skb->nf_bridge); | ||
| 54 | |||
| 55 | if ((*nf_bridge = kmalloc(sizeof(**nf_bridge), GFP_ATOMIC)) != NULL) { | ||
| 56 | atomic_set(&(*nf_bridge)->use, 1); | ||
| 57 | (*nf_bridge)->mask = 0; | ||
| 58 | (*nf_bridge)->physindev = (*nf_bridge)->physoutdev = NULL; | ||
| 59 | #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) | ||
| 60 | (*nf_bridge)->netoutdev = NULL; | ||
| 61 | #endif | ||
| 62 | } | ||
| 63 | |||
| 64 | return *nf_bridge; | ||
| 65 | } | ||
| 66 | 50 | ||
| 67 | /* Only used in br_forward.c */ | 51 | /* Only used in br_forward.c */ |
| 68 | static inline | 52 | static inline |
| @@ -77,17 +61,6 @@ void nf_bridge_maybe_copy_header(struct sk_buff *skb) | |||
| 77 | } | 61 | } |
| 78 | } | 62 | } |
| 79 | 63 | ||
| 80 | static inline | ||
| 81 | void nf_bridge_save_header(struct sk_buff *skb) | ||
| 82 | { | ||
| 83 | int header_size = 16; | ||
| 84 | |||
| 85 | if (skb->protocol == __constant_htons(ETH_P_8021Q)) | ||
| 86 | header_size = 18; | ||
| 87 | |||
| 88 | memcpy(skb->nf_bridge->data, skb->data - header_size, header_size); | ||
| 89 | } | ||
| 90 | |||
| 91 | /* This is called by the IP fragmenting code and it ensures there is | 64 | /* This is called by the IP fragmenting code and it ensures there is |
| 92 | * enough room for the encapsulating header (if there is one). */ | 65 | * enough room for the encapsulating header (if there is one). */ |
| 93 | static inline | 66 | static inline |
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; |
