aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid Miller <davem@davemloft.net>2015-04-05 22:19:04 -0400
committerDavid S. Miller <davem@davemloft.net>2015-04-07 15:25:55 -0400
commit7026b1ddb6b8d4e6ee33dc2bd06c0ca8746fa7ab (patch)
tree3e11ed0f186ea6066a3f7efecb88d85bc732ee51 /net
parent1c984f8a5df085bcf35364a8a870bd4db4da4ed3 (diff)
netfilter: Pass socket pointer down through okfn().
On the output paths in particular, we have to sometimes deal with two socket contexts. First, and usually skb->sk, is the local socket that generated the frame. And second, is potentially the socket used to control a tunneling socket, such as one the encapsulates using UDP. We do not want to disassociate skb->sk when encapsulating in order to fix this, because that would break socket memory accounting. The most extreme case where this can cause huge problems is an AF_PACKET socket transmitting over a vxlan device. We hit code paths doing checks that assume they are dealing with an ipv4 socket, but are actually operating upon the AF_PACKET one. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/bridge/br_forward.c13
-rw-r--r--net/bridge/br_input.c16
-rw-r--r--net/bridge/br_multicast.c3
-rw-r--r--net/bridge/br_netfilter.c56
-rw-r--r--net/bridge/br_private.h6
-rw-r--r--net/bridge/br_stp_bpdu.c5
-rw-r--r--net/core/dev.c10
-rw-r--r--net/decnet/dn_neigh.c35
-rw-r--r--net/decnet/dn_nsp_in.c5
-rw-r--r--net/decnet/dn_route.c26
-rw-r--r--net/ipv4/arp.c10
-rw-r--r--net/ipv4/ip_forward.c8
-rw-r--r--net/ipv4/ip_input.c10
-rw-r--r--net/ipv4/ip_output.c45
-rw-r--r--net/ipv4/ipmr.c7
-rw-r--r--net/ipv4/raw.c4
-rw-r--r--net/ipv4/xfrm4_input.c5
-rw-r--r--net/ipv4/xfrm4_output.c12
-rw-r--r--net/ipv6/ip6_input.c11
-rw-r--r--net/ipv6/ip6_output.c33
-rw-r--r--net/ipv6/ip6mr.c7
-rw-r--r--net/ipv6/mcast.c9
-rw-r--r--net/ipv6/ndisc.c5
-rw-r--r--net/ipv6/netfilter/nf_defrag_ipv6_hooks.c2
-rw-r--r--net/ipv6/output_core.c4
-rw-r--r--net/ipv6/raw.c4
-rw-r--r--net/ipv6/xfrm6_input.c3
-rw-r--r--net/ipv6/xfrm6_output.c15
-rw-r--r--net/netfilter/ipvs/ip_vs_xmit.c8
-rw-r--r--net/netfilter/nf_queue.c2
-rw-r--r--net/xfrm/xfrm_output.c16
31 files changed, 219 insertions, 176 deletions
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
index 3304a5442331..e97572b5d2cc 100644
--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
@@ -35,7 +35,7 @@ static inline int should_deliver(const struct net_bridge_port *p,
35 p->state == BR_STATE_FORWARDING; 35 p->state == BR_STATE_FORWARDING;
36} 36}
37 37
38int br_dev_queue_push_xmit(struct sk_buff *skb) 38int br_dev_queue_push_xmit(struct sock *sk, struct sk_buff *skb)
39{ 39{
40 if (!is_skb_forwardable(skb->dev, skb)) { 40 if (!is_skb_forwardable(skb->dev, skb)) {
41 kfree_skb(skb); 41 kfree_skb(skb);
@@ -49,9 +49,10 @@ int br_dev_queue_push_xmit(struct sk_buff *skb)
49} 49}
50EXPORT_SYMBOL_GPL(br_dev_queue_push_xmit); 50EXPORT_SYMBOL_GPL(br_dev_queue_push_xmit);
51 51
52int br_forward_finish(struct sk_buff *skb) 52int br_forward_finish(struct sock *sk, struct sk_buff *skb)
53{ 53{
54 return NF_HOOK(NFPROTO_BRIDGE, NF_BR_POST_ROUTING, skb, NULL, skb->dev, 54 return NF_HOOK(NFPROTO_BRIDGE, NF_BR_POST_ROUTING, sk, skb,
55 NULL, skb->dev,
55 br_dev_queue_push_xmit); 56 br_dev_queue_push_xmit);
56 57
57} 58}
@@ -75,7 +76,8 @@ static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb)
75 return; 76 return;
76 } 77 }
77 78
78 NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, 79 NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, NULL, skb,
80 NULL, skb->dev,
79 br_forward_finish); 81 br_forward_finish);
80} 82}
81 83
@@ -96,7 +98,8 @@ static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb)
96 skb->dev = to->dev; 98 skb->dev = to->dev;
97 skb_forward_csum(skb); 99 skb_forward_csum(skb);
98 100
99 NF_HOOK(NFPROTO_BRIDGE, NF_BR_FORWARD, skb, indev, skb->dev, 101 NF_HOOK(NFPROTO_BRIDGE, NF_BR_FORWARD, NULL, skb,
102 indev, skb->dev,
100 br_forward_finish); 103 br_forward_finish);
101} 104}
102 105
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 052c5ebbc947..f921a5dce22d 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -55,8 +55,9 @@ static int br_pass_frame_up(struct sk_buff *skb)
55 if (!skb) 55 if (!skb)
56 return NET_RX_DROP; 56 return NET_RX_DROP;
57 57
58 return NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL, 58 return NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, NULL, skb,
59 netif_receive_skb); 59 indev, NULL,
60 netif_receive_skb_sk);
60} 61}
61 62
62static void br_do_proxy_arp(struct sk_buff *skb, struct net_bridge *br, 63static void br_do_proxy_arp(struct sk_buff *skb, struct net_bridge *br,
@@ -119,7 +120,7 @@ static void br_do_proxy_arp(struct sk_buff *skb, struct net_bridge *br,
119} 120}
120 121
121/* note: already called with rcu_read_lock */ 122/* note: already called with rcu_read_lock */
122int br_handle_frame_finish(struct sk_buff *skb) 123int br_handle_frame_finish(struct sock *sk, struct sk_buff *skb)
123{ 124{
124 const unsigned char *dest = eth_hdr(skb)->h_dest; 125 const unsigned char *dest = eth_hdr(skb)->h_dest;
125 struct net_bridge_port *p = br_port_get_rcu(skb->dev); 126 struct net_bridge_port *p = br_port_get_rcu(skb->dev);
@@ -207,7 +208,7 @@ drop:
207EXPORT_SYMBOL_GPL(br_handle_frame_finish); 208EXPORT_SYMBOL_GPL(br_handle_frame_finish);
208 209
209/* note: already called with rcu_read_lock */ 210/* note: already called with rcu_read_lock */
210static int br_handle_local_finish(struct sk_buff *skb) 211static int br_handle_local_finish(struct sock *sk, struct sk_buff *skb)
211{ 212{
212 struct net_bridge_port *p = br_port_get_rcu(skb->dev); 213 struct net_bridge_port *p = br_port_get_rcu(skb->dev);
213 u16 vid = 0; 214 u16 vid = 0;
@@ -277,8 +278,8 @@ rx_handler_result_t br_handle_frame(struct sk_buff **pskb)
277 } 278 }
278 279
279 /* Deliver packet to local host only */ 280 /* Deliver packet to local host only */
280 if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, 281 if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, NULL, skb,
281 NULL, br_handle_local_finish)) { 282 skb->dev, NULL, br_handle_local_finish)) {
282 return RX_HANDLER_CONSUMED; /* consumed by filter */ 283 return RX_HANDLER_CONSUMED; /* consumed by filter */
283 } else { 284 } else {
284 *pskb = skb; 285 *pskb = skb;
@@ -302,7 +303,8 @@ forward:
302 if (ether_addr_equal(p->br->dev->dev_addr, dest)) 303 if (ether_addr_equal(p->br->dev->dev_addr, dest))
303 skb->pkt_type = PACKET_HOST; 304 skb->pkt_type = PACKET_HOST;
304 305
305 NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, 306 NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, NULL, skb,
307 skb->dev, NULL,
306 br_handle_frame_finish); 308 br_handle_frame_finish);
307 break; 309 break;
308 default: 310 default:
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index c465876c7861..4b6722f8f179 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -814,7 +814,8 @@ static void __br_multicast_send_query(struct net_bridge *br,
814 814
815 if (port) { 815 if (port) {
816 skb->dev = port->dev; 816 skb->dev = port->dev;
817 NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, 817 NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, NULL, skb,
818 NULL, skb->dev,
818 br_dev_queue_push_xmit); 819 br_dev_queue_push_xmit);
819 } else { 820 } else {
820 br_multicast_select_own_querier(br, ip, skb); 821 br_multicast_select_own_querier(br, ip, skb);
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 7527e94dd5dc..acd31c9f2116 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -261,7 +261,7 @@ static void nf_bridge_update_protocol(struct sk_buff *skb)
261/* PF_BRIDGE/PRE_ROUTING *********************************************/ 261/* PF_BRIDGE/PRE_ROUTING *********************************************/
262/* Undo the changes made for ip6tables PREROUTING and continue the 262/* Undo the changes made for ip6tables PREROUTING and continue the
263 * bridge PRE_ROUTING hook. */ 263 * bridge PRE_ROUTING hook. */
264static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb) 264static int br_nf_pre_routing_finish_ipv6(struct sock *sk, struct sk_buff *skb)
265{ 265{
266 struct nf_bridge_info *nf_bridge = skb->nf_bridge; 266 struct nf_bridge_info *nf_bridge = skb->nf_bridge;
267 struct rtable *rt; 267 struct rtable *rt;
@@ -282,7 +282,8 @@ static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb)
282 skb->dev = nf_bridge->physindev; 282 skb->dev = nf_bridge->physindev;