aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2007-05-03 06:36:16 -0400
committerDavid S. Miller <davem@davemloft.net>2007-05-03 06:36:16 -0400
commitfc38582db98533066f4ba64f948720483fbfe7b2 (patch)
tree350d7e725e4dedfbf41b3ee54d585ed2d609b607 /net
parentcfd6c38096d75c8b86782683c5f45c415a505b78 (diff)
[NETFILTER]: bridge netfilter: consolidate header pushing/pulling code
Consolidate the common push/pull sequences into a few helper functions. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/bridge/br_netfilter.c138
1 files changed, 40 insertions, 98 deletions
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 9b2986b182ba..fa779874b9dd 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -142,14 +142,33 @@ static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb)
142 return skb->nf_bridge; 142 return skb->nf_bridge;
143} 143}
144 144
145static inline void nf_bridge_save_header(struct sk_buff *skb) 145static inline void nf_bridge_push_encap_header(struct sk_buff *skb)
146{
147 unsigned int len = nf_bridge_encap_header_len(skb);
148
149 skb_push(skb, len);
150 skb->network_header -= len;
151}
152
153static inline void nf_bridge_pull_encap_header(struct sk_buff *skb)
146{ 154{
147 int header_size = ETH_HLEN; 155 unsigned int len = nf_bridge_encap_header_len(skb);
156
157 skb_pull(skb, len);
158 skb->network_header += len;
159}
148 160
149 if (skb->protocol == htons(ETH_P_8021Q)) 161static inline void nf_bridge_pull_encap_header_rcsum(struct sk_buff *skb)
150 header_size += VLAN_HLEN; 162{
151 else if (skb->protocol == htons(ETH_P_PPP_SES)) 163 unsigned int len = nf_bridge_encap_header_len(skb);
152 header_size += PPPOE_SES_HLEN; 164
165 skb_pull_rcsum(skb, len);
166 skb->network_header += len;
167}
168
169static inline void nf_bridge_save_header(struct sk_buff *skb)
170{
171 int header_size = ETH_HLEN + nf_bridge_encap_header_len(skb);
153 172
154 skb_copy_from_linear_data_offset(skb, -header_size, 173 skb_copy_from_linear_data_offset(skb, -header_size,
155 skb->nf_bridge->data, header_size); 174 skb->nf_bridge->data, header_size);
@@ -162,12 +181,7 @@ static inline void nf_bridge_save_header(struct sk_buff *skb)
162int nf_bridge_copy_header(struct sk_buff *skb) 181int nf_bridge_copy_header(struct sk_buff *skb)
163{ 182{
164 int err; 183 int err;
165 int header_size = ETH_HLEN; 184 int header_size = ETH_HLEN + nf_bridge_encap_header_len(skb);
166
167 if (skb->protocol == htons(ETH_P_8021Q))
168 header_size += VLAN_HLEN;
169 else if (skb->protocol == htons(ETH_P_PPP_SES))
170 header_size += PPPOE_SES_HLEN;
171 185
172 err = skb_cow(skb, header_size); 186 err = skb_cow(skb, header_size);
173 if (err) 187 if (err)
@@ -175,11 +189,7 @@ int nf_bridge_copy_header(struct sk_buff *skb)
175 189
176 skb_copy_to_linear_data_offset(skb, -header_size, 190 skb_copy_to_linear_data_offset(skb, -header_size,
177 skb->nf_bridge->data, header_size); 191 skb->nf_bridge->data, header_size);
178 192 __skb_push(skb, nf_bridge_encap_header_len(skb));
179 if (skb->protocol == htons(ETH_P_8021Q))
180 __skb_push(skb, VLAN_HLEN);
181 else if (skb->protocol == htons(ETH_P_PPP_SES))
182 __skb_push(skb, PPPOE_SES_HLEN);
183 return 0; 193 return 0;
184} 194}
185 195
@@ -200,13 +210,7 @@ static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb)
200 dst_hold(skb->dst); 210 dst_hold(skb->dst);
201 211
202 skb->dev = nf_bridge->physindev; 212 skb->dev = nf_bridge->physindev;
203 if (skb->protocol == htons(ETH_P_8021Q)) { 213 nf_bridge_push_encap_header(skb);
204 skb_push(skb, VLAN_HLEN);
205 skb->network_header -= VLAN_HLEN;
206 } else if (skb->protocol == htons(ETH_P_PPP_SES)) {
207 skb_push(skb, PPPOE_SES_HLEN);
208 skb->network_header -= PPPOE_SES_HLEN;
209 }
210 NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, 214 NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
211 br_handle_frame_finish, 1); 215 br_handle_frame_finish, 1);
212 216
@@ -284,13 +288,7 @@ static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
284 if (!skb->dev) 288 if (!skb->dev)
285 kfree_skb(skb); 289 kfree_skb(skb);
286 else { 290 else {
287 if (skb->protocol == htons(ETH_P_8021Q)) { 291 nf_bridge_pull_encap_header(skb);
288 skb_pull(skb, VLAN_HLEN);
289 skb->network_header += VLAN_HLEN;
290 } else if (skb->protocol == htons(ETH_P_PPP_SES)) {
291 skb_pull(skb, PPPOE_SES_HLEN);
292 skb->network_header += PPPOE_SES_HLEN;
293 }
294 skb->dst->output(skb); 292 skb->dst->output(skb);
295 } 293 }
296 return 0; 294 return 0;
@@ -356,15 +354,7 @@ bridged_dnat:
356 * bridged frame */ 354 * bridged frame */
357 nf_bridge->mask |= BRNF_BRIDGED_DNAT; 355 nf_bridge->mask |= BRNF_BRIDGED_DNAT;
358 skb->dev = nf_bridge->physindev; 356 skb->dev = nf_bridge->physindev;
359 if (skb->protocol == 357 nf_bridge_push_encap_header(skb);
360 htons(ETH_P_8021Q)) {
361 skb_push(skb, VLAN_HLEN);
362 skb->network_header -= VLAN_HLEN;
363 } else if(skb->protocol ==
364 htons(ETH_P_PPP_SES)) {
365 skb_push(skb, PPPOE_SES_HLEN);
366 skb->network_header -= PPPOE_SES_HLEN;
367 }
368 NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, 358 NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING,
369 skb, skb->dev, NULL, 359 skb, skb->dev, NULL,
370 br_nf_pre_routing_finish_bridge, 360 br_nf_pre_routing_finish_bridge,
@@ -380,13 +370,7 @@ bridged_dnat:
380 } 370 }
381 371
382 skb->dev = nf_bridge->physindev; 372 skb->dev = nf_bridge->physindev;
383 if (skb->protocol == htons(ETH_P_8021Q)) { 373 nf_bridge_push_encap_header(skb);
384 skb_push(skb, VLAN_HLEN);
385 skb->network_header -= VLAN_HLEN;
386 } else if (skb->protocol == htons(ETH_P_PPP_SES)) {
387 skb_push(skb, PPPOE_SES_HLEN);
388 skb->network_header -= PPPOE_SES_HLEN;
389 }
390 NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, 374 NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
391 br_handle_frame_finish, 1); 375 br_handle_frame_finish, 1);
392 376
@@ -536,14 +520,7 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
536#endif 520#endif
537 if ((skb = skb_share_check(*pskb, GFP_ATOMIC)) == NULL) 521 if ((skb = skb_share_check(*pskb, GFP_ATOMIC)) == NULL)
538 goto out; 522 goto out;
539 523 nf_bridge_pull_encap_header_rcsum(skb);
540 if (skb->protocol == htons(ETH_P_8021Q)) {
541 skb_pull_rcsum(skb, VLAN_HLEN);
542 skb->network_header += VLAN_HLEN;
543 } else if (skb->protocol == htons(ETH_P_PPP_SES)) {
544 skb_pull_rcsum(skb, PPPOE_SES_HLEN);
545 skb->network_header += PPPOE_SES_HLEN;
546 }
547 return br_nf_pre_routing_ipv6(hook, skb, in, out, okfn); 524 return br_nf_pre_routing_ipv6(hook, skb, in, out, okfn);
548 } 525 }
549#ifdef CONFIG_SYSCTL 526#ifdef CONFIG_SYSCTL
@@ -557,14 +534,7 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
557 534
558 if ((skb = skb_share_check(*pskb, GFP_ATOMIC)) == NULL) 535 if ((skb = skb_share_check(*pskb, GFP_ATOMIC)) == NULL)
559 goto out; 536 goto out;
560 537 nf_bridge_pull_encap_header_rcsum(skb);
561 if (skb->protocol == htons(ETH_P_8021Q)) {
562 skb_pull_rcsum(skb, VLAN_HLEN);
563 skb->network_header += VLAN_HLEN;
564 } else if (skb->protocol == htons(ETH_P_PPP_SES)) {
565 skb_pull_rcsum(skb, PPPOE_SES_HLEN);
566 skb->network_header += PPPOE_SES_HLEN;
567 }
568 538
569 if (!pskb_may_pull(skb, sizeof(struct iphdr))) 539 if (!pskb_may_pull(skb, sizeof(struct iphdr)))
570 goto inhdr_error; 540 goto inhdr_error;
@@ -642,13 +612,7 @@ static int br_nf_forward_finish(struct sk_buff *skb)
642 } else { 612 } else {
643 in = *((struct net_device **)(skb->cb)); 613 in = *((struct net_device **)(skb->cb));
644 } 614 }
645 if (skb->protocol == htons(ETH_P_8021Q)) { 615 nf_bridge_push_encap_header(skb);
646 skb_push(skb, VLAN_HLEN);
647 skb->network_header -= VLAN_HLEN;
648 } else if (skb->protocol == htons(ETH_P_PPP_SES)) {
649 skb_push(skb, PPPOE_SES_HLEN);
650 skb->network_header -= PPPOE_SES_HLEN;
651 }
652 NF_HOOK_THRESH(PF_BRIDGE, NF_BR_FORWARD, skb, in, 616 NF_HOOK_THRESH(PF_BRIDGE, NF_BR_FORWARD, skb, in,
653 skb->dev, br_forward_finish, 1); 617 skb->dev, br_forward_finish, 1);
654 return 0; 618 return 0;
@@ -682,13 +646,7 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb,
682 else 646 else
683 pf = PF_INET6; 647 pf = PF_INET6;
684 648
685 if (skb->protocol == htons(ETH_P_8021Q)) { 649 nf_bridge_pull_encap_header(*pskb);
686 skb_pull(*pskb, VLAN_HLEN);
687 (*pskb)->network_header += VLAN_HLEN;
688 } else if (skb->protocol == htons(ETH_P_PPP_SES)) {
689 skb_pull(*pskb, PPPOE_SES_HLEN);
690 (*pskb)->network_header += PPPOE_SES_HLEN;
691 }
692 650
693 nf_bridge = skb->nf_bridge; 651 nf_bridge = skb->nf_bridge;
694 if (skb->pkt_type == PACKET_OTHERHOST) { 652 if (skb->pkt_type == PACKET_OTHERHOST) {
@@ -722,15 +680,12 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb,
722 if (skb->protocol != htons(ETH_P_ARP)) { 680 if (skb->protocol != htons(ETH_P_ARP)) {
723 if (!IS_VLAN_ARP(skb)) 681 if (!IS_VLAN_ARP(skb))
724 return NF_ACCEPT; 682 return NF_ACCEPT;
725 skb_pull(*pskb, VLAN_HLEN); 683 nf_bridge_pull_encap_header(*pskb);
726 (*pskb)->network_header += VLAN_HLEN;
727 } 684 }
728 685
729 if (arp_hdr(skb)->ar_pln != 4) { 686 if (arp_hdr(skb)->ar_pln != 4) {
730 if (IS_VLAN_ARP(skb)) { 687 if (IS_VLAN_ARP(skb))
731 skb_push(*pskb, VLAN_HLEN); 688 nf_bridge_push_encap_header(*pskb);
732 (*pskb)->network_header -= VLAN_HLEN;
733 }
734 return NF_ACCEPT; 689 return NF_ACCEPT;
735 } 690 }
736 *d = (struct net_device *)in; 691 *d = (struct net_device *)in;
@@ -777,13 +732,7 @@ static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb,
777 skb->pkt_type = PACKET_OTHERHOST; 732 skb->pkt_type = PACKET_OTHERHOST;
778 nf_bridge->mask ^= BRNF_PKT_TYPE; 733 nf_bridge->mask ^= BRNF_PKT_TYPE;
779 } 734 }
780 if (skb->protocol == htons(ETH_P_8021Q)) { 735 nf_bridge_push_encap_header(skb);
781 skb_push(skb, VLAN_HLEN);
782 skb->network_header -= VLAN_HLEN;
783 } else if (skb->protocol == htons(ETH_P_PPP_SES)) {
784 skb_push(skb, PPPOE_SES_HLEN);
785 skb->network_header -= PPPOE_SES_HLEN;
786 }
787 736
788 NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev, skb->dev, 737 NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev, skb->dev,
789 br_forward_finish); 738 br_forward_finish);
@@ -848,14 +797,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb,
848 nf_bridge->mask |= BRNF_PKT_TYPE; 797 nf_bridge->mask |= BRNF_PKT_TYPE;
849 } 798 }
850 799
851 if (skb->protocol == htons(ETH_P_8021Q)) { 800 nf_bridge_pull_encap_header(skb);
852 skb_pull(skb, VLAN_HLEN);
853 skb->network_header += VLAN_HLEN;
854 } else if (skb->protocol == htons(ETH_P_PPP_SES)) {
855 skb_pull(skb, PPPOE_SES_HLEN);
856 skb->network_header += PPPOE_SES_HLEN;
857 }
858
859 nf_bridge_save_header(skb); 801 nf_bridge_save_header(skb);
860 802
861#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) 803#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)