--- zzzz-none-000/linux-2.6.28.10/net/bridge/br_if.c 2009-05-02 18:54:43.000000000 +0000 +++ puma5-6360-529/linux-2.6.28.10/net/bridge/br_if.c 2011-07-13 15:44:32.000000000 +0000 @@ -10,6 +10,24 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ +/*---------------------------------------------------------------------------- +// Copyright 2007, Texas Instruments Incorporated +// +// This program has been modified from its original operation by Texas Instruments +// to do the following: +// +// 1. TI Layer 2 Selective Packet Handling Framework +// +// THIS MODIFIED SOFTWARE AND DOCUMENTATION ARE PROVIDED +// "AS IS," AND TEXAS INSTRUMENTS MAKES NO REPRESENTATIONS +// OR WARRENTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY +// PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR +// DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, +// COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. +// +// These changes are covered as per original license +//-----------------------------------------------------------------------------*/ #include #include @@ -20,8 +38,31 @@ #include #include #include +#if defined(CONFIG_FUSIV_KERNEL_AP_2_AP) || defined(CONFIG_FUSIV_KERNEL_AP_2_AP_MODULE) +#include +#endif /*--- #if defined(CONFIG_FUSIV_VX180) ---*/ #include "br_private.h" +#if defined(CONFIG_FUSIV_KERNEL_AP_2_AP) || defined(CONFIG_FUSIV_KERNEL_AP_2_AP_MODULE) +char (*get_apid_by_name_ptr)(char *name) = NULL; +int (*apResetBridgePorts_ptr)(struct net_device *dev) = NULL; +simResult_t (*apBridgeTable_ptr)( unsigned char, unsigned char, unsigned long) = NULL; +short (*apAddNewBridgePort_ptr)( struct net_bridge_port* p) = NULL; +#endif + +#if defined(CONFIG_FUSIV_KERNEL_IGMP_SNOOP) || defined(CONFIG_FUSIV_KERNEL_IGMP_SNOOP_MODULE) +void (*br_dev_mcast_cleanup)(struct net_bridge* br, struct net_device* dev) = + NULL; +void (*br_mcast_cleanup)(struct net_bridge* br) = NULL; +#endif + +#if (defined(CONFIG_FUSIV_KERNEL_PPPOE_PASSTHROUGH) && CONFIG_FUSIV_KERNEL_PPPOE_PASSTHROUGH) || (defined(CONFIG_FUSIV_KERNEL_PPPOE_RELAY_FASTPATH) && CONFIG_FUSIV_KERNEL_PPPOE_RELAY_FASTPATH) +int (*checkPPPoERelayIf_ptr)(struct net_bridge *br, struct net_device *dev) = NULL; +#endif + +#if defined(CONFIG_FUSIV_KERNEL_PPPOE_RELAY_FASTPATH) && CONFIG_FUSIV_KERNEL_PPPOE_RELAY_FASTPATH +int (*check_PPPoERelay_bridge_if_ptr)(struct net_bridge *br) = NULL; +#endif /* * Determine initial path cost based on speed. @@ -104,6 +145,7 @@ struct net_device *dev = p->dev; p->br = NULL; + p->dev->br_port = NULL; p->dev = NULL; dev_put(dev); @@ -131,6 +173,10 @@ struct net_bridge *br = p->br; struct net_device *dev = p->dev; +#if defined(CONFIG_FUSIV_KERNEL_AP_2_AP) || defined(CONFIG_FUSIV_KERNEL_AP_2_AP_MODULE) + char apId = -1; +#endif + sysfs_remove_link(br->ifobj, dev->name); dev_set_promiscuity(dev, -1); @@ -143,6 +189,11 @@ br_fdb_delete_by_port(br, p, 1); +#if defined(CONFIG_FUSIV_KERNEL_AP_2_AP) || defined(CONFIG_FUSIV_KERNEL_AP_2_AP_MODULE) + if(apResetBridgePorts_ptr != NULL) + (*apResetBridgePorts_ptr)(dev); +#endif + list_del_rcu(&p->list); rcu_assign_pointer(dev->br_port, NULL); @@ -151,6 +202,22 @@ kobject_del(&p->kobj); call_rcu(&p->rcu, destroy_nbp_rcu); + +#if defined(CONFIG_FUSIV_KERNEL_AP_2_AP) || defined(CONFIG_FUSIV_KERNEL_AP_2_AP_MODULE) + if(get_apid_by_name_ptr != NULL) { + apId = (*get_apid_by_name_ptr)(dev->name); + } else + printk("\nbr_del_if: ap2ap_lkm not initialized properly...\n"); + + if(apId != -1) { + if(apBridgeTable_ptr != NULL) { + (*apBridgeTable_ptr)(apId, 0xDD, 0xff); + } else + printk("\nbr_del_if: ap2ap_lkm not initialized properly. ..\n"); + } + printk("br_del_if() : is called with apId %d -> %s\n",apId,dev->name); +#endif + } /* called with RTNL */ @@ -158,12 +225,35 @@ { struct net_bridge_port *p, *n; +#if (defined(CONFIG_FUSIV_KERNEL_PPPOE_PASSTHROUGH) && CONFIG_FUSIV_KERNEL_PPPOE_PASSTHROUGH ) || (defined(CONFIG_FUSIV_KERNEL_PPPOE_RELAY_FASTPATH) && CONFIG_FUSIV_KERNEL_PPPOE_RELAY_FASTPATH) + + /* Check if any of the bridge interfaces are part of PPPoE Relay + configuration, if yes, then return */ + + if (checkPPPoERelayIf_ptr) { + if (!checkPPPoERelayIf_ptr(br, NULL)) { + printk("PPPoE Relay/Passthrough is configured on this bridge...." \ + "First delete PPPoE Relay/Passthrough and then delete the " \ + "bridge configuration....\r\n"); + return; + } + } +#endif + list_for_each_entry_safe(p, n, &br->port_list, list) { del_nbp(p); } del_timer_sync(&br->gc_timer); +#if defined(CONFIG_FUSIV_KERNEL_IGMP_SNOOP) || defined(CONFIG_FUSIV_KERNEL_IGMP_SNOOP_MODULE) + // For IGMP Snoop cleanup + if (br->mfdb) { + if(br_mcast_cleanup) + br_mcast_cleanup(br); + } +#endif + br_sysfs_delbr(br->dev); unregister_netdevice(br->dev); } @@ -206,10 +296,19 @@ br_netfilter_rtable_init(br); +#if defined(CONFIG_FUSIV_KERNEL_IGMP_SNOOP) || defined(CONFIG_FUSIV_KERNEL_IGMP_SNOOP_MODULE) + br->mfdb = NULL; //Init for IGMP Snoop +#endif +#if defined(CONFIG_FUSIV_KERNEL_AP_2_AP) || defined(CONFIG_FUSIV_KERNEL_AP_2_AP_MODULE) + br->bridgeVlanAddr = 0; +#endif + INIT_LIST_HEAD(&br->age_list); br_stp_timer_init(br); - +#ifdef CONFIG_TI_L2_SELECTIVE_PACKET_HANDLING + br->selective_packet_handler = NULL; +#endif /* CONFIG_TI_L2_SELECTIVE_PACKET_HANDLING */ return dev; } @@ -369,6 +468,9 @@ { struct net_bridge_port *p; int err = 0; +#if defined(CONFIG_FUSIV_KERNEL_AP_2_AP) || defined(CONFIG_FUSIV_KERNEL_AP_2_AP_MODULE) + int ret = 0; +#endif if (dev->flags & IFF_LOOPBACK || dev->type != ARPHRD_ETHER) return -EINVAL; @@ -379,6 +481,21 @@ if (dev->br_port != NULL) return -EBUSY; +#if defined(CONFIG_FUSIV_KERNEL_PPPOE_RELAY_FASTPATH) && CONFIG_FUSIV_KERNEL_PPPOE_RELAY_FASTPATH + /* Check if any of the bridge interfaces are part of PPPoE Relay + configuration, if yes, then return */ + if (check_PPPoERelay_bridge_if_ptr) { + if (!check_PPPoERelay_bridge_if_ptr(br)) { + printk("PPPoE Relay is configured on this bridge [%s]....\n" \ + "First delete PPPoE Relay and then add the " \ + "interface %s to bridge....\r\n",br->dev->name, dev->name); + /* returning 0 even on a failure case, as the function + is getting called twice if FAILURE is returned...*/ + return 0; + } + } +#endif + p = new_nbp(br, dev); if (IS_ERR(p)) return PTR_ERR(p); @@ -406,7 +523,16 @@ list_add_rcu(&p->list, &br->port_list); spin_lock_bh(&br->lock); - br_stp_recalculate_bridge_id(br); + if (!br->automatic_mac_disabled) { + br_stp_recalculate_bridge_id(br); + } else { + /* + * AVM: be sure that the bridge id is still in the fdb + * note the the port in the fdb-entry will not be overwritten with 0, + * if the entry exists + */ + br_fdb_insert(br, 0, br->bridge_id.addr); + } br_features_recompute(br); if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) && @@ -420,6 +546,18 @@ kobject_uevent(&p->kobj, KOBJ_ADD); +#if defined(CONFIG_FUSIV_KERNEL_AP_2_AP) || defined(CONFIG_FUSIV_KERNEL_AP_2_AP_MODULE) + if(apAddNewBridgePort_ptr != NULL) + ret = (*apAddNewBridgePort_ptr)(p); +#endif + + /* + * AVM/RSP 20100408 + * Raise needed_headroom to the maximum of all interfaces in the bridge + */ + if (dev->needed_headroom > br->dev->needed_headroom) + br->dev->needed_headroom = dev->needed_headroom; + return 0; err2: br_fdb_delete_by_port(br, p, 1); @@ -438,13 +576,45 @@ { struct net_bridge_port *p = dev->br_port; +#if (defined(CONFIG_FUSIV_KERNEL_PPPOE_PASSTHROUGH) && CONFIG_FUSIV_KERNEL_PPPOE_PASSTHROUGH) || (defined(CONFIG_FUSIV_KERNEL_PPPOE_RELAY_FASTPATH) && CONFIG_FUSIV_KERNEL_PPPOE_RELAY_FASTPATH) + + /* Check if any of the bridge interfaces are part of PPPoE Relay + configuration, if yes, then return */ + if (checkPPPoERelayIf_ptr) { + if (!checkPPPoERelayIf_ptr(br, dev)) { + printk("PPPoE Relay/Passthrough is configured on this interface...." \ + "First delete PPPoE Relay/Passthrough and then delete the " \ + "bridge configuration....\r\n"); + /* returning 0 even on a failure case, as the function + is getting called twice if FAILURE is returned...*/ + return 0; + } + } +#endif + if (!p || p->br != br) return -EINVAL; +#if defined(CONFIG_FUSIV_KERNEL_IGMP_SNOOP) || defined(CONFIG_FUSIV_KERNEL_IGMP_SNOOP_MODULE) + // Cleaning for IGMP Snooping + if (br->mfdb) { + if (br_dev_mcast_cleanup) + br_dev_mcast_cleanup(br , dev); + } +#endif del_nbp(p); spin_lock_bh(&br->lock); - br_stp_recalculate_bridge_id(br); + if (!br->automatic_mac_disabled) { + br_stp_recalculate_bridge_id(br); + } else { + /* + * AVM: be sure that the bridge id is still in the fdb + * note the the port in the fdb-entry will not be overwritten with 0, + * if the entry exists + */ + br_fdb_insert(br, 0, br->bridge_id.addr); + } br_features_recompute(br); spin_unlock_bh(&br->lock); @@ -466,3 +636,25 @@ rtnl_unlock(); } + + +#if (defined(CONFIG_FUSIV_KERNEL_PPPOE_PASSTHROUGH) && CONFIG_FUSIV_KERNEL_PPPOE_PASSTHROUGH) || (defined(CONFIG_FUSIV_KERNEL_PPPOE_RELAY_FASTPATH) && CONFIG_FUSIV_KERNEL_PPPOE_RELAY_FASTPATH) +EXPORT_SYMBOL(checkPPPoERelayIf_ptr); +#endif + +#if defined(CONFIG_FUSIV_KERNEL_PPPOE_RELAY_FASTPATH) && CONFIG_FUSIV_KERNEL_PPPOE_RELAY_FASTPATH +EXPORT_SYMBOL(check_PPPoERelay_bridge_if_ptr); +#endif + +#if defined(CONFIG_FUSIV_KERNEL_IGMP_SNOOP) || defined(CONFIG_FUSIV_KERNEL_IGMP_SNOOP_MODULE) +EXPORT_SYMBOL(br_dev_mcast_cleanup); +EXPORT_SYMBOL(br_mcast_cleanup); +#endif + +#if defined(CONFIG_FUSIV_KERNEL_AP_2_AP) || defined(CONFIG_FUSIV_KERNEL_AP_2_AP_MODULE) +EXPORT_SYMBOL(apResetBridgePorts_ptr); +EXPORT_SYMBOL(get_apid_by_name_ptr); +EXPORT_SYMBOL(apBridgeTable_ptr); +EXPORT_SYMBOL(apAddNewBridgePort_ptr); +#endif +