From patchwork Tue Apr 25 00:02:16 2017 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: 17012 X-Patchwork-Delegate: sw@simonwunderlich.de Return-Path: X-Original-To: patchwork@open-mesh.org Delivered-To: patchwork@open-mesh.org Received: from open-mesh.org (localhost [IPv6:::1]) by open-mesh.org (Postfix) with ESMTP id 7C82583739; Tue, 25 Apr 2017 02:03:47 +0200 (CEST) Authentication-Results: open-mesh.org; dmarc=none header.from=c0d3.blue Received-SPF: None (no SPF record) identity=mailfrom; client-ip=138.201.29.205; helo=mail.aperture-lab.de; envelope-from=linus.luessing@c0d3.blue; receiver=b.a.t.m.a.n@lists.open-mesh.org Authentication-Results: open-mesh.org; dmarc=none header.from=c0d3.blue Received: from mail.aperture-lab.de (mail.aperture-lab.de [138.201.29.205]) by open-mesh.org (Postfix) with ESMTPS id F2BEA83714 for ; Tue, 25 Apr 2017 02:03:16 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by mail.aperture-lab.de (Postfix) with ESMTP id 36B1BE0597; Tue, 25 Apr 2017 02:03:17 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at aperture-lab.de Received: from mail.aperture-lab.de ([127.0.0.1]) by localhost (mail.aperture-lab.de [127.0.0.1]) (amavisd-new, port 10025) with ESMTP id 8WEEFbTmUn7W; Tue, 25 Apr 2017 02:03:16 +0200 (CEST) Received: from localhost (unknown [IPv6:2001:67c:2d50:0:c85:8cff:fe0f:63fe]) (Authenticated sender: linus.luessing@c0d3.blue) by mail.aperture-lab.de (Postfix) with ESMTPSA; Tue, 25 Apr 2017 02:03:16 +0200 (CEST) From: =?utf-8?q?Linus_L=C3=BCssing?= To: b.a.t.m.a.n@lists.open-mesh.org Date: Tue, 25 Apr 2017 02:02:16 +0200 Message-Id: <20170425000218.23721-4-linus.luessing@c0d3.blue> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170425000218.23721-1-linus.luessing@c0d3.blue> References: <20170425000218.23721-1-linus.luessing@c0d3.blue> MIME-Version: 1.0 Subject: [B.A.T.M.A.N.] [PATCH v3 3/5] batman-adv: aggregation packet reception X-BeenThere: b.a.t.m.a.n@lists.open-mesh.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: The list for a Better Approach To Mobile Ad-hoc Networking List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: The list for a Better Approach To Mobile Ad-hoc Networking Errors-To: b.a.t.m.a.n-bounces@lists.open-mesh.org Sender: "B.A.T.M.A.N" This patch implements the de-aggregation and reception of broadcast aggregation packets, which are introduced through the new BATADV_BCAST_AGGR packet type. It enables us to receive aggregation packets consisting of any batman packet type with a broadcast ethernet destination. Signed-off-by: Linus Lüssing --- Makefile | 3 + gen-compat-autoconf.sh | 1 + net/batman-adv/Makefile | 1 + net/batman-adv/aggregation.c | 177 ++++++++++++++++++++++++++++++++++++++++ net/batman-adv/aggregation.h | 51 ++++++++++++ net/batman-adv/main.c | 9 ++ net/batman-adv/packet.h | 18 ++++ net/batman-adv/routing.c | 61 ++++++++++++++ net/batman-adv/routing.h | 2 + net/batman-adv/soft-interface.c | 6 ++ net/batman-adv/tvlv.c | 13 ++- net/batman-adv/types.h | 38 +++++++++ 12 files changed, 378 insertions(+), 2 deletions(-) create mode 100644 net/batman-adv/aggregation.c create mode 100644 net/batman-adv/aggregation.h diff --git a/Makefile b/Makefile index 1eb6821..6b9d565 100644 --- a/Makefile +++ b/Makefile @@ -29,6 +29,8 @@ export CONFIG_BATMAN_ADV_DAT=y export CONFIG_BATMAN_ADV_NC=n # B.A.T.M.A.N. multicast optimizations: export CONFIG_BATMAN_ADV_MCAST=y +# B.A.T.M.A.N. generic broadcast aggregation: +export CONFIG_BATMAN_ADV_AGGR=y # B.A.T.M.A.N. V routing algorithm (experimental): export CONFIG_BATMAN_ADV_BATMAN_V=n @@ -83,6 +85,7 @@ BUILD_FLAGS := \ CONFIG_BATMAN_ADV_DAT=$(CONFIG_BATMAN_ADV_DAT) \ CONFIG_BATMAN_ADV_NC=$(CONFIG_BATMAN_ADV_NC) \ CONFIG_BATMAN_ADV_MCAST=$(CONFIG_BATMAN_ADV_MCAST) \ + CONFIG_BATMAN_ADV_AGGR=$(CONFIG_BATMAN_ADV_AGGR) \ CONFIG_BATMAN_ADV_BATMAN_V=$(CONFIG_BATMAN_ADV_BATMAN_V) \ INSTALL_MOD_DIR=updates/ diff --git a/gen-compat-autoconf.sh b/gen-compat-autoconf.sh index cf36e55..c835a6d 100755 --- a/gen-compat-autoconf.sh +++ b/gen-compat-autoconf.sh @@ -41,6 +41,7 @@ gen_config 'CONFIG_BATMAN_ADV_DEBUG' ${CONFIG_BATMAN_ADV_DEBUG:="n"} >> "${TMP}" gen_config 'CONFIG_BATMAN_ADV_BLA' ${CONFIG_BATMAN_ADV_BLA:="y"} >> "${TMP}" gen_config 'CONFIG_BATMAN_ADV_DAT' ${CONFIG_BATMAN_ADV_DAT:="y"} >> "${TMP}" gen_config 'CONFIG_BATMAN_ADV_MCAST' ${CONFIG_BATMAN_ADV_MCAST:="y"} >> "${TMP}" +gen_config 'CONFIG_BATMAN_ADV_AGGR' ${CONFIG_BATMAN_ADV_AGGR:="y"} >> "${TMP}" gen_config 'CONFIG_BATMAN_ADV_NC' ${CONFIG_BATMAN_ADV_NC:="n"} >> "${TMP}" gen_config 'CONFIG_BATMAN_ADV_BATMAN_V' ${CONFIG_BATMAN_ADV_BATMAN_V:="n"} >> "${TMP}" diff --git a/net/batman-adv/Makefile b/net/batman-adv/Makefile index 915987b..00f3e92 100644 --- a/net/batman-adv/Makefile +++ b/net/batman-adv/Makefile @@ -17,6 +17,7 @@ # obj-$(CONFIG_BATMAN_ADV) += batman-adv.o +batman-adv-$(CONFIG_BATMAN_ADV_AGGR) += aggregation.o batman-adv-y += bat_algo.o batman-adv-y += bat_iv_ogm.o batman-adv-$(CONFIG_BATMAN_ADV_BATMAN_V) += bat_v.o diff --git a/net/batman-adv/aggregation.c b/net/batman-adv/aggregation.c new file mode 100644 index 0000000..f8b40d1 --- /dev/null +++ b/net/batman-adv/aggregation.c @@ -0,0 +1,177 @@ +/* Copyright (C) 2016 B.A.T.M.A.N. contributors: + * + * Linus Lüssing + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "aggregation.h" +#include "main.h" + +#include +#include +#include +#include +#include + +#include "tvlv.h" + +/** + * batadv_aggr_add_counter_rx - update aggregation rx statistics + * @bat_priv: the bat priv with all the soft interface information + * @skb: the skb to count + * + * Updates statistics for received aggregation packets with the given skb. + */ +void batadv_aggr_add_counter_rx(struct batadv_priv *bat_priv, + struct sk_buff *skb) +{ + batadv_inc_counter(bat_priv, BATADV_CNT_AGGR_RX); + batadv_add_counter(bat_priv, BATADV_CNT_AGGR_RX_BYTES, + skb->len + ETH_HLEN); +} + +/** + * batadv_aggr_put_ethhdr - append a mac header to skb + * @skb: the packet to append to + * @h_source: the ethernet source address to set + * + * Appends a mac header to the given skb with the ethernet source address + * set to the provided h_source and the ethernet destination address to + * a broadcast one. Furthermore, sets the ethernet type to ETH_P_BATMAN. + * + * Also sets the skb mac header pointer to the beginning of the appended mac + * header. + */ +static void batadv_aggr_put_ethhdr(struct sk_buff *skb, unsigned char *h_source) +{ + struct ethhdr *ethhdr; + + skb_reset_mac_header(skb); + + ethhdr = (struct ethhdr *)skb_put(skb, ETH_HLEN); + ethhdr->h_proto = htons(ETH_P_BATMAN); + ether_addr_copy(ethhdr->h_source, h_source); + ether_addr_copy(ethhdr->h_dest, batadv_broadcast_addr); +} + +/** + * batadv_aggr_put_batadv - append batman header and data to skb + * @skb: the packet to append to + * @data: the data to append after the batman header + * @data_len: the length of the data to append + * @packet_type: the packet type to set in the batman header + * + * First appends a batman header consisting of the given packet type and the + * compatibility version to the given skb. Then copies the given data behind + * this minimal batman header in the skb. + * + * Also sets the skb network header pointer to the beginning of the batman + * header. + */ +static void batadv_aggr_put_batadv(struct sk_buff *skb, void *data, + u16 data_len, u8 packet_type) +{ + u8 version = BATADV_COMPAT_VERSION; + u8 *pos; + + skb_reset_network_header(skb); + skb_reset_mac_len(skb); + + pos = (u8 *)skb_put(skb, sizeof(packet_type)); + *pos = packet_type; + pos = (u8 *)skb_put(skb, sizeof(version)); + *pos = version; + + pos = (u8 *)skb_put(skb, data_len); + memcpy(pos, data, data_len); +} + +/** + * batadv_aggr_tvlv_handler - process incoming aggregation tvlv container + * @bat_priv: the bat priv with all the soft interface information + * @tvlv_value: tvlv buffer containing an aggregated packet + * @tvlv_value_len: length of the aggregated packet + * @ctx: handler specific context information + * (here: recv_if, h_source and packet type of aggregated packet) + * + * De-aggregates the given, specific broadcast packet and transparently + * forwards it for broadcast packet reception. + * + * Return: NET_RX_SUCCESS on success, NET_RX_DROP otherwise. + */ +static int batadv_aggr_tvlv_handler(struct batadv_priv *bat_priv, + void *tvlv_value, u16 tvlv_value_len, + void *ctx) +{ + struct batadv_aggr_ctx *aggr_ctx = ctx; + struct batadv_hard_iface *recv_if = aggr_ctx->recv_if; + struct sk_buff *skb; + unsigned int size; + u8 version = BATADV_COMPAT_VERSION; + u8 packet_type = aggr_ctx->handler.tvlv_type; + + /* disallow aggr-in-aggr-in-... to avoid stack overflows */ + if (packet_type == BATADV_BCAST_AGGR) + return NET_RX_DROP; + + size = NET_IP_ALIGN + ETH_HLEN; + size += sizeof(packet_type) + sizeof(version); + size += tvlv_value_len; + + skb = dev_alloc_skb(size); + if (!skb) + return NET_RX_DROP; + + skb_reserve(skb, NET_IP_ALIGN); + batadv_aggr_put_ethhdr(skb, aggr_ctx->h_source); + skb_pull(skb, ETH_HLEN); + batadv_aggr_put_batadv(skb, tvlv_value, tvlv_value_len, packet_type); + + skb->protocol = htons(ETH_P_BATMAN); + skb->dev = recv_if->net_dev; + + batadv_inc_counter(bat_priv, BATADV_CNT_AGGR_PARTS_RX); + batadv_add_counter(bat_priv, BATADV_CNT_AGGR_PARTS_RX_BYTES, + skb->len + ETH_HLEN); + + return batadv_batman_skb_recv(skb, recv_if->net_dev, + &recv_if->batman_adv_ptype, NULL); +} + +/** + * batadv_aggr_mesh_init - initialise the generic aggregation engine + * @bat_priv: the bat priv with all the soft interface information + * + * Return: 0 on success or a negative error code in case of failure + */ +int batadv_aggr_mesh_init(struct batadv_priv *bat_priv) +{ + batadv_tvlv_handler_register2(bat_priv, batadv_aggr_tvlv_handler, + BATADV_BCAST_AGGR, BATADV_TVLV_ANY, 1, + BATADV_TVLV_HANDLER_MORECTX); + batadv_tvlv_container_register(bat_priv, BATADV_TVLV_AGGR, 1, NULL, 0); + + return 0; +} + +/** + * batadv_mcast_free - shutdown the generic aggregation engine + * @bat_priv: the bat priv with all the soft interface information + */ +void batadv_aggr_mesh_free(struct batadv_priv *bat_priv) +{ + batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_AGGR, 1); + batadv_tvlv_handler_unregister2(bat_priv, BATADV_BCAST_AGGR, + BATADV_TVLV_ANY, 1); +} diff --git a/net/batman-adv/aggregation.h b/net/batman-adv/aggregation.h new file mode 100644 index 0000000..5b577e6 --- /dev/null +++ b/net/batman-adv/aggregation.h @@ -0,0 +1,51 @@ +/* Copyright (C) 2016 B.A.T.M.A.N. contributors: + * + * Linus Lüssing + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef _NET_BATMAN_ADV_AGGREGATION_H_ +#define _NET_BATMAN_ADV_AGGREGATION_H_ + +#include "main.h" + +struct sk_buff; + +#ifdef CONFIG_BATMAN_ADV_AGGR + +void batadv_aggr_add_counter_rx(struct batadv_priv *bat_priv, + struct sk_buff *skb); + +int batadv_aggr_mesh_init(struct batadv_priv *bat_priv); +void batadv_aggr_mesh_free(struct batadv_priv *bat_priv); + +#else + +static inline void batadv_aggr_add_counter_rx(struct batadv_priv *bat_priv, + struct sk_buff *skb) +{ +} + +static inline int batadv_aggr_mesh_init(struct batadv_priv *bat_priv) +{ + return 0; +} + +static inline void batadv_aggr_mesh_free(struct batadv_priv *bat_priv) +{ +} + +#endif /* CONFIG_BATMAN_ADV_AGGR */ + +#endif /* _NET_BATMAN_ADV_AGGREGATION_H_ */ diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index fb381fb..28caafa 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -47,6 +47,7 @@ #include #include +#include "aggregation.h" #include "bat_algo.h" #include "bat_iv_ogm.h" #include "bat_v.h" @@ -179,6 +180,10 @@ int batadv_mesh_init(struct net_device *soft_iface) INIT_HLIST_HEAD(&bat_priv->softif_vlan_list); INIT_HLIST_HEAD(&bat_priv->tp_list); + ret = batadv_aggr_mesh_init(bat_priv); + if (ret < 0) + goto err; + ret = batadv_v_mesh_init(bat_priv); if (ret < 0) goto err; @@ -226,6 +231,7 @@ void batadv_mesh_free(struct net_device *soft_iface) batadv_gw_node_free(bat_priv); + batadv_aggr_mesh_free(bat_priv); batadv_v_mesh_free(bat_priv); batadv_nc_mesh_free(bat_priv); batadv_dat_free(bat_priv); @@ -507,6 +513,7 @@ static void batadv_recv_handler_init(void) BUILD_BUG_ON(sizeof(struct batadv_unicast_packet) != 10); BUILD_BUG_ON(sizeof(struct batadv_unicast_4addr_packet) != 18); BUILD_BUG_ON(sizeof(struct batadv_frag_packet) != 20); + BUILD_BUG_ON(sizeof(struct batadv_aggr_packet) != 4); BUILD_BUG_ON(sizeof(struct batadv_bcast_packet) != 14); BUILD_BUG_ON(sizeof(struct batadv_coded_packet) != 46); BUILD_BUG_ON(sizeof(struct batadv_unicast_tvlv_packet) != 20); @@ -533,6 +540,8 @@ static void batadv_recv_handler_init(void) batadv_rx_handler[BATADV_ICMP] = batadv_recv_icmp_packet; /* Fragmented packets */ batadv_rx_handler[BATADV_UNICAST_FRAG] = batadv_recv_frag_packet; + /* Aggregation packets */ + batadv_rx_handler[BATADV_BCAST_AGGR] = batadv_recv_aggr_packet; } int diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h index 8e8a5db..76c1901 100644 --- a/net/batman-adv/packet.h +++ b/net/batman-adv/packet.h @@ -30,6 +30,7 @@ * @BATADV_CODED: network coded packets * @BATADV_ELP: echo location packets for B.A.T.M.A.N. V * @BATADV_OGM2: originator messages for B.A.T.M.A.N. V + * @BATADV_AGGR: broadcast aggregation packets * * @BATADV_UNICAST: unicast packets carrying unicast payload traffic * @BATADV_UNICAST_FRAG: unicast packets carrying a fragment of the original @@ -46,6 +47,7 @@ enum batadv_packettype { BATADV_CODED = 0x02, BATADV_ELP = 0x03, BATADV_OGM2 = 0x04, + BATADV_BCAST_AGGR = 0x05, /* 0x40 - 0x7f: unicast */ #define BATADV_UNICAST_MIN 0x40 BATADV_UNICAST = 0x40, @@ -153,6 +155,8 @@ enum batadv_bla_claimframe { * @BATADV_TVLV_TT: translation table tvlv * @BATADV_TVLV_ROAM: roaming advertisement tvlv * @BATADV_TVLV_MCAST: multicast capability tvlv + * @BATADV_TVLV_AGGR: generic broadcast aggregation capability tvlv + * @BATADV_ANYTYPE: internal place holder for TVLV handlers, not for the "wire" */ enum batadv_tvlv_type { BATADV_TVLV_GW = 0x01, @@ -161,6 +165,8 @@ enum batadv_tvlv_type { BATADV_TVLV_TT = 0x04, BATADV_TVLV_ROAM = 0x05, BATADV_TVLV_MCAST = 0x06, + BATADV_TVLV_AGGR = 0x07, + BATADV_TVLV_ANY = 0xff, }; #pragma pack(2) @@ -455,6 +461,18 @@ struct batadv_frag_packet { }; /** + * struct batadv_aggr_packet - aggregation packet for broadcast packets + * @packet_type: batman-adv packet type, part of the general header + * @version: batman-adv protocol version, part of the genereal header + * @tvlv_len: length of tvlv data following the aggregation header + */ +struct batadv_aggr_packet { + u8 packet_type; + u8 version; /* batman version field */ + __be16 tvlv_len; +}; + +/** * struct batadv_bcast_packet - broadcast packet for network payload * @packet_type: batman-adv packet type, part of the general header * @version: batman-adv protocol version, part of the genereal header diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index e1ebe14..1d74e62 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -34,6 +34,7 @@ #include #include +#include "aggregation.h" #include "bitarray.h" #include "bridge_loop_avoidance.h" #include "distributed-arp-table.h" @@ -1155,6 +1156,66 @@ int batadv_recv_frag_packet(struct sk_buff *skb, return ret; } +/** + * batadv_recv_aggr_get_tvlv_len - get tvlv_len of an aggregation packet + * @skb: the aggregation packet to parse + * + * Return: Length of the tvlv data of the given skb on success, + * -EINVAL otherwise (i.e. packet is too short). + */ +static int batadv_recv_aggr_get_tvlv_len(struct sk_buff *skb) +{ + unsigned int tvlv_len_offset; + __be16 *tvlv_len, tvlv_len_buff; + + tvlv_len_offset = offsetof(struct batadv_aggr_packet, tvlv_len); + tvlv_len = skb_header_pointer(skb, tvlv_len_offset, + sizeof(tvlv_len_buff), &tvlv_len_buff); + + if (!tvlv_len) + return -EINVAL; + + return ntohs(*tvlv_len); +} + +/** + * batadv_recv_aggr_packet - process received aggregation packet + * @skb: the aggregation packet to process + * @recv_if: interface that the skb is received on + * + * This function de-aggregates broadcast packets from the given + * aggregation packet. + * + * Frees/consumes the provided skb. + * + * Return: NET_RX_SUCCESS on success, NET_RX_DROP otherwise. + */ +int batadv_recv_aggr_packet(struct sk_buff *skb, + struct batadv_hard_iface *recv_if) +{ + struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); + struct batadv_aggr_ctx aggr_ctx; + unsigned int tvlv_offset = sizeof(struct batadv_aggr_packet); + int tvlv_len, ret; + + aggr_ctx.recv_if = recv_if; + aggr_ctx.h_source = eth_hdr(skb)->h_source; + tvlv_len = batadv_recv_aggr_get_tvlv_len(skb); + + if (tvlv_len < 0) { + kfree_skb(skb); + return NET_RX_DROP; + } + + batadv_aggr_add_counter_rx(bat_priv, skb); + + ret = batadv_tvlv_containers_process2(bat_priv, skb, BATADV_BCAST_AGGR, + tvlv_offset, tvlv_len, &aggr_ctx); + + consume_skb(skb); + return ret; +} + int batadv_recv_bcast_packet(struct sk_buff *skb, struct batadv_hard_iface *recv_if) { diff --git a/net/batman-adv/routing.h b/net/batman-adv/routing.h index 5ede16c..7e9225a 100644 --- a/net/batman-adv/routing.h +++ b/net/batman-adv/routing.h @@ -37,6 +37,8 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, struct batadv_hard_iface *recv_if); int batadv_recv_frag_packet(struct sk_buff *skb, struct batadv_hard_iface *iface); +int batadv_recv_aggr_packet(struct sk_buff *skb, + struct batadv_hard_iface *recv_if); int batadv_recv_bcast_packet(struct sk_buff *skb, struct batadv_hard_iface *recv_if); int batadv_recv_tt_query(struct sk_buff *skb, diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index b25789a..32a34a2 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -961,6 +961,12 @@ static const struct { { "frag_rx_bytes" }, { "frag_fwd" }, { "frag_fwd_bytes" }, +#ifdef CONFIG_BATMAN_ADV_AGGR + { "aggr_rx" }, + { "aggr_rx_bytes" }, + { "aggr_parts_rx" }, + { "aggr_parts_rx_bytes" }, +#endif { "tt_request_tx" }, { "tt_request_rx" }, { "tt_response_tx" }, diff --git a/net/batman-adv/tvlv.c b/net/batman-adv/tvlv.c index 9179e87..3048ed5 100644 --- a/net/batman-adv/tvlv.c +++ b/net/batman-adv/tvlv.c @@ -87,10 +87,12 @@ batadv_tvlv_handler_get(struct batadv_priv *bat_priv, int packet_type, if (tvlv_handler_tmp->packet_type != packet_type) continue; - if (tvlv_handler_tmp->tvlv_type != tvlv_type) + if (tvlv_handler_tmp->tvlv_type != BATADV_TVLV_ANY && + tvlv_handler_tmp->tvlv_type != tvlv_type) continue; - if (tvlv_handler_tmp->tvlv_version != tvlv_version) + if (tvlv_handler_tmp->tvlv_type != BATADV_TVLV_ANY && + tvlv_handler_tmp->tvlv_version != tvlv_version) continue; if (!kref_get_unless_zero(&tvlv_handler_tmp->refcount)) @@ -430,6 +432,7 @@ static int batadv_tvlv_call_handler2(struct batadv_priv *bat_priv, u8 tvlv_version, void *tvlv_value, u16 tvlv_value_len, void *ctx) { + struct batadv_tvlv_handler_ctx *handler_ctx; struct batadv_tvlv_handler *tvlv_handler; int ret; @@ -438,6 +441,12 @@ static int batadv_tvlv_call_handler2(struct batadv_priv *bat_priv, if (!tvlv_handler) return NET_RX_DROP; + if (tvlv_handler->flags & BATADV_TVLV_HANDLER_MORECTX) { + handler_ctx = (struct batadv_tvlv_handler_ctx *)ctx; + handler_ctx->tvlv_type = tvlv_type; + handler_ctx->tvlv_version = tvlv_version; + } + ret = tvlv_handler->handler(bat_priv, tvlv_value, tvlv_value_len, ctx); tvlv_handler->flags |= BATADV_TVLV_HANDLER_CALLED; diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index e7f25a1..e9d7b99 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -556,6 +556,10 @@ struct batadv_bcast_duplist_entry { * @BATADV_CNT_FRAG_RX_BYTES: received fragment traffic bytes counter * @BATADV_CNT_FRAG_FWD: forwarded fragment traffic packet counter * @BATADV_CNT_FRAG_FWD_BYTES: forwarded fragment traffic bytes counter + * @BATADV_CNT_AGGR_RX: received aggregation traffic packet count + * @BATADV_CNT_AGGR_RX_BYTES: received aggregation traffic bytes counter + * @BATADV_CNT_AGGR_PARTS_RX: received aggregated traffic packet counter + * @BATADV_CNT_AGGR_PARTS_RX_BYTES: received aggregated bytes counter * @BATADV_CNT_TT_REQUEST_TX: transmitted tt req traffic packet counter * @BATADV_CNT_TT_REQUEST_RX: received tt req traffic packet counter * @BATADV_CNT_TT_RESPONSE_TX: transmitted tt resp traffic packet counter @@ -599,6 +603,12 @@ enum batadv_counters { BATADV_CNT_FRAG_RX_BYTES, BATADV_CNT_FRAG_FWD, BATADV_CNT_FRAG_FWD_BYTES, +#ifdef CONFIG_BATMAN_ADV_AGGR + BATADV_CNT_AGGR_RX, + BATADV_CNT_AGGR_RX_BYTES, + BATADV_CNT_AGGR_PARTS_RX, + BATADV_CNT_AGGR_PARTS_RX_BYTES, +#endif BATADV_CNT_TT_REQUEST_TX, BATADV_CNT_TT_REQUEST_RX, BATADV_CNT_TT_RESPONSE_TX, @@ -1625,16 +1635,44 @@ struct batadv_tvlv_handler { }; /** + * struct batadv_tvlv_handler_ctx - handler meta information + * @tvlv_type: type of the processed tvlv + * @tvlv_version: version of the processed tvlv + * + * This structure is provided to a tvlv handler if the + * BATADV_TVLV_HANDLER_MORECTX flag was set during registration. + */ +struct batadv_tvlv_handler_ctx { + u8 tvlv_type; + u8 tvlv_version; +}; + +/** + * struct batadv_aggr_ctx - aggregation tvlv context + * @handler: information regarding the tvlv handler itself + * @recv_if: interface the packet was received from + * @h_source: ethernet address of the neighbor the packet was received from + */ +struct batadv_aggr_ctx { + struct batadv_tvlv_handler_ctx handler; + struct batadv_hard_iface *recv_if; + unsigned char *h_source; +}; + +/** * enum batadv_tvlv_handler_flags - tvlv handler flags definitions * @BATADV_TVLV_HANDLER_CIFNOTFND: tvlv processing function will call * this handler even if its type was not found (with no data) * @BATADV_TVLV_HANDLER_CALLED: internal tvlv handling flag - the API marks * a handler as being called, so it won't be called if the * BATADV_TVLV_HANDLER_CIFNOTFND flag was set + * @BATADV_TVLV_HANDLER_MORECTX: tvlv processing function will be provided with + * handler specific context (e.g. tvlv type and version) */ enum batadv_tvlv_handler_flags { BATADV_TVLV_HANDLER_CIFNOTFND = BIT(1), BATADV_TVLV_HANDLER_CALLED = BIT(2), + BATADV_TVLV_HANDLER_MORECTX = BIT(3), }; /**