netfilter: bridge: replace physindev with physinif in nf_bridge_info
[platform/kernel/linux-starfive.git] / net / bridge / br_netfilter_hooks.c
index 033034d..92dae4c 100644 (file)
@@ -279,8 +279,17 @@ int br_nf_pre_routing_finish_bridge(struct net *net, struct sock *sk, struct sk_
 
                if ((READ_ONCE(neigh->nud_state) & NUD_CONNECTED) &&
                    READ_ONCE(neigh->hh.hh_len)) {
+                       struct net_device *br_indev;
+
+                       br_indev = nf_bridge_get_physindev(skb, net);
+                       if (!br_indev) {
+                               neigh_release(neigh);
+                               goto free_skb;
+                       }
+
                        neigh_hh_bridge(&neigh->hh, skb);
-                       skb->dev = nf_bridge->physindev;
+                       skb->dev = br_indev;
+
                        ret = br_handle_frame_finish(net, sk, skb);
                } else {
                        /* the neighbour function below overwrites the complete
@@ -352,12 +361,18 @@ br_nf_ipv4_daddr_was_changed(const struct sk_buff *skb,
  */
 static int br_nf_pre_routing_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
-       struct net_device *dev = skb->dev;
+       struct net_device *dev = skb->dev, *br_indev;
        struct iphdr *iph = ip_hdr(skb);
        struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
        struct rtable *rt;
        int err;
 
+       br_indev = nf_bridge_get_physindev(skb, net);
+       if (!br_indev) {
+               kfree_skb(skb);
+               return 0;
+       }
+
        nf_bridge->frag_max_size = IPCB(skb)->frag_max_size;
 
        if (nf_bridge->pkt_otherhost) {
@@ -397,7 +412,7 @@ free_skb:
                } else {
                        if (skb_dst(skb)->dev == dev) {
 bridged_dnat:
-                               skb->dev = nf_bridge->physindev;
+                               skb->dev = br_indev;
                                nf_bridge_update_protocol(skb);
                                nf_bridge_push_encap_header(skb);
                                br_nf_hook_thresh(NF_BR_PRE_ROUTING,
@@ -410,7 +425,7 @@ bridged_dnat:
                        skb->pkt_type = PACKET_HOST;
                }
        } else {
-               rt = bridge_parent_rtable(nf_bridge->physindev);
+               rt = bridge_parent_rtable(br_indev);
                if (!rt) {
                        kfree_skb(skb);
                        return 0;
@@ -419,7 +434,7 @@ bridged_dnat:
                skb_dst_set_noref(skb, &rt->dst);
        }
 
-       skb->dev = nf_bridge->physindev;
+       skb->dev = br_indev;
        nf_bridge_update_protocol(skb);
        nf_bridge_push_encap_header(skb);
        br_nf_hook_thresh(NF_BR_PRE_ROUTING, net, sk, skb, skb->dev, NULL,
@@ -456,7 +471,7 @@ struct net_device *setup_pre_routing(struct sk_buff *skb, const struct net *net)
        }
 
        nf_bridge->in_prerouting = 1;
-       nf_bridge->physindev = skb->dev;
+       nf_bridge->physinif = skb->dev->ifindex;
        skb->dev = brnf_get_logical_dev(skb, skb->dev, net);
 
        if (skb->protocol == htons(ETH_P_8021Q))
@@ -553,7 +568,11 @@ static int br_nf_forward_finish(struct net *net, struct sock *sk, struct sk_buff
                if (skb->protocol == htons(ETH_P_IPV6))
                        nf_bridge->frag_max_size = IP6CB(skb)->frag_max_size;
 
-               in = nf_bridge->physindev;
+               in = nf_bridge_get_physindev(skb, net);
+               if (!in) {
+                       kfree_skb(skb);
+                       return 0;
+               }
                if (nf_bridge->pkt_otherhost) {
                        skb->pkt_type = PACKET_OTHERHOST;
                        nf_bridge->pkt_otherhost = false;
@@ -897,6 +916,13 @@ static unsigned int ip_sabotage_in(void *priv,
 static void br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb)
 {
        struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
+       struct net_device *br_indev;
+
+       br_indev = nf_bridge_get_physindev(skb, dev_net(skb->dev));
+       if (!br_indev) {
+               kfree_skb(skb);
+               return;
+       }
 
        skb_pull(skb, ETH_HLEN);
        nf_bridge->bridged_dnat = 0;
@@ -906,7 +932,7 @@ static void br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb)
        skb_copy_to_linear_data_offset(skb, -(ETH_HLEN - ETH_ALEN),
                                       nf_bridge->neigh_header,
                                       ETH_HLEN - ETH_ALEN);
-       skb->dev = nf_bridge->physindev;
+       skb->dev = br_indev;
 
        nf_bridge->physoutdev = NULL;
        br_handle_frame_finish(dev_net(skb->dev), NULL, skb);