--- zzzz-none-000/linux-3.10.107/net/ipv4/ipmr.c 2017-06-27 09:49:32.000000000 +0000 +++ vr9-7490-729/linux-3.10.107/net/ipv4/ipmr.c 2021-11-10 11:53:56.000000000 +0000 @@ -26,6 +26,12 @@ * */ +/** + * Some part of this file is modified by Ikanos Communications. + * + * Copyright (C) 2013-2014 Ikanos Communications. + */ + #include #include #include @@ -312,6 +318,9 @@ } #endif +#if defined(CONFIG_FUSIV_KERNEL_AP_2_AP) || defined(CONFIG_FUSIV_KERNEL_AP_2_AP_MODULE) +int (*ap2apMcastRtPortForwarded_ptr)(struct sk_buff* , struct vif_device *vif_dev) = NULL; +#endif static struct mr_table *ipmr_new_table(struct net *net, u32 id) { struct mr_table *mrt; @@ -1105,7 +1114,21 @@ { int line; struct mfc_cache *c, *next; - +#if defined(CONFIG_FUSIV_KERNEL_AP_2_AP) || defined(CONFIG_FUSIV_KERNEL_AP_2_AP_MODULE) + /* IKANOS IGMPRT temp patch starts */ + if (mfc->mfcc_origin.s_addr == 0) { + for (line = 0; line < MFC_LINES; line ++) { + list_for_each_entry_safe(c, next, &mrt->mfc_cache_array[line], list) { + if (c->mfc_mcastgrp == mfc->mfcc_mcastgrp.s_addr) { + list_del_rcu(&c->list); + ipmr_cache_free(c); + return 0; + } + } + } + return 0; + }/* IKANOS IGMPRT temp patch ends */ +#endif line = MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr); list_for_each_entry_safe(c, next, &mrt->mfc_cache_array[line], list) { @@ -1130,7 +1153,26 @@ if (mfc->mfcc_parent >= MAXVIFS) return -ENFILE; - +#if defined(CONFIG_FUSIV_KERNEL_AP_2_AP) || defined(CONFIG_FUSIV_KERNEL_AP_2_AP_MODULE) + //IKANOS IGMPRT temp patch starts + if (mfc->mfcc_origin.s_addr == 0) { + for (line = 0; line < MFC_LINES; line ++) { + list_for_each_entry(c, &mrt->mfc_cache_array[line], list) { + if (c->mfc_mcastgrp == mfc->mfcc_mcastgrp.s_addr) { + write_lock_bh(&mrt_lock); + c->mfc_parent = mfc->mfcc_parent; + ipmr_update_thresholds(mrt, c, mfc->mfcc_ttls); + if (!mrtsock) + c->mfc_flags |= MFC_STATIC; + write_unlock_bh(&mrt_lock); + //break; + } + } + } + return 0; + } + //IKANOS IGMPRT temp patch ends +#endif line = MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr); list_for_each_entry(c, &mrt->mfc_cache_array[line], list) { @@ -1890,12 +1932,28 @@ if ((cache->mfc_origin != htonl(INADDR_ANY) || ct != true_vifi) && ip_hdr(skb)->ttl > cache->mfc_un.res.ttls[ct]) { +#if defined(CONFIG_FUSIV_KERNEL_AP_2_AP) || defined(CONFIG_FUSIV_KERNEL_AP_2_AP_MODULE) + if (ap2apMcastRtPortForwarded_ptr) + { + if (ap2apMcastRtPortForwarded_ptr(skb , &(mrt->vif_table[ct])) == 0) + continue; + } +#endif if (psend != -1) { struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); - if (skb2) + if (skb2) { +#if defined(CONFIG_FUSIV_KERNEL_BWMON_STATS) || defined(CONFIG_FUSIV_KERNEL_BWMON_STATS_MODULE) + /* SKB received on WAN is getting duplicated, since all + clones will also pass through bandwidth monitoring + module we reset length in them so that only received + length is updated only once i.e.from original SKB. + */ + skb2->apFlowData.bwmonInfo.usReceivedLength = 0 ; +#endif ipmr_queue_xmit(net, mrt, skb2, cache, psend); + } } psend = ct; } @@ -2783,3 +2841,20 @@ kmem_cache_destroy(mrt_cachep); return err; } +#if defined(CONFIG_FUSIV_KERNEL_AP_2_AP) || defined(CONFIG_FUSIV_KERNEL_AP_2_AP_MODULE) +struct mfc_cache *ap_ipmr_cache_find(struct net *net, + __be32 origin, + __be32 mcastgrp, + struct vif_device **vif_table) +{ + struct mr_table *mrt; + mrt = ipmr_get_table(net, RT_TABLE_DEFAULT); + if (mrt == NULL) + return NULL; + *vif_table = mrt->vif_table; + return ipmr_cache_find(mrt,origin,mcastgrp); +} +EXPORT_SYMBOL(ap_ipmr_cache_find); +EXPORT_SYMBOL(ap2apMcastRtPortForwarded_ptr); +EXPORT_SYMBOL(mrt_lock); +#endif