#define __LINUX_BRIDGE_NETFILTER_H
 
 #include <uapi/linux/netfilter_bridge.h>
-
+#include <linux/skbuff.h>
 
 enum nf_br_hook_priorities {
        NF_BR_PRI_FIRST = INT_MIN,
                skb_dst_drop(skb);
 }
 
+static inline int nf_bridge_get_physinif(const struct sk_buff *skb)
+{
+       return skb->nf_bridge ? skb->nf_bridge->physindev->ifindex : 0;
+}
+
+static inline int nf_bridge_get_physoutif(const struct sk_buff *skb)
+{
+       return skb->nf_bridge ? skb->nf_bridge->physoutdev->ifindex : 0;
+}
+
+static inline struct net_device *
+nf_bridge_get_physindev(const struct sk_buff *skb)
+{
+       return skb->nf_bridge ? skb->nf_bridge->physindev : NULL;
+}
+
+static inline struct net_device *
+nf_bridge_get_physoutdev(const struct sk_buff *skb)
+{
+       return skb->nf_bridge ? skb->nf_bridge->physoutdev : NULL;
+}
 #else
 #define br_drop_fake_rtable(skb)               do { } while (0)
 #endif /* CONFIG_BRIDGE_NETFILTER */
 
 #include <net/dst.h>
 #include <net/netfilter/ipv4/nf_reject.h>
 #include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_bridge.h>
 #include <net/netfilter/ipv4/nf_reject.h>
 
 const struct tcphdr *nf_reject_ip_tcphdr_get(struct sk_buff *oldskb,
         */
        if (oldskb->nf_bridge) {
                struct ethhdr *oeth = eth_hdr(oldskb);
-               nskb->dev = oldskb->nf_bridge->physindev;
+
+               nskb->dev = nf_bridge_get_physindev(oldskb);
                niph->tot_len = htons(nskb->len);
                ip_send_check(niph);
                if (dev_hard_header(nskb, nskb->dev, ntohs(nskb->protocol),
 
 #include <net/ip6_checksum.h>
 #include <net/netfilter/ipv6/nf_reject.h>
 #include <linux/netfilter_ipv6.h>
+#include <linux/netfilter_bridge.h>
 #include <net/netfilter/ipv6/nf_reject.h>
 
 const struct tcphdr *nf_reject_ip6_tcphdr_get(struct sk_buff *oldskb,
         */
        if (oldskb->nf_bridge) {
                struct ethhdr *oeth = eth_hdr(oldskb);
-               nskb->dev = oldskb->nf_bridge->physindev;
+
+               nskb->dev = nf_bridge_get_physindev(oldskb);
                nskb->protocol = htons(ETH_P_IPV6);
                ip6h->payload_len = htons(sizeof(struct tcphdr));
                if (dev_hard_header(nskb, nskb->dev, ntohs(nskb->protocol),
 
 #include <net/netlink.h>
 
 #include <linux/netfilter.h>
+#include <linux/netfilter_bridge.h>
 #include <linux/netfilter/ipset/pfxlen.h>
 #include <linux/netfilter/ipset/ip_set.h>
 #include <linux/netfilter/ipset/ip_set_hash.h>
 #define HKEY_DATALEN   sizeof(struct hash_netiface4_elem_hashed)
 #include "ip_set_hash_gen.h"
 
+#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
+static const char *get_physindev_name(const struct sk_buff *skb)
+{
+       struct net_device *dev = nf_bridge_get_physindev(skb);
+
+       return dev ? dev->name : NULL;
+}
+
+static const char *get_phyoutdev_name(const struct sk_buff *skb)
+{
+       struct net_device *dev = nf_bridge_get_physoutdev(skb);
+
+       return dev ? dev->name : NULL;
+}
+#endif
+
 static int
 hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb,
                    const struct xt_action_param *par,
        e.ip &= ip_set_netmask(e.cidr);
 
 #define IFACE(dir)     (par->dir ? par->dir->name : NULL)
-#define PHYSDEV(dir)   (nf_bridge->dir ? nf_bridge->dir->name : NULL)
 #define SRCDIR         (opt->flags & IPSET_DIM_TWO_SRC)
 
        if (opt->cmdflags & IPSET_FLAG_PHYSDEV) {
 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
-               const struct nf_bridge_info *nf_bridge = skb->nf_bridge;
+               e.iface = SRCDIR ? get_physindev_name(skb) :
+                                  get_phyoutdev_name(skb);
 
-               if (!nf_bridge)
+               if (!e.iface)
                        return -EINVAL;
-               e.iface = SRCDIR ? PHYSDEV(physindev) : PHYSDEV(physoutdev);
                e.physdev = 1;
 #else
                e.iface = NULL;
 
        if (opt->cmdflags & IPSET_FLAG_PHYSDEV) {
 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
-               const struct nf_bridge_info *nf_bridge = skb->nf_bridge;
-
-               if (!nf_bridge)
+               e.iface = SRCDIR ? get_physindev_name(skb) :
+                                  get_phyoutdev_name(skb);
+               if (!e.iface)
                        return -EINVAL;
-               e.iface = SRCDIR ? PHYSDEV(physindev) : PHYSDEV(physoutdev);
+
                e.physdev = 1;
 #else
                e.iface = NULL;
 
 #include <net/route.h>
 
 #include <linux/netfilter.h>
+#include <linux/netfilter_bridge.h>
 #include <linux/netfilter/xt_LOG.h>
 #include <net/netfilter/nf_log.h>
 
                const struct net_device *physindev;
                const struct net_device *physoutdev;
 
-               physindev = skb->nf_bridge->physindev;
+               physindev = nf_bridge_get_physindev(skb);
                if (physindev && in != physindev)
                        nf_log_buf_add(m, "PHYSIN=%s ", physindev->name);
-               physoutdev = skb->nf_bridge->physoutdev;
+               physoutdev = nf_bridge_get_physoutdev(skb);
                if (physoutdev && out != physoutdev)
                        nf_log_buf_add(m, "PHYSOUT=%s ", physoutdev->name);
        }
 
 #include <linux/proc_fs.h>
 #include <linux/skbuff.h>
 #include <linux/netfilter.h>
+#include <linux/netfilter_bridge.h>
 #include <linux/seq_file.h>
 #include <linux/rcupdate.h>
 #include <net/protocol.h>
                dev_put(entry->outdev);
 #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. */
                dev_hold(entry->outdev);
 #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);
        }
 
 #include <linux/ipv6.h>
 #include <linux/netdevice.h>
 #include <linux/netfilter.h>
+#include <linux/netfilter_bridge.h>
 #include <net/netlink.h>
 #include <linux/netfilter/nfnetlink.h>
 #include <linux/netfilter/nfnetlink_log.h>
                                         htonl(br_port_get_rcu(indev)->br->dev->ifindex)))
                                goto nla_put_failure;
                } else {
+                       struct net_device *physindev;
+
                        /* Case 2: indev is bridge group, we need to look for
                         * physical device (when called from ipv4) */
                        if (nla_put_be32(inst->skb, NFULA_IFINDEX_INDEV,
                                         htonl(indev->ifindex)))
                                goto nla_put_failure;
-                       if (skb->nf_bridge && skb->nf_bridge->physindev &&
+
+                       physindev = nf_bridge_get_physindev(skb);
+                       if (physindev &&
                            nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSINDEV,
-                                        htonl(skb->nf_bridge->physindev->ifindex)))
+                                        htonl(physindev->ifindex)))
                                goto nla_put_failure;
                }
 #endif
                                         htonl(br_port_get_rcu(outdev)->br->dev->ifindex)))
                                goto nla_put_failure;
                } else {
+                       struct net_device *physoutdev;
+
                        /* Case 2: indev is a bridge group, we need to look
                         * for physical device (when called from ipv4) */
                        if (nla_put_be32(inst->skb, NFULA_IFINDEX_OUTDEV,
                                         htonl(outdev->ifindex)))
                                goto nla_put_failure;
-                       if (skb->nf_bridge && skb->nf_bridge->physoutdev &&
+
+                       physoutdev = nf_bridge_get_physoutdev(skb);
+                       if (physoutdev &&
                            nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
-                                        htonl(skb->nf_bridge->physoutdev->ifindex)))
+                                        htonl(physoutdev->ifindex)))
                                goto nla_put_failure;
                }
 #endif
 
 #include <linux/proc_fs.h>
 #include <linux/netfilter_ipv4.h>
 #include <linux/netfilter_ipv6.h>
