--- zzzz-none-000/linux-2.6.28.10/net/ipv4/ipmr.c 2009-05-02 18:54:43.000000000 +0000 +++ puma5-6360-529/linux-2.6.28.10/net/ipv4/ipmr.c 2011-04-14 10:28:24.000000000 +0000 @@ -63,11 +63,15 @@ #include #include +#if defined(CONFIG_IFX_PPA_API) || defined(CONFIG_IFX_PPA_API_MODULE) + #include +#endif + #if defined(CONFIG_IP_PIMSM_V1) || defined(CONFIG_IP_PIMSM_V2) #define CONFIG_IP_PIMSM 1 #endif -static struct sock *mroute_socket; +struct sock *mroute_socket; /* Big lock, protecting vif table, mrt cache and mroute socket state. @@ -80,7 +84,7 @@ * Multicast router control variables */ -static struct vif_device vif_table[MAXVIFS]; /* Devices */ +struct vif_device vif_table[MAXVIFS]; /* Devices */ static int maxvif; #define VIF_EXISTS(idx) (vif_table[idx].dev != NULL) @@ -114,6 +118,11 @@ static struct net_protocol pim_protocol; #endif + +#if defined(CONFIG_FUSIV_KERNEL_AP_2_AP) || defined(CONFIG_FUSIV_KERNEL_AP_2_AP_MODULE) +int (*ap2apMcastRtPortForwarded_ptr)(struct sk_buff* , int) = NULL; +#endif + static struct timer_list ipmr_expire_timer; /* Service routines creating virtual interfaces: DVMRP tunnels and PIMREG */ @@ -455,8 +464,17 @@ return err; } break; + case VIFF_USE_IFINDEX: case 0: - dev = ip_dev_find(&init_net, vifc->vifc_lcl_addr.s_addr); + if (vifc->vifc_flags == VIFF_USE_IFINDEX) { + dev = dev_get_by_index(&init_net, vifc->vifc_lcl_ifindex); + if (dev && __in_dev_get_rtnl(dev) == NULL) { + dev_put(dev); + return -EADDRNOTAVAIL; + } + } else { + dev = ip_dev_find(&init_net, vifc->vifc_lcl_addr.s_addr); + } if (!dev) return -EADDRNOTAVAIL; err = dev_set_allmulti(dev, 1); @@ -505,11 +523,41 @@ return 0; } -static struct mfc_cache *ipmr_cache_find(__be32 origin, __be32 mcastgrp) +struct mfc_cache *ipmr_cache_find(__be32 origin, __be32 mcastgrp) { - int line=MFC_HASH(mcastgrp,origin); + int line = MFC_HASH(mcastgrp, origin); struct mfc_cache *c; +#if defined(CONFIG_FUSIV) && 0 /* ERROR Patch ist fehlerhaft MaPom */ + struct mfc_cache *uc, **cp; + //IKANOS IGMPRT temp patch starts + if (origin == 0) + { + for (line = 0; line < MFC_LINES; line ++) + { + for (cp = &mfc_cache_array[line]; (c = *cp) != NULL; cp = &c->next) + { + if (c->mfc_mcastgrp == origin) + break; + } + + if (c) + { + write_lock_bh(&mrt_lock); + c->mfc_parent = mfc->mfcc_parent; + ipmr_update_thresholds(c, mfc->mfcc_ttls); + if (!mrtsock) + c->mfc_flags |= MFC_STATIC; + write_unlock_bh(&mrt_lock); + } + } + + return 0; + } + //IKANOS IGMPRT temp patch ends + line = MFC_HASH(mcastgrp, origin); +#endif /*--- #if defined(CONFIG_FUSIV) ---*/ + for (c=mfc_cache_array[line]; c; c = c->next) { if (c->mfc_origin==origin && c->mfc_mcastgrp==mcastgrp) break; @@ -745,6 +793,56 @@ int line; struct mfc_cache *c, **cp; + /* IKANOS IGMPRT temp patch starts */ + if (mfc->mfcc_origin.s_addr == 0) + { + for (line = 0; line < MFC_LINES; line ++) + { + for (cp=&mfc_cache_array[line]; (c=*cp) != NULL; cp = &c->next) + { + if (c->mfc_mcastgrp == mfc->mfcc_mcastgrp.s_addr) + break; + } + + if (c) + { + write_lock_bh(&mrt_lock); + *cp = c->next; + write_unlock_bh(&mrt_lock); + + kmem_cache_free(mrt_cachep, c); + return 0; + } + } + + return 0; + } /* IKANOS IGMPRT temp patch ends */ + + /* IKANOS IGMPRT temp patch starts */ + if (mfc->mfcc_origin.s_addr == 0) + { + for (line = 0; line < MFC_LINES; line ++) + { + for (cp=&mfc_cache_array[line]; (c=*cp) != NULL; cp = &c->next) + { + if (c->mfc_mcastgrp == mfc->mfcc_mcastgrp.s_addr) + break; + } + + if (c) + { + write_lock_bh(&mrt_lock); + *cp = c->next; + write_unlock_bh(&mrt_lock); + + kmem_cache_free(mrt_cachep, c); + return 0; + } + } + + return 0; + } /* IKANOS IGMPRT temp patch ends */ + line=MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr); for (cp=&mfc_cache_array[line]; (c=*cp) != NULL; cp = &c->next) { @@ -754,6 +852,36 @@ *cp = c->next; write_unlock_bh(&mrt_lock); +#if defined(CONFIG_IFX_PPA_API) || defined(CONFIG_IFX_PPA_API_MODULE) + if ( ppa_hook_mc_group_get_fn != NULL && ppa_hook_mc_group_update_fn != NULL ) + { + PPA_MC_GROUP ppa_mc_entry = {0}, ppa_mc_entry_cmp = {0}; + int n, idx; + + ppa_hook_mc_group_get_fn(c->mfc_mcastgrp, &ppa_mc_entry_cmp, 0); + + ppa_mc_entry.if_mask = ppa_mc_entry_cmp.if_mask; + for ( n = c->mfc_un.res.minvif; n < c->mfc_un.res.maxvif; n++ ) + { + int i; + struct net_device *dev = NULL; + + dev = vif_table[n].dev; + for ( i = 0, idx = 0; i < ppa_mc_entry_cmp.num_ifs; i++ ) + { + if ( strcmp(dev->name, ppa_mc_entry_cmp.array_mem_ifs[i].ifname) == 0 ) + ppa_mc_entry.if_mask &= ~(1 << idx); + } + ppa_mc_entry.array_mem_ifs[idx].ifname = dev->name; + ppa_mc_entry.array_mem_ifs[idx].ttl = c->mfc_un.res.ttls[n]; + ppa_mc_entry.ip_mc_group = c->mfc_mcastgrp; + ppa_mc_entry.num_ifs++; + idx++; + } + + ppa_hook_mc_group_update_fn(&ppa_mc_entry, 0); + } +#endif kmem_cache_free(mrt_cachep, c); return 0; } @@ -766,6 +894,31 @@ int line; struct mfc_cache *uc, *c, **cp; + //IKANOS IGMPRT temp patch starts + if (mfc->mfcc_origin.s_addr == 0) + { + for (line = 0; line < MFC_LINES; line ++) + { + for (cp=&mfc_cache_array[line]; (c=*cp) != NULL; cp = &c->next) + { + if (c->mfc_mcastgrp == mfc->mfcc_mcastgrp.s_addr) + break; + } + + if (c) + { + write_lock_bh(&mrt_lock); + c->mfc_parent = mfc->mfcc_parent; + ipmr_update_thresholds(c, mfc->mfcc_ttls); + if (!mrtsock) + c->mfc_flags |= MFC_STATIC; + write_unlock_bh(&mrt_lock); + } + } + + return 0; + } + //IKANOS IGMPRT temp patch ends line=MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr); for (cp=&mfc_cache_array[line]; (c=*cp) != NULL; cp = &c->next) { @@ -798,6 +951,36 @@ if (!mrtsock) c->mfc_flags |= MFC_STATIC; +#if defined(CONFIG_IFX_PPA_API) || defined(CONFIG_IFX_PPA_API_MODULE) + if ( ppa_hook_mc_group_update_fn != NULL ) + { + PPA_MC_GROUP ppa_mc_entry = {0}; + int n, idx; + + for ( n = c->mfc_un.res.minvif, idx = 0; n < c->mfc_un.res.maxvif; n++ ) + { + if ( VIF_EXISTS(n) && c->mfc_un.res.ttls[n] < 255 ) + { + // only dst itf are added here by kernel + + struct net_device *dev = vif_table[n].dev; + + ppa_mc_entry.array_mem_ifs[idx].ifname = dev->name; + ppa_mc_entry.array_mem_ifs[idx].ttl = c->mfc_un.res.ttls[n]; + ppa_mc_entry.if_mask |= 1 << idx; + ppa_mc_entry.ip_mc_group = c->mfc_mcastgrp; + ppa_mc_entry.num_ifs++; + idx++; + } + } + + if ( idx > 0 ) + ppa_mc_entry.src_ifname = vif_table[c->mfc_parent].dev->name; + + ppa_hook_mc_group_update_fn(&ppa_mc_entry, 0); + } +#endif + write_lock_bh(&mrt_lock); c->next = mfc_cache_array[line]; mfc_cache_array[line] = c; @@ -1359,6 +1542,13 @@ */ for (ct = cache->mfc_un.res.maxvif-1; ct >= cache->mfc_un.res.minvif; ct--) { if (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 , ct) == 0) + continue; + } +#endif if (psend != -1) { struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); if (skb2) @@ -1956,3 +2146,11 @@ kmem_cache_destroy(mrt_cachep); return err; } + +#if defined(CONFIG_FUSIV_KERNEL_AP_2_AP) || defined(CONFIG_FUSIV_KERNEL_AP_2_AP_MODULE) +EXPORT_SYMBOL(ipmr_cache_find); +EXPORT_SYMBOL(vif_table); +EXPORT_SYMBOL(ap2apMcastRtPortForwarded_ptr); +EXPORT_SYMBOL(mrt_lock); +#endif +