X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;ds=sidebyside;f=net%2Fbridge%2Fbr_netfilter.c;h=8245f051ccbbcb63f95755f663c1503f0cc954b9;hb=f26e51f67ae6a75ffc57b96cf5fe096f75e778cb;hp=9b2986b182ba0a7630ac30d0b3305d9fd6cc89b1;hpb=afc2e82c0851317931a9bfdb98271253371825c6;p=powerpc.git diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 9b2986b182..8245f051cc 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) return skb->nf_bridge; } -static inline void nf_bridge_save_header(struct sk_buff *skb) +static inline void nf_bridge_push_encap_header(struct sk_buff *skb) +{ + unsigned int len = nf_bridge_encap_header_len(skb); + + skb_push(skb, len); + skb->network_header -= len; +} + +static inline void nf_bridge_pull_encap_header(struct sk_buff *skb) +{ + unsigned int len = nf_bridge_encap_header_len(skb); + + skb_pull(skb, len); + skb->network_header += len; +} + +static inline void nf_bridge_pull_encap_header_rcsum(struct sk_buff *skb) { - int header_size = ETH_HLEN; + unsigned int len = nf_bridge_encap_header_len(skb); + + skb_pull_rcsum(skb, len); + skb->network_header += len; +} - if (skb->protocol == htons(ETH_P_8021Q)) - header_size += VLAN_HLEN; - else if (skb->protocol == htons(ETH_P_PPP_SES)) - header_size += PPPOE_SES_HLEN; +static inline void nf_bridge_save_header(struct sk_buff *skb) +{ + int header_size = ETH_HLEN + nf_bridge_encap_header_len(skb); skb_copy_from_linear_data_offset(skb, -header_size, skb->nf_bridge->data, header_size); @@ -162,24 +181,15 @@ static inline void nf_bridge_save_header(struct sk_buff *skb) int nf_bridge_copy_header(struct sk_buff *skb) { int err; - int header_size = ETH_HLEN; - - if (skb->protocol == htons(ETH_P_8021Q)) - header_size += VLAN_HLEN; - else if (skb->protocol == htons(ETH_P_PPP_SES)) - header_size += PPPOE_SES_HLEN; + int header_size = ETH_HLEN + nf_bridge_encap_header_len(skb); - err = skb_cow(skb, header_size); + err = skb_cow_head(skb, header_size); if (err) return err; skb_copy_to_linear_data_offset(skb, -header_size, skb->nf_bridge->data, header_size); - - if (skb->protocol == htons(ETH_P_8021Q)) - __skb_push(skb, VLAN_HLEN); - else if (skb->protocol == htons(ETH_P_PPP_SES)) - __skb_push(skb, PPPOE_SES_HLEN); + __skb_push(skb, nf_bridge_encap_header_len(skb)); return 0; } @@ -200,13 +210,7 @@ static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb) dst_hold(skb->dst); skb->dev = nf_bridge->physindev; - if (skb->protocol == htons(ETH_P_8021Q)) { - skb_push(skb, VLAN_HLEN); - skb->network_header -= VLAN_HLEN; - } else if (skb->protocol == htons(ETH_P_PPP_SES)) { - skb_push(skb, PPPOE_SES_HLEN); - skb->network_header -= PPPOE_SES_HLEN; - } + nf_bridge_push_encap_header(skb); NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, br_handle_frame_finish, 1); @@ -284,13 +288,7 @@ static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb) if (!skb->dev) kfree_skb(skb); else { - if (skb->protocol == htons(ETH_P_8021Q)) { - skb_pull(skb, VLAN_HLEN); - skb->network_header += VLAN_HLEN; - } else if (skb->protocol == htons(ETH_P_PPP_SES)) { - skb_pull(skb, PPPOE_SES_HLEN); - skb->network_header += PPPOE_SES_HLEN; - } + nf_bridge_pull_encap_header(skb); skb->dst->output(skb); } return 0; @@ -356,15 +354,7 @@ bridged_dnat: * bridged frame */ nf_bridge->mask |= BRNF_BRIDGED_DNAT; skb->dev = nf_bridge->physindev; - if (skb->protocol == - htons(ETH_P_8021Q)) { - skb_push(skb, VLAN_HLEN); - skb->network_header -= VLAN_HLEN; - } else if(skb->protocol == - htons(ETH_P_PPP_SES)) { - skb_push(skb, PPPOE_SES_HLEN); - skb->network_header -= PPPOE_SES_HLEN; - } + nf_bridge_push_encap_header(skb); NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, br_nf_pre_routing_finish_bridge, @@ -380,13 +370,7 @@ bridged_dnat: } skb->dev = nf_bridge->physindev; - if (skb->protocol == htons(ETH_P_8021Q)) { - skb_push(skb, VLAN_HLEN); - skb->network_header -= VLAN_HLEN; - } else if (skb->protocol == htons(ETH_P_PPP_SES)) { - skb_push(skb, PPPOE_SES_HLEN); - skb->network_header -= PPPOE_SES_HLEN; - } + nf_bridge_push_encap_header(skb); NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, br_handle_frame_finish, 1); @@ -525,8 +509,14 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb, int (*okfn)(struct sk_buff *)) { struct iphdr *iph; - __u32 len; struct sk_buff *skb = *pskb; + __u32 len = nf_bridge_encap_header_len(skb); + + if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) + return NF_STOLEN; + + if (unlikely(!pskb_may_pull(skb, len))) + goto out; if (skb->protocol == htons(ETH_P_IPV6) || IS_VLAN_IPV6(skb) || IS_PPPOE_IPV6(skb)) { @@ -534,16 +524,7 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb, if (!brnf_call_ip6tables) return NF_ACCEPT; #endif - if ((skb = skb_share_check(*pskb, GFP_ATOMIC)) == NULL) - goto out; - - if (skb->protocol == htons(ETH_P_8021Q)) { - skb_pull_rcsum(skb, VLAN_HLEN); - skb->network_header += VLAN_HLEN; - } else if (skb->protocol == htons(ETH_P_PPP_SES)) { - skb_pull_rcsum(skb, PPPOE_SES_HLEN); - skb->network_header += PPPOE_SES_HLEN; - } + nf_bridge_pull_encap_header_rcsum(skb); return br_nf_pre_routing_ipv6(hook, skb, in, out, okfn); } #ifdef CONFIG_SYSCTL @@ -555,16 +536,7 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb, !IS_PPPOE_IP(skb)) return NF_ACCEPT; - if ((skb = skb_share_check(*pskb, GFP_ATOMIC)) == NULL) - goto out; - - if (skb->protocol == htons(ETH_P_8021Q)) { - skb_pull_rcsum(skb, VLAN_HLEN); - skb->network_header += VLAN_HLEN; - } else if (skb->protocol == htons(ETH_P_PPP_SES)) { - skb_pull_rcsum(skb, PPPOE_SES_HLEN); - skb->network_header += PPPOE_SES_HLEN; - } + nf_bridge_pull_encap_header_rcsum(skb); if (!pskb_may_pull(skb, sizeof(struct iphdr))) goto inhdr_error; @@ -642,13 +614,7 @@ static int br_nf_forward_finish(struct sk_buff *skb) } else { in = *((struct net_device **)(skb->cb)); } - if (skb->protocol == htons(ETH_P_8021Q)) { - skb_push(skb, VLAN_HLEN); - skb->network_header -= VLAN_HLEN; - } else if (skb->protocol == htons(ETH_P_PPP_SES)) { - skb_push(skb, PPPOE_SES_HLEN); - skb->network_header -= PPPOE_SES_HLEN; - } + nf_bridge_push_encap_header(skb); NF_HOOK_THRESH(PF_BRIDGE, NF_BR_FORWARD, skb, in, skb->dev, br_forward_finish, 1); return 0; @@ -682,13 +648,7 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb, else pf = PF_INET6; - if (skb->protocol == htons(ETH_P_8021Q)) { - skb_pull(*pskb, VLAN_HLEN); - (*pskb)->network_header += VLAN_HLEN; - } else if (skb->protocol == htons(ETH_P_PPP_SES)) { - skb_pull(*pskb, PPPOE_SES_HLEN); - (*pskb)->network_header += PPPOE_SES_HLEN; - } + nf_bridge_pull_encap_header(*pskb); nf_bridge = skb->nf_bridge; if (skb->pkt_type == PACKET_OTHERHOST) { @@ -722,15 +682,12 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb, if (skb->protocol != htons(ETH_P_ARP)) { if (!IS_VLAN_ARP(skb)) return NF_ACCEPT; - skb_pull(*pskb, VLAN_HLEN); - (*pskb)->network_header += VLAN_HLEN; + nf_bridge_pull_encap_header(*pskb); } if (arp_hdr(skb)->ar_pln != 4) { - if (IS_VLAN_ARP(skb)) { - skb_push(*pskb, VLAN_HLEN); - (*pskb)->network_header -= VLAN_HLEN; - } + if (IS_VLAN_ARP(skb)) + nf_bridge_push_encap_header(*pskb); return NF_ACCEPT; } *d = (struct net_device *)in; @@ -777,13 +734,7 @@ static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb, skb->pkt_type = PACKET_OTHERHOST; nf_bridge->mask ^= BRNF_PKT_TYPE; } - if (skb->protocol == htons(ETH_P_8021Q)) { - skb_push(skb, VLAN_HLEN); - skb->network_header -= VLAN_HLEN; - } else if (skb->protocol == htons(ETH_P_PPP_SES)) { - skb_push(skb, PPPOE_SES_HLEN); - skb->network_header -= PPPOE_SES_HLEN; - } + nf_bridge_push_encap_header(skb); NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev, skb->dev, br_forward_finish); @@ -848,14 +799,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb, nf_bridge->mask |= BRNF_PKT_TYPE; } - if (skb->protocol == htons(ETH_P_8021Q)) { - skb_pull(skb, VLAN_HLEN); - skb->network_header += VLAN_HLEN; - } else if (skb->protocol == htons(ETH_P_PPP_SES)) { - skb_pull(skb, PPPOE_SES_HLEN); - skb->network_header += PPPOE_SES_HLEN; - } - + nf_bridge_pull_encap_header(skb); nf_bridge_save_header(skb); #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) @@ -960,7 +904,6 @@ int brnf_sysctl_call_tables(ctl_table * ctl, int write, struct file *filp, static ctl_table brnf_table[] = { { - .ctl_name = NET_BRIDGE_NF_CALL_ARPTABLES, .procname = "bridge-nf-call-arptables", .data = &brnf_call_arptables, .maxlen = sizeof(int), @@ -968,7 +911,6 @@ static ctl_table brnf_table[] = { .proc_handler = &brnf_sysctl_call_tables, }, { - .ctl_name = NET_BRIDGE_NF_CALL_IPTABLES, .procname = "bridge-nf-call-iptables", .data = &brnf_call_iptables, .maxlen = sizeof(int), @@ -976,7 +918,6 @@ static ctl_table brnf_table[] = { .proc_handler = &brnf_sysctl_call_tables, }, { - .ctl_name = NET_BRIDGE_NF_CALL_IP6TABLES, .procname = "bridge-nf-call-ip6tables", .data = &brnf_call_ip6tables, .maxlen = sizeof(int), @@ -984,7 +925,6 @@ static ctl_table brnf_table[] = { .proc_handler = &brnf_sysctl_call_tables, }, { - .ctl_name = NET_BRIDGE_NF_FILTER_VLAN_TAGGED, .procname = "bridge-nf-filter-vlan-tagged", .data = &brnf_filter_vlan_tagged, .maxlen = sizeof(int), @@ -992,7 +932,6 @@ static ctl_table brnf_table[] = { .proc_handler = &brnf_sysctl_call_tables, }, { - .ctl_name = NET_BRIDGE_NF_FILTER_PPPOE_TAGGED, .procname = "bridge-nf-filter-pppoe-tagged", .data = &brnf_filter_pppoe_tagged, .maxlen = sizeof(int),