br_handle_local_finish is called by NF_HOOK after accepting the packet.
If the return value of NF_HOOK is zero (i.e. the return value of
br_handle_local_finish), the packet is passed to the network stack. This
behavior conflicts with netfilter hooks which return NF_STOLEN/NF_QUEUE.
In this case, NF_HOOK returns also zero (see nf_hook_slow) but
br_handle_local_finish was never called. The packet will still passed to
the network stack.

Signed-off-by: Martin Faecknitz <faeckn...@hotsplots.de>

diff --git
a/target/linux/generic/patches-3.12/120-bridge_allow_receiption_on_disabled_port.patch
b/target/linux/generic/patches-3.12/120-bridge_allow_receiption_on_disabled_port.patch
index 8a2fb41..1673d9e 100644
---
a/target/linux/generic/patches-3.12/120-bridge_allow_receiption_on_disabled_port.patch
+++
b/target/linux/generic/patches-3.12/120-bridge_allow_receiption_on_disabled_port.patch
@@ -15,7 +15,7 @@ Signed-off-by: Felix Fietkau <n...@openwrt.org>

 --- a/net/bridge/br_input.c
 +++ b/net/bridge/br_input.c
-@@ -144,11 +144,13 @@ drop:
+@@ -144,12 +144,14 @@ drop:
  static int br_handle_local_finish(struct sk_buff *skb)
  {
        struct net_bridge_port *p = br_port_get_rcu(skb->dev);
@@ -26,13 +26,24 @@ Signed-off-by: Felix Fietkau <n...@openwrt.org>
 -      br_vlan_get_tag(skb, &vid);
 -      if (p->flags & BR_LEARNING)
 -              br_fdb_update(p->br, p, eth_hdr(skb)->h_source, vid);
+-      return 0;        /* process further */
 +              br_vlan_get_tag(skb, &vid);
 +              if (p->flags & BR_LEARNING)
 +                      br_fdb_update(p->br, p, eth_hdr(skb)->h_source, vid);
 +      }
-       return 0;        /* process further */
++      return 1;        /* process further */
  }

+ /*
+@@ -208,7 +210,7 @@
+
+               /* Deliver packet to local host only */
+               if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,
+-                          NULL, br_handle_local_finish)) {
++                          NULL, br_handle_local_finish) != 1) {
+                       return RX_HANDLER_CONSUMED; /* consumed by filter */
+               } else {
+                       *pskb = skb;
 @@ -218,6 +220,18 @@ rx_handler_result_t br_handle_frame(stru

  forward:
@@ -42,7 +53,7 @@ Signed-off-by: Felix Fietkau <n...@openwrt.org>
 +                      skb->pkt_type = PACKET_HOST;
 +
 +              if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, 
NULL,
-+                      br_handle_local_finish))
++                      br_handle_local_finish) != 1)
 +                      break;
 +
 +              BR_INPUT_SKB_CB(skb)->brdev = p->br->dev;
diff --git
a/target/linux/generic/patches-3.12/644-bridge_optimize_netfilter_hooks.patch
b/target/linux/generic/patches-3.12/644-bridge_optimize_netfilter_hooks.patch
index 85def08..82ca5c8 100644
--- 
a/target/linux/generic/patches-3.12/644-bridge_optimize_netfilter_hooks.patch
+++ 
b/target/linux/generic/patches-3.12/644-bridge_optimize_netfilter_hooks.patch
@@ -44,7 +44,7 @@
                /* Deliver packet to local host only */
 -              if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,
 +              if (BR_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,
-                           NULL, br_handle_local_finish)) {
+                           NULL, br_handle_local_finish) != 1) {
                        return RX_HANDLER_CONSUMED; /* consumed by filter */
                } else {
 @@ -228,7 +228,7 @@ forward:
@@ -53,7 +53,7 @@

 -              if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, 
NULL,
 +              if (BR_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, 
NULL,
-                       br_handle_local_finish))
+                       br_handle_local_finish) != 1)
                        break;

 @@ -250,7 +250,7 @@ forward:
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

Reply via email to