> There is one case missing: the brouter case. If br0=eth0+eth1 and a
> packet arrives at eth0 (not br0) in the IP code (not the bridge code),
> then the indev must be eth0, not br0.  How about something like this?

Ok, I've implemented your suggested modifications now.

Dave: Please apply to your net-2.6.14 tree. Thanks!

-- 
- Harald Welte <[EMAIL PROTECTED]>                 http://netfilter.org/
============================================================================
  "Fragmentation is like classful addressing -- an interesting early
   architectural error that shows how much experimentation was going
   on while IP was being designed."                    -- Paul Vixie
[NETFILTER] add correct bridging support to nfnetlink_{queue,log}

This patch adds support for passing the real 'physical' device ifindex down
to userspace via nfnetlink_log and nfnetlink_queue.

This feature basically obsoletes net/bridge/netfilter/ebt_ulog.c, and it
is likely ebt_ulog.c will die with one of the next couple of patches.

Signed-off-by: Harald Welte <[EMAIL PROTECTED]>

---
commit 5f748d529c9bf1f0f52453d02a5e3aa9eca351e3
tree f337de87d43b721ba0653e759c7d54d5daa27c52
parent e9d42778324d0432fe18b1a26d915d342a067351
author Harald Welte <[EMAIL PROTECTED]> Mo, 08 Aug 2005 15:20:14 +0200
committer Harald Welte <[EMAIL PROTECTED]> Mo, 08 Aug 2005 15:20:14 +0200

 include/linux/netfilter/nfnetlink_log.h   |    2 +
 include/linux/netfilter/nfnetlink_queue.h |    2 +
 net/netfilter/nfnetlink_log.c             |   58 +++++++++++++++++++++++++++++
 net/netfilter/nfnetlink_queue.c           |   58 +++++++++++++++++++++++++++++
 4 files changed, 120 insertions(+), 0 deletions(-)