+#include <linux/netfilter_bridge.h>
 #include <linux/netfilter/nfnetlink.h>
 #include <linux/netfilter/nfnetlink_queue.h>
 #include <linux/list.h>
                                         htonl(br_port_get_rcu(indev)->br->dev->ifindex)))
                                goto nla_put_failure;
                } else {
+                       int physinif;
+
                        /* Case 2: indev is bridge group, we need to look for
                         * physical device (when called from ipv4) */
                        if (nla_put_be32(skb, NFQA_IFINDEX_INDEV,
                                         htonl(indev->ifindex)))
                                goto nla_put_failure;
-                       if (entskb->nf_bridge && entskb->nf_bridge->physindev &&
+
+                       physinif = nf_bridge_get_physinif(entskb);
+                       if (physinif &&
                            nla_put_be32(skb, NFQA_IFINDEX_PHYSINDEV,
-                                        htonl(entskb->nf_bridge->physindev->ifindex)))
+                                        htonl(physinif)))
                                goto nla_put_failure;
                }
 #endif
                                         htonl(br_port_get_rcu(outdev)->br->dev->ifindex)))
                                goto nla_put_failure;
                } else {
+                       int physoutif;
+
                        /* Case 2: outdev is bridge group, we need to look for
                         * physical output device (when called from ipv4) */
                        if (nla_put_be32(skb, NFQA_IFINDEX_OUTDEV,
                                         htonl(outdev->ifindex)))
                                goto nla_put_failure;
-                       if (entskb->nf_bridge && entskb->nf_bridge->physoutdev &&
+
+                       physoutif = nf_bridge_get_physoutif(entskb);
+                       if (physoutif &&
                            nla_put_be32(skb, NFQA_IFINDEX_PHYSOUTDEV,
-                                        htonl(entskb->nf_bridge->physoutdev->ifindex)))
+                                        htonl(physoutif)))
                                goto nla_put_failure;
                }
 #endif
                        return 1;
 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
        if (entry->skb->nf_bridge) {
-               if (entry->skb->nf_bridge->physindev &&
-                   entry->skb->nf_bridge->physindev->ifindex == ifindex)
-                       return 1;
-               if (entry->skb->nf_bridge->physoutdev &&
-                   entry->skb->nf_bridge->physoutdev->ifindex == ifindex)
+               int physinif, physoutif;
+
+               physinif = nf_bridge_get_physinif(entry->skb);
+               physoutif = nf_bridge_get_physoutif(entry->skb);
+
+               if (physinif == ifindex || physoutif == ifindex)
                        return 1;
        }
 #endif