--- zzzz-none-000/linux-3.10.107/net/bridge/br_if.c 2017-06-27 09:49:32.000000000 +0000 +++ vr9-7490-729/linux-3.10.107/net/bridge/br_if.c 2021-11-10 11:53:56.000000000 +0000 @@ -11,6 +11,12 @@ * 2 of the License, or (at your option) any later version. */ +/** + * Some part of this file is modified by Ikanos Communications. + * + * Copyright (C) 2013-2014 Ikanos Communications. + */ + #include #include #include @@ -26,6 +32,26 @@ #include #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; +void (*apResetBridgePorts_ptr)(struct net_device *dev) = NULL; +int (*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) || defined(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) +int (*check_PPPoERelay_bridge_if_ptr)(struct net_bridge *br) = NULL; +#endif /* * Determine initial path cost based on speed. @@ -61,7 +87,7 @@ } -/* Check for port carrier transistions. */ +/* Check for port carrier transitions. */ void br_port_carrier_check(struct net_bridge_port *p) { struct net_device *dev = p->dev; @@ -130,9 +156,19 @@ { 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 + +#if defined(CONFIG_FUSIV_KERNEL_AP_2_AP) || defined(CONFIG_FUSIV_KERNEL_AP_2_AP_MODULE) + if(apResetBridgePorts_ptr != NULL) + (*apResetBridgePorts_ptr)(dev); +#endif sysfs_remove_link(br->ifobj, p->dev->name); + br_isol_remove_port(p); /* expects to be called with br->lock held */ + dev_set_promiscuity(dev, -1); spin_lock_bh(&br->lock); @@ -160,6 +196,20 @@ br_netpoll_disable(p); 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 } /* Delete bridge device */ @@ -168,14 +218,37 @@ struct net_bridge *br = netdev_priv(dev); struct net_bridge_port *p, *n; +#if defined(CONFIG_FUSIV_KERNEL_PPPOE_PASSTHROUGH) || defined(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); } br_fdb_delete_by_port(br, NULL, 1); + br_vlan_flush(br); 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_queue(br->dev, head); } @@ -223,7 +296,7 @@ p->path_cost = port_cost(dev); p->priority = 0x8000 >> BR_PORT_BITS; p->port_no = index; - p->flags = 0; + p->flags = BR_LEARNING | BR_FLOOD; br_init_port(p); p->state = BR_STATE_DISABLED; br_stp_port_timer_init(p); @@ -345,6 +418,20 @@ /* No bridging devices that dislike that (e.g. wireless) */ if (dev->priv_flags & IFF_DONT_BRIDGE) return -EOPNOTSUPP; +#if defined(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)) @@ -365,7 +452,8 @@ if (err) goto err2; - if (br_netpoll_info(br) && ((err = br_netpoll_enable(p, GFP_KERNEL)))) + err = br_netpoll_enable(p); + if (err) goto err3; err = netdev_master_upper_dev_link(dev, br->dev); @@ -384,6 +472,12 @@ netdev_update_features(br->dev); + if (br->dev->needed_headroom < dev->needed_headroom) + br->dev->needed_headroom = dev->needed_headroom; + + if (br_fdb_insert(br, p, dev->dev_addr, 0)) + netdev_err(dev, "failed insert local address bridge forwarding table\n"); + spin_lock_bh(&br->lock); changed_addr = br_stp_recalculate_bridge_id(br); @@ -399,11 +493,11 @@ dev_set_mtu(br->dev, br_min_mtu(br)); - if (br_fdb_insert(br, p, dev->dev_addr, 0)) - netdev_err(dev, "failed insert local address bridge forwarding table\n"); - 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) + (*apAddNewBridgePort_ptr)(p); +#endif return 0; err5: @@ -429,10 +523,34 @@ struct net_bridge_port *p; bool changed_addr; +#if defined(CONFIG_FUSIV_KERNEL_PPPOE_PASSTHROUGH) || defined(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 + p = br_port_get_rtnl(dev); 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 + /* Since more than one interface can be attached to a bridge, * there still maybe an alternate path for netconsole to use; * therefore there is no reason for a NETDEV_RELEASE event. @@ -465,3 +583,24 @@ rtnl_unlock(); } + +#if defined(CONFIG_FUSIV_KERNEL_PPPOE_PASSTHROUGH) || defined(CONFIG_FUSIV_KERNEL_PPPOE_RELAY_FASTPATH) +EXPORT_SYMBOL(checkPPPoERelayIf_ptr); +#endif + +#if defined(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 +