From patchwork Sat Aug 4 13:48:48 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Lindner X-Patchwork-Id: 17437 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 862BC82C43; Sat, 4 Aug 2018 15:49:44 +0200 (CEST) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=5.148.176.60; helo=s2.neomailbox.net; envelope-from=mareklindner@neomailbox.ch; receiver= Received: from s2.neomailbox.net (s2.neomailbox.net [5.148.176.60]) by open-mesh.org (Postfix) with ESMTPS id 6131082C43 for ; Sat, 4 Aug 2018 15:49:43 +0200 (CEST) From: Marek Lindner To: b.a.t.m.a.n@lists.open-mesh.org Date: Sat, 4 Aug 2018 21:48:48 +0800 Message-Id: <20180804134854.4075-2-mareklindner@neomailbox.ch> In-Reply-To: <20180804134854.4075-1-mareklindner@neomailbox.ch> References: <20180804134854.4075-1-mareklindner@neomailbox.ch> Subject: [B.A.T.M.A.N.] [PATCH v3 1/7] batman-adv: tp_meter - prevent concurrent tp_meter sessions by using workqueue X-BeenThere: b.a.t.m.a.n@lists.open-mesh.org X-Mailman-Version: 2.1.23 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 Cc: Antonio Quartulli Errors-To: b.a.t.m.a.n-bounces@lists.open-mesh.org Sender: "B.A.T.M.A.N" From: Antonio Quartulli To ensure that no more than one tp_meter session runs at the same time, use an ordered workqueue instead of spawning one kthread per session. Signed-off-by: Antonio Quartulli --- net/batman-adv/main.c | 10 ++++- net/batman-adv/tp_meter.c | 77 +++++++++++++++++++-------------------- net/batman-adv/tp_meter.h | 3 +- net/batman-adv/types.h | 3 ++ 4 files changed, 50 insertions(+), 43 deletions(-) diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 69c0d85b..cd3f1924 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -91,6 +91,10 @@ static int __init batadv_init(void) if (ret < 0) return ret; + ret = batadv_tp_meter_init(); + if (ret < 0) + goto err_tp_meter; + INIT_LIST_HEAD(&batadv_hardif_list); batadv_algo_init(); @@ -99,7 +103,6 @@ static int __init batadv_init(void) batadv_v_init(); batadv_iv_init(); batadv_nc_init(); - batadv_tp_meter_init(); batadv_event_workqueue = create_singlethread_workqueue("bat_events"); if (!batadv_event_workqueue) @@ -118,9 +121,11 @@ static int __init batadv_init(void) return 0; err_create_wq: + batadv_tp_meter_destroy(); +err_tp_meter: batadv_tt_cache_destroy(); - return -ENOMEM; + return ret; } static void __exit batadv_exit(void) @@ -138,6 +143,7 @@ static void __exit batadv_exit(void) rcu_barrier(); batadv_tt_cache_destroy(); + batadv_tp_meter_destroy(); } /** diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c index 11520de9..c0d27f7d 100644 --- a/net/batman-adv/tp_meter.c +++ b/net/batman-adv/tp_meter.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -97,6 +96,9 @@ static u8 batadv_tp_prerandom[4096] __read_mostly; +/* ordered work queue */ +static struct workqueue_struct *batadv_tp_meter_queue; + /** * batadv_tp_session_cookie() - generate session cookie based on session ids * @session: TP session identifier @@ -808,19 +810,22 @@ static int batadv_tp_wait_available(struct batadv_tp_vars *tp_vars, size_t plen) /** * batadv_tp_send() - main sending thread of a tp meter session - * @arg: address of the related tp_vars + * @work: delayed work reference of the related tp_vars * * Return: nothing, this function never returns */ -static int batadv_tp_send(void *arg) +static void batadv_tp_send(struct work_struct *work) { - struct batadv_tp_vars *tp_vars = arg; - struct batadv_priv *bat_priv = tp_vars->bat_priv; struct batadv_hard_iface *primary_if = NULL; struct batadv_orig_node *orig_node = NULL; + struct batadv_tp_vars *tp_vars; size_t payload_len, packet_len; + struct batadv_priv *bat_priv; int err = 0; + tp_vars = container_of(work, struct batadv_tp_vars, test_work); + bat_priv = tp_vars->bat_priv; + if (unlikely(tp_vars->role != BATADV_TP_SENDER)) { err = BATADV_TP_REASON_DST_UNREACHABLE; tp_vars->reason = err; @@ -901,40 +906,17 @@ static int batadv_tp_send(void *arg) batadv_tp_sender_cleanup(bat_priv, tp_vars); batadv_tp_vars_put(tp_vars); - - do_exit(0); } /** - * batadv_tp_start_kthread() - start new thread which manages the tp meter - * sender + * batadv_tp_start_work - start new thread which manages the tp meter sender * @tp_vars: the private data of the current TP meter session */ -static void batadv_tp_start_kthread(struct batadv_tp_vars *tp_vars) +static void batadv_tp_start_work(struct batadv_tp_vars *tp_vars) { - struct task_struct *kthread; - struct batadv_priv *bat_priv = tp_vars->bat_priv; - u32 session_cookie; - - kref_get(&tp_vars->refcount); - kthread = kthread_create(batadv_tp_send, tp_vars, "kbatadv_tp_meter"); - if (IS_ERR(kthread)) { - session_cookie = batadv_tp_session_cookie(tp_vars->session, - tp_vars->icmp_uid); - pr_err("batadv: cannot create tp meter kthread\n"); - batadv_tp_batctl_error_notify(BATADV_TP_REASON_MEMORY_ERROR, - tp_vars->other_end, - bat_priv, session_cookie); - - /* drop reserved reference for kthread */ - batadv_tp_vars_put(tp_vars); - - /* cleanup of failed tp meter variables */ - batadv_tp_sender_cleanup(bat_priv, tp_vars); - return; - } - - wake_up_process(kthread); + /* init work item that will actually execute the test and schedule it */ + INIT_WORK(&tp_vars->test_work, batadv_tp_send); + queue_work(batadv_tp_meter_queue, &tp_vars->test_work); } /** @@ -1053,13 +1035,10 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst, /* init work item for finished tp tests */ INIT_DELAYED_WORK(&tp_vars->finish_work, batadv_tp_sender_finish); - /* start tp kthread. This way the write() call issued from userspace can - * happily return and avoid to block + /* schedule the tp worker. This way the write() call issued from + * userspace can happily return and avoid to block */ - batadv_tp_start_kthread(tp_vars); - - /* don't return reference to new tp_vars */ - batadv_tp_vars_put(tp_vars); + batadv_tp_start_work(tp_vars); } /** @@ -1498,8 +1477,26 @@ void batadv_tp_meter_recv(struct batadv_priv *bat_priv, struct sk_buff *skb) /** * batadv_tp_meter_init() - initialize global tp_meter structures + * + * Return: 0 on success, -ENOMEM if the tp_meter queue allocation fails */ -void __init batadv_tp_meter_init(void) +int __init batadv_tp_meter_init(void) { get_random_bytes(batadv_tp_prerandom, sizeof(batadv_tp_prerandom)); + + batadv_tp_meter_queue = alloc_ordered_workqueue("bat_tp_meter", 0); + if (!batadv_tp_meter_queue) + return -ENOMEM; + + return 0; +} + +/** + * batadv_tp_meter_destroy() - destroy tp meter memory allocations + */ +void batadv_tp_meter_destroy(void) +{ + flush_workqueue(batadv_tp_meter_queue); + destroy_workqueue(batadv_tp_meter_queue); + batadv_tp_meter_queue = NULL; } diff --git a/net/batman-adv/tp_meter.h b/net/batman-adv/tp_meter.h index 68e60097..ab0bde26 100644 --- a/net/batman-adv/tp_meter.h +++ b/net/batman-adv/tp_meter.h @@ -25,7 +25,8 @@ struct sk_buff; -void batadv_tp_meter_init(void); +int batadv_tp_meter_init(void); +void batadv_tp_meter_destroy(void); void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst, u32 test_length, u32 *cookie); void batadv_tp_stop(struct batadv_priv *bat_priv, const u8 *dst, diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 343d3048..2696b093 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -1355,6 +1355,9 @@ struct batadv_tp_vars { /** @finish_work: work item for the finishing procedure */ struct delayed_work finish_work; + /** @test_work: work item for the test process */ + struct work_struct test_work; + /** @test_length: test length in milliseconds */ u32 test_length; From patchwork Sat Aug 4 13:48:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Lindner X-Patchwork-Id: 17438 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 3246D82C90; Sat, 4 Aug 2018 15:49:53 +0200 (CEST) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=5.148.176.60; helo=s2.neomailbox.net; envelope-from=mareklindner@neomailbox.ch; receiver= Received: from s2.neomailbox.net (s2.neomailbox.net [5.148.176.60]) by open-mesh.org (Postfix) with ESMTPS id BE7D88020A for ; Sat, 4 Aug 2018 15:49:51 +0200 (CEST) From: Marek Lindner To: b.a.t.m.a.n@lists.open-mesh.org Date: Sat, 4 Aug 2018 21:48:49 +0800 Message-Id: <20180804134854.4075-3-mareklindner@neomailbox.ch> In-Reply-To: <20180804134854.4075-1-mareklindner@neomailbox.ch> References: <20180804134854.4075-1-mareklindner@neomailbox.ch> Subject: [B.A.T.M.A.N.] [PATCH v3 2/7] batman-adv: tp_meter - don't check for existing session X-BeenThere: b.a.t.m.a.n@lists.open-mesh.org X-Mailman-Version: 2.1.23 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 Cc: Antonio Quartulli Errors-To: b.a.t.m.a.n-bounces@lists.open-mesh.org Sender: "B.A.T.M.A.N" From: Antonio Quartulli Since the conversion from kthread to queue worker it is not possible to run more than one "sender" session at a time. For this reason, checking if another session to the same destination is already scheduled is not useful anymore. Remove such check and allow the user to enqueue a new session to a previously targeted node. Signed-off-by: Antonio Quartulli --- net/batman-adv/tp_meter.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c index c0d27f7d..a416c36d 100644 --- a/net/batman-adv/tp_meter.c +++ b/net/batman-adv/tp_meter.c @@ -939,21 +939,7 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst, session_cookie = batadv_tp_session_cookie(session_id, icmp_uid); *cookie = session_cookie; - /* look for an already existing test towards this node */ - spin_lock_bh(&bat_priv->tp_list_lock); - tp_vars = batadv_tp_list_find(bat_priv, dst); - if (tp_vars) { - spin_unlock_bh(&bat_priv->tp_list_lock); - batadv_tp_vars_put(tp_vars); - batadv_dbg(BATADV_DBG_TP_METER, bat_priv, - "Meter: test to or from the same node already ongoing, aborting\n"); - batadv_tp_batctl_error_notify(BATADV_TP_REASON_ALREADY_ONGOING, - dst, bat_priv, session_cookie); - return; - } - if (!atomic_add_unless(&bat_priv->tp_num, 1, BATADV_TP_MAX_NUM)) { - spin_unlock_bh(&bat_priv->tp_list_lock); batadv_dbg(BATADV_DBG_TP_METER, bat_priv, "Meter: too many ongoing sessions, aborting (SEND)\n"); batadv_tp_batctl_error_notify(BATADV_TP_REASON_TOO_MANY, dst, @@ -963,10 +949,6 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst, tp_vars = kmalloc(sizeof(*tp_vars), GFP_ATOMIC); if (!tp_vars) { - spin_unlock_bh(&bat_priv->tp_list_lock); - batadv_dbg(BATADV_DBG_TP_METER, bat_priv, - "Meter: %s cannot allocate list elements\n", - __func__); batadv_tp_batctl_error_notify(BATADV_TP_REASON_MEMORY_ERROR, dst, bat_priv, session_cookie); return; @@ -1021,6 +1003,7 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst, spin_lock_init(&tp_vars->prerandom_lock); kref_get(&tp_vars->refcount); + spin_lock_bh(&bat_priv->tp_list_lock); hlist_add_head_rcu(&tp_vars->list, &bat_priv->tp_list); spin_unlock_bh(&bat_priv->tp_list_lock); From patchwork Sat Aug 4 13:48:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Lindner X-Patchwork-Id: 17439 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 418F482C62; Sat, 4 Aug 2018 15:50:03 +0200 (CEST) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=5.148.176.60; helo=s2.neomailbox.net; envelope-from=mareklindner@neomailbox.ch; receiver= Received: from s2.neomailbox.net (s2.neomailbox.net [5.148.176.60]) by open-mesh.org (Postfix) with ESMTPS id 178BF82C62 for ; Sat, 4 Aug 2018 15:50:01 +0200 (CEST) From: Marek Lindner To: b.a.t.m.a.n@lists.open-mesh.org Date: Sat, 4 Aug 2018 21:48:50 +0800 Message-Id: <20180804134854.4075-4-mareklindner@neomailbox.ch> In-Reply-To: <20180804134854.4075-1-mareklindner@neomailbox.ch> References: <20180804134854.4075-1-mareklindner@neomailbox.ch> Subject: [B.A.T.M.A.N.] [PATCH v3 3/7] batman-adv: tp_meter - allow up to 10 queued sessions X-BeenThere: b.a.t.m.a.n@lists.open-mesh.org X-Mailman-Version: 2.1.23 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 Cc: Marek Lindner Errors-To: b.a.t.m.a.n-bounces@lists.open-mesh.org Sender: "B.A.T.M.A.N" Signed-off-by: Marek Lindner --- net/batman-adv/main.h | 6 ++++-- net/batman-adv/tp_meter.c | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index 8da3c933..89dfaf87 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h @@ -137,9 +137,11 @@ #define BATADV_NC_NODE_TIMEOUT 10000 /* Milliseconds */ /** - * BATADV_TP_MAX_NUM - maximum number of simultaneously active tp sessions + * BATADV_TP_MAX_NUM_QUEUE - maximum number of queued (outgoing) tp sessions + * BATADV_TP_MAX_NUM_RECV - maximum number of simultaneous receiving streams */ -#define BATADV_TP_MAX_NUM 5 +#define BATADV_TP_MAX_NUM_QUEUE 10 +#define BATADV_TP_MAX_NUM_RECV 1 /** * enum batadv_mesh_state - State of a soft interface diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c index a416c36d..e89d3942 100644 --- a/net/batman-adv/tp_meter.c +++ b/net/batman-adv/tp_meter.c @@ -939,7 +939,7 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst, session_cookie = batadv_tp_session_cookie(session_id, icmp_uid); *cookie = session_cookie; - if (!atomic_add_unless(&bat_priv->tp_num, 1, BATADV_TP_MAX_NUM)) { + if (!atomic_add_unless(&bat_priv->tp_num, 1, BATADV_TP_MAX_NUM_QUEUE)) { batadv_dbg(BATADV_DBG_TP_METER, bat_priv, "Meter: too many ongoing sessions, aborting (SEND)\n"); batadv_tp_batctl_error_notify(BATADV_TP_REASON_TOO_MANY, dst, @@ -1313,7 +1313,7 @@ batadv_tp_init_recv(struct batadv_priv *bat_priv, if (tp_vars) goto out_unlock; - if (!atomic_add_unless(&bat_priv->tp_num, 1, BATADV_TP_MAX_NUM)) { + if (!atomic_add_unless(&bat_priv->tp_num, 1, BATADV_TP_MAX_NUM_RECV)) { batadv_dbg(BATADV_DBG_TP_METER, bat_priv, "Meter: too many ongoing sessions, aborting (RECV)\n"); goto out_unlock; From patchwork Sat Aug 4 13:48:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Lindner X-Patchwork-Id: 17440 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 35D6C82C87; Sat, 4 Aug 2018 15:50:09 +0200 (CEST) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=5.148.176.60; helo=s2.neomailbox.net; envelope-from=mareklindner@neomailbox.ch; receiver= Received: from s2.neomailbox.net (s2.neomailbox.net [5.148.176.60]) by open-mesh.org (Postfix) with ESMTPS id 097D182C87 for ; Sat, 4 Aug 2018 15:50:07 +0200 (CEST) From: Marek Lindner To: b.a.t.m.a.n@lists.open-mesh.org Date: Sat, 4 Aug 2018 21:48:51 +0800 Message-Id: <20180804134854.4075-5-mareklindner@neomailbox.ch> In-Reply-To: <20180804134854.4075-1-mareklindner@neomailbox.ch> References: <20180804134854.4075-1-mareklindner@neomailbox.ch> Subject: [B.A.T.M.A.N.] [PATCH v3 4/7] batman-adv: tp_meter - add caller distinction X-BeenThere: b.a.t.m.a.n@lists.open-mesh.org X-Mailman-Version: 2.1.23 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 Cc: Marek Lindner Errors-To: b.a.t.m.a.n-bounces@lists.open-mesh.org Sender: "B.A.T.M.A.N" The throughput meter can be called from user space as well as from the batman-adv kernel module itself. Add infrastructure to handle the different callers. Signed-off-by: Marek Lindner --- net/batman-adv/netlink.c | 3 +- net/batman-adv/tp_meter.c | 108 ++++++++++++++++++++++---------------- net/batman-adv/tp_meter.h | 3 +- net/batman-adv/types.h | 13 +++++ 4 files changed, 79 insertions(+), 48 deletions(-) diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c index 0d9459b6..b0e1b73c 100644 --- a/net/batman-adv/netlink.c +++ b/net/batman-adv/netlink.c @@ -378,7 +378,8 @@ batadv_netlink_tp_meter_start(struct sk_buff *skb, struct genl_info *info) } bat_priv = netdev_priv(soft_iface); - batadv_tp_start(bat_priv, dst, test_length, &cookie); + batadv_tp_start(bat_priv, dst, test_length, &cookie, + BATADV_TP_USERSPACE); ret = batadv_netlink_tp_meter_put(msg, cookie); diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c index e89d3942..50a0e4fa 100644 --- a/net/batman-adv/tp_meter.c +++ b/net/batman-adv/tp_meter.c @@ -215,50 +215,71 @@ static void batadv_tp_update_rto(struct batadv_tp_vars *tp_vars, } /** - * batadv_tp_batctl_notify() - send client status result to client - * @reason: reason for tp meter session stop - * @dst: destination of tp_meter session + * batadv_tp_caller_notify() - send tp meter status result to caller * @bat_priv: the bat priv with all the soft interface information - * @start_time: start of transmission in jiffies - * @total_sent: bytes acked to the receiver - * @cookie: cookie of tp_meter session + * @tp_vars: the private data of the current TP meter session + * @reason: reason for tp meter session stop */ -static void batadv_tp_batctl_notify(enum batadv_tp_meter_reason reason, - const u8 *dst, struct batadv_priv *bat_priv, - unsigned long start_time, u64 total_sent, - u32 cookie) +static void batadv_tp_caller_notify(struct batadv_priv *bat_priv, + struct batadv_tp_vars *tp_vars, + enum batadv_tp_meter_reason reason) { - u32 test_time; - u8 result; u32 total_bytes; + u32 test_time; + u32 cookie; + bool reason_is_error; - if (!batadv_tp_is_error(reason)) { - result = BATADV_TP_REASON_COMPLETE; - test_time = jiffies_to_msecs(jiffies - start_time); - total_bytes = total_sent; - } else { - result = reason; - test_time = 0; - total_bytes = 0; - } + reason_is_error = batadv_tp_is_error(reason); + + switch (tp_vars->caller) { + case BATADV_TP_USERSPACE: + cookie = batadv_tp_session_cookie(tp_vars->session, + tp_vars->icmp_uid); - batadv_netlink_tpmeter_notify(bat_priv, dst, result, test_time, - total_bytes, cookie); + if (reason_is_error) { + batadv_netlink_tpmeter_notify(bat_priv, + tp_vars->other_end, + reason, 0, 0, cookie); + return; + } + + test_time = jiffies_to_msecs(jiffies - tp_vars->start_time); + total_bytes = atomic64_read(&tp_vars->tot_sent); + batadv_netlink_tpmeter_notify(bat_priv, tp_vars->other_end, + BATADV_TP_REASON_COMPLETE, + test_time, total_bytes, cookie); + + break; + case BATADV_TP_ELP: + break; + default: + break; + } } /** - * batadv_tp_batctl_error_notify() - send client error result to client + * batadv_tp_caller_init_error() - report early tp meter errors to caller + * @bat_priv: the bat priv with all the soft interface information + * @caller: caller of tp meter session (user space or ELP) * @reason: reason for tp meter session stop * @dst: destination of tp_meter session - * @bat_priv: the bat priv with all the soft interface information * @cookie: cookie of tp_meter session */ -static void batadv_tp_batctl_error_notify(enum batadv_tp_meter_reason reason, - const u8 *dst, - struct batadv_priv *bat_priv, - u32 cookie) +static void batadv_tp_caller_init_error(struct batadv_priv *bat_priv, + enum batadv_tp_meter_caller caller, + enum batadv_tp_meter_reason reason, + const u8 *dst, u32 cookie) { - batadv_tp_batctl_notify(reason, dst, bat_priv, 0, 0, cookie); + switch (caller) { + case BATADV_TP_USERSPACE: + batadv_netlink_tpmeter_notify(bat_priv, dst, reason, 0, 0, + cookie); + break; + case BATADV_TP_ELP: + break; + default: + break; + } } /** @@ -411,8 +432,6 @@ static void batadv_tp_sender_cleanup(struct batadv_priv *bat_priv, static void batadv_tp_sender_end(struct batadv_priv *bat_priv, struct batadv_tp_vars *tp_vars) { - u32 session_cookie; - batadv_dbg(BATADV_DBG_TP_METER, bat_priv, "Test towards %pM finished..shutting down (reason=%d)\n", tp_vars->other_end, tp_vars->reason); @@ -425,15 +444,7 @@ static void batadv_tp_sender_end(struct batadv_priv *bat_priv, "Final values: cwnd=%u ss_threshold=%u\n", tp_vars->cwnd, tp_vars->ss_threshold); - session_cookie = batadv_tp_session_cookie(tp_vars->session, - tp_vars->icmp_uid); - - batadv_tp_batctl_notify(tp_vars->reason, - tp_vars->other_end, - bat_priv, - tp_vars->start_time, - atomic64_read(&tp_vars->tot_sent), - session_cookie); + batadv_tp_caller_notify(bat_priv, tp_vars, tp_vars->reason); } /** @@ -925,9 +936,11 @@ static void batadv_tp_start_work(struct batadv_tp_vars *tp_vars) * @dst: the receiver MAC address * @test_length: test length in milliseconds * @cookie: session cookie + * @caller: caller of tp meter session (user space or ELP) */ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst, - u32 test_length, u32 *cookie) + u32 test_length, u32 *cookie, + enum batadv_tp_meter_caller caller) { struct batadv_tp_vars *tp_vars; u8 session_id[2]; @@ -942,15 +955,17 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst, if (!atomic_add_unless(&bat_priv->tp_num, 1, BATADV_TP_MAX_NUM_QUEUE)) { batadv_dbg(BATADV_DBG_TP_METER, bat_priv, "Meter: too many ongoing sessions, aborting (SEND)\n"); - batadv_tp_batctl_error_notify(BATADV_TP_REASON_TOO_MANY, dst, - bat_priv, session_cookie); + batadv_tp_caller_init_error(bat_priv, caller, + BATADV_TP_REASON_TOO_MANY, dst, + session_cookie); return; } tp_vars = kmalloc(sizeof(*tp_vars), GFP_ATOMIC); if (!tp_vars) { - batadv_tp_batctl_error_notify(BATADV_TP_REASON_MEMORY_ERROR, - dst, bat_priv, session_cookie); + batadv_tp_caller_init_error(bat_priv, caller, + BATADV_TP_REASON_MEMORY_ERROR, dst, + session_cookie); return; } @@ -958,6 +973,7 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst, ether_addr_copy(tp_vars->other_end, dst); kref_init(&tp_vars->refcount); tp_vars->role = BATADV_TP_SENDER; + tp_vars->caller = caller; atomic_set(&tp_vars->sending, 1); memcpy(tp_vars->session, session_id, sizeof(session_id)); tp_vars->icmp_uid = icmp_uid; diff --git a/net/batman-adv/tp_meter.h b/net/batman-adv/tp_meter.h index ab0bde26..3b11a3e9 100644 --- a/net/batman-adv/tp_meter.h +++ b/net/batman-adv/tp_meter.h @@ -28,7 +28,8 @@ struct sk_buff; int batadv_tp_meter_init(void); void batadv_tp_meter_destroy(void); void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst, - u32 test_length, u32 *cookie); + u32 test_length, u32 *cookie, + enum batadv_tp_meter_caller caller); void batadv_tp_stop(struct batadv_priv *bat_priv, const u8 *dst, u8 return_value); void batadv_tp_meter_recv(struct batadv_priv *bat_priv, struct sk_buff *skb); diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 2696b093..56034b54 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -1324,6 +1324,16 @@ enum batadv_tp_meter_role { BATADV_TP_SENDER }; +/** + * enum batadv_tp_meter_caller - initiator of the tp meter session + * @BATADV_TP_USERSPACE: initiated by user space + * @BATADV_TP_ELP: initiated by ELP + */ +enum batadv_tp_meter_caller { + BATADV_TP_USERSPACE, + BATADV_TP_ELP +}; + /** * struct batadv_tp_vars - tp meter private variables per session */ @@ -1346,6 +1356,9 @@ struct batadv_tp_vars { /** @role: receiver/sender modi */ enum batadv_tp_meter_role role; + /** @caller: caller of tp meter session (user space or ELP) */ + enum batadv_tp_meter_caller caller; + /** @sending: sending binary semaphore: 1 if sending, 0 is not */ atomic_t sending; From patchwork Sat Aug 4 13:48:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Lindner X-Patchwork-Id: 17441 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 445AA82C7E; Sat, 4 Aug 2018 15:50:16 +0200 (CEST) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=5.148.176.60; helo=s2.neomailbox.net; envelope-from=mareklindner@neomailbox.ch; receiver= Received: from s2.neomailbox.net (s2.neomailbox.net [5.148.176.60]) by open-mesh.org (Postfix) with ESMTPS id 6508680967 for ; Sat, 4 Aug 2018 15:50:12 +0200 (CEST) From: Marek Lindner To: b.a.t.m.a.n@lists.open-mesh.org Date: Sat, 4 Aug 2018 21:48:52 +0800 Message-Id: <20180804134854.4075-6-mareklindner@neomailbox.ch> In-Reply-To: <20180804134854.4075-1-mareklindner@neomailbox.ch> References: <20180804134854.4075-1-mareklindner@neomailbox.ch> Subject: [B.A.T.M.A.N.] [PATCH v3 5/7] batman-adv: tp_meter - add option to perform one-hop test X-BeenThere: b.a.t.m.a.n@lists.open-mesh.org X-Mailman-Version: 2.1.23 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 Cc: Antonio Quartulli Errors-To: b.a.t.m.a.n-bounces@lists.open-mesh.org Sender: "B.A.T.M.A.N" From: Antonio Quartulli A link test is a TP session ran over a specific one-hop link, rather than towards an originator in the mesh. Signed-off-by: Antonio Quartulli --- include/uapi/linux/batadv_packet.h | 2 + net/batman-adv/netlink.c | 2 +- net/batman-adv/routing.c | 6 +- net/batman-adv/tp_meter.c | 232 +++++++++++++++++++---------- net/batman-adv/tp_meter.h | 5 +- net/batman-adv/types.h | 3 + 6 files changed, 167 insertions(+), 83 deletions(-) diff --git a/include/uapi/linux/batadv_packet.h b/include/uapi/linux/batadv_packet.h index 894d8d2f..4e6e075b 100644 --- a/include/uapi/linux/batadv_packet.h +++ b/include/uapi/linux/batadv_packet.h @@ -351,10 +351,12 @@ struct batadv_icmp_tp_packet { * enum batadv_icmp_tp_subtype - ICMP TP Meter packet subtypes * @BATADV_TP_MSG: Msg from sender to receiver * @BATADV_TP_ACK: acknowledgment from receiver to sender + * @BATADV_TP_MSG_LINK: Msg from sender to receiver used for link test (one-hop) */ enum batadv_icmp_tp_subtype { BATADV_TP_MSG = 0, BATADV_TP_ACK, + BATADV_TP_MSG_LINK, }; #define BATADV_RR_LEN 16 diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c index b0e1b73c..064020cc 100644 --- a/net/batman-adv/netlink.c +++ b/net/batman-adv/netlink.c @@ -378,7 +378,7 @@ batadv_netlink_tp_meter_start(struct sk_buff *skb, struct genl_info *info) } bat_priv = netdev_priv(soft_iface); - batadv_tp_start(bat_priv, dst, test_length, &cookie, + batadv_tp_start(bat_priv, dst, NULL, test_length, &cookie, BATADV_TP_USERSPACE); ret = batadv_netlink_tp_meter_put(msg, cookie); diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index cc3ed93a..dbf2d556 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -223,12 +223,14 @@ bool batadv_check_management_packet(struct sk_buff *skb, /** * batadv_recv_my_icmp_packet() - receive an icmp packet locally * @bat_priv: the bat priv with all the soft interface information + * @recv_if: interface that the skb is received on * @skb: icmp packet to process * * Return: NET_RX_SUCCESS if the packet has been consumed or NET_RX_DROP * otherwise. */ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv, + struct batadv_hard_iface *recv_if, struct sk_buff *skb) { struct batadv_hard_iface *primary_if = NULL; @@ -281,7 +283,7 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv, if (!pskb_may_pull(skb, sizeof(struct batadv_icmp_tp_packet))) goto out; - batadv_tp_meter_recv(bat_priv, skb); + batadv_tp_meter_recv(bat_priv, recv_if, skb); ret = NET_RX_SUCCESS; /* skb was consumed */ skb = NULL; @@ -418,7 +420,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb, /* packet for me */ if (batadv_is_my_mac(bat_priv, icmph->dst)) - return batadv_recv_my_icmp_packet(bat_priv, skb); + return batadv_recv_my_icmp_packet(bat_priv, recv_if, skb); /* TTL exceeded */ if (icmph->ttl < 2) diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c index 50a0e4fa..87aaeb1d 100644 --- a/net/batman-adv/tp_meter.c +++ b/net/batman-adv/tp_meter.c @@ -381,6 +381,9 @@ static void batadv_tp_vars_release(struct kref *ref) } spin_unlock_bh(&tp_vars->unacked_lock); + if (tp_vars->hardif_neigh) + batadv_hardif_neigh_put(tp_vars->hardif_neigh); + kfree_rcu(tp_vars, rcu); } @@ -579,9 +582,8 @@ static void batadv_tp_fill_prerandom(struct batadv_tp_vars *tp_vars, /** * batadv_tp_send_msg() - send a single message + * @bat_priv: the bat priv with all the soft interface information * @tp_vars: the private TP meter data for this session - * @src: source mac address - * @orig_node: the originator of the destination * @seqno: sequence number of this packet * @len: length of the entire packet * @session: session identifier @@ -594,26 +596,56 @@ static void batadv_tp_fill_prerandom(struct batadv_tp_vars *tp_vars, * not reachable, BATADV_TP_REASON_MEMORY_ERROR if the packet couldn't be * allocated */ -static int batadv_tp_send_msg(struct batadv_tp_vars *tp_vars, const u8 *src, - struct batadv_orig_node *orig_node, - u32 seqno, size_t len, const u8 *session, - int uid, u32 timestamp) +static int batadv_tp_send_msg(struct batadv_priv *bat_priv, + struct batadv_tp_vars *tp_vars, u32 seqno, + size_t len, const u8 *session, int uid, + u32 timestamp) { + struct batadv_hard_iface *primary_if = NULL; + struct batadv_orig_node *orig_node = NULL; struct batadv_icmp_tp_packet *icmp; struct sk_buff *skb; - int r; - u8 *data; + int r, ret = 0; + u8 *data, *src, *dst, subtype; + struct net_device *netdev; size_t data_len; - skb = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN); - if (unlikely(!skb)) - return BATADV_TP_REASON_MEMORY_ERROR; + /* link test */ + if (tp_vars->hardif_neigh) { + dst = tp_vars->hardif_neigh->addr; + src = tp_vars->hardif_neigh->if_incoming->net_dev->dev_addr; + subtype = BATADV_TP_MSG_LINK; + netdev = tp_vars->hardif_neigh->if_incoming->net_dev; + } else { + orig_node = batadv_orig_hash_find(bat_priv, tp_vars->other_end); + if (unlikely(!orig_node)) { + ret = BATADV_TP_REASON_DST_UNREACHABLE; + goto out; + } + + primary_if = batadv_primary_if_get_selected(bat_priv); + if (unlikely(!primary_if)) { + ret = BATADV_TP_REASON_DST_UNREACHABLE; + goto out; + } + + dst = orig_node->orig; + src = primary_if->net_dev->dev_addr; + subtype = BATADV_TP_MSG; + netdev = NULL; + } + + skb = netdev_alloc_skb_ip_align(netdev, len + ETH_HLEN); + if (unlikely(!skb)) { + ret = BATADV_TP_REASON_MEMORY_ERROR; + goto out; + } skb_reserve(skb, ETH_HLEN); icmp = skb_put(skb, sizeof(*icmp)); /* fill the icmp header */ - ether_addr_copy(icmp->dst, orig_node->orig); + ether_addr_copy(icmp->dst, dst); ether_addr_copy(icmp->orig, src); icmp->version = BATADV_COMPAT_VERSION; icmp->packet_type = BATADV_ICMP; @@ -621,7 +653,7 @@ static int batadv_tp_send_msg(struct batadv_tp_vars *tp_vars, const u8 *src, icmp->msg_type = BATADV_TP; icmp->uid = uid; - icmp->subtype = BATADV_TP_MSG; + icmp->subtype = subtype; memcpy(icmp->session, session, sizeof(icmp->session)); icmp->seqno = htonl(seqno); icmp->timestamp = htonl(timestamp); @@ -630,11 +662,23 @@ static int batadv_tp_send_msg(struct batadv_tp_vars *tp_vars, const u8 *src, data = skb_put(skb, data_len); batadv_tp_fill_prerandom(tp_vars, data, data_len); - r = batadv_send_skb_to_orig(skb, orig_node, NULL); - if (r == NET_XMIT_SUCCESS) - return 0; + if (tp_vars->hardif_neigh) + r = batadv_send_skb_packet(skb, + tp_vars->hardif_neigh->if_incoming, + dst); + else + r = batadv_send_skb_to_orig(skb, orig_node, NULL); - return BATADV_TP_REASON_CANT_SEND; + if (unlikely(r != NET_XMIT_SUCCESS)) + ret = BATADV_TP_REASON_CANT_SEND; + +out: + if (likely(primary_if)) + batadv_hardif_put(primary_if); + if (likely(orig_node)) + batadv_orig_node_put(orig_node); + + return ret; } /** @@ -653,7 +697,6 @@ static void batadv_tp_recv_ack(struct batadv_priv *bat_priv, struct batadv_tp_vars *tp_vars; size_t packet_len, mss; u32 rtt, recv_ack, cwnd; - unsigned char *dev_addr; packet_len = BATADV_TP_PLEN; mss = BATADV_TP_PLEN; @@ -675,13 +718,11 @@ static void batadv_tp_recv_ack(struct batadv_priv *bat_priv, (u32)atomic_read(&tp_vars->last_acked))) goto out; - primary_if = batadv_primary_if_get_selected(bat_priv); - if (unlikely(!primary_if)) - goto out; - - orig_node = batadv_orig_hash_find(bat_priv, icmp->orig); - if (unlikely(!orig_node)) - goto out; + if (!tp_vars->hardif_neigh) { + primary_if = batadv_primary_if_get_selected(bat_priv); + if (unlikely(!primary_if)) + goto out; + } /* update RTO with the new sampled RTT, if any */ rtt = jiffies_to_msecs(jiffies) - ntohl(icmp->timestamp); @@ -703,8 +744,11 @@ static void batadv_tp_recv_ack(struct batadv_priv *bat_priv, goto out; /* if this is the third duplicate ACK do Fast Retransmit */ - batadv_tp_send_msg(tp_vars, primary_if->net_dev->dev_addr, - orig_node, recv_ack, packet_len, + + /* if we have a hardif_neigh, it means that this is a LINK test, + * therefore use the according function + */ + batadv_tp_send_msg(bat_priv, tp_vars, recv_ack, packet_len, icmp->session, icmp->uid, jiffies_to_msecs(jiffies)); @@ -741,9 +785,7 @@ static void batadv_tp_recv_ack(struct batadv_priv *bat_priv, * immediately as specified by NewReno (see * Section 3.2 of RFC6582 for details) */ - dev_addr = primary_if->net_dev->dev_addr; - batadv_tp_send_msg(tp_vars, dev_addr, - orig_node, recv_ack, + batadv_tp_send_msg(bat_priv, tp_vars, recv_ack, packet_len, icmp->session, icmp->uid, jiffies_to_msecs(jiffies)); @@ -827,8 +869,6 @@ static int batadv_tp_wait_available(struct batadv_tp_vars *tp_vars, size_t plen) */ static void batadv_tp_send(struct work_struct *work) { - struct batadv_hard_iface *primary_if = NULL; - struct batadv_orig_node *orig_node = NULL; struct batadv_tp_vars *tp_vars; size_t payload_len, packet_len; struct batadv_priv *bat_priv; @@ -843,20 +883,6 @@ static void batadv_tp_send(struct work_struct *work) goto out; } - orig_node = batadv_orig_hash_find(bat_priv, tp_vars->other_end); - if (unlikely(!orig_node)) { - err = BATADV_TP_REASON_DST_UNREACHABLE; - tp_vars->reason = err; - goto out; - } - - primary_if = batadv_primary_if_get_selected(bat_priv); - if (unlikely(!primary_if)) { - err = BATADV_TP_REASON_DST_UNREACHABLE; - tp_vars->reason = err; - goto out; - } - /* assume that all the hard_interfaces have a correctly * configured MTU, so use the soft_iface MTU as MSS. * This might not be true and in that case the fragmentation @@ -883,10 +909,9 @@ static void batadv_tp_send(struct work_struct *work) */ packet_len = payload_len + sizeof(struct batadv_unicast_packet); - err = batadv_tp_send_msg(tp_vars, primary_if->net_dev->dev_addr, - orig_node, tp_vars->last_sent, - packet_len, - tp_vars->session, tp_vars->icmp_uid, + err = batadv_tp_send_msg(bat_priv, tp_vars, tp_vars->last_sent, + packet_len, tp_vars->session, + tp_vars->icmp_uid, jiffies_to_msecs(jiffies)); /* something went wrong during the preparation/transmission */ @@ -908,11 +933,6 @@ static void batadv_tp_send(struct work_struct *work) } out: - if (likely(primary_if)) - batadv_hardif_put(primary_if); - if (likely(orig_node)) - batadv_orig_node_put(orig_node); - batadv_tp_sender_end(bat_priv, tp_vars); batadv_tp_sender_cleanup(bat_priv, tp_vars); @@ -934,23 +954,27 @@ static void batadv_tp_start_work(struct batadv_tp_vars *tp_vars) * batadv_tp_start() - start a new tp meter session * @bat_priv: the bat priv with all the soft interface information * @dst: the receiver MAC address + * @neigh: neighbour towars which we have to run the test (one-hop test) * @test_length: test length in milliseconds * @cookie: session cookie * @caller: caller of tp meter session (user space or ELP) */ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst, + struct batadv_hardif_neigh_node *neigh, u32 test_length, u32 *cookie, enum batadv_tp_meter_caller caller) { struct batadv_tp_vars *tp_vars; u8 session_id[2]; u8 icmp_uid; - u32 session_cookie; + u32 session_cookie = 0; get_random_bytes(session_id, sizeof(session_id)); get_random_bytes(&icmp_uid, 1); - session_cookie = batadv_tp_session_cookie(session_id, icmp_uid); - *cookie = session_cookie; + if (cookie) { + session_cookie = batadv_tp_session_cookie(session_id, icmp_uid); + *cookie = session_cookie; + } if (!atomic_add_unless(&bat_priv->tp_num, 1, BATADV_TP_MAX_NUM_QUEUE)) { batadv_dbg(BATADV_DBG_TP_METER, bat_priv, @@ -971,6 +995,10 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst, /* initialize tp_vars */ ether_addr_copy(tp_vars->other_end, dst); + if (neigh) { + kref_get(&neigh->refcount); + tp_vars->hardif_neigh = neigh; + } kref_init(&tp_vars->refcount); tp_vars->role = BATADV_TP_SENDER; tp_vars->caller = caller; @@ -1132,7 +1160,7 @@ static void batadv_tp_receiver_shutdown(struct timer_list *t) /** * batadv_tp_send_ack() - send an ACK packet * @bat_priv: the bat priv with all the soft interface information - * @dst: the mac address of the destination originator + * @tp_vars: the private data of the current TP meter session * @seq: the sequence number to ACK * @timestamp: the timestamp to echo back in the ACK * @session: session identifier @@ -1141,29 +1169,42 @@ static void batadv_tp_receiver_shutdown(struct timer_list *t) * Return: 0 on success, a positive integer representing the reason of the * failure otherwise */ -static int batadv_tp_send_ack(struct batadv_priv *bat_priv, const u8 *dst, +static int batadv_tp_send_ack(struct batadv_priv *bat_priv, + struct batadv_tp_vars *tp_vars, u32 seq, __be32 timestamp, const u8 *session, int socket_index) { struct batadv_hard_iface *primary_if = NULL; - struct batadv_orig_node *orig_node; + struct batadv_orig_node *orig_node = NULL; struct batadv_icmp_tp_packet *icmp; + struct net_device *netdev = NULL; struct sk_buff *skb; + u8 *src, *dst; int r, ret; - orig_node = batadv_orig_hash_find(bat_priv, dst); - if (unlikely(!orig_node)) { - ret = BATADV_TP_REASON_DST_UNREACHABLE; - goto out; - } + if (tp_vars->hardif_neigh) { + dst = tp_vars->hardif_neigh->addr; + src = tp_vars->hardif_neigh->if_incoming->net_dev->dev_addr; + netdev = tp_vars->hardif_neigh->if_incoming->net_dev; + } else { + orig_node = batadv_orig_hash_find(bat_priv, tp_vars->other_end); + if (unlikely(!orig_node)) { + ret = BATADV_TP_REASON_DST_UNREACHABLE; + goto out; + } - primary_if = batadv_primary_if_get_selected(bat_priv); - if (unlikely(!primary_if)) { - ret = BATADV_TP_REASON_DST_UNREACHABLE; - goto out; + primary_if = batadv_primary_if_get_selected(bat_priv); + if (unlikely(!primary_if)) { + ret = BATADV_TP_REASON_DST_UNREACHABLE; + goto out; + } + + dst = orig_node->orig; + src = primary_if->net_dev->dev_addr; + netdev = NULL; } - skb = netdev_alloc_skb_ip_align(NULL, sizeof(*icmp) + ETH_HLEN); + skb = netdev_alloc_skb_ip_align(netdev, sizeof(*icmp) + ETH_HLEN); if (unlikely(!skb)) { ret = BATADV_TP_REASON_MEMORY_ERROR; goto out; @@ -1175,8 +1216,8 @@ static int batadv_tp_send_ack(struct batadv_priv *bat_priv, const u8 *dst, icmp->version = BATADV_COMPAT_VERSION; icmp->ttl = BATADV_TTL; icmp->msg_type = BATADV_TP; - ether_addr_copy(icmp->dst, orig_node->orig); - ether_addr_copy(icmp->orig, primary_if->net_dev->dev_addr); + ether_addr_copy(icmp->dst, dst); + ether_addr_copy(icmp->orig, src); icmp->uid = socket_index; icmp->subtype = BATADV_TP_ACK; @@ -1185,7 +1226,13 @@ static int batadv_tp_send_ack(struct batadv_priv *bat_priv, const u8 *dst, icmp->timestamp = timestamp; /* send the ack */ - r = batadv_send_skb_to_orig(skb, orig_node, NULL); + if (tp_vars->hardif_neigh) + r = batadv_send_skb_packet(skb, + tp_vars->hardif_neigh->if_incoming, + dst); + else + r = batadv_send_skb_to_orig(skb, orig_node, NULL); + if (unlikely(r < 0) || r == NET_XMIT_DROP) { ret = BATADV_TP_REASON_DST_UNREACHABLE; goto out; @@ -1313,14 +1360,17 @@ static void batadv_tp_ack_unordered(struct batadv_tp_vars *tp_vars) /** * batadv_tp_init_recv() - return matching or create new receiver tp_vars * @bat_priv: the bat priv with all the soft interface information + * @recv_if: interface that the skb is received on * @icmp: received icmp tp msg * * Return: corresponding tp_vars or NULL on errors */ static struct batadv_tp_vars * batadv_tp_init_recv(struct batadv_priv *bat_priv, + struct batadv_hard_iface *recv_if, const struct batadv_icmp_tp_packet *icmp) { + struct batadv_hardif_neigh_node *neigh = NULL; struct batadv_tp_vars *tp_vars; spin_lock_bh(&bat_priv->tp_list_lock); @@ -1335,15 +1385,30 @@ batadv_tp_init_recv(struct batadv_priv *bat_priv, goto out_unlock; } + /* the sender is starting a LINK test, therefore we have retrieve its + * corresponding hardif_neigh_node that we'll use later to send ACKs + * back + */ + if (icmp->subtype == BATADV_TP_MSG_LINK) { + neigh = batadv_hardif_neigh_get(recv_if, icmp->orig); + if (!neigh) { + batadv_dbg(BATADV_DBG_TP_METER, bat_priv, + "Meter: %s() can't retrieve sender neigh object for %pM\n", + __func__, icmp->orig); + goto out_unlock; + } + } + tp_vars = kmalloc(sizeof(*tp_vars), GFP_ATOMIC); if (!tp_vars) - goto out_unlock; + goto err_neigh_put; ether_addr_copy(tp_vars->other_end, icmp->orig); tp_vars->role = BATADV_TP_RECEIVER; memcpy(tp_vars->session, icmp->session, sizeof(tp_vars->session)); tp_vars->last_recv = BATADV_TP_FIRST_SEQ; tp_vars->bat_priv = bat_priv; + tp_vars->hardif_neigh = neigh; kref_init(&tp_vars->refcount); spin_lock_init(&tp_vars->unacked_lock); @@ -1356,7 +1421,10 @@ batadv_tp_init_recv(struct batadv_priv *bat_priv, timer_setup(&tp_vars->timer, batadv_tp_receiver_shutdown, 0); batadv_tp_reset_receiver_timer(tp_vars); + goto out_unlock; +err_neigh_put: + batadv_hardif_neigh_put(neigh); out_unlock: spin_unlock_bh(&bat_priv->tp_list_lock); @@ -1366,11 +1434,13 @@ batadv_tp_init_recv(struct batadv_priv *bat_priv, /** * batadv_tp_recv_msg() - process a single data message * @bat_priv: the bat priv with all the soft interface information + * @recv_if: interface that the skb is received on * @skb: the buffer containing the received packet * * Process a received TP MSG packet */ static void batadv_tp_recv_msg(struct batadv_priv *bat_priv, + struct batadv_hard_iface *recv_if, const struct sk_buff *skb) { const struct batadv_icmp_tp_packet *icmp; @@ -1385,7 +1455,7 @@ static void batadv_tp_recv_msg(struct batadv_priv *bat_priv, * first packet is lost, the tp meter does not work anymore! */ if (seqno == BATADV_TP_FIRST_SEQ) { - tp_vars = batadv_tp_init_recv(bat_priv, icmp); + tp_vars = batadv_tp_init_recv(bat_priv, recv_if, icmp); if (!tp_vars) { batadv_dbg(BATADV_DBG_TP_METER, bat_priv, "Meter: seqno != BATADV_TP_FIRST_SEQ cannot initiate connection\n"); @@ -1441,7 +1511,7 @@ static void batadv_tp_recv_msg(struct batadv_priv *bat_priv, * is going to be sent is a duplicate (the sender will count them and * possibly enter Fast Retransmit as soon as it has reached 3) */ - batadv_tp_send_ack(bat_priv, icmp->orig, tp_vars->last_recv, + batadv_tp_send_ack(bat_priv, tp_vars, tp_vars->last_recv, icmp->timestamp, icmp->session, icmp->uid); out: if (likely(tp_vars)) @@ -1451,9 +1521,12 @@ static void batadv_tp_recv_msg(struct batadv_priv *bat_priv, /** * batadv_tp_meter_recv() - main TP Meter receiving function * @bat_priv: the bat priv with all the soft interface information + * @recv_if: interface that the skb is received on * @skb: the buffer containing the received packet */ -void batadv_tp_meter_recv(struct batadv_priv *bat_priv, struct sk_buff *skb) +void batadv_tp_meter_recv(struct batadv_priv *bat_priv, + struct batadv_hard_iface *recv_if, + struct sk_buff *skb) { struct batadv_icmp_tp_packet *icmp; @@ -1461,7 +1534,8 @@ void batadv_tp_meter_recv(struct batadv_priv *bat_priv, struct sk_buff *skb) switch (icmp->subtype) { case BATADV_TP_MSG: - batadv_tp_recv_msg(bat_priv, skb); + case BATADV_TP_MSG_LINK: + batadv_tp_recv_msg(bat_priv, recv_if, skb); break; case BATADV_TP_ACK: batadv_tp_recv_ack(bat_priv, skb); diff --git a/net/batman-adv/tp_meter.h b/net/batman-adv/tp_meter.h index 3b11a3e9..3a1be483 100644 --- a/net/batman-adv/tp_meter.h +++ b/net/batman-adv/tp_meter.h @@ -28,10 +28,13 @@ struct sk_buff; int batadv_tp_meter_init(void); void batadv_tp_meter_destroy(void); void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst, + struct batadv_hardif_neigh_node *neigh, u32 test_length, u32 *cookie, enum batadv_tp_meter_caller caller); void batadv_tp_stop(struct batadv_priv *bat_priv, const u8 *dst, u8 return_value); -void batadv_tp_meter_recv(struct batadv_priv *bat_priv, struct sk_buff *skb); +void batadv_tp_meter_recv(struct batadv_priv *bat_priv, + struct batadv_hard_iface *recv_if, + struct sk_buff *skb); #endif /* _NET_BATMAN_ADV_TP_METER_H_ */ diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 56034b54..f72db6cf 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -1455,6 +1455,9 @@ struct batadv_tp_vars { /** @rcu: struct used for freeing in an RCU-safe manner */ struct rcu_head rcu; + + /** @hardif_neigh: in case of LINK test, represents the other-end */ + struct batadv_hardif_neigh_node *hardif_neigh; }; /** From patchwork Sat Aug 4 13:48:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Lindner X-Patchwork-Id: 17442 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 F2F0C82CBF; Sat, 4 Aug 2018 15:50:22 +0200 (CEST) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=5.148.176.60; helo=s2.neomailbox.net; envelope-from=mareklindner@neomailbox.ch; receiver= Received: from s2.neomailbox.net (s2.neomailbox.net [5.148.176.60]) by open-mesh.org (Postfix) with ESMTPS id 3634582CC5 for ; Sat, 4 Aug 2018 15:50:21 +0200 (CEST) From: Marek Lindner To: b.a.t.m.a.n@lists.open-mesh.org Date: Sat, 4 Aug 2018 21:48:53 +0800 Message-Id: <20180804134854.4075-7-mareklindner@neomailbox.ch> In-Reply-To: <20180804134854.4075-1-mareklindner@neomailbox.ch> References: <20180804134854.4075-1-mareklindner@neomailbox.ch> Subject: [B.A.T.M.A.N.] [PATCH v3 6/7] batman-adv: ELP - use tp meter to estimate the throughput if otherwise not available X-BeenThere: b.a.t.m.a.n@lists.open-mesh.org X-Mailman-Version: 2.1.23 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 Cc: Marek Lindner Errors-To: b.a.t.m.a.n-bounces@lists.open-mesh.org Sender: "B.A.T.M.A.N" Signed-off-by: Marek Lindner --- net/batman-adv/bat_v_elp.c | 67 ++++++++++++++++++++++++++++++++++++-- net/batman-adv/bat_v_elp.h | 21 ++++++++++++ net/batman-adv/main.h | 1 + net/batman-adv/tp_meter.c | 43 +++++++++++++++++++----- net/batman-adv/types.h | 14 ++++++++ 5 files changed, 135 insertions(+), 11 deletions(-) diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c index 71c20c1d..2d206a08 100644 --- a/net/batman-adv/bat_v_elp.c +++ b/net/batman-adv/bat_v_elp.c @@ -51,6 +51,7 @@ #include "originator.h" #include "routing.h" #include "send.h" +#include "tp_meter.h" /** * batadv_v_elp_start_timer() - restart timer for ELP periodic work @@ -67,6 +68,42 @@ static void batadv_v_elp_start_timer(struct batadv_hard_iface *hard_iface) msecs_to_jiffies(msecs)); } +/** + * batadv_v_elp_tp_start() - start a tp meter session for a neighbor + * @neigh: neighbor to run tp meter on + */ +static void batadv_v_elp_tp_start(struct batadv_hardif_neigh_node *neigh) +{ + struct batadv_hard_iface *hard_iface = neigh->if_incoming; + struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); + + neigh->bat_v.tp_meter_running = true; + batadv_tp_start(bat_priv, neigh->addr, neigh, + 1000, NULL, BATADV_TP_ELP); +} + +/** + * batadv_v_elp_tp_fail() - handle tp meter session failure + * @neigh: neighbor to run tp meter on + */ +void batadv_v_elp_tp_fail(struct batadv_hardif_neigh_node *neigh) +{ + neigh->bat_v.tp_meter_running = false; +} + +/** + * batadv_v_elp_tp_finish() - post-process tp meter results + * @neigh: neighbor tp meter on + * @throughput: tp meter throughput result + */ +void batadv_v_elp_tp_finish(struct batadv_hardif_neigh_node *neigh, + u32 throughput) +{ + neigh->bat_v.tp_meter_throughput = throughput; + neigh->bat_v.last_tp_meter_run = jiffies; + neigh->bat_v.tp_meter_running = false; +} + /** * batadv_v_elp_get_throughput() - get the throughput towards a neighbour * @neigh: the neighbour for which the throughput has to be obtained @@ -112,10 +149,13 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) */ return 0; } + + /* unsupported WiFi driver */ if (ret) - goto default_throughput; + goto fallback_throughput; + if (!(sinfo.filled & BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT))) - goto default_throughput; + goto fallback_throughput; return sinfo.expected_throughput / 100; } @@ -152,6 +192,29 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) return throughput * 10; } +fallback_throughput: + /* check the tp_meter_running flag before checking the timestamp to + * avoid a race condition where a new tp meter session is scheduled + * right after the previous tp meter session has completed. + * + * No lock is required because this is the only point where + * batadv_v_elp_tp_start() is invoked and we get here only through a + * periodic timer. This means we will never run this function + * concurrently with itself. + */ + if (!neigh->bat_v.tp_meter_running && + batadv_has_timed_out(neigh->bat_v.last_tp_meter_run, + BATADV_ELP_TP_RUN_INTERVAL)) + batadv_v_elp_tp_start(neigh); + + /* discard too old tp test results */ + if (batadv_has_timed_out(neigh->bat_v.last_tp_meter_run, + 2 * BATADV_ELP_TP_RUN_INTERVAL)) + neigh->bat_v.tp_meter_throughput = 0; + + if (neigh->bat_v.tp_meter_throughput) + return neigh->bat_v.tp_meter_throughput; + default_throughput: if (!(hard_iface->bat_v.flags & BATADV_WARNING_DEFAULT)) { batadv_info(hard_iface->soft_iface, diff --git a/net/batman-adv/bat_v_elp.h b/net/batman-adv/bat_v_elp.h index e8c7b7fd..4ffb1fde 100644 --- a/net/batman-adv/bat_v_elp.h +++ b/net/batman-adv/bat_v_elp.h @@ -21,6 +21,8 @@ #include "main.h" +#include + struct sk_buff; struct work_struct; @@ -33,4 +35,23 @@ int batadv_v_elp_packet_recv(struct sk_buff *skb, struct batadv_hard_iface *if_incoming); void batadv_v_elp_throughput_metric_update(struct work_struct *work); +#ifdef CONFIG_BATMAN_ADV_BATMAN_V + +void batadv_v_elp_tp_fail(struct batadv_hardif_neigh_node *neigh); +void batadv_v_elp_tp_finish(struct batadv_hardif_neigh_node *neigh, + u32 throughput); + +#else + +static inline void batadv_v_elp_tp_fail(struct batadv_hardif_neigh_node *neigh) +{ +} + +static inline void +batadv_v_elp_tp_finish(struct batadv_hardif_neigh_node *neigh, u32 throughput) +{ +} + +#endif /* CONFIG_BATMAN_ADV_BATMAN_V */ + #endif /* _NET_BATMAN_ADV_BAT_V_ELP_H_ */ diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index 89dfaf87..ed4ae913 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h @@ -69,6 +69,7 @@ #define BATADV_ELP_MIN_PROBE_SIZE 200 /* bytes */ #define BATADV_ELP_PROBE_MAX_TX_DIFF 100 /* milliseconds */ #define BATADV_ELP_MAX_AGE 64 +#define BATADV_ELP_TP_RUN_INTERVAL 60000 /* milliseconds */ #define BATADV_OGM_MAX_ORIGDIFF 5 #define BATADV_OGM_MAX_AGE 64 diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c index 87aaeb1d..243a03b9 100644 --- a/net/batman-adv/tp_meter.c +++ b/net/batman-adv/tp_meter.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -33,9 +33,9 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -51,6 +51,7 @@ #include #include +#include "bat_v_elp.h" #include "hard-interface.h" #include "log.h" #include "netlink.h" @@ -224,7 +225,7 @@ static void batadv_tp_caller_notify(struct batadv_priv *bat_priv, struct batadv_tp_vars *tp_vars, enum batadv_tp_meter_reason reason) { - u32 total_bytes; + u64 total_bytes; u32 test_time; u32 cookie; bool reason_is_error; @@ -251,6 +252,26 @@ static void batadv_tp_caller_notify(struct batadv_priv *bat_priv, break; case BATADV_TP_ELP: + if (reason_is_error) { + batadv_v_elp_tp_fail(tp_vars->hardif_neigh); + return; + } + + test_time = jiffies_to_msecs(jiffies - tp_vars->start_time); + if (!test_time) { + batadv_v_elp_tp_fail(tp_vars->hardif_neigh); + return; + } + + total_bytes = atomic64_read(&tp_vars->tot_sent); + + /* The following calculation includes these steps: + * - divide bytes by the test length (msecs) + * - convert result from bits/ms to 0.1Mb/s (1Mb/s==1000000b/s) + */ + total_bytes = atomic64_read(&tp_vars->tot_sent); + do_div(total_bytes, test_time * 125); + batadv_v_elp_tp_finish(tp_vars->hardif_neigh, total_bytes); break; default: break; @@ -264,11 +285,14 @@ static void batadv_tp_caller_notify(struct batadv_priv *bat_priv, * @reason: reason for tp meter session stop * @dst: destination of tp_meter session * @cookie: cookie of tp_meter session + * @hardif_neigh: neighbor towards which the test was ran (for one-hop test) */ -static void batadv_tp_caller_init_error(struct batadv_priv *bat_priv, - enum batadv_tp_meter_caller caller, - enum batadv_tp_meter_reason reason, - const u8 *dst, u32 cookie) +static void +batadv_tp_caller_init_error(struct batadv_priv *bat_priv, + enum batadv_tp_meter_caller caller, + enum batadv_tp_meter_reason reason, const u8 *dst, + u32 cookie, + struct batadv_hardif_neigh_node *hardif_neigh) { switch (caller) { case BATADV_TP_USERSPACE: @@ -276,6 +300,7 @@ static void batadv_tp_caller_init_error(struct batadv_priv *bat_priv, cookie); break; case BATADV_TP_ELP: + batadv_v_elp_tp_fail(hardif_neigh); break; default: break; @@ -981,7 +1006,7 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst, "Meter: too many ongoing sessions, aborting (SEND)\n"); batadv_tp_caller_init_error(bat_priv, caller, BATADV_TP_REASON_TOO_MANY, dst, - session_cookie); + session_cookie, neigh); return; } @@ -989,7 +1014,7 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst, if (!tp_vars) { batadv_tp_caller_init_error(bat_priv, caller, BATADV_TP_REASON_MEMORY_ERROR, dst, - session_cookie); + session_cookie, neigh); return; } diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index f72db6cf..fe763410 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -584,6 +584,20 @@ struct batadv_hardif_neigh_node_bat_v { /** @metric_work: work queue callback item for metric update */ struct work_struct metric_work; + + /** + * @tp_meter_running: tp meter measurements towards this neighbor in + * progress + */ + unsigned char tp_meter_running:1; + + /** + * @last_tp_meter_run: timestamp of last tp meter measurement completion + */ + unsigned long last_tp_meter_run; + + /** @tp_meter_throughput: throughput information measured by tp meter */ + unsigned long tp_meter_throughput; }; /** From patchwork Sat Aug 4 13:48:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Lindner X-Patchwork-Id: 17443 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 1FA6582CC5; Sat, 4 Aug 2018 15:50:28 +0200 (CEST) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=5.148.176.60; helo=s2.neomailbox.net; envelope-from=mareklindner@neomailbox.ch; receiver= Received: from s2.neomailbox.net (s2.neomailbox.net [5.148.176.60]) by open-mesh.org (Postfix) with ESMTPS id 25B6A82C76 for ; Sat, 4 Aug 2018 15:50:26 +0200 (CEST) From: Marek Lindner To: b.a.t.m.a.n@lists.open-mesh.org Date: Sat, 4 Aug 2018 21:48:54 +0800 Message-Id: <20180804134854.4075-8-mareklindner@neomailbox.ch> In-Reply-To: <20180804134854.4075-1-mareklindner@neomailbox.ch> References: <20180804134854.4075-1-mareklindner@neomailbox.ch> Subject: [B.A.T.M.A.N.] [PATCH v3 7/7] batman-adv: ELP - add throughput meter test duration attribute X-BeenThere: b.a.t.m.a.n@lists.open-mesh.org X-Mailman-Version: 2.1.23 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 Cc: Marek Lindner Errors-To: b.a.t.m.a.n-bounces@lists.open-mesh.org Sender: "B.A.T.M.A.N" When the ELP throughput meter fallback kicks in to trigger a throughput meter measurement the test duration can be configured via this attribute. Default tp test duration: 1000ms Signed-off-by: Marek Lindner --- Documentation/ABI/testing/sysfs-class-net-batman-adv | 7 +++++++ net/batman-adv/bat_v.c | 1 + net/batman-adv/bat_v_elp.c | 6 ++++-- net/batman-adv/sysfs.c | 3 +++ net/batman-adv/types.h | 3 +++ 5 files changed, 18 insertions(+), 2 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-class-net-batman-adv b/Documentation/ABI/testing/sysfs-class-net-batman-adv index 89810684..7b3974a5 100644 --- a/Documentation/ABI/testing/sysfs-class-net-batman-adv +++ b/Documentation/ABI/testing/sysfs-class-net-batman-adv @@ -6,6 +6,13 @@ Description: Defines the interval in milliseconds in which batman emits probing packets for neighbor sensing (ELP). +What: /sys/class/net//batman-adv/elp_tp_duration +Date: May 2018 +Contact: Marek Lindner +Description: + Defines measurement duration in milliseconds upon + ELP fallback throughput meter measurements. + What: /sys/class/net//batman-adv/iface_status Date: May 2010 Contact: Marek Lindner diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c index 6baec4e6..1b3a250f 100644 --- a/net/batman-adv/bat_v.c +++ b/net/batman-adv/bat_v.c @@ -1086,6 +1086,7 @@ void batadv_v_hardif_init(struct batadv_hard_iface *hard_iface) */ atomic_set(&hard_iface->bat_v.throughput_override, 0); atomic_set(&hard_iface->bat_v.elp_interval, 500); + atomic_set(&hard_iface->bat_v.elp_tp_duration, 1000); } /** diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c index 2d206a08..9a106fab 100644 --- a/net/batman-adv/bat_v_elp.c +++ b/net/batman-adv/bat_v_elp.c @@ -76,10 +76,12 @@ static void batadv_v_elp_tp_start(struct batadv_hardif_neigh_node *neigh) { struct batadv_hard_iface *hard_iface = neigh->if_incoming; struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); + u32 elp_tp_duration; neigh->bat_v.tp_meter_running = true; - batadv_tp_start(bat_priv, neigh->addr, neigh, - 1000, NULL, BATADV_TP_ELP); + elp_tp_duration = atomic_read(&hard_iface->bat_v.elp_tp_duration); + batadv_tp_start(bat_priv, neigh->addr, neigh, elp_tp_duration, + NULL, BATADV_TP_ELP); } /** diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c index f2eef43b..d8d08bfa 100644 --- a/net/batman-adv/sysfs.c +++ b/net/batman-adv/sysfs.c @@ -1128,6 +1128,8 @@ static BATADV_ATTR(iface_status, 0444, batadv_show_iface_status, NULL); #ifdef CONFIG_BATMAN_ADV_BATMAN_V BATADV_ATTR_HIF_UINT(elp_interval, bat_v.elp_interval, 0644, 2 * BATADV_JITTER, INT_MAX, NULL); +BATADV_ATTR_HIF_UINT(elp_tp_duration, bat_v.elp_tp_duration, 0644, + 1, INT_MAX, NULL); static BATADV_ATTR(throughput_override, 0644, batadv_show_throughput_override, batadv_store_throughput_override); #endif @@ -1137,6 +1139,7 @@ static struct batadv_attribute *batadv_batman_attrs[] = { &batadv_attr_iface_status, #ifdef CONFIG_BATMAN_ADV_BATMAN_V &batadv_attr_elp_interval, + &batadv_attr_elp_tp_duration, &batadv_attr_throughput_override, #endif NULL, diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index fe763410..62c9b49d 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -118,6 +118,9 @@ struct batadv_hard_iface_bat_v { /** @elp_interval: time interval between two ELP transmissions */ atomic_t elp_interval; + /** @elp_tp_duration: throughput meter fallback test duration */ + atomic_t elp_tp_duration; + /** @elp_seqno: current ELP sequence number */ atomic_t elp_seqno;