From: Pablo Neira Ayuso Date: Wed, 8 Apr 2015 15:40:17 +0000 (+0200) Subject: Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=aadd51aa71f8d013c818a312bb2a0c5714830dbc;p=GitHub%2FLineageOS%2FG12%2Fandroid_kernel_amlogic_linux-4.9.git Merge git://git./linux/kernel/git/davem/net-next Resolve conflicts between 5888b93 ("Merge branch 'nf-hook-compress'") and Florian Westphal br_netfilter works. Conflicts: net/bridge/br_netfilter.c Signed-off-by: Pablo Neira Ayuso --- aadd51aa71f8d013c818a312bb2a0c5714830dbc diff --cc net/bridge/br_netfilter.c index e8ac7432acb6,acd31c9f2116..ab55e2472beb --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@@ -277,14 -261,14 +277,14 @@@ static void nf_bridge_update_protocol(s /* PF_BRIDGE/PRE_ROUTING *********************************************/ /* Undo the changes made for ip6tables PREROUTING and continue the * bridge PRE_ROUTING hook. */ - static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb) + static int br_nf_pre_routing_finish_ipv6(struct sock *sk, struct sk_buff *skb) { - struct nf_bridge_info *nf_bridge = skb->nf_bridge; + struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb); struct rtable *rt; - if (nf_bridge->mask & BRNF_PKT_TYPE) { + if (nf_bridge->pkt_otherhost) { skb->pkt_type = PACKET_OTHERHOST; - nf_bridge->mask ^= BRNF_PKT_TYPE; + nf_bridge->pkt_otherhost = false; } nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING; @@@ -309,8 -294,9 +310,8 @@@ * don't, we use the neighbour framework to find out. In both cases, we make * sure that br_handle_frame_finish() is called afterwards. */ - static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb) + static int br_nf_pre_routing_finish_bridge(struct sock *sk, struct sk_buff *skb) { - struct nf_bridge_info *nf_bridge = skb->nf_bridge; struct neighbour *neigh; struct dst_entry *dst; @@@ -697,9 -678,9 +695,9 @@@ static unsigned int br_nf_local_in(cons } /* PF_BRIDGE/FORWARD *************************************************/ - static int br_nf_forward_finish(struct sk_buff *skb) + static int br_nf_forward_finish(struct sock *sk, struct sk_buff *skb) { - struct nf_bridge_info *nf_bridge = skb->nf_bridge; + struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb); struct net_device *in; if (!IS_ARP(skb) && !IS_VLAN_ARP(skb)) { @@@ -750,11 -722,7 +746,11 @@@ static unsigned int br_nf_forward_ip(co if (!nf_bridge_unshare(skb)) return NF_DROP; + nf_bridge = nf_bridge_info_get(skb); + if (!nf_bridge) + return NF_DROP; + - parent = bridge_parent(out); + parent = bridge_parent(state->out); if (!parent) return NF_DROP; @@@ -830,26 -792,34 +825,26 @@@ static unsigned int br_nf_forward_arp(c } #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4) - static int br_nf_push_frag_xmit(struct sk_buff *skb) -static bool nf_bridge_copy_header(struct sk_buff *skb) ++static int br_nf_push_frag_xmit(struct sock *sk, struct sk_buff *skb) { + struct brnf_frag_data *data; int err; - unsigned int header_size; - nf_bridge_update_protocol(skb); - header_size = ETH_HLEN + nf_bridge_encap_header_len(skb); - err = skb_cow_head(skb, header_size); - if (err) - return false; - - skb_copy_to_linear_data_offset(skb, -header_size, - skb->nf_bridge->data, header_size); - __skb_push(skb, nf_bridge_encap_header_len(skb)); - return true; -} + data = this_cpu_ptr(&brnf_frag_data_storage); + err = skb_cow_head(skb, data->size); -static int br_nf_push_frag_xmit(struct sock *sk, struct sk_buff *skb) -{ - if (!nf_bridge_copy_header(skb)) { + if (err) { kfree_skb(skb); return 0; } + skb_copy_to_linear_data_offset(skb, -data->size, data->mac, data->size); + __skb_push(skb, data->encap_size); + - return br_dev_queue_push_xmit(skb); + return br_dev_queue_push_xmit(sk, skb); } - static int br_nf_dev_queue_xmit(struct sk_buff *skb) + static int br_nf_dev_queue_xmit(struct sock *sk, struct sk_buff *skb) { int ret; int frag_max_size; @@@ -870,20 -838,9 +865,20 @@@ /* Drop invalid packet */ return NF_DROP; IPCB(skb)->frag_max_size = frag_max_size; + + nf_bridge_update_protocol(skb); + + data = this_cpu_ptr(&brnf_frag_data_storage); + data->encap_size = nf_bridge_encap_header_len(skb); + data->size = ETH_HLEN + data->encap_size; + + skb_copy_from_linear_data_offset(skb, -data->size, data->mac, + data->size); + - ret = ip_fragment(skb, br_nf_push_frag_xmit); + ret = ip_fragment(sk, skb, br_nf_push_frag_xmit); - } else + } else { - ret = br_dev_queue_push_xmit(skb); + ret = br_dev_queue_push_xmit(sk, skb); + } return ret; } @@@ -897,11 -854,9 +892,9 @@@ static int br_nf_dev_queue_xmit(struct /* PF_BRIDGE/POST_ROUTING ********************************************/ static unsigned int br_nf_post_routing(const struct nf_hook_ops *ops, struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - int (*okfn)(struct sk_buff *)) + const struct nf_hook_state *state) { - struct nf_bridge_info *nf_bridge = skb->nf_bridge; + struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb); struct net_device *realoutdev = bridge_parent(skb->dev); u_int8_t pf; @@@ -975,13 -930,10 +967,13 @@@ static void br_nf_pre_routing_finish_br skb_pull(skb, ETH_HLEN); nf_bridge->mask &= ~BRNF_BRIDGED_DNAT; - skb_copy_to_linear_data_offset(skb, -(ETH_HLEN-ETH_ALEN), - skb->nf_bridge->data, ETH_HLEN-ETH_ALEN); + BUILD_BUG_ON(sizeof(nf_bridge->neigh_header) != (ETH_HLEN - ETH_ALEN)); + + skb_copy_to_linear_data_offset(skb, -(ETH_HLEN - ETH_ALEN), + nf_bridge->neigh_header, + ETH_HLEN - ETH_ALEN); skb->dev = nf_bridge->physindev; - br_handle_frame_finish(skb); + br_handle_frame_finish(NULL, skb); } static int br_nf_dev_xmit(struct sk_buff *skb) diff --cc net/netfilter/nf_queue.c index fb045b4c2966,3f3ac57b2998..2e88032cd5ad --- a/net/netfilter/nf_queue.c +++ b/net/netfilter/nf_queue.c @@@ -48,21 -47,23 +48,25 @@@ EXPORT_SYMBOL(nf_unregister_queue_handl void nf_queue_entry_release_refs(struct nf_queue_entry *entry) { + struct nf_hook_state *state = &entry->state; + /* Release those devices we held, or Alexey will kill me. */ - if (entry->indev) - dev_put(entry->indev); - if (entry->outdev) - dev_put(entry->outdev); + if (state->in) + dev_put(state->in); + if (state->out) + dev_put(state->out); + if (state->sk) + sock_put(state->sk); #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) if (entry->skb->nf_bridge) { - struct nf_bridge_info *nf_bridge = entry->skb->nf_bridge; + struct net_device *physdev; - if (nf_bridge->physindev) - dev_put(nf_bridge->physindev); - if (nf_bridge->physoutdev) - dev_put(nf_bridge->physoutdev); + physdev = nf_bridge_get_physindev(entry->skb); + if (physdev) + dev_put(physdev); + physdev = nf_bridge_get_physoutdev(entry->skb); + if (physdev) + dev_put(physdev); } #endif /* Drop reference to owner of hook which queued us. */ @@@ -76,18 -79,21 +82,20 @@@ bool nf_queue_entry_get_refs(struct nf_ if (!try_module_get(entry->elem->owner)) return false; - if (entry->indev) - dev_hold(entry->indev); - if (entry->outdev) - dev_hold(entry->outdev); + if (state->in) + dev_hold(state->in); + if (state->out) + dev_hold(state->out); + if (state->sk) + sock_hold(state->sk); #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) if (entry->skb->nf_bridge) { - struct nf_bridge_info *nf_bridge = entry->skb->nf_bridge; struct net_device *physdev; - physdev = nf_bridge->physindev; + physdev = nf_bridge_get_physindev(entry->skb); if (physdev) dev_hold(physdev); - physdev = nf_bridge->physoutdev; + physdev = nf_bridge_get_physoutdev(entry->skb); if (physdev) dev_hold(physdev); }