Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Florian Westphal and committed by
Pablo Neira Ayuso
c737b7c4 e70deecb

+97 -34
+22 -1
include/linux/netfilter_bridge.h
··· 2 2 #define __LINUX_BRIDGE_NETFILTER_H 3 3 4 4 #include <uapi/linux/netfilter_bridge.h> 5 - 5 + #include <linux/skbuff.h> 6 6 7 7 enum nf_br_hook_priorities { 8 8 NF_BR_PRI_FIRST = INT_MIN, ··· 40 40 skb_dst_drop(skb); 41 41 } 42 42 43 + static inline int nf_bridge_get_physinif(const struct sk_buff *skb) 44 + { 45 + return skb->nf_bridge ? skb->nf_bridge->physindev->ifindex : 0; 46 + } 47 + 48 + static inline int nf_bridge_get_physoutif(const struct sk_buff *skb) 49 + { 50 + return skb->nf_bridge ? skb->nf_bridge->physoutdev->ifindex : 0; 51 + } 52 + 53 + static inline struct net_device * 54 + nf_bridge_get_physindev(const struct sk_buff *skb) 55 + { 56 + return skb->nf_bridge ? skb->nf_bridge->physindev : NULL; 57 + } 58 + 59 + static inline struct net_device * 60 + nf_bridge_get_physoutdev(const struct sk_buff *skb) 61 + { 62 + return skb->nf_bridge ? skb->nf_bridge->physoutdev : NULL; 63 + } 43 64 #else 44 65 #define br_drop_fake_rtable(skb) do { } while (0) 45 66 #endif /* CONFIG_BRIDGE_NETFILTER */
+3 -1
net/ipv4/netfilter/nf_reject_ipv4.c
··· 13 13 #include <net/dst.h> 14 14 #include <net/netfilter/ipv4/nf_reject.h> 15 15 #include <linux/netfilter_ipv4.h> 16 + #include <linux/netfilter_bridge.h> 16 17 #include <net/netfilter/ipv4/nf_reject.h> 17 18 18 19 const struct tcphdr *nf_reject_ip_tcphdr_get(struct sk_buff *oldskb, ··· 147 146 */ 148 147 if (oldskb->nf_bridge) { 149 148 struct ethhdr *oeth = eth_hdr(oldskb); 150 - nskb->dev = oldskb->nf_bridge->physindev; 149 + 150 + nskb->dev = nf_bridge_get_physindev(oldskb); 151 151 niph->tot_len = htons(nskb->len); 152 152 ip_send_check(niph); 153 153 if (dev_hard_header(nskb, nskb->dev, ntohs(nskb->protocol),
+3 -1
net/ipv6/netfilter/nf_reject_ipv6.c
··· 13 13 #include <net/ip6_checksum.h> 14 14 #include <net/netfilter/ipv6/nf_reject.h> 15 15 #include <linux/netfilter_ipv6.h> 16 + #include <linux/netfilter_bridge.h> 16 17 #include <net/netfilter/ipv6/nf_reject.h> 17 18 18 19 const struct tcphdr *nf_reject_ip6_tcphdr_get(struct sk_buff *oldskb, ··· 196 195 */ 197 196 if (oldskb->nf_bridge) { 198 197 struct ethhdr *oeth = eth_hdr(oldskb); 199 - nskb->dev = oldskb->nf_bridge->physindev; 198 + 199 + nskb->dev = nf_bridge_get_physindev(oldskb); 200 200 nskb->protocol = htons(ETH_P_IPV6); 201 201 ip6h->payload_len = htons(sizeof(struct tcphdr)); 202 202 if (dev_hard_header(nskb, nskb->dev, ntohs(nskb->protocol),
+24 -8
net/netfilter/ipset/ip_set_hash_netiface.c
··· 19 19 #include <net/netlink.h> 20 20 21 21 #include <linux/netfilter.h> 22 + #include <linux/netfilter_bridge.h> 22 23 #include <linux/netfilter/ipset/pfxlen.h> 23 24 #include <linux/netfilter/ipset/ip_set.h> 24 25 #include <linux/netfilter/ipset/ip_set_hash.h> ··· 212 211 #define HKEY_DATALEN sizeof(struct hash_netiface4_elem_hashed) 213 212 #include "ip_set_hash_gen.h" 214 213 214 + #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) 215 + static const char *get_physindev_name(const struct sk_buff *skb) 216 + { 217 + struct net_device *dev = nf_bridge_get_physindev(skb); 218 + 219 + return dev ? dev->name : NULL; 220 + } 221 + 222 + static const char *get_phyoutdev_name(const struct sk_buff *skb) 223 + { 224 + struct net_device *dev = nf_bridge_get_physoutdev(skb); 225 + 226 + return dev ? dev->name : NULL; 227 + } 228 + #endif 229 + 215 230 static int 216 231 hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb, 217 232 const struct xt_action_param *par, ··· 251 234 e.ip &= ip_set_netmask(e.cidr); 252 235 253 236 #define IFACE(dir) (par->dir ? par->dir->name : NULL) 254 - #define PHYSDEV(dir) (nf_bridge->dir ? nf_bridge->dir->name : NULL) 255 237 #define SRCDIR (opt->flags & IPSET_DIM_TWO_SRC) 256 238 257 239 if (opt->cmdflags & IPSET_FLAG_PHYSDEV) { 258 240 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) 259 - const struct nf_bridge_info *nf_bridge = skb->nf_bridge; 241 + e.iface = SRCDIR ? get_physindev_name(skb) : 242 + get_phyoutdev_name(skb); 260 243 261 - if (!nf_bridge) 244 + if (!e.iface) 262 245 return -EINVAL; 263 - e.iface = SRCDIR ? PHYSDEV(physindev) : PHYSDEV(physoutdev); 264 246 e.physdev = 1; 265 247 #else 266 248 e.iface = NULL; ··· 492 476 493 477 if (opt->cmdflags & IPSET_FLAG_PHYSDEV) { 494 478 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) 495 - const struct nf_bridge_info *nf_bridge = skb->nf_bridge; 496 - 497 - if (!nf_bridge) 479 + e.iface = SRCDIR ? get_physindev_name(skb) : 480 + get_phyoutdev_name(skb); 481 + if (!e.iface) 498 482 return -EINVAL; 499 - e.iface = SRCDIR ? PHYSDEV(physindev) : PHYSDEV(physoutdev); 483 + 500 484 e.physdev = 1; 501 485 #else 502 486 e.iface = NULL;
+3 -2
net/netfilter/nf_log_common.c
··· 17 17 #include <net/route.h> 18 18 19 19 #include <linux/netfilter.h> 20 + #include <linux/netfilter_bridge.h> 20 21 #include <linux/netfilter/xt_LOG.h> 21 22 #include <net/netfilter/nf_log.h> 22 23 ··· 164 163 const struct net_device *physindev; 165 164 const struct net_device *physoutdev; 166 165 167 - physindev = skb->nf_bridge->physindev; 166 + physindev = nf_bridge_get_physindev(skb); 168 167 if (physindev && in != physindev) 169 168 nf_log_buf_add(m, "PHYSIN=%s ", physindev->name); 170 - physoutdev = skb->nf_bridge->physoutdev; 169 + physoutdev = nf_bridge_get_physoutdev(skb); 171 170 if (physoutdev && out != physoutdev) 172 171 nf_log_buf_add(m, "PHYSOUT=%s ", physoutdev->name); 173 172 }
+10 -8
net/netfilter/nf_queue.c
··· 10 10 #include <linux/proc_fs.h> 11 11 #include <linux/skbuff.h> 12 12 #include <linux/netfilter.h> 13 + #include <linux/netfilter_bridge.h> 13 14 #include <linux/seq_file.h> 14 15 #include <linux/rcupdate.h> 15 16 #include <net/protocol.h> ··· 55 54 dev_put(entry->outdev); 56 55 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) 57 56 if (entry->skb->nf_bridge) { 58 - struct nf_bridge_info *nf_bridge = entry->skb->nf_bridge; 57 + struct net_device *physdev; 59 58 60 - if (nf_bridge->physindev) 61 - dev_put(nf_bridge->physindev); 62 - if (nf_bridge->physoutdev) 63 - dev_put(nf_bridge->physoutdev); 59 + physdev = nf_bridge_get_physindev(entry->skb); 60 + if (physdev) 61 + dev_put(physdev); 62 + physdev = nf_bridge_get_physoutdev(entry->skb); 63 + if (physdev) 64 + dev_put(physdev); 64 65 } 65 66 #endif 66 67 /* Drop reference to owner of hook which queued us. */ ··· 82 79 dev_hold(entry->outdev); 83 80 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) 84 81 if (entry->skb->nf_bridge) { 85 - struct nf_bridge_info *nf_bridge = entry->skb->nf_bridge; 86 82 struct net_device *physdev; 87 83 88 - physdev = nf_bridge->physindev; 84 + physdev = nf_bridge_get_physindev(entry->skb); 89 85 if (physdev) 90 86 dev_hold(physdev); 91 - physdev = nf_bridge->physoutdev; 87 + physdev = nf_bridge_get_physoutdev(entry->skb); 92 88 if (physdev) 93 89 dev_hold(physdev); 94 90 }