diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/bridge/br_forward.c | 5 | ||||
-rw-r--r-- | net/bridge/br_netfilter.c | 27 |
2 files changed, 26 insertions, 6 deletions
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index 864fbbc7b24d..191b861e5e53 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c | |||
@@ -38,13 +38,10 @@ int br_dev_queue_push_xmit(struct sk_buff *skb) | |||
38 | if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb)) | 38 | if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb)) |
39 | kfree_skb(skb); | 39 | kfree_skb(skb); |
40 | else { | 40 | else { |
41 | #ifdef CONFIG_BRIDGE_NETFILTER | ||
42 | /* ip_refrag calls ip_fragment, doesn't copy the MAC header. */ | 41 | /* ip_refrag calls ip_fragment, doesn't copy the MAC header. */ |
43 | if (nf_bridge_maybe_copy_header(skb)) | 42 | if (nf_bridge_maybe_copy_header(skb)) |
44 | kfree_skb(skb); | 43 | kfree_skb(skb); |
45 | else | 44 | else { |
46 | #endif | ||
47 | { | ||
48 | skb_push(skb, ETH_HLEN); | 45 | skb_push(skb, ETH_HLEN); |
49 | 46 | ||
50 | dev_queue_xmit(skb); | 47 | dev_queue_xmit(skb); |
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 05b3de888243..b498efcfe451 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c | |||
@@ -127,14 +127,37 @@ static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb) | |||
127 | 127 | ||
128 | static inline void nf_bridge_save_header(struct sk_buff *skb) | 128 | static inline void nf_bridge_save_header(struct sk_buff *skb) |
129 | { | 129 | { |
130 | int header_size = 16; | 130 | int header_size = ETH_HLEN; |
131 | 131 | ||
132 | if (skb->protocol == htons(ETH_P_8021Q)) | 132 | if (skb->protocol == htons(ETH_P_8021Q)) |
133 | header_size = 18; | 133 | header_size += VLAN_HLEN; |
134 | 134 | ||
135 | memcpy(skb->nf_bridge->data, skb->data - header_size, header_size); | 135 | memcpy(skb->nf_bridge->data, skb->data - header_size, header_size); |
136 | } | 136 | } |
137 | 137 | ||
138 | /* | ||
139 | * When forwarding bridge frames, we save a copy of the original | ||
140 | * header before processing. | ||
141 | */ | ||
142 | int nf_bridge_copy_header(struct sk_buff *skb) | ||
143 | { | ||
144 | int err; | ||
145 | int header_size = ETH_HLEN; | ||
146 | |||
147 | if (skb->protocol == htons(ETH_P_8021Q)) | ||
148 | header_size += VLAN_HLEN; | ||
149 | |||
150 | err = skb_cow(skb, header_size); | ||
151 | if (err) | ||
152 | return err; | ||
153 | |||
154 | memcpy(skb->data - header_size, skb->nf_bridge->data, header_size); | ||
155 | |||
156 | if (skb->protocol == htons(ETH_P_8021Q)) | ||
157 | __skb_push(skb, VLAN_HLEN); | ||
158 | return 0; | ||
159 | } | ||
160 | |||
138 | /* PF_BRIDGE/PRE_ROUTING *********************************************/ | 161 | /* PF_BRIDGE/PRE_ROUTING *********************************************/ |
139 | /* Undo the changes made for ip6tables PREROUTING and continue the | 162 | /* Undo the changes made for ip6tables PREROUTING and continue the |
140 | * bridge PRE_ROUTING hook. */ | 163 | * bridge PRE_ROUTING hook. */ |