diff --git a/include/linux/netfilter/nfnetlink_log.h 
b/include/linux/netfilter/nfnetlink_log.h
--- a/include/linux/netfilter/nfnetlink_log.h
+++ b/include/linux/netfilter/nfnetlink_log.h
@@ -40,6 +40,8 @@ enum nfulnl_attr_type {
        NFULA_TIMESTAMP,                /* nfulnl_msg_packet_timestamp */
        NFULA_IFINDEX_INDEV,            /* u_int32_t ifindex */
        NFULA_IFINDEX_OUTDEV,           /* u_int32_t ifindex */
+       NFULA_IFINDEX_PHYSINDEV,        /* u_int32_t ifindex */
+       NFULA_IFINDEX_PHYSOUTDEV,       /* u_int32_t ifindex */
        NFULA_HWADDR,                   /* nfulnl_msg_packet_hw */
        NFULA_PAYLOAD,                  /* opaque data payload */
        NFULA_PREFIX,                   /* string prefix */
diff --git a/include/linux/netfilter/nfnetlink_queue.h 
b/include/linux/netfilter/nfnetlink_queue.h
--- a/include/linux/netfilter/nfnetlink_queue.h
+++ b/include/linux/netfilter/nfnetlink_queue.h
@@ -36,6 +36,8 @@ enum nfqnl_attr_type {
        NFQA_TIMESTAMP,                 /* nfqnl_msg_packet_timestamp */
        NFQA_IFINDEX_INDEV,             /* u_int32_t ifindex */
        NFQA_IFINDEX_OUTDEV,            /* u_int32_t ifindex */
+       NFQA_IFINDEX_PHYSINDEV,         /* u_int32_t ifindex */
+       NFQA_IFINDEX_PHYSOUTDEV,        /* u_int32_t ifindex */
        NFQA_HWADDR,                    /* nfqnl_msg_packet_hw */
        NFQA_PAYLOAD,                   /* opaque data payload */
 
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -33,6 +33,10 @@
 
 #include <asm/atomic.h>
 
+#ifdef CONFIG_BRIDGE_NETFILTER
+#include "../bridge/br_private.h"
+#endif
+
 #define NFULNL_NLBUFSIZ_DEFAULT        4096
 #define NFULNL_TIMEOUT_DEFAULT         100     /* every second */
 #define NFULNL_QTHRESH_DEFAULT         100     /* 100 packets */
@@ -412,14 +416,64 @@ __build_packet_message(struct nfulnl_ins
 
        if (indev) {
                tmp_uint = htonl(indev->ifindex);
+#ifndef CONFIG_BRIDGE_NETFILTER
                NFA_PUT(inst->skb, NFULA_IFINDEX_INDEV, sizeof(tmp_uint),
                        &tmp_uint);
+#else
+               if (pf == PF_BRIDGE) {
+                       /* Case 1: outdev is physical input device, we need to
+                        * look for bridge group (when called from
+                        * netfilter_bridge) */
+                       NFA_PUT(inst->skb, NFULA_IFINDEX_PHYSINDEV,
+                               sizeof(tmp_uint), &tmp_uint);
+                       /* this is the bridge group "brX" */
+                       tmp_uint = htonl(indev->br_port->br->dev->ifindex);
+                       NFA_PUT(inst->skb, NFULA_IFINDEX_INDEV,
+                               sizeof(tmp_uint), &tmp_uint);
+               } else {
+                       /* Case 2: indev is bridge group, we need to look for
+                        * physical device (when called from ipv4) */
+                       NFA_PUT(inst->skb, NFULA_IFINDEX_INDEV,
+                               sizeof(tmp_uint), &tmp_uint);
+                       if (skb->nf_bridge && skb->nf_bridge->physindev) {
+                               tmp_uint = 
+                                   htonl(skb->nf_bridge->physindev->ifindex);
+                               NFA_PUT(inst->skb, NFULA_IFINDEX_PHYSINDEV,
+                                       sizeof(tmp_uint), &tmp_uint);
+                       }
+               }
+#endif
        }
 
        if (outdev) {
                tmp_uint = htonl(outdev->ifindex);
+#ifndef CONFIG_BRIDGE_NETFILTER
                NFA_PUT(inst->skb, NFULA_IFINDEX_OUTDEV, sizeof(tmp_uint),
                        &tmp_uint);
+#else
+               if (pf == PF_BRIDGE) {
+                       /* Case 1: outdev is physical output device, we need to
+                        * look for bridge group (when called from
+                        * netfilter_bridge) */
+                       NFA_PUT(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
+                               sizeof(tmp_uint), &tmp_uint);
+                       /* this is the bridge group "brX" */
+                       tmp_uint = htonl(outdev->br_port->br->dev->ifindex);
+                       NFA_PUT(inst->skb, NFULA_IFINDEX_OUTDEV,
+                               sizeof(tmp_uint), &tmp_uint);
+               } else {
+                       /* Case 2: indev is a bridge group, we need to look
+                        * for physical device (when called from ipv4) */
+                       NFA_PUT(inst->skb, NFULA_IFINDEX_OUTDEV,
+                               sizeof(tmp_uint), &tmp_uint);
+                       if (skb->nf_bridge) {
+                               tmp_uint = 
+                                   htonl(skb->nf_bridge->physoutdev->ifindex);
+                               NFA_PUT(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
+                                       sizeof(tmp_uint), &tmp_uint);
+                       }
+               }
+#endif
        }
 
        if (skb->nfmark) {
@@ -536,6 +590,10 @@ nfulnl_log_packet(unsigned int pf,
                + NFA_SPACE(sizeof(struct nfulnl_msg_packet_hdr))
                + NFA_SPACE(sizeof(u_int32_t))  /* ifindex */
                + NFA_SPACE(sizeof(u_int32_t))  /* ifindex */
+#ifdef CONFIG_BRIDGE_NETFILTER
+               + NFA_SPACE(sizeof(u_int32_t))  /* ifindex */
+               + NFA_SPACE(sizeof(u_int32_t))  /* ifindex */
+#endif
                + NFA_SPACE(sizeof(u_int32_t))  /* mark */
                + NFA_SPACE(sizeof(u_int32_t))  /* uid */
                + NFA_SPACE(NFULNL_PREFIXLEN)   /* prefix */
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -30,6 +30,10 @@
 
 #include <asm/atomic.h>
 
+#ifdef CONFIG_BRIDGE_NETFILTER
+#include "../bridge/br_private.h"
+#endif
+
 #define NFQNL_QMAX_DEFAULT 1024
 
 #if 0
@@ -361,6 +365,10 @@ nfqnl_build_packet_message(struct nfqnl_
        size =    NLMSG_SPACE(sizeof(struct nfqnl_msg_packet_hdr))
                + NLMSG_SPACE(sizeof(u_int32_t))        /* ifindex */
                + NLMSG_SPACE(sizeof(u_int32_t))        /* ifindex */
+#ifdef CONFIG_BRIDGE_NETFILTER
+               + NLMSG_SPACE(sizeof(u_int32_t))        /* ifindex */
+               + NLMSG_SPACE(sizeof(u_int32_t))        /* ifindex */
+#endif
                + NLMSG_SPACE(sizeof(u_int32_t))        /* mark */
                + NLMSG_SPACE(sizeof(struct nfqnl_msg_packet_hw))
                + NLMSG_SPACE(sizeof(struct nfqnl_msg_packet_timestamp));
@@ -412,12 +420,62 @@ nfqnl_build_packet_message(struct nfqnl_
 
        if (entry->info->indev) {
                tmp_uint = htonl(entry->info->indev->ifindex);
+#ifndef CONFIG_BRIDGE_NETFILTER
                NFA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint), &tmp_uint);
+#else
+               if (entry->info->pf == PF_BRIDGE) {
+                       /* Case 1: indev is physical input device, we need to
+                        * look for bridge group (when called from 
+                        * netfilter_bridge) */
+                       NFA_PUT(skb, NFQA_IFINDEX_PHYSINDEV, sizeof(tmp_uint), 
+                               &tmp_uint);
+                       /* this is the bridge group "brX" */
+                       tmp_uint = 
htonl(entry->info->indev->br_port->br->dev->ifindex);
+                       NFA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint),
+                               &tmp_uint);
+               } else {
+                       /* Case 2: indev is bridge group, we need to look for
+                        * physical device (when called from ipv4) */
+                       NFA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint),
+                               &tmp_uint);
+                       if (entry->skb->nf_bridge
+                           && entry->skb->nf_bridge->physindev) {
+                               tmp_uint = 
htonl(entry->skb->nf_bridge->physindev->ifindex);
+                               NFA_PUT(skb, NFQA_IFINDEX_PHYSINDEV,
+                                       sizeof(tmp_uint), &tmp_uint);
+                       }
+               }
+#endif
        }
 
        if (entry->info->outdev) {
                tmp_uint = htonl(entry->info->outdev->ifindex);
+#ifndef CONFIG_BRIDGE_NETFILTER
                NFA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint), &tmp_uint);
