From patchwork Tue Dec 7 22:32:14 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Linus_L=C3=BCssing?= X-Patchwork-Id: 656 Return-Path: Received: from fmmailgate03.web.de (fmmailgate03.web.de [217.72.192.234]) by open-mesh.org (Postfix) with ESMTP id 6CE5415463C for ; Tue, 7 Dec 2010 23:34:02 +0100 (CET) Received: from smtp07.web.de ( [172.20.5.215]) by fmmailgate03.web.de (Postfix) with ESMTP id 51BC617C685CD; Tue, 7 Dec 2010 23:32:30 +0100 (CET) Received: from [46.126.246.98] (helo=localhost) by smtp07.web.de with asmtp (TLSv1:AES128-SHA:128) (WEB.DE 4.110 #24) id 1PQ65F-0001m1-00; Tue, 07 Dec 2010 23:32:29 +0100 From: =?UTF-8?q?Linus=20L=C3=BCssing?= To: b.a.t.m.a.n@lists.open-mesh.org Date: Tue, 7 Dec 2010 23:32:14 +0100 Message-Id: <1291761150-29818-4-git-send-email-linus.luessing@saxnet.de> X-Mailer: git-send-email 1.7.1 In-Reply-To: <20101207221351.GA19474@Sellars> References: <20101207221351.GA19474@Sellars> MIME-Version: 1.0 Sender: linus.luessing@web.de X-Sender: linus.luessing@web.de X-Provags-ID: V01U2FsdGVkX19yKa8qOyp2Ji3PSvMl1807P7M1VJmE9jDP1Gof YzODzpp0FZXQ6279MPVeTNnVkN3CFbqr4SyDlEUaIKOyDi3tQc bxQMCehkwhvONrqbLcGA== Cc: =?UTF-8?q?Linus=20L=C3=BCssing?= Subject: [B.A.T.M.A.N.] [PATCH 04/20] batman-adv: Attach local MCAs to OGMs X-BeenThere: b.a.t.m.a.n@lists.open-mesh.org X-Mailman-Version: 2.1.11 Precedence: list Reply-To: The list for a Better Approach To Mobile Ad-hoc Networking List-Id: The list for a Better Approach To Mobile Ad-hoc Networking List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 07 Dec 2010 22:34:02 -0000 This patch introduces multicast announcements - MCA for short - which are now being attached to an OGM if an optimized multicast mode needing MCAs has been selected (i.e. proactive_tracking). MCA entries are multicast mac addresses used by a multicast receiver in the mesh cloud. Currently MCAs are only fetched locally from the according batman interface itself, bridged-in hosts will not yet get announced and will need a more complex patch for supporting IGMP/MLD snooping. However, the local fetching also allows to have multicast optimizations on layer 2 already for batman nodes, not depending on IP at all. Signed-off-by: Linus Lüssing --- aggregation.c | 12 +++++++- aggregation.h | 6 +++- main.h | 2 + send.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++------- 4 files changed, 87 insertions(+), 15 deletions(-) diff --git a/aggregation.c b/aggregation.c index 0c92e3b..d4de296 100644 --- a/aggregation.c +++ b/aggregation.c @@ -30,6 +30,12 @@ static int hna_len(struct batman_packet *batman_packet) return batman_packet->num_hna * ETH_ALEN; } +/* calculate the size of the mca information for a given packet */ +static int mca_len(struct batman_packet *batman_packet) +{ + return batman_packet->num_mca * ETH_ALEN; +} + /* return true if new_packet can be aggregated with forw_packet */ static bool can_aggregate_with(struct batman_packet *new_batman_packet, int packet_len, @@ -265,9 +271,11 @@ void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff, hna_buff, hna_len(batman_packet), if_incoming); - buff_pos += BAT_PACKET_LEN + hna_len(batman_packet); + buff_pos += BAT_PACKET_LEN + hna_len(batman_packet) + + mca_len(batman_packet); batman_packet = (struct batman_packet *) (packet_buff + buff_pos); } while (aggregated_packet(buff_pos, packet_len, - batman_packet->num_hna)); + batman_packet->num_hna, + batman_packet->num_mca)); } diff --git a/aggregation.h b/aggregation.h index 71a91b3..93f2496 100644 --- a/aggregation.h +++ b/aggregation.h @@ -25,9 +25,11 @@ #include "main.h" /* is there another aggregated packet here? */ -static inline int aggregated_packet(int buff_pos, int packet_len, int num_hna) +static inline int aggregated_packet(int buff_pos, int packet_len, int num_hna, + int num_mca) { - int next_buff_pos = buff_pos + BAT_PACKET_LEN + (num_hna * ETH_ALEN); + int next_buff_pos = buff_pos + BAT_PACKET_LEN + (num_hna * ETH_ALEN) + + (num_mca * ETH_ALEN); return (next_buff_pos <= packet_len) && (next_buff_pos <= MAX_AGGREGATION_BYTES); diff --git a/main.h b/main.h index a362433..772d621 100644 --- a/main.h +++ b/main.h @@ -105,6 +105,8 @@ /* #define VIS_SUBCLUSTERS_DISABLED */ +#define UINT8_MAX 255 + /* * Kernel headers */ diff --git a/send.c b/send.c index b89b9f7..ba7ebfe 100644 --- a/send.c +++ b/send.c @@ -122,7 +122,8 @@ static void send_packet_to_if(struct forw_packet *forw_packet, /* adjust all flags and log packets */ while (aggregated_packet(buff_pos, forw_packet->packet_len, - batman_packet->num_hna)) { + batman_packet->num_hna, + batman_packet->num_mca)) { /* we might have aggregated direct link packets with an * ordinary base packet */ @@ -214,18 +215,71 @@ static void send_packet(struct forw_packet *forw_packet) rcu_read_unlock(); } +static void add_own_MCA(struct batman_packet *batman_packet, int num_mca, + struct net_device *soft_iface) +{ + MC_LIST *mc_list_entry; + int num_mca_done = 0; + unsigned long flags; + char *mca_entry = (char *)(batman_packet + 1); + + if (num_mca == 0) + goto out; + + if (num_mca > UINT8_MAX) { + pr_warning("Too many multicast announcements here, " + "just adding %i\n", UINT8_MAX); + num_mca = UINT8_MAX; + } + + mca_entry = mca_entry + batman_packet->num_hna * ETH_ALEN; + + MC_LIST_LOCK(soft_iface, flags); + netdev_for_each_mc_addr(mc_list_entry, soft_iface) { + memcpy(mca_entry, &mc_list_entry->MC_LIST_ADDR, ETH_ALEN); + mca_entry += ETH_ALEN; + + /* A multicast address might just have been added, + * avoid writing outside of buffer */ + if(++num_mca_done == num_mca) + break; + } + MC_LIST_UNLOCK(soft_iface, flags); + +out: + batman_packet->num_mca = num_mca_done; +} + static void rebuild_batman_packet(struct bat_priv *bat_priv, struct batman_if *batman_if) { - int new_len; - unsigned char *new_buff; + int new_len, mcast_mode, num_mca = 0; + unsigned long flags; + unsigned char *new_buff = NULL; struct batman_packet *batman_packet; - new_len = sizeof(struct batman_packet) + - (bat_priv->num_local_hna * ETH_ALEN); - new_buff = kmalloc(new_len, GFP_ATOMIC); + batman_packet = (struct batman_packet *)batman_if->packet_buff; + mcast_mode = atomic_read(&bat_priv->mcast_mode); + + /* Avoid attaching MCAs, if multicast optimization is disabled */ + if (mcast_mode == MCAST_MODE_PROACT_TRACKING) { + MC_LIST_LOCK(batman_if->soft_iface, flags); + num_mca = netdev_mc_count(batman_if->soft_iface); + MC_LIST_UNLOCK(batman_if->soft_iface, flags); + } - /* keep old buffer if kmalloc should fail */ + if (atomic_read(&bat_priv->hna_local_changed) || + num_mca != batman_packet->num_mca) { + new_len = sizeof(struct batman_packet) + + (bat_priv->num_local_hna * ETH_ALEN) + + num_mca * ETH_ALEN; + new_buff = kmalloc(new_len, GFP_ATOMIC); + } + + /* + * if local hna or mca has changed but kmalloc failed + * then just keep the old buffer + */ if (new_buff) { memcpy(new_buff, batman_if->packet_buff, sizeof(struct batman_packet)); @@ -239,6 +293,13 @@ static void rebuild_batman_packet(struct bat_priv *bat_priv, batman_if->packet_buff = new_buff; batman_if->packet_len = new_len; } + + /** + * always copy mca entries (if there are any) - we have to + * traverse the list anyway, so we can just do a memcpy instead of memcmp + * for the sake of simplicity + */ + add_own_MCA(batman_packet, num_mca, batman_if->soft_iface); } void schedule_own_packet(struct batman_if *batman_if) @@ -264,9 +325,7 @@ void schedule_own_packet(struct batman_if *batman_if) if (batman_if->if_status == IF_TO_BE_ACTIVATED) batman_if->if_status = IF_ACTIVE; - /* if local hna has changed and interface is a primary interface */ - if ((atomic_read(&bat_priv->hna_local_changed)) && - (batman_if == bat_priv->primary_if)) + if (batman_if == bat_priv->primary_if) rebuild_batman_packet(bat_priv, batman_if); /** @@ -359,7 +418,8 @@ void schedule_forward_packet(struct orig_node *orig_node, send_time = forward_send_time(bat_priv); add_bat_packet_to_list(bat_priv, (unsigned char *)batman_packet, - sizeof(struct batman_packet) + hna_buff_len, + sizeof(struct batman_packet) + hna_buff_len + + batman_packet->num_mca * ETH_ALEN, if_incoming, 0, send_time); }