aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/bridge/br_forward.c5
-rw-r--r--net/bridge/br_netfilter.c27
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
128static inline void nf_bridge_save_header(struct sk_buff *skb) 128static 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 */
142int 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. */