+#else
+               if (entry->info->pf == PF_BRIDGE) {
+                       /* Case 1: outdev is physical output device, we need to
+                        * look for bridge group (when called from 
+                        * netfilter_bridge) */
+                       NFA_PUT(skb, NFQA_IFINDEX_PHYSOUTDEV, sizeof(tmp_uint),
+                               &tmp_uint);
+                       /* this is the bridge group "brX" */
+                       tmp_uint = 
htonl(entry->info->outdev->br_port->br->dev->ifindex);
+                       NFA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint),
+                               &tmp_uint);
+               } else {
+                       /* Case 2: outdev is bridge group, we need to look for
+                        * physical output device (when called from ipv4) */
+                       NFA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint),
+                               &tmp_uint);
+                       if (entry->skb->nf_bridge
+                           && entry->skb->nf_bridge->physoutdev) {
+                               tmp_uint = 
htonl(entry->skb->nf_bridge->physoutdev->ifindex);
+                               NFA_PUT(skb, NFQA_IFINDEX_PHYSOUTDEV,
+                                       sizeof(tmp_uint), &tmp_uint);
+                       }
+               }
+#endif
        }
 
        if (entry->skb->nfmark) {

Attachment: pgp3FXZsyNFSy.pgp
Description: PGP signature

Reply via email to