On Tue, Dec 07, 2010 at 11:32:23PM +0100, Linus L??ssing wrote:
This patch adds the capability to encapsulate and send a node's own multicast data packets. Based on the previously established multicast forwarding table, the sender can decide wheather it actually has to send the multicast data to one or more of its interfaces or not.
Furthermore, the sending procedure also decides whether to broadcast or unicast a multicast data packet to its next-hops, depending on the configured mcast_fanout (default: < 3 next hops on an interface, send seperate unicast packets).
Signed-off-by: Linus L??ssing linus.luessing@saxnet.de
multicast.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ multicast.h | 1 + soft-interface.c | 25 +++++++++-- types.h | 1 + 4 files changed, 156 insertions(+), 4 deletions(-)
diff --git a/multicast.c b/multicast.c index 2b1bfde..72249ef 100644 --- a/multicast.c +++ b/multicast.c @@ -23,6 +23,7 @@ #include "multicast.h" #include "hash.h" #include "send.h" +#include "soft-interface.h" #include "compat.h"
/* If auto mode for tracker timeout has been selected, @@ -1058,6 +1059,138 @@ int mcast_forw_table_seq_print_text(struct seq_file *seq, void *offset) return 0; }
+static void route_mcast_packet(struct sk_buff *skb, struct bat_priv *bat_priv) +{
- struct sk_buff *skb1;
- struct mcast_packet *mcast_packet;
- struct ethhdr *ethhdr;
- struct batman_if *batman_if;
- unsigned long flags;
- struct mcast_forw_table_entry *table_entry;
- struct mcast_forw_orig_entry *orig_entry;
- struct mcast_forw_if_entry *if_entry;
- struct mcast_forw_nexthop_entry *nexthop_entry;
- int mcast_fanout = atomic_read(&bat_priv->mcast_fanout);
- int num_bcasts = 3, i;
- struct dest_entries_list dest_list, *dest_entry, *tmp;
- mcast_packet = (struct mcast_packet*)skb->data;
- ethhdr = (struct ethhdr*)(mcast_packet + 1);
- INIT_LIST_HEAD(&dest_list.list);
- mcast_packet->ttl--;
- rcu_read_lock();
- spin_lock_irqsave(&bat_priv->mcast_forw_table_lock, flags);
- list_for_each_entry(table_entry, &bat_priv->mcast_forw_table, list) {
if (memcmp(ethhdr->h_dest, table_entry->mcast_addr, ETH_ALEN))
continue;
list_for_each_entry(orig_entry, &table_entry->mcast_orig_list,
list) {
if (memcmp(mcast_packet->orig,
orig_entry->orig, ETH_ALEN))
continue;
list_for_each_entry(if_entry,
&orig_entry->mcast_if_list, list) {
batman_if = if_num_to_batman_if(
if_entry->if_num);
/* send via broadcast */
if (if_entry->num_nexthops > mcast_fanout) {
dest_entry = kmalloc(sizeof(struct
dest_entries_list),
GFP_ATOMIC);
memcpy(dest_entry->dest,
broadcast_addr, ETH_ALEN);
dest_entry->batman_if = batman_if;
list_add(&dest_entry->list,
&dest_list.list);
continue;
}
/* send seperate unicast packets */
list_for_each_entry(nexthop_entry,
&if_entry->mcast_nexthop_list,
list) {
if (!get_remaining_timeout(
nexthop_entry,
bat_priv))
continue;
Again, refactor this into four functions.
Andrew