aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2015-04-02 08:31:41 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2015-04-08 10:49:08 -0400
commitc737b7c4510026c200e14de51eb0006adea0fb2f (patch)
tree4f9e007c999e42652ca111d22edf2cfeb99c2954 /net
parente70deecbf8e1562cac0b19f23848919e2f5d65aa (diff)
netfilter: bridge: add helpers for fetching physin/outdev
right now we store this in the nf_bridge_info struct, accessible via skb->nf_bridge. This patch prepares removal of this pointer from skb: Instead of using skb->nf_bridge->x, we use helpers to obtain the in/out device (or ifindexes). Followup patches to netfilter will then allow nf_bridge_info to be obtained by a call into the br_netfilter core, rather than keeping a pointer to it in sk_buff. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/netfilter/nf_reject_ipv4.c4
-rw-r--r--net/ipv6/netfilter/nf_reject_ipv6.c4
-rw-r--r--net/netfilter/ipset/ip_set_hash_netiface.c32
-rw-r--r--net/netfilter/nf_log_common.c5
-rw-r--r--net/netfilter/nf_queue.c18
-rw-r--r--net/netfilter/nfnetlink_log.c17
-rw-r--r--net/netfilter/nfnetlink_queue_core.c28
7 files changed, 75 insertions, 33 deletions
diff --git a/net/ipv4/netfilter/nf_reject_ipv4.c b/net/ipv4/netfilter/nf_reject_ipv4.c
index c5b794da51a9..3262e41ff76f 100644
--- a/net/ipv4/netfilter/nf_reject_ipv4.c
+++ b/net/ipv4/netfilter/nf_reject_ipv4.c
@@ -13,6 +13,7 @@
13#include <net/dst.h> 13#include <net/dst.h>
14#include <net/netfilter/ipv4/nf_reject.h> 14#include <net/netfilter/ipv4/nf_reject.h>
15#include <linux/netfilter_ipv4.h> 15#include <linux/netfilter_ipv4.h>
16#include <linux/netfilter_bridge.h>
16#include <net/netfilter/ipv4/nf_reject.h> 17#include <net/netfilter/ipv4/nf_reject.h>
17 18
18const struct tcphdr *nf_reject_ip_tcphdr_get(struct sk_buff *oldskb, 19const struct tcphdr *nf_reject_ip_tcphdr_get(struct sk_buff *oldskb,
@@ -146,7 +147,8 @@ void nf_send_reset(struct sk_buff *oldskb, int hook)
146 */ 147 */
147 if (oldskb->nf_bridge) { 148 if (oldskb->nf_bridge) {
148 struct ethhdr *oeth = eth_hdr(oldskb); 149 struct ethhdr *oeth = eth_hdr(oldskb);
149 nskb->dev = oldskb->nf_bridge->physindev; 150
151 nskb->dev = nf_bridge_get_physindev(oldskb);
150 niph->tot_len = htons(nskb->len); 152 niph->tot_len = htons(nskb->len);
151 ip_send_check(niph); 153 ip_send_check(niph);
152 if (dev_hard_header(nskb, nskb->dev, ntohs(nskb->protocol), 154 if (dev_hard_header(nskb, nskb->dev, ntohs(nskb->protocol),
diff --git a/net/ipv6/netfilter/nf_reject_ipv6.c b/net/ipv6/netfilter/nf_reject_ipv6.c
index 3afdce03d94e..94b4c6dfb400 100644
--- a/net/ipv6/netfilter/nf_reject_ipv6.c
+++ b/net/ipv6/netfilter/nf_reject_ipv6.c
@@ -13,6 +13,7 @@
13#include <net/ip6_checksum.h> 13#include <net/ip6_checksum.h>
14#include <net/netfilter/ipv6/nf_reject.h> 14#include <net/netfilter/ipv6/nf_reject.h>
15#include <linux/netfilter_ipv6.h> 15#include <linux/netfilter_ipv6.h>
16#include <linux/netfilter_bridge.h>
16#include <net/netfilter/ipv6/nf_reject.h> 17#include <net/netfilter/ipv6/nf_reject.h>
17 18
18const struct tcphdr *nf_reject_ip6_tcphdr_get(struct sk_buff *oldskb, 19const struct tcphdr *nf_reject_ip6_tcphdr_get(struct sk_buff *oldskb,
@@ -195,7 +196,8 @@ void nf_send_reset6(struct net *net, struct sk_buff *oldskb, int hook)
195 */ 196 */
196 if (oldskb->nf_bridge) { 197 if (oldskb->nf_bridge) {
197 struct ethhdr *oeth = eth_hdr(oldskb); 198 struct ethhdr *oeth = eth_hdr(oldskb);
198 nskb->dev = oldskb->nf_bridge->physindev; 199
200 nskb->dev = nf_bridge_get_physindev(oldskb);
199 nskb->protocol = htons(ETH_P_IPV6); 201 nskb->protocol = htons(ETH_P_IPV6);
200 ip6h->payload_len = htons(sizeof(struct tcphdr)); 202 ip6h->payload_len = htons(sizeof(struct tcphdr));
201 if (dev_hard_header(nskb, nskb->dev, ntohs(nskb->protocol), 203 if (dev_hard_header(nskb, nskb->dev, ntohs(nskb->protocol),
diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c
index 758b002130d9..380ef5148ea1 100644
--- a/net/netfilter/ipset/ip_set_hash_netiface.c
+++ b/net/netfilter/ipset/ip_set_hash_netiface.c
@@ -19,6 +19,7 @@
19#include <net/netlink.h> 19#include <net/netlink.h>
20 20
21#include <linux/netfilter.h> 21#include <linux/netfilter.h>
22#include <linux/netfilter_bridge.h>
22#include <linux/netfilter/ipset/pfxlen.h> 23#include <linux/netfilter/ipset/pfxlen.h>
23#include <linux/netfilter/ipset/ip_set.h> 24#include <linux/netfilter/ipset/ip_set.h>
24#include <linux/netfilter/ipset/ip_set_hash.h> 25#include <linux/netfilter/ipset/ip_set_hash.h>
@@ -211,6 +212,22 @@ hash_netiface4_data_next(struct hash_netiface4_elem *next,
211#define HKEY_DATALEN sizeof(struct hash_netiface4_elem_hashed) 212#define HKEY_DATALEN sizeof(struct hash_netiface4_elem_hashed)
212#include "ip_set_hash_gen.h" 213#include "ip_set_hash_gen.h"
213 214
215#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
216static const char *get_physindev_name(const struct sk_buff *skb)
217{
218 struct net_device *dev = nf_bridge_get_physindev(skb);
219
220 return dev ? dev->name : NULL;
221}
222
223static const char *get_phyoutdev_name(const struct sk_buff *skb)
224{
225 struct net_device *dev = nf_bridge_get_physoutdev(skb);
226
227 return dev ? dev->name : NULL;
228}
229#endif
230
214static int 231static int
215hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb, 232hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb,
216 const struct xt_action_param *par, 233 const struct xt_action_param *par,
@@ -234,16 +251,15 @@ hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb,
234 e.ip &= ip_set_netmask(e.cidr); 251 e.ip &= ip_set_netmask(e.cidr);
235 252
236#define IFACE(dir) (par->dir ? par->dir->name : NULL) 253#define IFACE(dir) (par->dir ? par->dir->name : NULL)
237#define PHYSDEV(dir) (nf_bridge->dir ? nf_bridge->dir->name : NULL)
238#define SRCDIR (opt->flags & IPSET_DIM_TWO_SRC) 254#define SRCDIR (opt->flags & IPSET_DIM_TWO_SRC)
239 255
240 if (opt->cmdflags & IPSET_FLAG_PHYSDEV) { 256 if (opt->cmdflags & IPSET_FLAG_PHYSDEV) {
241#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) 257#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
242 const struct nf_bridge_info *nf_bridge = skb->nf_bridge; 258 e.iface = SRCDIR ? get_physindev_name(skb) :
259 get_phyoutdev_name(skb);
243 260
244 if (!nf_bridge) 261 if (!e.iface)
245 return -EINVAL; 262 return -EINVAL;
246 e.iface = SRCDIR ? PHYSDEV(physindev) : PHYSDEV(physoutdev);
247 e.physdev = 1; 263 e.physdev = 1;
248#else 264#else
249 e.iface = NULL; 265 e.iface = NULL;
@@ -476,11 +492,11 @@ hash_netiface6_kadt(struct ip_set *set, const struct sk_buff *skb,
476 492
477 if (opt->cmdflags & IPSET_FLAG_PHYSDEV) { 493 if (opt->cmdflags & IPSET_FLAG_PHYSDEV) {
478#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) 494#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
479 const struct nf_bridge_info *nf_bridge = skb->nf_bridge; 495 e.iface = SRCDIR ? get_physindev_name(skb) :
480 496 get_phyoutdev_name(skb);
481 if (!nf_bridge) 497 if (!e.iface)
482 return -EINVAL; 498 return -EINVAL;
483 e.iface = SRCDIR ? PHYSDEV(physindev) : PHYSDEV(physoutdev); 499
484 e.physdev = 1; 500 e.physdev = 1;
485#else 501#else
486 e.iface = NULL; 502 e.iface = NULL;
diff --git a/net/netfilter/nf_log_common.c b/net/netfilter/nf_log_common.c
index 2631876ac55b..a5aa5967b8e1 100644
--- a/net/netfilter/nf_log_common.c
+++ b/net/netfilter/nf_log_common.c
@@ -17,6 +17,7 @@
17#include <net/route.h> 17#include <net/route.h>
18 18
19#include <linux/netfilter.h> 19#include <linux/netfilter.h>
20#include <linux/netfilter_bridge.h>
20#include <linux/netfilter/xt_LOG.h> 21#include <linux/netfilter/xt_LOG.h>
21#include <net/netfilter/nf_log.h> 22#include <net/netfilter/nf_log.h>
22 23
@@ -163,10 +164,10 @@ nf_log_dump_packet_common(struct nf_log_buf *m, u_int8_t pf,
163 const struct net_device *physindev; 164 const struct net_device *physindev;
164 const struct net_device *physoutdev; 165 const struct net_device *physoutdev;
165 166
166 physindev = skb->nf_bridge->physindev; 167 physindev = nf_bridge_get_physindev(skb);
167 if (physindev && in != physindev) 168 if (physindev && in != physindev)
168 nf_log_buf_add(m, "PHYSIN=%s ", physindev->name); 169 nf_log_buf_add(m, "PHYSIN=%s ", physindev->name);
169 physoutdev = skb->nf_bridge->physoutdev; 170 physoutdev = nf_bridge_get_physoutdev(skb);
170 if (physoutdev && out != physoutdev) 171 if (physoutdev && out != physoutdev)
171 nf_log_buf_add(m, "PHYSOUT=%s ", physoutdev->name); 172 nf_log_buf_add(m, "PHYSOUT=%s ", physoutdev->name);
172 } 173 }
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
index 4c8b68e5fa16..fb045b4c2966 100644
--- a/net/netfilter/nf_queue.c
+++ b/net/netfilter/nf_queue.c
@@ -10,6 +10,7 @@
10#include <linux/proc_fs.h> 10#include <linux/proc_fs.h>
11#include <linux/skbuff.h> 11#include <linux/skbuff.h>
12#include <linux/netfilter.h> 12#include <linux/netfilter.h>
13#include <linux/netfilter_bridge.h>
13#include <linux/seq_file.h> 14#include <linux/seq_file.h>
14#include <linux/rcupdate.h> 15#include <linux/rcupdate.h>
15#include <net/protocol.h> 16#include <net/protocol.h>
@@ -54,12 +55,14 @@ void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
54 dev_put(entry->outdev); 55 dev_put(entry->outdev);
55#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) 56#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
56 if (entry->skb->nf_bridge) { 57 if (entry->skb->nf_bridge) {
57 struct nf_bridge_info *nf_bridge = entry->skb->nf_bridge; 58 struct net_device *physdev;
58 59
59 if (nf_bridge->physindev) 60 physdev = nf_bridge_get_physindev(entry->skb);
60 dev_put(nf_bridge->physindev); 61 if (physdev)
61 if (nf_bridge->physoutdev) 62 dev_put(physdev);
62 dev_put(nf_bridge->physoutdev); 63 physdev = nf_bridge_get_physoutdev(entry->skb);
64 if (physdev)
65 dev_put(physdev);
63 } 66 }
64#endif 67#endif
65 /* Drop reference to owner of hook which queued us. */ 68 /* Drop reference to owner of hook which queued us. */
@@ -79,13 +82,12 @@ bool nf_queue_entry_get_refs(struct nf_queue_entry *entry)
79 dev_hold(entry->outdev); 82 dev_hold(entry->outdev);
80#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) 83#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
81 if (entry->skb->nf_bridge) { 84 if (entry->skb->nf_bridge) {
82 struct nf_bridge_info *nf_bridge = entry->skb->nf_bridge;
83 struct net_device *physdev; 85 struct net_device *physdev;
84 86
85 physdev = nf_bridge->physindev; 87 physdev = nf_bridge_get_physindev(entry->skb);
86 if (physdev) 88 if (physdev)
87 dev_hold(physdev); 89 dev_hold(physdev);
88 physdev = nf_bridge->physoutdev; 90 physdev = nf_bridge_get_physoutdev(entry->skb);
89 if (physdev) 91 if (physdev)
90 dev_hold(physdev); 92 dev_hold(physdev);
91 } 93 }
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 957b83a0223b..51afea4b0af7 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -23,6 +23,7 @@
23#include <linux/ipv6.h> 23#include <linux/ipv6.h>
24#include <linux/netdevice.h> 24#include <linux/netdevice.h>
25#include <linux/netfilter.h> 25#include <linux/netfilter.h>
26#include <linux/netfilter_bridge.h>
26#include <net/netlink.h> 27#include <net/netlink.h>
27#include <linux/netfilter/nfnetlink.h> 28#include <linux/netfilter/nfnetlink.h>
28#include <linux/netfilter/nfnetlink_log.h> 29#include <linux/netfilter/nfnetlink_log.h>
@@ -448,14 +449,18 @@ __build_packet_message(struct nfnl_log_net *log,
448 htonl(br_port_get_rcu(indev)->br->dev->ifindex))) 449 htonl(br_port_get_rcu(indev)->br->dev->ifindex)))
449 goto nla_put_failure; 450 goto nla_put_failure;
450 } else { 451 } else {
452 struct net_device *physindev;
453
451 /* Case 2: indev is bridge group, we need to look for 454 /* Case 2: indev is bridge group, we need to look for
452 * physical device (when called from ipv4) */ 455 * physical device (when called from ipv4) */
453 if (nla_put_be32(inst->skb, NFULA_IFINDEX_INDEV, 456 if (nla_put_be32(inst->skb, NFULA_IFINDEX_INDEV,
454 htonl(indev->ifindex))) 457 htonl(indev->ifindex)))
455 goto nla_put_failure; 458 goto nla_put_failure;
456 if (skb->nf_bridge && skb->nf_bridge->physindev && 459
460 physindev = nf_bridge_get_physindev(skb);
461 if (physindev &&
457 nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSINDEV, 462 nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSINDEV,
458 htonl(skb->nf_bridge->physindev->ifindex))) 463 htonl(physindev->ifindex)))
459 goto nla_put_failure; 464 goto nla_put_failure;
460 } 465 }
461#endif 466#endif
@@ -479,14 +484,18 @@ __build_packet_message(struct nfnl_log_net *log,
479 htonl(br_port_get_rcu(outdev)->br->dev->ifindex))) 484 htonl(br_port_get_rcu(outdev)->br->dev->ifindex)))
480 goto nla_put_failure; 485 goto nla_put_failure;
481 } else { 486 } else {
487 struct net_device *physoutdev;
488
482 /* Case 2: indev is a bridge group, we need to look 489 /* Case 2: indev is a bridge group, we need to look
483 * for physical device (when called from ipv4) */ 490 * for physical device (when called from ipv4) */
484 if (nla_put_be32(inst->skb, NFULA_IFINDEX_OUTDEV, 491 if (nla_put_be32(inst->skb, NFULA_IFINDEX_OUTDEV,
485 htonl(outdev->ifindex))) 492 htonl(outdev->ifindex)))
486 goto nla_put_failure; 493 goto nla_put_failure;
487 if (skb->nf_bridge && skb->nf_bridge->physoutdev && 494
495 physoutdev = nf_bridge_get_physoutdev(skb);
496 if (physoutdev &&
488 nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV, 497 nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
489 htonl(skb->nf_bridge->physoutdev->ifindex))) 498 htonl(physoutdev->ifindex)))
490 goto nla_put_failure; 499 goto nla_put_failure;
491 } 500 }
492#endif 501#endif
diff --git a/net/netfilter/nfnetlink_queue_core.c b/net/netfilter/nfnetlink_queue_core.c
index 86ee8b05adae..94e1aaf86070 100644
--- a/net/netfilter/nfnetlink_queue_core.c
+++ b/net/netfilter/nfnetlink_queue_core.c
@@ -25,6 +25,7 @@
25#include <linux/proc_fs.h> 25#include <linux/proc_fs.h>
26#include <linux/netfilter_ipv4.h> 26#include <linux/netfilter_ipv4.h>
27#include <linux/netfilter_ipv6.h> 27#include <linux/netfilter_ipv6.h>
28#include <linux/netfilter_bridge.h>
28#include <linux/netfilter/nfnetlink.h> 29#include <linux/netfilter/nfnetlink.h>
29#include <linux/netfilter/nfnetlink_queue.h> 30#include <linux/netfilter/nfnetlink_queue.h>
30#include <linux/list.h> 31#include <linux/list.h>
@@ -396,14 +397,18 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
396 htonl(br_port_get_rcu(indev)->br->dev->ifindex))) 397 htonl(br_port_get_rcu(indev)->br->dev->ifindex)))
397 goto nla_put_failure; 398 goto nla_put_failure;
398 } else { 399 } else {
400 int physinif;
401
399 /* Case 2: indev is bridge group, we need to look for 402 /* Case 2: indev is bridge group, we need to look for
400 * physical device (when called from ipv4) */ 403 * physical device (when called from ipv4) */
401 if (nla_put_be32(skb, NFQA_IFINDEX_INDEV, 404 if (nla_put_be32(skb, NFQA_IFINDEX_INDEV,
402 htonl(indev->ifindex))) 405 htonl(indev->ifindex)))
403 goto nla_put_failure; 406 goto nla_put_failure;
404 if (entskb->nf_bridge && entskb->nf_bridge->physindev && 407
408 physinif = nf_bridge_get_physinif(entskb);
409 if (physinif &&
405 nla_put_be32(skb, NFQA_IFINDEX_PHYSINDEV, 410 nla_put_be32(skb, NFQA_IFINDEX_PHYSINDEV,
406 htonl(entskb->nf_bridge->physindev->ifindex))) 411 htonl(physinif)))
407 goto nla_put_failure; 412 goto nla_put_failure;
408 } 413 }
409#endif 414#endif
@@ -426,14 +431,18 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
426 htonl(br_port_get_rcu(outdev)->br->dev->ifindex))) 431 htonl(br_port_get_rcu(outdev)->br->dev->ifindex)))
427 goto nla_put_failure; 432 goto nla_put_failure;
428 } else { 433 } else {
434 int physoutif;
435
429 /* Case 2: outdev is bridge group, we need to look for 436 /* Case 2: outdev is bridge group, we need to look for
430 * physical output device (when called from ipv4) */ 437 * physical output device (when called from ipv4) */
431 if (nla_put_be32(skb, NFQA_IFINDEX_OUTDEV, 438 if (nla_put_be32(skb, NFQA_IFINDEX_OUTDEV,
432 htonl(outdev->ifindex))) 439 htonl(outdev->ifindex)))
433 goto nla_put_failure; 440 goto nla_put_failure;
434 if (entskb->nf_bridge && entskb->nf_bridge->physoutdev && 441
442 physoutif = nf_bridge_get_physoutif(entskb);
443 if (physoutif &&
435 nla_put_be32(skb, NFQA_IFINDEX_PHYSOUTDEV, 444 nla_put_be32(skb, NFQA_IFINDEX_PHYSOUTDEV,
436 htonl(entskb->nf_bridge->physoutdev->ifindex))) 445 htonl(physoutif)))
437 goto nla_put_failure; 446 goto nla_put_failure;
438 } 447 }
439#endif 448#endif
@@ -765,11 +774,12 @@ dev_cmp(struct nf_queue_entry *entry, unsigned long ifindex)
765 return 1; 774 return 1;
766#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) 775#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
767 if (entry->skb->nf_bridge) { 776 if (entry->skb->nf_bridge) {
768 if (entry->skb->nf_bridge->physindev && 777 int physinif, physoutif;
769 entry->skb->nf_bridge->physindev->ifindex == ifindex) 778
770 return 1; 779 physinif = nf_bridge_get_physinif(entry->skb);
771 if (entry->skb->nf_bridge->physoutdev && 780 physoutif = nf_bridge_get_physoutif(entry->skb);
772 entry->skb->nf_bridge->physoutdev->ifindex == ifindex) 781
782 if (physinif == ifindex || physoutif == ifindex)
773 return 1; 783 return 1;
774 } 784 }
775#endif 785#endif