From: Markus Elfring <elfring(a)users.sourceforge.net>
Date: Tue, 3 Nov 2015 21:34:29 +0100
Further update suggestions were taken into account after a patch
was applied from static source code analysis.
Markus Elfring (3):
Delete an unnecessary check before the function call "batadv_softif_vlan_free_ref"
Split a condition check
Less function calls in batadv_is_ap_isolated() after error detection
net/batman-adv/translation-table.c | 29 ++++++++++++++---------------
1 file changed, 14 insertions(+), 15 deletions(-)
--
2.6.2
Hi, it's Germano from Ninux.org community.
For personal purposes, I am commenting vis.c/vis.h alfred code, at the
beginning of each function, explaining also most important local
variables (keeping in mind documentation guidelines [1])
I would like to know if you are interested in such documentation
process. If yes, I could extend this kind of work to the whole alfred
code.
Have a nice day
[1]: https://www.kernel.org/doc/Documentation/kernel-doc-nano-HOWTO.txt
So far on purging broadcast and ogm queues we temporarily give up the
spin lock of these queues to be able to cancel any scheduled forwarding
work. However this is unsafe and can lead to a general protection error
in batadv_purge_outstanding_packets().
With this patch we split the queue purging into two steps: First
removing forward packets from those queues and signaling the
cancelation. Secondly, we are actively canceling any scheduled
forwarding, wait for any running forwarding to finish and only free a
forw_packet afterwards.
Signed-off-by: Linus Lüssing <linus.luessing(a)web.de>
---
Fixes issue #168
send.c | 117 ++++++++++++++++++++++++++++++++++++++-------------------------
types.h | 1 +
2 files changed, 71 insertions(+), 47 deletions(-)
diff --git a/send.c b/send.c
index 0a0bb45..f93476b 100644
--- a/send.c
+++ b/send.c
@@ -245,6 +245,10 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work)
bat_priv = netdev_priv(soft_iface);
spin_lock_bh(&bat_priv->forw_bcast_list_lock);
+ if (hlist_unhashed(&forw_packet->list)) {
+ spin_unlock_bh(&bat_priv->forw_bcast_list_lock);
+ return;
+ }
hlist_del(&forw_packet->list);
spin_unlock_bh(&bat_priv->forw_bcast_list_lock);
@@ -293,6 +297,10 @@ void batadv_send_outstanding_bat_ogm_packet(struct work_struct *work)
delayed_work);
bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface);
spin_lock_bh(&bat_priv->forw_bat_list_lock);
+ if (hlist_unhashed(&forw_packet->list)) {
+ spin_unlock_bh(&bat_priv->forw_bat_list_lock);
+ return;
+ }
hlist_del(&forw_packet->list);
spin_unlock_bh(&bat_priv->forw_bat_list_lock);
@@ -316,13 +324,68 @@ out:
batadv_forw_packet_free(forw_packet);
}
+/**
+ * batadv_cancel_packets - Cancels a list of forward packets
+ * @forw_list: The to be canceled forward packets
+ * @canceled_list: The backup list.
+ *
+ * This canceles any scheduled forwarding packet tasks in the provided
+ * forw_list. The packets are being moved from the forw_list to the
+ * canceled_list afterwards to unhash the forward packet list pointer,
+ * allowing any already running task to notice the cancelation.
+ */
+static void batadv_cancel_packets(struct hlist_head *forw_list,
+ struct hlist_head *canceled_list,
+ const struct batadv_hard_iface *hard_iface)
+{
+ struct batadv_forw_packet *forw_packet;
+ struct hlist_node *tmp_node, *safe_tmp_node;
+
+ hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
+ forw_list, list) {
+ /* if purge_outstanding_packets() was called with an argument
+ * we delete only packets belonging to the given interface
+ */
+ if ((hard_iface) &&
+ (forw_packet->if_incoming != hard_iface))
+ continue;
+
+ hlist_del_init(&forw_packet->list);
+ hlist_add_head(&forw_packet->canceled_list, canceled_list);
+ }
+}
+
+/**
+ * batadv_canceled_packets_free - Frees canceled forward packets
+ * @head: A list of to be freed forw_packets
+ *
+ * This function canceles the scheduling of any packet in the provided list,
+ * waits for any possibly running packet forwarding thread to finish and
+ * finally, safely frees this forward packet.
+ *
+ * This function might sleep.
+ */
+static void batadv_canceled_packets_free(struct hlist_head *head)
+{
+ struct batadv_forw_packet *forw_packet;
+ struct hlist_node *tmp_node, *safe_tmp_node;
+
+ hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node, head,
+ canceled_list) {
+ cancel_delayed_work_sync(&forw_packet->delayed_work);
+
+ hlist_del(&forw_packet->canceled_list);
+ batadv_forw_packet_free(forw_packet);
+ }
+}
+
void
batadv_purge_outstanding_packets(struct batadv_priv *bat_priv,
const struct batadv_hard_iface *hard_iface)
{
- struct batadv_forw_packet *forw_packet;
- struct hlist_node *tmp_node, *safe_tmp_node;
- bool pending;
+ struct hlist_head head;
+
+ INIT_HLIST_HEAD(&head);
if (hard_iface)
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
@@ -334,53 +397,13 @@ batadv_purge_outstanding_packets(struct batadv_priv *bat_priv,
/* free bcast list */
spin_lock_bh(&bat_priv->forw_bcast_list_lock);
- hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
- &bat_priv->forw_bcast_list, list) {
- /* if purge_outstanding_packets() was called with an argument
- * we delete only packets belonging to the given interface
- */
- if ((hard_iface) &&
- (forw_packet->if_incoming != hard_iface))
- continue;
-
- spin_unlock_bh(&bat_priv->forw_bcast_list_lock);
-
- /* batadv_send_outstanding_bcast_packet() will lock the list to
- * delete the item from the list
- */
- pending = cancel_delayed_work_sync(&forw_packet->delayed_work);
- spin_lock_bh(&bat_priv->forw_bcast_list_lock);
-
- if (pending) {
- hlist_del(&forw_packet->list);
- batadv_forw_packet_free(forw_packet);
- }
- }
+ batadv_cancel_packets(&bat_priv->forw_bcast_list, &head, hard_iface);
spin_unlock_bh(&bat_priv->forw_bcast_list_lock);
/* free batman packet list */
spin_lock_bh(&bat_priv->forw_bat_list_lock);
- hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
- &bat_priv->forw_bat_list, list) {
- /* if purge_outstanding_packets() was called with an argument
- * we delete only packets belonging to the given interface
- */
- if ((hard_iface) &&
- (forw_packet->if_incoming != hard_iface))
- continue;
-
- spin_unlock_bh(&bat_priv->forw_bat_list_lock);
-
- /* send_outstanding_bat_packet() will lock the list to
- * delete the item from the list
- */
- pending = cancel_delayed_work_sync(&forw_packet->delayed_work);
- spin_lock_bh(&bat_priv->forw_bat_list_lock);
-
- if (pending) {
- hlist_del(&forw_packet->list);
- batadv_forw_packet_free(forw_packet);
- }
- }
+ batadv_cancel_packets(&bat_priv->forw_bat_list, &head, hard_iface);
spin_unlock_bh(&bat_priv->forw_bat_list_lock);
+
+ batadv_canceled_packets_free(&head);
}
diff --git a/types.h b/types.h
index aba8364..f62a35f 100644
--- a/types.h
+++ b/types.h
@@ -853,6 +853,7 @@ struct batadv_skb_cb {
*/
struct batadv_forw_packet {
struct hlist_node list;
+ struct hlist_node canceled_list;
unsigned long send_time;
uint8_t own;
struct sk_buff *skb;
--
1.7.10.4
Dropped patch #1, since it has been merged
Fixed the socket leak
Removed redundant calls to mount debugfs
Andrew Lunn (2):
alfred: Add support for network namespaces
alfred: Mount debugfs before reducing capabilities
batadv_query.c | 19 +------------------
debugfs.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
main.c | 4 ++++
vis/vis.h | 2 +-
4 files changed, 54 insertions(+), 20 deletions(-)
--
2.7.0.rc3
Based on top of Sven's last kref patchset.
Patch is untested, so would be great if Martin could verify that it at
least fixes some log spam.
If yes, not sure whether it is worth for maint though.
Cheers, Linus
As announced in A.L.F.R.E.D. issue #202 (https://www.open-mesh.org/issues/202),
I gave implementing server-to-server communication via TCP a spin.
The result is this - rather large - patch. I'd be glad for comments on the
implementation. Also, I might split this into more commits, but I think I need
ideas on how to properly separate the various parts - they mostly make sense
to me as a unit only.
A rough overview:
alfred.h:
* struct tcp_connection is new, stores socket fd, pointer to data buffer,
a counter for data already read from socket (TCP is a stream and we can't
rely on self-contained datagrams), and list management
* struct interface is extended by a socket fd for the TCP socket and
a list of "tcp_connection"s
* struct globals is extended by a "requestproto" field that stores desired
operation mode.
main.c:
* TCP operation is for now triggered by a command line flag "-t".
netsock.c:
* for each interface, a TCP socket, bound/listening, is created and teared
down along with the UDP sockets
* a list of tcp_connection sockets is kept, managed and cleared alongside
* the sockets are incorporated into the fd_set management for select()
recv.c:
* process_alfred_request() gets another argument for a socket fd. It just
gets handed over to push_data() for sending the reply over the same
socket the request came from.
* recv_alfred_stream() is new and the analog function to recv_alfred_packet().
It manages the data buffer and will act on a received packet if and when
it is completely received.
ALFRED_REQUEST, ALFRED_PUSH_DATA and ALFRED_STATUS_TXEND packets are
handled for now.
send.c:
* connect_tcp() function for setting up a new connection to a (TCP) server
* push_data() gets a new argument for a socket fd (c.f.
process_alfred_request() in recv.c). If said argument is >=0, the function
will operate on the socket rather than recvmsg() a datagram.
* sync_data() will act on requestproto configuration in globals struct and
opt to make the sync via TCP if configured to do so
* send_alfred_stream() will use connect_tcp() to create a new connection,
then send a packet analog to send_alfred_packet() and will then register
the socket to the list of "tcp_connection"s for the interface it is
currently operating upon. This way, the socket can receive a reply and
will be handled as long as it is not closed on the other end.
server.c:
* check_if_socket() will tear down the TCP server and client sockets
along with the UDP sockets
unix_sock.c:
* depending on the globals' requestproto setting, a REQUEST will be send
via TCP rather than UDP.
Testing has been only in an artificial virtual setup for now. I have some
hopes to get "mission clearance" for giving it a spin in our local
"Freifunk" setup. Even then TCP will most certainly only be used on a
handful of gateways since on the majority of nodes, reading values from
A.L.F.R.E.D. is not really needed (they are mostly push-only).
I'd be glad to hear some feedback.
-hwh
Hans-Werner Hilse (1):
alfred: implement TCP support for server-to-server communication
alfred.h | 24 +++++++++-
main.c | 8 +++-
netsock.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
recv.c | 88 ++++++++++++++++++++++++++++++++++--
send.c | 119 +++++++++++++++++++++++++++++++++++++++++++-----
server.c | 11 +++++
unix_sock.c | 8 ++++
7 files changed, 389 insertions(+), 17 deletions(-)
--
2.7.3
This patchset enables the usage of the batman-adv multicast optimizations
for scenarios involving bridges on top of e.g. bat0, too.
The first one alters the forwarding behaviour for IGMP and MLD reports
which is a prerequisite before enabling multicast optimizations in
bridged setups. It also increases the MCAST TVLV version number to 2.
More on the issue of insufficient report handling with the v1
MCAST TVLV can be found here:
http://www.open-mesh.org/projects/batman-adv/wiki/Multicast-optimizations-l…
The second patch finally enables the multicast optimizations for
bridged setups.
Along come two more patches adding according debugging facilities
to make it possible for the user to check why the multicast
optimizations might not work ideally to give hints about
what they might change about their topology.
This patchset can be found in the current linus/multicast-bridge
branch.
Cheers, Linus
-----
Changes in v12:
* Rebase to current master branch
(automatic 3-way merge, then batadv_hardif_free_ref() -> batadv_hardif_put())
* Adding Linux upstream fix to compat-sources/net/core/skbuff.c
-> "net: fix bridge multicast packet checksum validation"
(9b368814b33, present since v4.5, queued for stable)
Changes in v11:
* Rewording of commit messages (PATCH 1/4+2/4)
* Rebasing to master (solving conflict with kernel doc "return" changes)
* Updating kerneldoc to proper "Return:" syntax
* Using eth_zero_addr() over memset (fixes a new checkpatch warning)
* Changing uint8_t to u8 and uint32_t to u32 (fixes new checkpatch warnings)
* Turning some batadv_dbg() into batadv_info(), making querier presence more
visible (i.e. in dmesg too) (PATCH 3/4)
Changes in v10:
- PATCH 1/4:
* Former "[PATCH 4/4] batman-adv: Forward IGMP/MLD reports to selected querier (only)"
substituted by the interim branch "batman-adv: Always flood IGMP/MLD reports"
with the following changes:
* Increased compatibility to mcast-v1-tvlv nodes by
registering a v1 tvlv container and handler, too
(note: PATCH 2/4 needs to still unregister the handler
if the node is bridged bc. it can't "trust" v1 nodes)
* Removed skb_set_network_header() call
(extra patch pending for review for maint)
* Compared to patchset v9 this substitution makes things
compilable again for kernels < 2.6.35
- PATCH 2/4:
* Moved enum introduction of BATADV_DBG_MCAST to PATCH 3/4,
not needed in PATCH 2/4 yet
* Adjusted compat code to new compat layout
* Adjustments to batadv_mcast_mla_tvlv_update() to fit now
preceding PATCH 1/4
* bat_priv->mcast.bridged flag already introduced here
(instead of in PATCH 3/4) because we need it for the new
mcast-v1-tvlv handling
---
Interim Changlog of
"batman-adv: Always flood IGMP/MLD reports"
v1:
* Removed query snooping and state
* Squashed all three patches into one
* Renamed "batadv_mcast_tvlv_ogm_handler_v1()" to *_v2()
* Added explicit icmpv6.h include
* Rebased on top of master
-----
Interim Interim Changelog of
"batman-adv: Unicasting multicast reports to querier-node only"
v6:
* compat: copied copyright headers from original upstream c files
* compat: unified ordering in compat c files:
-> copyright header, then includes, then kernel specific functions
v5:
* Removed RFC tag: Needed exports got merged to net-next and are going to
be available with Linux 4.2
* Redid compat solution - now fully backwards compatible down to 2.6.33
v4:
* excluded bridge part from this patchset, they should
hopefully be added to net-next soon
* Added a compat solution (PATCH 3/3)
* Removed Kconfig-depends as by David's suggestion the needed parsing
functions for MLD are going to be forced built-ins even if IPv6 is
going to be built as a module
* Removed unused variable 'int ret' in batadv_mcast_is_report_ipv6()
* Adjusted to new folder structure
v3:
* Adding Kconfig-depends and #if's
(so basically adding similar dependancy constraints as the bridge code
has, except that there are no depends if batman-adv gets compiled without
multicast optimizations)
-> the case of IPv6=M and batman-adv=y is still impossible if multicast
optimizations are enabled; but I don't see the practical demand for that
either - people who use IPv6 as a module will probably also want to
use batman-adv as a module
v2:
* various bugfixes (now runtime tested, too - should(tm) work)
* added netdev+bridge mailinglists
-----
---
Changes in v9:
- PATCH 1/4:
* fix: added compat code for pr_warn_once()
* compat fix for bridge export stubs: fixes compile error
with kernels < 3.16 without bridge (snooping) support
- PATCH 2/4:
* perform updates of variables within bat_priv->mcast.querier_ipv{4,6}
individually (there's a new, third member in 4/4 which shouldn't be
overriden)
* PATCH 4/4: NEW
Changes in v8 (thanks to Simon's suggestions):
- PATCH 2/3:
* print shadowing status log of an appearing and shadowing querier, too
(the bridge-querier-existence call has an additional 10s delay
to ensure reports had their time to arrive -
the bridge-querier-port call doesn't have that)
- PATCH 3/3:
* changing debugfs output from "+" and "-" to "U/4/6" and "."
* fixing "no querier present" logic (introduced in [PATCHv7 3/3])
Changes in v7 (thanks to Simon's suggestions):
- PATCH 2/3:
* renaming old/new_querier to old/new_state
* slightly extended kerneldoc of batadv_mcast_querier_log()
* removing words "good" and "bad" from debug output
* simplified batadv_mcast_flags_log()
* assignment instead of memset in batadv_mcast_mla_tvlv_update()
and batadv_softif_init_late()
* simple struct member assignments instead of one complex struct
assigment
* removing unnecessary memcmp's
* substituting return statement for an if-block in
batadv_mcast_querier_log() and batadv_mcast_bridge_log()
* print "Unsnoopables(U)-flag" instead of just "U-flag"
- PATCH 3/3:
* use bat_priv values instead of querying bridge ABI in
batadv_mcast_flags_print_header()
Changes in v6:
* New PATCH 2/3 inserted, moving logging to separate patch
* More verbose logging added to PATCH 2/3:
Bridge and querier state changes are logged too
* upper case to lower case for kernel doc of batadv_mcast_flags_open
(PATCH 2/3)
* Adding note to kernel doc of batadv_mcast_get_bridge about
increased refcount (PATCH 1/3)
* Printing some lines about current bridge and querier state to
debugfs too (PATCH 3/3)
Changes in v5 (PATCH 2/2 only):
* s/dat_cache/mcast_flags/ in kerneldoc (copy&paste error)
Changes in v4 (PATCH 2/2 only):
* initial {ad,e}dition of this patch
Changes in v3 (PATCH 1/2 only):
* Removed "RFC" tag in title again: The stubs and new export are upstream
in net-next and therefore going to be included in 3.17
* Added some debug output:
* Two warning messages:
-> Old kernel version or no bridge IGMP/MLD snooping compiled
* New batman-adv log-level "mcast":
-> Logging mcast flag changes
(a third debugging facility, a new table for debugfs for a global
mcast flag overview will be added in a separate patch later
as discussed with Simon)
Changes in v2 (PATCH 1/2 only):
* fetching local (= on this same kernel) multicast listeners from
the bridge instead of the bat0 interface if a bridge is present
- just like ip addresses and routes should be used from br0, the
same goes for multicast listeners
* beautification of batadv_mcast_mla_br_addr_cpy(), now using already
present functions from the kernel instead of own, hackish approach
* changed names of some goto-labels (not using "skip" anymore)
* using new, third bridge multicast export (because this export is
not upstream yet, I've added the "RFC" in the title):
br_multicast_has_querier_anywhere()
* adding compat stubs for two bridge multicast exports, to make
batman-adv compile- and usable even if a 3.16 kernel was compiled
without bridge code - the stubs are supposed to be upstream in the
bridge code in 3.17 (therefore just 'compat')
* updated kerneldocs for batadv_mcast_mla_bridge_get() and
batadv_mcast_mla_softif_get()
* The two sentences in the commit message starting with "Queriers: ..."
were slightly modified to include the third bridge multicast export
This patchset makes batman-adv network namespace aware. A soft
interface can be creates in a namespace and hard interfaces added to
it. soft interfaces cannot be moved between name spaces.
The biggest change is to debugfs, which is not natively netns aware,
unlike sysfs which is. A new netns directory has been added and within
that, a directory per network name space which batman is used within.
The changes are backwards compatible, in that interfaces in the global
namespace are not placed into a subdirectory.
v2:
Added missing includes
Added missing forward declarations
Rearranged debugfs code
Fixed kernel doc
Rebased on https://git.open-mesh.org/batman-adv.git master
Andrew Lunn (4):
batman-adv: NETIF_F_NETNS_LOCAL feature to prevent netns moves
batman-adv: Create batman soft interfaces within correct netns.
batman-adv: Handle parent interfaces in a different netns
batman-adv: debugfs: Add netns support
net/batman-adv/debugfs.c | 119 ++++++++++++++++++++++++++++++++++++-
net/batman-adv/hard-interface.c | 36 ++++++++---
net/batman-adv/hard-interface.h | 3 +-
net/batman-adv/soft-interface.c | 9 ++-
net/batman-adv/soft-interface.h | 3 +-
net/batman-adv/sysfs.c | 3 +-
net/batman-adv/translation-table.c | 4 +-
7 files changed, 157 insertions(+), 20 deletions(-)
--
2.7.0.rc3