Stephen Hemminger wrote:
> I am not against making the bridge code smarter to handle other
> encapsulation.

Do you mean something like this patch?

The only drawback I see for this approach is that it means you
can only encapsulate the ethernet header if the gre interface is
bridged.  That's not too bad a restriction though.

This patch only works for local packets so far, and doesn't
handle the LLC_SAP_BSPAN packets.

Also, if the gre interface is the only port on the bridge, then
we have no mac address.


--- linux-2.6.x/net/bridge/br_device.c  18 Jun 2006 23:30:55 -0000      1.1.1.14
+++ linux-2.6.x/net/bridge/br_device.c  1 Aug 2006 09:12:42 -0000
@@ -17,6 +17,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
+#include <linux/if_arp.h>

 #include <asm/uaccess.h>
 #include "br_private.h"
@@ -95,7 +96,9 @@ static int br_set_mac_address(struct net

        spin_lock_bh(&br->lock);
        list_for_each_entry(port, &br->port_list, list) {
-               if (!compare_ether_addr(port->dev->dev_addr, addr->sa_data)) {
+               if (port->dev->type == ARPHRD_ETHER &&
+                               !compare_ether_addr(port->dev->dev_addr,
+                                                   addr->sa_data)) {
                        br_stp_change_bridge_id(br, addr->sa_data);
                        err = 0;
                        break;
--- linux-2.6.x/net/bridge/br_fdb.c     18 Jun 2006 23:30:55 -0000      1.1.1.13
+++ linux-2.6.x/net/bridge/br_fdb.c     1 Aug 2006 09:12:42 -0000
@@ -20,6 +20,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/jhash.h>
+#include <linux/if_arp.h>
 #include <asm/atomic.h>
 #include "br_private.h"

@@ -86,6 +87,7 @@ void br_fdb_changeaddr(struct net_bridge
                                struct net_bridge_port *op;
                                list_for_each_entry(op, &br->port_list, list) {
                                        if (op != p &&
+                                           op->dev->type == ARPHRD_ETHER &&
                                            
!compare_ether_addr(op->dev->dev_addr,
                                                                f->addr.addr)) {
                                                f->dst = op;
@@ -151,6 +153,7 @@ void br_fdb_delete_by_port(struct net_br
                                struct net_bridge_port *op;
                                list_for_each_entry(op, &br->port_list, list) {
                                        if (op != p &&
+                                           op->dev->type == ARPHRD_ETHER &&
                                            
!compare_ether_addr(op->dev->dev_addr,
                                                                f->addr.addr)) {
                                                f->dst = op;
--- linux-2.6.x/net/bridge/br_forward.c 18 Jun 2006 23:30:55 -0000      1.1.1.15
+++ linux-2.6.x/net/bridge/br_forward.c 1 Aug 2006 09:12:42 -0000
@@ -18,6 +18,7 @@
 #include <linux/skbuff.h>
 #include <linux/if_vlan.h>
 #include <linux/netfilter_bridge.h>
+#include <linux/if_arp.h>
 #include "br_private.h"

 static inline int should_deliver(const struct net_bridge_port *p,
@@ -46,6 +47,8 @@ int br_dev_queue_push_xmit(struct sk_buf
                nf_bridge_maybe_copy_header(skb);
 #endif
                skb_push(skb, ETH_HLEN);
+               if (skb->dev->type == ARPHRD_IPGRE)
+                       skb->protocol = htons(ETH_P_BRIDGE);

                dev_queue_xmit(skb);
        }
--- linux-2.6.x/net/bridge/br_if.c      18 Jun 2006 23:30:55 -0000      1.1.1.23
+++ linux-2.6.x/net/bridge/br_if.c      1 Aug 2006 09:12:42 -0000
@@ -391,7 +391,10 @@ int br_add_if(struct net_bridge *br, str
        struct net_bridge_port *p;
        int err = 0;

-       if (dev->flags & IFF_LOOPBACK || dev->type != ARPHRD_ETHER)
+       if (dev->flags & IFF_LOOPBACK)
+               return -EINVAL;
+
+       if (dev->type != ARPHRD_ETHER && dev->type != ARPHRD_IPGRE)
                return -EINVAL;

        if (dev->hard_start_xmit == br_dev_xmit)
@@ -408,9 +411,11 @@ int br_add_if(struct net_bridge *br, str
        if (err)
                goto err0;

-       err = br_fdb_insert(br, p, dev->dev_addr);
-       if (err)
-               goto err1;
+       if (dev->type == ARPHRD_ETHER) {
+               err = br_fdb_insert(br, p, dev->dev_addr);
+               if (err)
+                       goto err1;
+       }

        err = br_sysfs_addif(p);
        if (err)
--- linux-2.6.x/net/bridge/br_input.c   18 Jun 2006 23:30:55 -0000      1.1.1.18
+++ linux-2.6.x/net/bridge/br_input.c   1 Aug 2006 09:12:42 -0000
@@ -17,6 +17,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/netfilter_bridge.h>
+#include <linux/if_arp.h>
 #include "br_private.h"

 /* Bridge group multicast address 802.1d (pg 51). */
@@ -124,11 +125,22 @@ static inline int is_link_local(const un
 int br_handle_frame(struct net_bridge_port *p, struct sk_buff **pskb)
 {
        struct sk_buff *skb = *pskb;
-       const unsigned char *dest = eth_hdr(skb)->h_dest;
+       const unsigned char *dest;
+
+       if (skb->dev->type == ARPHRD_IPGRE) {
+               if (skb->protocol != htons(ETH_P_BRIDGE))
+                       return 0;
+               if (!pskb_may_pull(skb, ETH_HLEN))
+                       goto err;
+               skb->protocol = eth_type_trans(skb, p->br->dev);
+               skb_postpull_rcsum(skb, skb->mac.raw, ETH_HLEN);
+               skb->nh.raw += ETH_HLEN;
+       }

        if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
                goto err;

+       dest = eth_hdr(skb)->h_dest;
        if (unlikely(is_link_local(dest))) {
                skb->pkt_type = PACKET_HOST;
                return NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,
--- linux-2.6.x/net/bridge/br_notify.c  21 Mar 2006 01:35:39 -0000      1.1.1.12
+++ linux-2.6.x/net/bridge/br_notify.c  1 Aug 2006 09:12:42 -0000
@@ -14,6 +14,7 @@
  */

 #include <linux/kernel.h>
+#include <linux/if_arp.h>

 #include "br_private.h"

@@ -48,8 +49,10 @@ static int br_device_event(struct notifi
                break;

        case NETDEV_CHANGEADDR:
-               br_fdb_changeaddr(p, dev->dev_addr);
-               br_stp_recalculate_bridge_id(br);
+               if (dev->type == ARPHRD_ETHER) {
+                       br_fdb_changeaddr(p, dev->dev_addr);
+                       br_stp_recalculate_bridge_id(br);
+               }
                break;

        case NETDEV_CHANGE:
--- linux-2.6.x/include/linux/if_ether.h        18 Jun 2006 23:30:44 -0000      
1.1.1.11
+++ linux-2.6.x/include/linux/if_ether.h        1 Aug 2006 09:12:42 -0000
@@ -55,6 +55,7 @@
 #define ETH_P_DIAG      0x6005          /* DEC Diagnostics              */
 #define ETH_P_CUST      0x6006          /* DEC Customer use             */
 #define ETH_P_SCA       0x6007          /* DEC Systems Comms Arch       */
+#define ETH_P_BRIDGE    0x6558          /* Transparent Ethernet Bridging */
 #define ETH_P_RARP      0x8035         /* Reverse Addr Res packet      */
 #define ETH_P_ATALK    0x809B          /* Appletalk DDP                */
 #define ETH_P_AARP     0x80F3          /* Appletalk AARP               */
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to